1use serde::{Deserialize, Serialize};
4
5#[non_exhaustive]
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7#[serde(tag = "role")]
8pub enum Message {
9 #[serde(rename = "user")]
10 User(UserMessage),
11 #[serde(rename = "assistant")]
12 Assistant(AssistantMessage),
13 #[serde(rename = "tool_result")]
14 ToolResult(ToolResultMessage),
15}
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub struct UserMessage {
19 pub content: Vec<InputContent>,
20 pub timestamp_ms: i64,
21}
22
23#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
24pub struct AssistantMessage {
25 pub content: Vec<AssistantContent>,
26 pub api: crate::ApiKind,
27 pub provider: String,
28 pub model: String,
29 pub response_model: Option<String>,
30 pub response_id: Option<String>,
31 pub usage: crate::stream::Usage,
32 pub stop_reason: crate::stream::StopReason,
33 pub error_message: Option<String>,
34 pub timestamp_ms: i64,
35}
36
37#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
38pub struct ToolResultMessage {
39 pub tool_call_id: String,
40 pub tool_name: String,
41 pub content: Vec<OutputContent>,
42 pub details: Option<serde_json::Value>,
43 pub is_error: bool,
44 pub timestamp_ms: i64,
45}
46
47#[non_exhaustive]
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
50pub enum MediaType {
51 #[serde(rename = "image/png")]
52 Png,
53 #[serde(rename = "image/jpeg")]
54 Jpeg,
55 #[serde(rename = "image/gif")]
56 Gif,
57 #[serde(rename = "image/webp")]
58 WebP,
59}
60
61impl MediaType {
62 pub fn as_str(self) -> &'static str {
63 match self {
64 Self::Png => "image/png",
65 Self::Jpeg => "image/jpeg",
66 Self::Gif => "image/gif",
67 Self::WebP => "image/webp",
68 }
69 }
70}
71
72#[non_exhaustive]
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
75#[serde(tag = "type")]
76pub enum ImageSource {
77 #[serde(rename = "url")]
78 Url { url: String },
79 #[serde(rename = "base64")]
80 Base64 { data: String },
81 #[serde(rename = "bytes")]
82 Bytes { data: Vec<u8> },
83}
84
85#[non_exhaustive]
86#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
87#[serde(tag = "type")]
88pub enum InputContent {
89 #[serde(rename = "text")]
90 Text { text: String },
91 #[serde(rename = "image")]
92 Image {
93 source: ImageSource,
94 media_type: MediaType,
95 },
96}
97
98#[non_exhaustive]
99#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
100#[serde(tag = "type")]
101pub enum AssistantContent {
102 #[serde(rename = "text")]
103 Text { text: String },
104 #[serde(rename = "thinking")]
105 Thinking { thinking: String },
106 #[serde(rename = "tool_call")]
107 ToolCall { tool_call: ToolCall },
108}
109
110#[non_exhaustive]
111#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
112#[serde(tag = "type")]
113pub enum OutputContent {
114 #[serde(rename = "text")]
115 Text { text: String },
116 #[serde(rename = "image")]
117 Image {
118 source: ImageSource,
119 media_type: MediaType,
120 },
121}
122
123#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
124pub struct ToolCall {
125 pub id: String,
126 pub name: String,
127 pub arguments: String,
128}
129
130#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
131pub struct ToolDef {
132 pub name: String,
133 pub description: String,
134 pub input_schema: serde_json::Value,
135}