1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum AgentId {
9 GeneralTranslation,
11 SlidesGlmAgent,
13 AiDrawingAgent,
15 ReceiptRecognitionAgent,
17 ClothesRecognitionAgent,
19 IntelligentEducationSolveAgent,
21 ViduTemplateAgent,
23}
24
25impl AgentId {
26 pub const fn as_str(self) -> &'static str {
28 match self {
29 Self::GeneralTranslation => "general_translation",
30 Self::SlidesGlmAgent => "slides_glm_agent",
31 Self::AiDrawingAgent => "ai_drawing_agent",
32 Self::ReceiptRecognitionAgent => "receipt_recognition_agent",
33 Self::ClothesRecognitionAgent => "clothes_recognition_agent",
34 Self::IntelligentEducationSolveAgent => "intelligent_education_solve_agent",
35 Self::ViduTemplateAgent => "vidu_template_agent",
36 }
37 }
38}
39
40impl std::fmt::Display for AgentId {
41 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 formatter.write_str(self.as_str())
43 }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
48#[serde(rename_all = "lowercase")]
49pub enum AgentRole {
50 System,
52 User,
54 Assistant,
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
60#[serde(rename_all = "snake_case")]
61pub enum AgentRequestContentType {
62 Text,
64 FileId,
66 FileUrl,
68 ImageUrl,
70}
71
72#[derive(Clone, Serialize, Deserialize)]
74#[serde(deny_unknown_fields)]
75pub struct AgentRequestContentPart {
76 #[serde(rename = "type")]
77 type_: AgentRequestContentType,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 text: Option<String>,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 file_id: Option<String>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 file_url: Option<String>,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 image_url: Option<String>,
86}
87
88impl std::fmt::Debug for AgentRequestContentPart {
89 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 formatter
91 .debug_struct("AgentRequestContentPart")
92 .field("type", &self.type_)
93 .field("value", &"[REDACTED]")
94 .finish()
95 }
96}
97
98impl AgentRequestContentPart {
99 fn with_value(type_: AgentRequestContentType, value: String) -> Self {
100 let mut part = Self {
101 type_,
102 text: None,
103 file_id: None,
104 file_url: None,
105 image_url: None,
106 };
107 match type_ {
108 AgentRequestContentType::Text => part.text = Some(value),
109 AgentRequestContentType::FileId => part.file_id = Some(value),
110 AgentRequestContentType::FileUrl => part.file_url = Some(value),
111 AgentRequestContentType::ImageUrl => part.image_url = Some(value),
112 }
113 part
114 }
115
116 pub fn text(value: impl Into<String>) -> Self {
118 Self::with_value(AgentRequestContentType::Text, value.into())
119 }
120
121 pub fn file_id(value: impl Into<String>) -> Self {
123 Self::with_value(AgentRequestContentType::FileId, value.into())
124 }
125
126 pub fn file_url(value: impl Into<String>) -> Self {
128 Self::with_value(AgentRequestContentType::FileUrl, value.into())
129 }
130
131 pub fn image_url(value: impl Into<String>) -> Self {
133 Self::with_value(AgentRequestContentType::ImageUrl, value.into())
134 }
135
136 pub const fn type_(&self) -> AgentRequestContentType {
138 self.type_
139 }
140}
141
142#[derive(Clone, Serialize, Deserialize)]
144#[serde(untagged)]
145pub enum AgentContent {
146 Text(String),
148 Part(AgentRequestContentPart),
150 Parts(Vec<AgentRequestContentPart>),
152}
153
154impl std::fmt::Debug for AgentContent {
155 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156 match self {
157 Self::Text(_) => formatter.write_str("AgentContent::Text([REDACTED])"),
158 Self::Part(part) => formatter
159 .debug_tuple("AgentContent::Part")
160 .field(part)
161 .finish(),
162 Self::Parts(parts) => formatter
163 .debug_struct("AgentContent::Parts")
164 .field("count", &parts.len())
165 .finish(),
166 }
167 }
168}
169
170impl From<String> for AgentContent {
171 fn from(value: String) -> Self {
172 Self::Text(value)
173 }
174}
175
176impl From<&str> for AgentContent {
177 fn from(value: &str) -> Self {
178 Self::Text(value.to_owned())
179 }
180}
181
182impl From<AgentRequestContentPart> for AgentContent {
183 fn from(value: AgentRequestContentPart) -> Self {
184 Self::Part(value)
185 }
186}
187
188impl From<Vec<AgentRequestContentPart>> for AgentContent {
189 fn from(value: Vec<AgentRequestContentPart>) -> Self {
190 Self::Parts(value)
191 }
192}
193
194#[derive(Clone, Serialize, Deserialize)]
196#[serde(deny_unknown_fields)]
197pub struct AgentMessage {
198 role: AgentRole,
199 content: AgentContent,
200}
201
202impl std::fmt::Debug for AgentMessage {
203 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
204 formatter
205 .debug_struct("AgentMessage")
206 .field("role", &self.role)
207 .field("content", &"[REDACTED]")
208 .finish()
209 }
210}
211
212impl AgentMessage {
213 pub fn new(role: AgentRole, content: impl Into<AgentContent>) -> Self {
215 Self {
216 role,
217 content: content.into(),
218 }
219 }
220
221 pub fn user(content: impl Into<AgentContent>) -> Self {
223 Self::new(AgentRole::User, content)
224 }
225
226 pub fn system(content: impl Into<AgentContent>) -> Self {
228 Self::new(AgentRole::System, content)
229 }
230
231 pub fn assistant(content: impl Into<AgentContent>) -> Self {
233 Self::new(AgentRole::Assistant, content)
234 }
235
236 pub const fn role(&self) -> AgentRole {
238 self.role
239 }
240
241 pub const fn content(&self) -> &AgentContent {
243 &self.content
244 }
245}