1use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct Text {
14 pub text: String,
15}
16
17impl From<&str> for Text {
18 fn from(s: &str) -> Self {
19 Self { text: s.to_owned() }
20 }
21}
22
23impl From<String> for Text {
24 fn from(s: String) -> Self {
25 Self { text: s }
26 }
27}
28
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
31pub struct ToolCall {
32 pub id: String,
34 pub name: String,
36 pub arguments: serde_json::Value,
38}
39
40#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
42pub struct ToolResult {
43 pub call_id: String,
45 pub name: String,
47 pub content: String,
49}
50
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
55#[serde(tag = "type", rename_all = "snake_case")]
56pub enum UserContent {
57 Text(Text),
59 ToolResult(ToolResult),
61}
62
63impl From<&str> for UserContent {
64 fn from(s: &str) -> Self {
65 UserContent::Text(s.into())
66 }
67}
68
69impl From<String> for UserContent {
70 fn from(s: String) -> Self {
71 UserContent::Text(s.into())
72 }
73}
74
75impl From<ToolResult> for UserContent {
76 fn from(r: ToolResult) -> Self {
77 UserContent::ToolResult(r)
78 }
79}
80
81#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85#[serde(tag = "type", rename_all = "snake_case")]
86pub enum AssistantContent {
87 Text(Text),
89 ToolCall(ToolCall),
91}
92
93#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97#[serde(tag = "role", rename_all = "lowercase")]
98pub enum Message {
99 System { content: String },
101 User { content: Vec<UserContent> },
103 Assistant { content: Vec<AssistantContent> },
105}
106
107impl Message {
108 pub fn user(text: impl Into<String>) -> Self {
110 Message::User {
111 content: vec![UserContent::Text(Text { text: text.into() })],
112 }
113 }
114
115 pub fn assistant(text: impl Into<String>) -> Self {
117 Message::Assistant {
118 content: vec![AssistantContent::Text(Text { text: text.into() })],
119 }
120 }
121
122 pub fn system(text: impl Into<String>) -> Self {
124 Message::System { content: text.into() }
125 }
126}