Skip to main content

synaps_cli/tools/
respond.rs

1//! RespondTool — reply to an event through its original source channel.
2use serde_json::{json, Value};
3use crate::Result;
4use super::{Tool, ToolContext};
5
6pub struct RespondTool;
7
8#[async_trait::async_trait]
9impl Tool for RespondTool {
10    fn name(&self) -> &str { "respond" }
11
12    fn description(&self) -> &str {
13        "Reply to an event through its original source channel. Sends the response text back via the event's callback URL or logs it if no callback is available."
14    }
15
16    fn parameters(&self) -> Value {
17        json!({
18            "type": "object",
19            "properties": {
20                "event_id": { "type": "string", "description": "ID of the event to respond to" },
21                "text":     { "type": "string", "description": "Response message" }
22            },
23            "required": ["event_id", "text"]
24        })
25    }
26
27    async fn execute(&self, params: Value, _ctx: ToolContext) -> Result<String> {
28        let event_id = params["event_id"].as_str()
29            .ok_or_else(|| crate::RuntimeError::Tool("Missing 'event_id' parameter".to_string()))?
30            .to_string();
31        let text = params["text"].as_str()
32            .ok_or_else(|| crate::RuntimeError::Tool("Missing 'text' parameter".to_string()))?
33            .to_string();
34
35        tracing::info!(event_id = %event_id, "respond tool invoked: {}", text);
36
37        // NOT YET IMPLEMENTED — return clear failure so the model knows
38        Ok(json!({
39            "responded": false,
40            "error": "respond tool is not yet implemented — callback dispatch not wired",
41            "event_id": event_id,
42        }).to_string())
43    }
44}