Skip to main content

buble/
types.rs

1use serde::{Deserialize, Serialize};
2use serde_json::{Map, Value};
3
4/// Common response shape for Buble media, file, and app endpoints.
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
6pub struct Envelope<T> {
7    /// Response payload.
8    pub data: T,
9}
10
11/// Lifecycle status of an asynchronous generation task.
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
13#[serde(rename_all = "snake_case")]
14pub enum TaskStatus {
15    /// Task has been accepted and is waiting to run.
16    Pending,
17    /// Provider is generating output.
18    Processing,
19    /// Generation completed successfully.
20    Success,
21    /// Generation failed.
22    Failed,
23    /// Generation was canceled.
24    Canceled,
25    /// Unknown status returned by the API.
26    #[serde(other)]
27    Unknown,
28}
29
30impl TaskStatus {
31    /// Returns true when the task is in a terminal state.
32    pub fn is_terminal(&self) -> bool {
33        matches!(self, Self::Success | Self::Failed | Self::Canceled)
34    }
35}
36
37/// API-ready media model returned by model discovery.
38#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
39pub struct MediaModel {
40    /// Stable model key.
41    pub model: String,
42    /// Human-readable name.
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub name: Option<String>,
45    /// Media type, such as `image` or `video`.
46    #[serde(default, skip_serializing_if = "Option::is_none")]
47    pub media_type: Option<String>,
48    /// Public operation modes.
49    #[serde(default, skip_serializing_if = "Vec::is_empty")]
50    pub operations: Vec<MediaModelOperation>,
51    /// Additional model metadata.
52    #[serde(flatten)]
53    pub extra: Map<String, Value>,
54}
55
56/// Public operation mode for a media model.
57#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
58pub struct MediaModelOperation {
59    /// Public mode key.
60    pub mode: String,
61    /// Optional operation description.
62    #[serde(default, skip_serializing_if = "Option::is_none")]
63    pub description: Option<String>,
64    /// Input requirements.
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    pub input: Option<Value>,
67    /// Public mode parameters.
68    #[serde(default, skip_serializing_if = "Vec::is_empty")]
69    pub parameters: Vec<MediaModelParameter>,
70    /// Additional operation metadata.
71    #[serde(flatten)]
72    pub extra: Map<String, Value>,
73}
74
75/// Request parameter accepted by a model mode.
76#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
77pub struct MediaModelParameter {
78    /// Parameter name to send at the generation request root.
79    pub name: String,
80    /// JSON value type.
81    #[serde(default, skip_serializing_if = "Option::is_none")]
82    pub r#type: Option<String>,
83    /// Display label.
84    #[serde(default, skip_serializing_if = "Option::is_none")]
85    pub label: Option<String>,
86    /// Default value.
87    #[serde(default, skip_serializing_if = "Option::is_none")]
88    pub default: Option<Value>,
89    /// Enum values.
90    #[serde(default, skip_serializing_if = "Option::is_none")]
91    pub r#enum: Option<Vec<Value>>,
92    /// Discrete values.
93    #[serde(default, skip_serializing_if = "Option::is_none")]
94    pub values: Option<Vec<Value>>,
95    /// Minimum value.
96    #[serde(default, skip_serializing_if = "Option::is_none")]
97    pub min: Option<Value>,
98    /// Maximum value.
99    #[serde(default, skip_serializing_if = "Option::is_none")]
100    pub max: Option<Value>,
101    /// Step value.
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub step: Option<Value>,
104    /// Whether this parameter is required.
105    #[serde(default)]
106    pub required: bool,
107    /// Additional parameter metadata.
108    #[serde(flatten)]
109    pub extra: Map<String, Value>,
110}
111
112/// Uploaded source asset.
113#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
114pub struct UploadedFile {
115    /// Object type.
116    pub object: String,
117    /// Storage provider.
118    pub provider: String,
119    /// Public URL to pass into generation inputs.
120    pub url: String,
121    /// Storage key.
122    pub key: String,
123    /// File type.
124    pub file_type: String,
125    /// MIME content type.
126    pub content_type: String,
127    /// File size in bytes.
128    pub size: u64,
129    /// Original filename.
130    pub filename: String,
131    /// Additional upload metadata.
132    #[serde(flatten)]
133    pub extra: Map<String, Value>,
134}
135
136/// Generated image asset.
137#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
138pub struct MediaResultImage {
139    /// Image URL.
140    pub url: String,
141    /// Additional image metadata.
142    #[serde(flatten)]
143    pub extra: Map<String, Value>,
144}
145
146/// Generated video asset.
147#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
148pub struct MediaResultVideo {
149    /// Video URL.
150    pub url: String,
151    /// Preview video URL.
152    #[serde(default, skip_serializing_if = "Option::is_none")]
153    pub preview_url: Option<String>,
154    /// Thumbnail URL.
155    #[serde(default, skip_serializing_if = "Option::is_none")]
156    pub thumbnail_url: Option<String>,
157    /// Video duration.
158    #[serde(default, skip_serializing_if = "Option::is_none")]
159    pub duration: Option<Value>,
160    /// Additional video metadata.
161    #[serde(flatten)]
162    pub extra: Map<String, Value>,
163}
164
165/// Generated audio asset.
166#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
167pub struct MediaResultAudio {
168    /// Audio URL.
169    pub url: String,
170    /// Cover image URL.
171    #[serde(default, skip_serializing_if = "Option::is_none")]
172    pub image_url: Option<String>,
173    /// Title.
174    #[serde(default, skip_serializing_if = "Option::is_none")]
175    pub title: Option<String>,
176    /// Audio duration.
177    #[serde(default, skip_serializing_if = "Option::is_none")]
178    pub duration: Option<Value>,
179    /// Additional audio metadata.
180    #[serde(flatten)]
181    pub extra: Map<String, Value>,
182}
183
184/// Generated media assets.
185#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
186pub struct GenerationResult {
187    /// Generated images.
188    #[serde(default, skip_serializing_if = "Vec::is_empty")]
189    pub images: Vec<MediaResultImage>,
190    /// Generated videos.
191    #[serde(default, skip_serializing_if = "Vec::is_empty")]
192    pub videos: Vec<MediaResultVideo>,
193    /// Generated audio files.
194    #[serde(default, skip_serializing_if = "Vec::is_empty")]
195    pub audios: Vec<MediaResultAudio>,
196    /// Additional result metadata.
197    #[serde(flatten)]
198    pub extra: Map<String, Value>,
199}
200
201/// Task-level generation error.
202#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
203pub struct GenerationTaskError {
204    /// Error code.
205    #[serde(default, skip_serializing_if = "Option::is_none")]
206    pub code: Option<String>,
207    /// Error message.
208    #[serde(default, skip_serializing_if = "Option::is_none")]
209    pub message: Option<String>,
210    /// Additional error metadata.
211    #[serde(flatten)]
212    pub extra: Map<String, Value>,
213}
214
215/// Direct media generation task.
216#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
217pub struct GenerationTask {
218    /// Task id.
219    pub id: String,
220    /// Task status.
221    pub status: TaskStatus,
222    /// Model key.
223    #[serde(default, skip_serializing_if = "Option::is_none")]
224    pub model: Option<String>,
225    /// Media type.
226    #[serde(default, skip_serializing_if = "Option::is_none")]
227    pub media_type: Option<String>,
228    /// Public mode.
229    #[serde(default, skip_serializing_if = "Option::is_none")]
230    pub mode: Option<String>,
231    /// Charged credits.
232    #[serde(default, skip_serializing_if = "Option::is_none")]
233    pub cost_credits: Option<u64>,
234    /// Created timestamp.
235    #[serde(default, skip_serializing_if = "Option::is_none")]
236    pub created_at: Option<String>,
237    /// Updated timestamp.
238    #[serde(default, skip_serializing_if = "Option::is_none")]
239    pub updated_at: Option<String>,
240    /// Generation result.
241    #[serde(default, skip_serializing_if = "Option::is_none")]
242    pub result: Option<GenerationResult>,
243    /// Task error.
244    #[serde(default, skip_serializing_if = "Option::is_none")]
245    pub error: Option<GenerationTaskError>,
246    /// Additional task metadata.
247    #[serde(flatten)]
248    pub extra: Map<String, Value>,
249}
250
251/// Callable Buble app workflow.
252#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
253pub struct PublicApp {
254    /// App id.
255    pub id: String,
256    /// Flat input parameters.
257    #[serde(default)]
258    pub input_parameters: Vec<AppInputParameter>,
259    /// Additional app metadata.
260    #[serde(flatten)]
261    pub extra: Map<String, Value>,
262}
263
264/// App input parameter.
265#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
266pub struct AppInputParameter {
267    /// Parameter name.
268    pub name: String,
269    /// JSON value type.
270    pub r#type: String,
271    /// Allowed values.
272    #[serde(default, skip_serializing_if = "Vec::is_empty")]
273    pub values: Vec<Value>,
274    /// Additional parameter metadata.
275    #[serde(flatten)]
276    pub extra: Map<String, Value>,
277}
278
279/// App generation task.
280#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
281pub struct AppGenerationTask {
282    /// Task id.
283    pub id: String,
284    /// Task status.
285    pub status: TaskStatus,
286    /// Generated media result.
287    #[serde(default, skip_serializing_if = "Option::is_none")]
288    pub result: Option<GenerationResult>,
289    /// Task error.
290    #[serde(default, skip_serializing_if = "Option::is_none")]
291    pub error: Option<GenerationTaskError>,
292    /// Additional app task metadata.
293    #[serde(flatten)]
294    pub extra: Map<String, Value>,
295}
296
297/// Callable chat model.
298#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
299pub struct ChatModel {
300    /// Stable model id.
301    pub id: String,
302    /// Object type.
303    pub object: String,
304    /// Unix creation timestamp.
305    #[serde(default, skip_serializing_if = "Option::is_none")]
306    pub created: Option<i64>,
307    /// Provider display name.
308    #[serde(default, skip_serializing_if = "Option::is_none")]
309    pub owned_by: Option<String>,
310    /// Human-readable name.
311    #[serde(default, skip_serializing_if = "Option::is_none")]
312    pub name: Option<String>,
313    /// Optional description.
314    #[serde(default, skip_serializing_if = "Option::is_none")]
315    pub description: Option<String>,
316    /// Capability flags.
317    #[serde(default, skip_serializing_if = "Map::is_empty")]
318    pub capabilities: Map<String, Value>,
319    /// Optional model tags.
320    #[serde(default, skip_serializing_if = "Vec::is_empty")]
321    pub tags: Vec<String>,
322    /// Additional model metadata.
323    #[serde(flatten)]
324    pub extra: Map<String, Value>,
325}
326
327/// OpenAI-style model list returned by chat model discovery.
328#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
329pub struct ChatModelList {
330    /// Object type.
331    pub object: String,
332    /// Chat models.
333    pub data: Vec<ChatModel>,
334}