1use std::collections::HashMap;
4
5use futures::Stream;
6use serde::{Deserialize, Serialize};
7use std::pin::Pin;
8use ts_rs::TS;
9
10use crate::error::AiMuxError;
11use crate::shared::FileData;
12use crate::stream_part::StreamPart;
13use crate::types::{FinishReason, ProviderMetadata, ResponseMetadata, Usage, Warning};
14
15use serde_json::Value;
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
19#[ts(export)]
20pub enum GenerateContent {
21 Text {
23 text: String,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 provider_metadata: Option<ProviderMetadata>,
26 },
27 ToolCall {
29 tool_call_id: String,
30 tool_name: String,
31 input: serde_json::Value,
32 #[serde(default, skip_serializing_if = "Option::is_none")]
35 provider_executed: Option<bool>,
36 #[serde(default, skip_serializing_if = "Option::is_none")]
38 dynamic: Option<bool>,
39 #[serde(default, skip_serializing_if = "Option::is_none")]
43 thought_signature: Option<String>,
44 #[serde(default, skip_serializing_if = "Option::is_none")]
46 provider_metadata: Option<ProviderMetadata>,
47 },
48 Source {
50 id: String,
51 source_type: String,
52 url: Option<String>,
53 title: Option<String>,
54 #[serde(default, skip_serializing_if = "Option::is_none")]
55 provider_metadata: Option<ProviderMetadata>,
56 },
57 Reasoning {
63 text: String,
64 provider_metadata: Option<ProviderMetadata>,
65 },
66 File {
71 data: FileData,
72 media_type: String,
73 #[serde(default, skip_serializing_if = "Option::is_none")]
74 provider_metadata: Option<ProviderMetadata>,
75 },
76 ToolResult {
80 tool_call_id: String,
81 tool_name: String,
82 result: Value,
83 #[serde(default, skip_serializing_if = "Option::is_none")]
85 is_error: Option<bool>,
86 #[serde(default, skip_serializing_if = "Option::is_none")]
88 preliminary: Option<bool>,
89 #[serde(default, skip_serializing_if = "Option::is_none")]
91 dynamic: Option<bool>,
92 #[serde(default, skip_serializing_if = "Option::is_none")]
94 provider_metadata: Option<ProviderMetadata>,
95 },
96}
97
98#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
106#[ts(export)]
107pub struct ReasoningPart {
108 pub text: String,
110}
111
112#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
114#[ts(export)]
115pub struct SourcePart {
116 pub id: String,
117 pub source_type: String,
118 #[serde(default, skip_serializing_if = "Option::is_none")]
119 pub url: Option<String>,
120 #[serde(default, skip_serializing_if = "Option::is_none")]
121 pub title: Option<String>,
122}
123
124#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
126#[ts(export)]
127pub struct FilePart {
128 pub data: FileData,
129 pub media_type: String,
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize, TS)]
136#[ts(export)]
137pub struct StreamTextResultAggregated {
138 pub text: String,
140 #[serde(default)]
142 pub reasoning: Vec<ReasoningPart>,
143 #[serde(default)]
145 pub reasoning_text: String,
146 #[serde(default)]
148 pub tool_calls: Vec<crate::tool::ToolCall>,
149 #[serde(default)]
151 pub sources: Vec<SourcePart>,
152 #[serde(default)]
154 pub files: Vec<FilePart>,
155 pub finish_reason: crate::types::FinishReason,
157 #[serde(default)]
159 pub raw_finish_reason: Option<String>,
160 #[serde(default)]
162 pub usage: crate::types::Usage,
163 #[serde(default)]
166 pub total_usage: crate::types::Usage,
167 #[serde(default)]
169 pub warnings: Vec<crate::types::Warning>,
170 #[serde(default)]
172 pub provider_metadata: Option<serde_json::Value>,
173 #[serde(default)]
175 pub response: Option<crate::types::ResponseMetadata>,
176 #[serde(default)]
178 pub response_messages: Vec<crate::message::ModelMessage>,
179}
180
181#[derive(Debug, Serialize, Deserialize, TS)]
183#[ts(export)]
184pub struct GenerateResult {
185 pub content: Vec<GenerateContent>,
187 pub finish_reason: FinishReason,
189 pub usage: Usage,
191 pub warnings: Vec<Warning>,
193 pub provider_metadata: Option<ProviderMetadata>,
195 pub response: ResponseMetadata,
197 pub request_body: Option<serde_json::Value>,
199 pub response_headers: Option<HashMap<String, String>>,
201}
202
203pub struct StreamResult {
205 pub stream: Pin<Box<dyn Stream<Item = Result<StreamPart, AiMuxError>> + Send>>,
207 pub request_body: Option<serde_json::Value>,
209 pub response_headers: Option<HashMap<String, String>>,
211}
212
213impl std::fmt::Debug for StreamResult {
214 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215 f.debug_struct("StreamResult")
216 .field("request_body", &self.request_body)
217 .field("response_headers", &self.response_headers)
218 .field("stream", &"<stream>")
219 .finish()
220 }
221}