synaps_cli/tools/subagent/
status.rs1use serde_json::{json, Value};
8use crate::{Result, RuntimeError};
9use super::super::{Tool, ToolContext};
10
11pub struct SubagentStatusTool;
12
13#[async_trait::async_trait]
14impl Tool for SubagentStatusTool {
15 fn name(&self) -> &str { "subagent_status" }
16
17 fn description(&self) -> &str {
18 "Poll the current state of a reactive subagent. Returns status \
19 (running/finished/timed_out/failed), the last 500 characters of output \
20 produced so far, elapsed time in seconds, and the number of tool calls \
21 made. Non-blocking — returns immediately."
22 }
23
24 fn parameters(&self) -> Value {
25 json!({
26 "type": "object",
27 "properties": {
28 "handle_id": {
29 "type": "string",
30 "description": "Handle ID returned by subagent_start (e.g. \"sa_3\")."
31 }
32 },
33 "required": ["handle_id"]
34 })
35 }
36
37 async fn execute(&self, params: Value, ctx: ToolContext) -> Result<String> {
38 let handle_id = params["handle_id"].as_str()
39 .ok_or_else(|| RuntimeError::Tool("Missing 'handle_id' parameter".to_string()))?
40 .to_string();
41
42 let registry = ctx.capabilities.subagent_registry.as_ref()
45 .ok_or_else(|| RuntimeError::Tool(
46 "SubagentRegistry not available on this ToolContext".to_string()
47 ))?;
48
49 let reg = registry.lock().unwrap();
50
51 let handle = reg.get(&handle_id)
52 .ok_or_else(|| RuntimeError::Tool(
53 format!("No subagent found with handle_id '{}'", handle_id)
54 ))?;
55
56 let full: String = handle.partial_output();
59 let agent_name = handle.agent_name.clone();
60 let status_str = handle.status().as_str().to_string();
61 let elapsed = handle.elapsed_secs();
62 let tool_count = handle.tool_log().len();
63 let _ = handle;
64 drop(reg);
65
66 let char_count = full.chars().count();
67 let partial_output: String = if char_count > 500 {
68 full.chars().skip(char_count - 500).collect()
69 } else {
70 full
71 };
72
73 Ok(json!({
74 "handle_id": handle_id,
75 "agent_name": agent_name,
76 "status": status_str,
77 "partial_output": partial_output,
78 "elapsed_secs": (elapsed * 10.0).round() / 10.0,
79 "tool_count": tool_count
80 }).to_string())
81 }
82}