Skip to main content

agent_code_lib/tools/
plan_mode.rs

1//! Plan mode tools: switch between execution and planning modes.
2//!
3//! Plan mode restricts the agent to read-only tools, preventing
4//! mutations while the user reviews and approves a plan.
5
6use async_trait::async_trait;
7use serde_json::json;
8
9use super::{Tool, ToolContext, ToolResult};
10use crate::error::ToolError;
11
12/// Enter plan mode (read-only operations only).
13pub struct EnterPlanModeTool;
14
15#[async_trait]
16impl Tool for EnterPlanModeTool {
17    fn name(&self) -> &'static str {
18        "EnterPlanMode"
19    }
20
21    fn description(&self) -> &'static str {
22        "Switch to plan mode. Only read-only tools will be available until \
23         ExitPlanMode is called. Use this when you need to think through \
24         an approach before making changes."
25    }
26
27    fn input_schema(&self) -> serde_json::Value {
28        json!({
29            "type": "object",
30            "properties": {}
31        })
32    }
33
34    fn is_read_only(&self) -> bool {
35        true
36    }
37
38    fn is_concurrency_safe(&self) -> bool {
39        true
40    }
41
42    async fn call(
43        &self,
44        _input: serde_json::Value,
45        _ctx: &ToolContext,
46    ) -> Result<ToolResult, ToolError> {
47        // Plan mode is tracked in AppState; the query engine enforces it.
48        Ok(ToolResult::success(
49            "Entered plan mode. Only read-only tools are available. \
50             Use ExitPlanMode when ready to execute.",
51        ))
52    }
53}
54
55/// Exit plan mode (re-enable all tools).
56pub struct ExitPlanModeTool;
57
58#[async_trait]
59impl Tool for ExitPlanModeTool {
60    fn name(&self) -> &'static str {
61        "ExitPlanMode"
62    }
63
64    fn description(&self) -> &'static str {
65        "Exit plan mode and re-enable all tools for execution."
66    }
67
68    fn input_schema(&self) -> serde_json::Value {
69        json!({
70            "type": "object",
71            "properties": {}
72        })
73    }
74
75    fn is_read_only(&self) -> bool {
76        true
77    }
78
79    fn is_concurrency_safe(&self) -> bool {
80        true
81    }
82
83    async fn call(
84        &self,
85        _input: serde_json::Value,
86        _ctx: &ToolContext,
87    ) -> Result<ToolResult, ToolError> {
88        Ok(ToolResult::success(
89            "Exited plan mode. All tools are now available.",
90        ))
91    }
92}