routa_core/rpc/methods/
agents.rs1use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12
13use crate::models::agent::{Agent, AgentRole, AgentStatus, ModelTier};
14use crate::rpc::error::RpcError;
15use crate::state::AppState;
16
17#[derive(Debug, Deserialize)]
22#[serde(rename_all = "camelCase")]
23pub struct ListParams {
24 #[serde(default = "default_workspace_id")]
25 pub workspace_id: String,
26 pub role: Option<String>,
27 pub status: Option<String>,
28 pub parent_id: Option<String>,
29}
30
31fn default_workspace_id() -> String {
32 "default".into()
33}
34
35#[derive(Debug, Serialize)]
36pub struct ListResult {
37 pub agents: Vec<Agent>,
38}
39
40pub async fn list(state: &AppState, params: ListParams) -> Result<ListResult, RpcError> {
41 let agents = if let Some(parent_id) = ¶ms.parent_id {
42 state.agent_store.list_by_parent(parent_id).await?
43 } else if let Some(role_str) = ¶ms.role {
44 let role = AgentRole::from_str(role_str)
45 .ok_or_else(|| RpcError::BadRequest(format!("Invalid role: {role_str}")))?;
46 state
47 .agent_store
48 .list_by_role(¶ms.workspace_id, &role)
49 .await?
50 } else if let Some(status_str) = ¶ms.status {
51 let status = AgentStatus::from_str(status_str)
52 .ok_or_else(|| RpcError::BadRequest(format!("Invalid status: {status_str}")))?;
53 state
54 .agent_store
55 .list_by_status(¶ms.workspace_id, &status)
56 .await?
57 } else {
58 state
59 .agent_store
60 .list_by_workspace(¶ms.workspace_id)
61 .await?
62 };
63
64 Ok(ListResult { agents })
65}
66
67#[derive(Debug, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub struct GetParams {
74 pub id: String,
75}
76
77pub async fn get(state: &AppState, params: GetParams) -> Result<Agent, RpcError> {
78 state
79 .agent_store
80 .get(¶ms.id)
81 .await?
82 .ok_or_else(|| RpcError::NotFound(format!("Agent {} not found", params.id)))
83}
84
85#[derive(Debug, Deserialize)]
90#[serde(rename_all = "camelCase")]
91pub struct CreateParams {
92 pub name: String,
93 pub role: String,
94 #[serde(default = "default_workspace_id")]
95 pub workspace_id: String,
96 pub parent_id: Option<String>,
97 pub model_tier: Option<String>,
98 pub metadata: Option<HashMap<String, String>>,
99}
100
101#[derive(Debug, Serialize)]
102#[serde(rename_all = "camelCase")]
103pub struct CreateResult {
104 pub agent_id: String,
105 pub agent: Agent,
106}
107
108pub async fn create(state: &AppState, params: CreateParams) -> Result<CreateResult, RpcError> {
109 let role = AgentRole::from_str(¶ms.role)
110 .ok_or_else(|| RpcError::BadRequest(format!("Invalid role: {}", params.role)))?;
111 let model_tier = params.model_tier.as_deref().and_then(ModelTier::from_str);
112
113 state.workspace_store.ensure_default().await?;
114
115 let agent = Agent::new(
116 uuid::Uuid::new_v4().to_string(),
117 params.name,
118 role,
119 params.workspace_id,
120 params.parent_id,
121 model_tier,
122 params.metadata,
123 );
124
125 state.agent_store.save(&agent).await?;
126
127 Ok(CreateResult {
128 agent_id: agent.id.clone(),
129 agent,
130 })
131}
132
133#[derive(Debug, Deserialize)]
138#[serde(rename_all = "camelCase")]
139pub struct DeleteParams {
140 pub id: String,
141}
142
143#[derive(Debug, Serialize)]
144pub struct DeleteResult {
145 pub deleted: bool,
146}
147
148pub async fn delete(state: &AppState, params: DeleteParams) -> Result<DeleteResult, RpcError> {
149 state.agent_store.delete(¶ms.id).await?;
150 Ok(DeleteResult { deleted: true })
151}
152
153#[derive(Debug, Deserialize)]
158#[serde(rename_all = "camelCase")]
159pub struct UpdateStatusParams {
160 pub id: String,
161 pub status: String,
162}
163
164#[derive(Debug, Serialize)]
165pub struct UpdateStatusResult {
166 pub updated: bool,
167}
168
169pub async fn update_status(
170 state: &AppState,
171 params: UpdateStatusParams,
172) -> Result<UpdateStatusResult, RpcError> {
173 let status = AgentStatus::from_str(¶ms.status)
174 .ok_or_else(|| RpcError::BadRequest(format!("Invalid status: {}", params.status)))?;
175 state.agent_store.update_status(¶ms.id, &status).await?;
176 Ok(UpdateStatusResult { updated: true })
177}