1use serde::{Deserialize, Serialize};
4use validator::Validate;
5
6#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
8pub struct AgentCreateRequest {
9 #[validate(length(min = 1, max = 100))]
11 pub name: String,
12
13 #[serde(skip_serializing_if = "Option::is_none")]
15 #[validate(length(max = 1000))]
16 pub description: Option<String>,
17
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub system_prompt: Option<String>,
21
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub model: Option<String>,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
28 pub tools: Option<Vec<serde_json::Value>>,
29
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub config: Option<AgentConfig>,
33}
34
35impl AgentCreateRequest {
36 pub fn builder() -> AgentCreateRequestBuilder {
38 AgentCreateRequestBuilder::default()
39 }
40}
41
42#[derive(Default)]
44pub struct AgentCreateRequestBuilder {
45 name: Option<String>,
46 description: Option<String>,
47 system_prompt: Option<String>,
48 model: Option<String>,
49 tools: Option<Vec<serde_json::Value>>,
50 config: Option<AgentConfig>,
51}
52
53impl AgentCreateRequestBuilder {
54 pub fn name(mut self, name: impl Into<String>) -> Self {
56 self.name = Some(name.into());
57 self
58 }
59
60 pub fn description(mut self, description: impl Into<String>) -> Self {
62 self.description = Some(description.into());
63 self
64 }
65
66 pub fn system_prompt(mut self, system_prompt: impl Into<String>) -> Self {
68 self.system_prompt = Some(system_prompt.into());
69 self
70 }
71
72 pub fn model(mut self, model: impl Into<String>) -> Self {
74 self.model = Some(model.into());
75 self
76 }
77
78 pub fn tools(mut self, tools: Vec<serde_json::Value>) -> Self {
80 self.tools = Some(tools);
81 self
82 }
83
84 pub fn config(mut self, config: AgentConfig) -> Self {
86 self.config = Some(config);
87 self
88 }
89
90 pub fn build(self) -> Result<AgentCreateRequest, crate::client::error::ZaiError> {
92 let name = self
93 .name
94 .ok_or_else(|| crate::client::error::ZaiError::ApiError {
95 code: 1200,
96 message: "name is required".to_string(),
97 })?;
98
99 let req = AgentCreateRequest {
100 name,
101 description: self.description,
102 system_prompt: self.system_prompt,
103 model: self.model,
104 tools: self.tools,
105 config: self.config,
106 };
107
108 req.validate()
110 .map_err(|e| crate::client::error::ZaiError::ApiError {
111 code: 1200,
112 message: format!("Validation error: {:?}", e),
113 })?;
114
115 Ok(req)
116 }
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
121pub struct AgentConfig {
122 #[serde(skip_serializing_if = "Option::is_none")]
124 #[validate(range(min = 0.0, max = 1.0))]
125 pub temperature: Option<f32>,
126
127 #[serde(skip_serializing_if = "Option::is_none")]
129 pub max_tokens: Option<u32>,
130
131 #[serde(skip_serializing_if = "Option::is_none")]
133 pub thinking_enabled: Option<bool>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
138pub struct AgentUpdateRequest {
139 #[serde(skip_serializing_if = "Option::is_none")]
141 #[validate(length(min = 1, max = 100))]
142 pub name: Option<String>,
143
144 #[serde(skip_serializing_if = "Option::is_none")]
146 #[validate(length(max = 1000))]
147 pub description: Option<String>,
148
149 #[serde(skip_serializing_if = "Option::is_none")]
151 pub system_prompt: Option<String>,
152
153 #[serde(skip_serializing_if = "Option::is_none")]
155 pub model: Option<String>,
156
157 #[serde(skip_serializing_if = "Option::is_none")]
159 pub tools: Option<Vec<serde_json::Value>>,
160
161 #[serde(skip_serializing_if = "Option::is_none")]
163 pub config: Option<AgentConfig>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
168pub struct AgentChatRequest {
169 #[validate(length(min = 1))]
171 pub message: String,
172
173 #[serde(skip_serializing_if = "Option::is_none")]
175 pub conversation_id: Option<String>,
176
177 #[serde(skip_serializing_if = "Option::is_none")]
179 pub session_id: Option<String>,
180
181 #[serde(skip_serializing_if = "Option::is_none")]
183 pub stream: Option<bool>,
184
185 #[serde(skip_serializing_if = "Option::is_none")]
187 pub parameters: Option<AgentChatParameters>,
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
192pub struct AgentChatParameters {
193 #[serde(skip_serializing_if = "Option::is_none")]
195 #[validate(range(min = 0.0, max = 1.0))]
196 pub temperature: Option<f32>,
197
198 #[serde(skip_serializing_if = "Option::is_none")]
200 pub max_tokens: Option<u32>,
201
202 #[serde(skip_serializing_if = "Option::is_none")]
204 pub thinking_enabled: Option<bool>,
205}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210
211 #[test]
212 fn test_builder_success() {
213 let req = AgentCreateRequest::builder()
214 .name("TestAgent")
215 .description("A test agent")
216 .model("glm-4.5")
217 .build()
218 .unwrap();
219
220 assert_eq!(req.name, "TestAgent");
221 assert_eq!(req.description, Some("A test agent".to_string()));
222 assert_eq!(req.model, Some("glm-4.5".to_string()));
223 }
224
225 #[test]
226 fn test_builder_missing_name() {
227 let result = AgentCreateRequest::builder().description("No name").build();
228 assert!(result.is_err());
229 }
230
231 #[test]
232 fn test_builder_name_too_long() {
233 let result = AgentCreateRequest::builder().name("a".repeat(101)).build();
234 assert!(result.is_err());
235 }
236
237 #[test]
238 fn test_builder_with_config() {
239 let req = AgentCreateRequest::builder()
240 .name("ConfigAgent")
241 .config(AgentConfig {
242 temperature: Some(0.7),
243 max_tokens: Some(1000),
244 thinking_enabled: Some(false),
245 })
246 .build()
247 .unwrap();
248
249 assert_eq!(req.config.unwrap().temperature, Some(0.7));
250 }
251
252 #[test]
253 fn test_serde_roundtrip() {
254 let req = AgentCreateRequest::builder()
255 .name("SerdeAgent")
256 .description("Serde test")
257 .build()
258 .unwrap();
259
260 let json = serde_json::to_string(&req).unwrap();
261 let parsed: AgentCreateRequest = serde_json::from_str(&json).unwrap();
262 assert_eq!(parsed.name, "SerdeAgent");
263 }
264
265 #[test]
266 fn test_chat_request_validation() {
267 let req = AgentChatRequest {
268 message: "Hello".to_string(),
269 conversation_id: None,
270 session_id: None,
271 stream: None,
272 parameters: None,
273 };
274 assert!(req.validate().is_ok());
275 }
276}