1#![allow(unused_imports, clippy::too_many_arguments)]
6
7use reqwest::Method;
8use serde::{Deserialize, Serialize};
9use futures_core::Stream;
10
11use crate::client::{Client, Request, NO_BODY, NO_QUERY};
12use crate::error::Result;
13use crate::generated::models;
14use crate::multipart::{field_text, FilePart};
15use crate::pagination::CursorGuard;
16use crate::util::encode_path;
17
18#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
20pub struct GetAgentActivityStatsParams {
21 #[serde(default, skip_serializing_if = "Option::is_none")]
22 pub days: Option<i64>,
23}
24
25#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
27pub struct GetAgentSystemCardParams {
28 #[serde(default, skip_serializing_if = "Option::is_none")]
30 pub format: Option<models::GetAgentSystemCardFormat>,
31}
32
33#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
35pub struct GetAgentVersionDiffParams {
36 #[serde(default, skip_serializing_if = "Option::is_none")]
38 pub compare_to: Option<i64>,
39}
40
41#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
43pub struct ListAgentsParams {
44 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub workspace_id: Option<String>,
47 #[serde(default, skip_serializing_if = "Option::is_none")]
48 pub limit: Option<i64>,
49 #[serde(default, skip_serializing_if = "Option::is_none")]
52 pub cursor: Option<String>,
53 #[serde(default, skip_serializing_if = "Option::is_none")]
56 pub include_offline: Option<bool>,
57}
58
59#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
61pub struct ListAgentMailParams {
62 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub thread_id: Option<String>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub agent_id: Option<String>,
68 #[serde(default, skip_serializing_if = "Option::is_none")]
69 pub limit: Option<i64>,
70}
71
72#[derive(Debug, Clone)]
74pub struct AgentsApi {
75 pub(crate) client: Client,
76}
77
78impl Client {
79 pub fn agents(&self) -> AgentsApi {
81 AgentsApi { client: self.clone() }
82 }
83}
84
85impl AgentsApi {
86 pub async fn activate_agent(&self, agent_id: &str) -> Result<models::Agent> {
92 self.client
93 .request_json(Request {
94 method: Method::POST,
95 path: format!("/api/v1/agents/{}/activate", encode_path(agent_id)),
96 query: NO_QUERY,
97 body: NO_BODY,
98 headers: Vec::new(),
99 idempotent: true,
100 })
101 .await
102 }
103
104 pub async fn create(&self, body: &models::CreateAgentRequest) -> Result<models::Agent> {
110 self.client
111 .request_json(Request {
112 method: Method::POST,
113 path: "/api/v1/agents".to_string(),
114 query: NO_QUERY,
115 body: Some(body),
116 headers: Vec::new(),
117 idempotent: true,
118 })
119 .await
120 }
121
122 pub async fn create_agent_bookmark(&self, agent_id: &str, body: &models::CreateAgentBookmarkRequest) -> Result<models::AgentBookmark> {
132 self.client
133 .request_json(Request {
134 method: Method::POST,
135 path: format!("/api/v1/agents/{}/bookmarks", encode_path(agent_id)),
136 query: NO_QUERY,
137 body: Some(body),
138 headers: Vec::new(),
139 idempotent: true,
140 })
141 .await
142 }
143
144 pub async fn create_agent_fria(&self, agent_id: &str, body: &models::CreateAgentFriaRequest) -> Result<models::FriaReport> {
150 self.client
151 .request_json(Request {
152 method: Method::POST,
153 path: format!("/api/v1/agents/{}/fria", encode_path(agent_id)),
154 query: NO_QUERY,
155 body: Some(body),
156 headers: Vec::new(),
157 idempotent: true,
158 })
159 .await
160 }
161
162 pub async fn create_agent_version(&self, agent_id: &str, body: &models::CreateAgentVersionRequest) -> Result<models::AgentVersion> {
168 self.client
169 .request_json(Request {
170 method: Method::POST,
171 path: format!("/api/v1/agents/{}/versions", encode_path(agent_id)),
172 query: NO_QUERY,
173 body: Some(body),
174 headers: Vec::new(),
175 idempotent: true,
176 })
177 .await
178 }
179
180 pub async fn delete(&self, agent_id: &str) -> Result<serde_json::Value> {
186 self.client
187 .request_json(Request {
188 method: Method::DELETE,
189 path: format!("/api/v1/agents/{}", encode_path(agent_id)),
190 query: NO_QUERY,
191 body: NO_BODY,
192 headers: Vec::new(),
193 idempotent: true,
194 })
195 .await
196 }
197
198 pub async fn delete_agent_bookmark(&self, agent_id: &str, message_id: &str) -> Result<models::DeleteAgentBookmarkResponse> {
204 self.client
205 .request_json(Request {
206 method: Method::DELETE,
207 path: format!("/api/v1/agents/{}/bookmarks/{}", encode_path(agent_id), encode_path(message_id)),
208 query: NO_QUERY,
209 body: NO_BODY,
210 headers: Vec::new(),
211 idempotent: true,
212 })
213 .await
214 }
215
216 pub async fn delete_agent_identity(&self, agent_id: &str) -> Result<models::DeleteAgentIdentityResponse> {
222 self.client
223 .request_json(Request {
224 method: Method::DELETE,
225 path: format!("/api/v1/agents/{}/identity", encode_path(agent_id)),
226 query: NO_QUERY,
227 body: NO_BODY,
228 headers: Vec::new(),
229 idempotent: true,
230 })
231 .await
232 }
233
234 pub async fn delete_all_agent_bookmarks(&self, agent_id: &str) -> Result<models::DeleteAllAgentBookmarksResponse> {
240 self.client
241 .request_json(Request {
242 method: Method::DELETE,
243 path: format!("/api/v1/agents/{}/bookmarks", encode_path(agent_id)),
244 query: NO_QUERY,
245 body: NO_BODY,
246 headers: Vec::new(),
247 idempotent: true,
248 })
249 .await
250 }
251
252 pub async fn get(&self, agent_id: &str) -> Result<models::Agent> {
258 self.client
259 .request_json(Request {
260 method: Method::GET,
261 path: format!("/api/v1/agents/{}", encode_path(agent_id)),
262 query: NO_QUERY,
263 body: NO_BODY,
264 headers: Vec::new(),
265 idempotent: false,
266 })
267 .await
268 }
269
270 pub async fn get_agent_activity_stats(&self, agent_id: &str, params: &GetAgentActivityStatsParams) -> Result<models::GetAgentActivityStatsResponse> {
276 self.client
277 .request_json(Request {
278 method: Method::GET,
279 path: format!("/api/v1/agents/{}/activity-stats", encode_path(agent_id)),
280 query: Some(params),
281 body: NO_BODY,
282 headers: Vec::new(),
283 idempotent: false,
284 })
285 .await
286 }
287
288 pub async fn get_agent_capabilities(&self, agent_id: &str) -> Result<models::AgentCapabilities> {
294 self.client
295 .request_json(Request {
296 method: Method::GET,
297 path: format!("/api/v1/agents/{}/capabilities", encode_path(agent_id)),
298 query: NO_QUERY,
299 body: NO_BODY,
300 headers: Vec::new(),
301 idempotent: false,
302 })
303 .await
304 }
305
306 pub async fn get_agent_fria(&self, agent_id: &str) -> Result<models::FriaReport> {
312 self.client
313 .request_json(Request {
314 method: Method::GET,
315 path: format!("/api/v1/agents/{}/fria", encode_path(agent_id)),
316 query: NO_QUERY,
317 body: NO_BODY,
318 headers: Vec::new(),
319 idempotent: false,
320 })
321 .await
322 }
323
324 pub async fn get_agent_identity(&self, agent_id: &str) -> Result<models::GetAgentIdentityResponse> {
330 self.client
331 .request_json(Request {
332 method: Method::GET,
333 path: format!("/api/v1/agents/{}/identity", encode_path(agent_id)),
334 query: NO_QUERY,
335 body: NO_BODY,
336 headers: Vec::new(),
337 idempotent: false,
338 })
339 .await
340 }
341
342 pub async fn get_agent_risk_classification(&self, agent_id: &str) -> Result<models::RiskClassification> {
348 self.client
349 .request_json(Request {
350 method: Method::GET,
351 path: format!("/api/v1/agents/{}/risk-classification", encode_path(agent_id)),
352 query: NO_QUERY,
353 body: NO_BODY,
354 headers: Vec::new(),
355 idempotent: false,
356 })
357 .await
358 }
359
360 pub async fn get_agent_spec_catalog(&self, agent_id: &str) -> Result<models::SpecToolCatalog> {
373 self.client
374 .request_json(Request {
375 method: Method::GET,
376 path: format!("/api/v1/agents/{}/spec-catalog", encode_path(agent_id)),
377 query: NO_QUERY,
378 body: NO_BODY,
379 headers: Vec::new(),
380 idempotent: false,
381 })
382 .await
383 }
384
385 pub async fn get_agent_system_card(&self, agent_id: &str, params: &GetAgentSystemCardParams) -> Result<models::AiSystemCard> {
391 self.client
392 .request_json(Request {
393 method: Method::GET,
394 path: format!("/api/v1/agents/{}/system-card", encode_path(agent_id)),
395 query: Some(params),
396 body: NO_BODY,
397 headers: Vec::new(),
398 idempotent: false,
399 })
400 .await
401 }
402
403 pub async fn get_agent_traffic(&self, agent_id: &str) -> Result<models::GetAgentTrafficResponse> {
409 self.client
410 .request_json(Request {
411 method: Method::GET,
412 path: format!("/api/v1/agents/{}/traffic", encode_path(agent_id)),
413 query: NO_QUERY,
414 body: NO_BODY,
415 headers: Vec::new(),
416 idempotent: false,
417 })
418 .await
419 }
420
421 pub async fn get_agent_version_diff(&self, agent_id: &str, version_num: i64, params: &GetAgentVersionDiffParams) -> Result<models::GetAgentVersionDiffResponse> {
427 self.client
428 .request_json(Request {
429 method: Method::GET,
430 path: format!("/api/v1/agents/{}/versions/{}/diff", encode_path(agent_id), encode_path(&version_num.to_string())),
431 query: Some(params),
432 body: NO_BODY,
433 headers: Vec::new(),
434 idempotent: false,
435 })
436 .await
437 }
438
439 pub async fn list(&self, params: &ListAgentsParams) -> Result<models::ListAgentsResponse> {
445 self.client
446 .request_json(Request {
447 method: Method::GET,
448 path: "/api/v1/agents".to_string(),
449 query: Some(params),
450 body: NO_BODY,
451 headers: Vec::new(),
452 idempotent: false,
453 })
454 .await
455 }
456
457 pub fn list_all<'a>(&'a self, params: &'a ListAgentsParams) -> impl Stream<Item = Result<models::Agent>> + 'a {
460 async_stream::try_stream! {
461 let mut guard = CursorGuard::new();
462 let mut cursor = params.cursor.clone();
463 loop {
464 let mut page_params = params.clone();
465 page_params.cursor = cursor.clone();
466 let page = self.list(&page_params).await?;
467 let items = page.items;
468 let was_empty = items.is_empty();
469 for item in items {
470 yield item;
471 }
472 match guard.advance(page.cursor, Some(page.has_more), was_empty) {
473 Some(next) => cursor = Some(next),
474 None => break,
475 }
476 }
477 }
478 }
479
480 pub async fn list_agent_bookmarks(&self, agent_id: &str) -> Result<models::ListAgentBookmarksResponse> {
488 self.client
489 .request_json(Request {
490 method: Method::GET,
491 path: format!("/api/v1/agents/{}/bookmarks", encode_path(agent_id)),
492 query: NO_QUERY,
493 body: NO_BODY,
494 headers: Vec::new(),
495 idempotent: false,
496 })
497 .await
498 }
499
500 pub async fn list_agent_mail(&self, params: &ListAgentMailParams) -> Result<models::ListAgentMailResponse> {
512 self.client
513 .request_json(Request {
514 method: Method::GET,
515 path: "/api/v1/agent-mail".to_string(),
516 query: Some(params),
517 body: NO_BODY,
518 headers: Vec::new(),
519 idempotent: false,
520 })
521 .await
522 }
523
524 pub async fn list_agent_versions(&self, agent_id: &str) -> Result<models::ListAgentVersionsResponse> {
533 self.client
534 .request_json(Request {
535 method: Method::GET,
536 path: format!("/api/v1/agents/{}/versions", encode_path(agent_id)),
537 query: NO_QUERY,
538 body: NO_BODY,
539 headers: Vec::new(),
540 idempotent: false,
541 })
542 .await
543 }
544
545 pub async fn patch(&self, agent_id: &str, body: &serde_json::Map<String, serde_json::Value>) -> Result<models::Agent> {
551 self.client
552 .request_json(Request {
553 method: Method::PATCH,
554 path: format!("/api/v1/agents/{}", encode_path(agent_id)),
555 query: NO_QUERY,
556 body: Some(body),
557 headers: Vec::new(),
558 idempotent: true,
559 })
560 .await
561 }
562
563 pub async fn reset_agent(&self, agent_id: &str) -> Result<models::ResetAgentResponse> {
580 self.client
581 .request_json(Request {
582 method: Method::POST,
583 path: format!("/api/v1/agents/{}/reset", encode_path(agent_id)),
584 query: NO_QUERY,
585 body: NO_BODY,
586 headers: Vec::new(),
587 idempotent: true,
588 })
589 .await
590 }
591
592 pub async fn rollback_agent(&self, agent_id: &str, body: &models::RollbackAgentRequest) -> Result<models::AgentVersion> {
598 self.client
599 .request_json(Request {
600 method: Method::POST,
601 path: format!("/api/v1/agents/{}/rollback", encode_path(agent_id)),
602 query: NO_QUERY,
603 body: Some(body),
604 headers: Vec::new(),
605 idempotent: true,
606 })
607 .await
608 }
609
610 pub async fn rotate_agent_identity(&self, agent_id: &str) -> Result<models::RotateAgentIdentityResponse> {
616 self.client
617 .request_json(Request {
618 method: Method::POST,
619 path: format!("/api/v1/agents/{}/identity/rotate", encode_path(agent_id)),
620 query: NO_QUERY,
621 body: NO_BODY,
622 headers: Vec::new(),
623 idempotent: true,
624 })
625 .await
626 }
627
628 pub async fn set_agent_capabilities(&self, agent_id: &str, body: &serde_json::Map<String, serde_json::Value>) -> Result<models::SetAgentCapabilitiesResponse> {
634 self.client
635 .request_json(Request {
636 method: Method::PUT,
637 path: format!("/api/v1/agents/{}/capabilities", encode_path(agent_id)),
638 query: NO_QUERY,
639 body: Some(body),
640 headers: Vec::new(),
641 idempotent: true,
642 })
643 .await
644 }
645
646 pub async fn set_agent_traffic(&self, agent_id: &str, body: &models::SetAgentTrafficRequest) -> Result<models::SetAgentTrafficResponse> {
652 self.client
653 .request_json(Request {
654 method: Method::PUT,
655 path: format!("/api/v1/agents/{}/traffic", encode_path(agent_id)),
656 query: NO_QUERY,
657 body: Some(body),
658 headers: Vec::new(),
659 idempotent: true,
660 })
661 .await
662 }
663
664 pub async fn suspend_agent(&self, agent_id: &str, body: &models::SuspendAgentRequest) -> Result<models::Agent> {
670 self.client
671 .request_json(Request {
672 method: Method::POST,
673 path: format!("/api/v1/agents/{}/suspend", encode_path(agent_id)),
674 query: NO_QUERY,
675 body: Some(body),
676 headers: Vec::new(),
677 idempotent: true,
678 })
679 .await
680 }
681
682 pub async fn terminate_agent(&self, agent_id: &str) -> Result<models::TerminateAgentResponse> {
688 self.client
689 .request_json(Request {
690 method: Method::POST,
691 path: format!("/api/v1/agents/{}/terminate", encode_path(agent_id)),
692 query: NO_QUERY,
693 body: NO_BODY,
694 headers: Vec::new(),
695 idempotent: true,
696 })
697 .await
698 }
699
700 pub async fn update(&self, agent_id: &str, body: &models::AgentUpdate) -> Result<models::Agent> {
706 self.client
707 .request_json(Request {
708 method: Method::PUT,
709 path: format!("/api/v1/agents/{}", encode_path(agent_id)),
710 query: NO_QUERY,
711 body: Some(body),
712 headers: Vec::new(),
713 idempotent: true,
714 })
715 .await
716 }
717
718 pub async fn update_agent_risk_classification(&self, agent_id: &str, body: &models::RiskClassificationUpdate) -> Result<models::Agent> {
724 self.client
725 .request_json(Request {
726 method: Method::PATCH,
727 path: format!("/api/v1/agents/{}/risk-classification", encode_path(agent_id)),
728 query: NO_QUERY,
729 body: Some(body),
730 headers: Vec::new(),
731 idempotent: true,
732 })
733 .await
734 }
735
736 pub async fn upsert_agent_tool_override(&self, agent_id: &str, body: &models::AgentToolOverrideUpdate) -> Result<models::UpsertAgentToolOverrideResponse> {
754 self.client
755 .request_json(Request {
756 method: Method::PATCH,
757 path: format!("/api/v1/agents/{}/autonomy/tool-override", encode_path(agent_id)),
758 query: NO_QUERY,
759 body: Some(body),
760 headers: Vec::new(),
761 idempotent: true,
762 })
763 .await
764 }
765}