use crate::command::chat::agent::thread_identity::current_agent_name;
use crate::command::chat::teammate::TeammateManager;
use crate::command::chat::tools::{
PlanDecision, Tool, ToolResult, parse_tool_args, schema_to_tool_params,
};
use schemars::JsonSchema;
use serde::Deserialize;
use serde_json::Value;
use std::sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
};
#[derive(Deserialize, JsonSchema)]
struct WorkDoneParams {
#[serde(default)]
summary: Option<String>,
}
pub struct WorkDoneTool {
pub work_done: Arc<AtomicBool>,
pub teammate_manager: Arc<Mutex<TeammateManager>>,
}
impl WorkDoneTool {
pub const NAME: &'static str = "WorkDone";
}
impl Tool for WorkDoneTool {
fn name(&self) -> &str {
Self::NAME
}
fn description(&self) -> &str {
r#"
Declare that you have finished your assigned work and exit the chat loop.
Call this when your role's task is complete and you don't need to do anything else.
Once called, you will stop responding to general messages — the team will see you as finished.
IMPORTANT:
- Before calling WorkDone, send a SendMessage to @Main summarizing your results.
- If another agent @mentions you after WorkDone, you will be re-activated and can continue working.
- If another agent might still need you, DO NOT call WorkDone — just stay idle and wait.
- Do not call WorkDone just because the conversation is quiet; only call when your role's task is objectively done.
Usage:
{"summary": "前端页面已完成,所有组件在 src/components/"}
"#
}
fn parameters_schema(&self) -> Value {
schema_to_tool_params::<WorkDoneParams>()
}
fn execute(&self, arguments: &str, _cancelled: &Arc<AtomicBool>) -> ToolResult {
let params: WorkDoneParams = match parse_tool_args(arguments) {
Ok(p) => p,
Err(e) => return e,
};
let from = current_agent_name();
if let Ok(manager) = self.teammate_manager.lock()
&& let Ok(mut shared) = manager.ui_messages.lock()
{
let text = match params.summary.as_deref() {
Some(s) if !s.trim().is_empty() => {
format!("<{}> [已完成工作] {}", from, s.trim())
}
_ => format!("<{}> [已完成工作]", from),
};
shared.push(crate::command::chat::storage::ChatMessage::text(
"assistant",
text,
));
}
self.work_done.store(true, Ordering::Relaxed);
ToolResult {
output: format!("Teammate '{}' marked as done; exiting chat loop.", from),
is_error: false,
images: vec![],
plan_decision: PlanDecision::None,
}
}
fn requires_confirmation(&self) -> bool {
false
}
}