use std::sync::Arc;
use async_trait::async_trait;
use serde_json::{json, Value};
use crate::error::Result;
use crate::tools::{Tool, ToolContext};
pub const FINISH_TOOL_NAME: &str = "finish";
pub struct Finish;
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
impl Tool for Finish {
fn name(&self) -> &str {
FINISH_TOOL_NAME
}
fn description(&self) -> &str {
"Signal that the turn is complete. This is the ABSOLUTE END of the turn — \
calling it stops the loop immediately; do NOT add a separate closing reply, \
and do NOT call it just to say a final sentence. Only pass `summary` (one or \
two sentences) when the turn would otherwise end SILENTLY — i.e. you ran \
tools but said nothing this turn; it is shown as the closing reply ONLY in \
that case and is ignored if you already replied in text. Pass `output` when \
the agent is configured with a response schema; it will be returned to the \
caller as the structured output of this turn."
}
fn input_schema(&self) -> Value {
json!({
"type": "object",
"properties": {
"summary": { "type": "string", "description": "Optional short closing message, shown ONLY when the turn would otherwise end silently after tool calls (ignored if you already replied in text this turn)." },
"output": { "description": "Optional structured output. Must conform to the agent's response_schema when one is set." }
}
})
}
async fn execute(&self, args: Value, _ctx: Option<Arc<ToolContext>>) -> Result<Value> {
Ok(json!({ "ok": true, "args": args }))
}
}