//! Sequential thinking tool — step-by-step reasoning. //! //! Allows the agent to record one step of a chain-of-thought reasoning process, //! tracking progress through a planned number of steps. use crate::tools::{Tool, ToolCtx}; use anyhow::Result; use serde_json::{json, Value}; use tracing::{info, instrument}; /// Perform sequential / step-by-step reasoning (chain-of-thought). /// /// Flow: extract thought, step number, total steps, and continuation flag from /// args → format into a reasoning step response. pub struct SeqThink; impl Tool for SeqThink { fn name(&self) -> &'static str { "sequential_think" } fn description(&self) -> &'static str { "Perform sequential / step-by-step reasoning (chain-of-thought)" } fn parameters(&self) -> Value { json!({ "type": "object", "properties": { "thought": { "type": "string", "description": "The current step of reasoning" }, "step_number": { "type": "integer", "description": "Current step number" }, "total_steps": { "type": "integer", "description": "Total number of steps planned" }, "next_thought_needed": { "type": "boolean", "description": "Whether another thinking step is needed" } }, "required": ["thought"] }) } #[instrument(skip(self, _ctx, args))] fn run(&self, _ctx: &ToolCtx, args: &Value) -> Result { let thought = crate::tools::arg_str(args, "thought")?; let step = args .get("step_number") .and_then(|v| v.as_i64()) .unwrap_or(0); let total = args .get("total_steps") .and_then(|v| v.as_i64()) .unwrap_or(1); let next_needed = args .get("next_thought_needed") .and_then(|v| v.as_bool()) .unwrap_or(false); info!(step, total, next_needed, "sequential think step"); Ok(format!( "Step {}/{}: {}\n{}", step, total, thought, if next_needed { "Continuing reasoning..." } else { "Reasoning complete." } )) } }