j_agent/tools/
ignore_message.rs1use crate::teammate::TeammateManager;
2use crate::tools::{PlanDecision, Tool, ToolResult, parse_tool_args, schema_to_tool_params};
3use schemars::JsonSchema;
4use serde::Deserialize;
5use serde_json::Value;
6use std::borrow::Cow;
7use std::sync::{Arc, Mutex, atomic::AtomicBool};
8
9#[derive(Deserialize, JsonSchema)]
10struct IgnoreMessageParams {
11 #[serde(default)]
13 #[allow(dead_code)]
14 reason: Option<String>,
15}
16
17pub struct IgnoreMessageTool {
27 pub teammate_manager: Option<Arc<Mutex<TeammateManager>>>,
28}
29
30impl IgnoreMessageTool {
31 pub const NAME: &'static str = "IgnoreMessage";
32}
33
34impl Tool for IgnoreMessageTool {
35 fn name(&self) -> &str {
36 Self::NAME
37 }
38
39 fn description(&self) -> Cow<'_, str> {
40 r#"
41 Acknowledge incoming broadcasts without producing any reply.
42
43 Call this when you were notified of broadcasts or @mentions but, after
44 reading them, decided no response is needed. This keeps you idle without
45 sending a noisy "ok"/"got it" message that would wake other agents.
46
47 Usage:
48 - reason: Optional one-line note for your own log (NOT broadcast).
49
50 Examples:
51 {}
52 {"reason": "B's progress update doesn't require my input"}
53 {"reason": "Noted schema change, does not affect my current task"}
54
55 IMPORTANT:
56 - Calling IgnoreMessage suppresses the prose of THIS turn — do NOT also
57 write any reply text; just call the tool.
58 - If a real response is needed, use SendMessage instead.
59 - You will remain idle until @mentioned again or until the chat is closed.
60 "#
61 .into()
62 }
63
64 fn parameters_schema(&self) -> Value {
65 schema_to_tool_params::<IgnoreMessageParams>()
66 }
67
68 fn execute(&self, arguments: &str, _cancelled: &Arc<AtomicBool>) -> ToolResult {
69 let _params: IgnoreMessageParams = match parse_tool_args(arguments) {
71 Ok(p) => p,
72 Err(e) => return e,
73 };
74
75 ToolResult {
76 output: "Messages acknowledged; no reply sent. Returning to idle.".to_string(),
77 is_error: false,
78 images: vec![],
79 plan_decision: PlanDecision::None,
80 }
81 }
82
83 fn requires_confirmation(&self) -> bool {
84 false
85 }
86
87 fn is_available(&self) -> bool {
88 match &self.teammate_manager {
89 Some(mgr) => mgr
90 .lock()
91 .map(|m| m.has_active_teammates())
92 .unwrap_or(false),
93 None => true,
94 }
95 }
96}