Skip to main content

claude_rust_tools/infrastructure/
send_message_tool.rs

1use claude_rust_errors::AppResult;
2use claude_rust_types::{PermissionLevel, Tool};
3use serde_json::{Value, json};
4
5/// Tool to send a message to an agent or team.
6///
7/// TODO: Phase 5 — integrate with real message routing.
8pub struct SendMessageTool;
9
10impl SendMessageTool {
11    pub fn new() -> Self {
12        Self
13    }
14}
15
16#[async_trait::async_trait]
17impl Tool for SendMessageTool {
18    fn name(&self) -> &str {
19        "send_message"
20    }
21
22    fn description(&self) -> &str {
23        "Send a message to a named agent or team."
24    }
25
26    fn input_schema(&self) -> Value {
27        json!({
28            "type": "object",
29            "properties": {
30                "to": {
31                    "type": "string",
32                    "description": "Name of the agent or team to send the message to"
33                },
34                "message": {
35                    "type": "string",
36                    "description": "The message content to send"
37                }
38            },
39            "required": ["to", "message"]
40        })
41    }
42
43    fn permission_level(&self) -> PermissionLevel {
44        PermissionLevel::Dangerous
45    }
46
47    async fn execute(&self, input: Value) -> AppResult<String> {
48        let to = input
49            .get("to")
50            .and_then(|v| v.as_str())
51            .ok_or_else(|| claude_rust_errors::AppError::Tool("missing 'to' field".into()))?;
52
53        let message = input
54            .get("message")
55            .and_then(|v| v.as_str())
56            .ok_or_else(|| claude_rust_errors::AppError::Tool("missing 'message' field".into()))?;
57
58        // TODO: Phase 5 — replace stub with real message routing
59        tracing::info!(to, message_len = message.len(), "sending message (stub)");
60
61        Ok(format!("Message delivered to '{to}'. Length: {} chars.", message.len()))
62    }
63}