1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
5pub enum ImageResolution {
6 #[default]
7 #[serde(rename = "1K")]
8 OneK,
9 #[serde(rename = "2K")]
10 TwoK,
11 #[serde(rename = "4K")]
12 FourK,
13}
14
15impl ImageResolution {
16 pub const fn as_str(&self) -> &str {
17 match self {
18 Self::OneK => "1K",
19 Self::TwoK => "2K",
20 Self::FourK => "4K",
21 }
22 }
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
26pub enum AspectRatio {
27 #[default]
28 #[serde(rename = "1:1")]
29 Square,
30 #[serde(rename = "16:9")]
31 Landscape169,
32 #[serde(rename = "9:16")]
33 Portrait916,
34 #[serde(rename = "4:3")]
35 Landscape43,
36 #[serde(rename = "3:4")]
37 Portrait34,
38 #[serde(rename = "21:9")]
39 UltraWide,
40}
41
42impl AspectRatio {
43 pub const fn as_str(&self) -> &str {
44 match self {
45 Self::Square => "1:1",
46 Self::Landscape169 => "16:9",
47 Self::Portrait916 => "9:16",
48 Self::Landscape43 => "4:3",
49 Self::Portrait34 => "3:4",
50 Self::UltraWide => "21:9",
51 }
52 }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct ImageGenerationRequest {
57 pub prompt: String,
58 pub model: Option<String>,
59 #[serde(default)]
60 pub resolution: ImageResolution,
61 #[serde(default)]
62 pub aspect_ratio: AspectRatio,
63 #[serde(default)]
64 pub reference_images: Vec<ReferenceImage>,
65 #[serde(default)]
66 pub enable_search_grounding: bool,
67 #[serde(default)]
68 pub user_id: Option<String>,
69 #[serde(default)]
70 pub session_id: Option<String>,
71 #[serde(default)]
72 pub trace_id: Option<String>,
73 #[serde(default)]
74 pub mcp_execution_id: Option<String>,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct ReferenceImage {
79 pub data: String,
80 pub mime_type: String,
81 pub description: Option<String>,
82}
83
84#[derive(Debug)]
85pub struct NewImageGenerationResponse {
86 pub provider: String,
87 pub model: String,
88 pub image_data: String,
89 pub mime_type: String,
90 pub resolution: ImageResolution,
91 pub aspect_ratio: AspectRatio,
92 pub generation_time_ms: u64,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct ImageGenerationResponse {
97 pub id: String,
98 pub request_id: String,
99 pub provider: String,
100 pub model: String,
101 pub image_data: String,
102 pub mime_type: String,
103 pub file_path: Option<String>,
104 pub public_url: Option<String>,
105 pub file_size_bytes: Option<usize>,
106 pub resolution: ImageResolution,
107 pub aspect_ratio: AspectRatio,
108 pub generation_time_ms: u64,
109 pub cost_estimate: Option<f32>,
110 pub created_at: chrono::DateTime<chrono::Utc>,
111}
112
113impl ImageGenerationResponse {
114 pub fn new(params: NewImageGenerationResponse) -> Self {
115 Self {
116 id: Uuid::new_v4().to_string(),
117 request_id: Uuid::new_v4().to_string(),
118 provider: params.provider,
119 model: params.model,
120 image_data: params.image_data,
121 mime_type: params.mime_type,
122 file_path: None,
123 public_url: None,
124 file_size_bytes: None,
125 resolution: params.resolution,
126 aspect_ratio: params.aspect_ratio,
127 generation_time_ms: params.generation_time_ms,
128 cost_estimate: None,
129 created_at: chrono::Utc::now(),
130 }
131 }
132}
133
134#[derive(Debug, Clone, Serialize, Deserialize)]
135pub struct GeneratedImageRecord {
136 pub uuid: String,
137 pub request_id: String,
138 pub prompt: String,
139 pub model: String,
140 pub provider: String,
141 pub file_path: String,
142 pub public_url: String,
143 pub file_size_bytes: Option<i32>,
144 pub mime_type: String,
145 pub resolution: Option<String>,
146 pub aspect_ratio: Option<String>,
147 pub generation_time_ms: Option<i32>,
148 pub cost_estimate: Option<f32>,
149 pub user_id: Option<String>,
150 pub session_id: Option<String>,
151 pub trace_id: Option<String>,
152 pub created_at: chrono::DateTime<chrono::Utc>,
153 pub expires_at: Option<chrono::DateTime<chrono::Utc>>,
154 pub deleted_at: Option<chrono::DateTime<chrono::Utc>>,
155}