synaps_cli/tools/subagent/
collect.rs1use serde_json::{json, Value};
10use crate::{Result, RuntimeError};
11use super::super::{Tool, ToolContext};
12use crate::runtime::subagent::SubagentStatus;
13
14
15pub struct SubagentCollectTool;
16
17#[async_trait::async_trait]
18impl Tool for SubagentCollectTool {
19 fn name(&self) -> &str { "subagent_collect" }
20
21 fn description(&self) -> &str {
22 "Check if a reactive subagent is done and return its result. Non-blocking — \
23 returns immediately. If still running, returns status and partial output. \
24 If finished, returns the full result. Call repeatedly to poll for completion."
25 }
26
27 fn parameters(&self) -> Value {
28 json!({
29 "type": "object",
30 "properties": {
31 "handle_id": {
32 "type": "string",
33 "description": "Handle ID returned by subagent_start (e.g. \"sa_3\")."
34 }
35 },
36 "required": ["handle_id"]
37 })
38 }
39
40 async fn execute(&self, params: Value, ctx: ToolContext) -> Result<String> {
41 let handle_id = params["handle_id"].as_str()
42 .ok_or_else(|| RuntimeError::Tool("Missing 'handle_id' parameter".to_string()))?
43 .to_string();
44
45 let registry = ctx.capabilities.subagent_registry.as_ref()
46 .ok_or_else(|| RuntimeError::Tool(
47 "SubagentRegistry not available on this ToolContext".to_string()
48 ))?;
49
50 let reg = registry.lock().unwrap();
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 status = handle.status();
58 let output: String = handle.partial_output();
59 let elapsed = handle.elapsed_secs();
60 let _ = handle;
61 drop(reg);
62
63 if status == SubagentStatus::Running {
64 let char_count = output.chars().count();
66 let output_so_far: String = if char_count > 500 {
67 output.chars().skip(char_count - 500).collect()
68 } else {
69 output
70 };
71 return Ok(json!({
72 "handle_id": handle_id,
73 "status": "running",
74 "elapsed_secs": (elapsed * 10.0).round() / 10.0,
75 "output_so_far": output_so_far
76 }).to_string());
77 }
78
79 Ok(json!({
81 "handle_id": handle_id,
82 "status": status.as_str(),
83 "output": output
84 }).to_string())
85 }
86}