1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5use super::Pagination;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
10pub struct ToolCall {
11 pub id: Uuid,
13 pub function_name: String,
15 pub function_arguments: serde_json::Value,
17 #[serde(default, skip_serializing_if = "Option::is_none")]
19 pub function_result: Option<serde_json::Value>,
20 pub created_at: DateTime<Utc>,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
26#[serde(rename_all = "snake_case")]
27pub enum MessageType {
28 UserMessage,
30 AssistantMessage,
32}
33
34impl std::fmt::Display for MessageType {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 match self {
37 Self::UserMessage => write!(f, "user_message"),
38 Self::AssistantMessage => write!(f, "assistant_message"),
39 }
40 }
41}
42
43#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct ParseMessageTypeError(String);
46
47impl std::fmt::Display for ParseMessageTypeError {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 write!(f, "Invalid message type: {}", self.0)
50 }
51}
52
53impl std::error::Error for ParseMessageTypeError {}
54
55impl std::str::FromStr for MessageType {
56 type Err = ParseMessageTypeError;
57
58 fn from_str(s: &str) -> Result<Self, Self::Err> {
59 match s {
60 "user_message" => Ok(Self::UserMessage),
61 "assistant_message" => Ok(Self::AssistantMessage),
62 _ => Err(ParseMessageTypeError(s.to_string())),
63 }
64 }
65}
66
67impl TryFrom<&str> for MessageType {
68 type Error = ParseMessageTypeError;
69
70 fn try_from(value: &str) -> Result<Self, Self::Error> {
71 value.parse()
72 }
73}
74
75impl TryFrom<String> for MessageType {
76 type Error = ParseMessageTypeError;
77
78 fn try_from(value: String) -> Result<Self, Self::Error> {
79 value.parse()
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
85#[serde(rename_all = "lowercase")]
86pub enum MessageRole {
87 User,
89 Assistant,
91}
92
93impl std::fmt::Display for MessageRole {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 match self {
96 Self::User => write!(f, "user"),
97 Self::Assistant => write!(f, "assistant"),
98 }
99 }
100}
101
102#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct ParseMessageRoleError(String);
105
106impl std::fmt::Display for ParseMessageRoleError {
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 write!(f, "Invalid message role: {}", self.0)
109 }
110}
111
112impl std::error::Error for ParseMessageRoleError {}
113
114impl std::str::FromStr for MessageRole {
115 type Err = ParseMessageRoleError;
116
117 fn from_str(s: &str) -> Result<Self, Self::Err> {
118 match s {
119 "user" => Ok(Self::User),
120 "assistant" => Ok(Self::Assistant),
121 _ => Err(ParseMessageRoleError(s.to_string())),
122 }
123 }
124}
125
126impl TryFrom<&str> for MessageRole {
127 type Error = ParseMessageRoleError;
128
129 fn try_from(value: &str) -> Result<Self, Self::Error> {
130 value.parse()
131 }
132}
133
134impl TryFrom<String> for MessageRole {
135 type Error = ParseMessageRoleError;
136
137 fn try_from(value: String) -> Result<Self, Self::Error> {
138 value.parse()
139 }
140}
141
142#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
144#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
145pub struct Message {
146 pub id: Uuid,
148 #[serde(rename = "type")]
150 pub message_type: MessageType,
151 pub role: MessageRole,
153 pub content: String,
155 #[serde(default, skip_serializing_if = "Option::is_none")]
157 pub model: Option<String>,
158 pub created_at: DateTime<Utc>,
160 pub updated_at: DateTime<Utc>,
162 #[serde(default, skip_serializing_if = "Option::is_none")]
164 pub tool_calls: Option<Vec<ToolCall>>,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
169#[serde(rename_all = "lowercase")]
170pub enum AiResponseStatus {
171 Pending,
173 Complete,
175 Failed,
177}
178
179impl std::fmt::Display for AiResponseStatus {
180 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181 match self {
182 Self::Pending => write!(f, "pending"),
183 Self::Complete => write!(f, "complete"),
184 Self::Failed => write!(f, "failed"),
185 }
186 }
187}
188
189#[derive(Debug, Clone, PartialEq, Eq)]
191pub struct ParseAiResponseStatusError(String);
192
193impl std::fmt::Display for ParseAiResponseStatusError {
194 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195 write!(f, "Invalid AI response status: {}", self.0)
196 }
197}
198
199impl std::error::Error for ParseAiResponseStatusError {}
200
201impl std::str::FromStr for AiResponseStatus {
202 type Err = ParseAiResponseStatusError;
203
204 fn from_str(s: &str) -> Result<Self, Self::Err> {
205 match s {
206 "pending" => Ok(Self::Pending),
207 "complete" => Ok(Self::Complete),
208 "failed" => Ok(Self::Failed),
209 _ => Err(ParseAiResponseStatusError(s.to_string())),
210 }
211 }
212}
213
214impl TryFrom<&str> for AiResponseStatus {
215 type Error = ParseAiResponseStatusError;
216
217 fn try_from(value: &str) -> Result<Self, Self::Error> {
218 value.parse()
219 }
220}
221
222impl TryFrom<String> for AiResponseStatus {
223 type Error = ParseAiResponseStatusError;
224
225 fn try_from(value: String) -> Result<Self, Self::Error> {
226 value.parse()
227 }
228}
229
230#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
232#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
233pub struct MessageResponse {
234 pub id: Uuid,
236 #[serde(rename = "type")]
238 pub message_type: MessageType,
239 pub role: MessageRole,
241 pub content: String,
243 #[serde(default, skip_serializing_if = "Option::is_none")]
245 pub model: Option<String>,
246 pub created_at: DateTime<Utc>,
248 pub updated_at: DateTime<Utc>,
250 #[serde(default, skip_serializing_if = "Option::is_none")]
252 pub tool_calls: Option<Vec<ToolCall>>,
253 pub chat_id: Uuid,
255 #[serde(default, skip_serializing_if = "Option::is_none")]
257 pub ai_response_status: Option<AiResponseStatus>,
258 #[serde(default, skip_serializing_if = "Option::is_none")]
260 pub ai_response_message: Option<String>,
261}
262
263#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
265#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
266pub struct ChatResource {
267 pub id: Uuid,
269 pub title: String,
271 #[serde(default, skip_serializing_if = "Option::is_none")]
273 pub error: Option<String>,
274 pub created_at: DateTime<Utc>,
276 pub updated_at: DateTime<Utc>,
278}
279
280#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
282#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
283pub struct ChatSummary {
284 pub id: Uuid,
286 pub title: String,
288 #[serde(default, skip_serializing_if = "Option::is_none")]
290 pub error: Option<String>,
291 pub created_at: DateTime<Utc>,
293 pub updated_at: DateTime<Utc>,
295 pub message_count: u32,
297 #[serde(default, skip_serializing_if = "Option::is_none")]
299 pub last_message_at: Option<DateTime<Utc>>,
300}
301
302#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
304#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
305pub struct ChatDetail {
306 pub id: Uuid,
308 pub title: String,
310 #[serde(default, skip_serializing_if = "Option::is_none")]
312 pub error: Option<String>,
313 pub created_at: DateTime<Utc>,
315 pub updated_at: DateTime<Utc>,
317 pub messages: Vec<Message>,
319 #[serde(default, skip_serializing_if = "Option::is_none")]
321 pub pagination: Option<Pagination>,
322}
323
324#[derive(Debug, Clone, Serialize, Deserialize)]
326#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
327pub struct ChatCollection {
328 pub chats: Vec<ChatSummary>,
330}
331
332#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
334#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
335pub struct RetryResponse {
336 pub message: String,
338 pub message_id: Uuid,
340}
341
342#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
344#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
345pub(crate) struct CreateChatRequest {
346 pub title: String,
348 #[serde(default, skip_serializing_if = "Option::is_none")]
350 pub message: Option<String>,
351 #[serde(default, skip_serializing_if = "Option::is_none")]
353 pub model: Option<String>,
354}
355
356#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
358#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
359pub(crate) struct UpdateChatRequest {
360 pub title: String,
362}
363
364#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
366#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
367pub(crate) struct CreateMessageRequest {
368 pub content: String,
370 #[serde(default, skip_serializing_if = "Option::is_none")]
372 pub model: Option<String>,
373}