Skip to main content

vtcode_config/constants/
tools.rs

1// ============================================================
2// MODEL-FACING TOOLS
3// ============================================================
4/// Canonical shell execution tool exposed to the model.
5pub const EXEC_COMMAND: &str = "exec_command";
6/// Canonical stdin writer for active execution sessions.
7pub const WRITE_STDIN: &str = "write_stdin";
8/// Canonical patch application tool exposed to the model.
9pub const APPLY_PATCH: &str = "apply_patch";
10/// Optional public rationale recording within the canonical current task.
11pub const RECORD_DECISION: &str = "record_decision";
12/// Advanced bounded syntactic code search tool for VTCode-specific profiles.
13pub const CODE_SEARCH: &str = "code_search";
14
15// ============================================================
16// LEGACY INTERNAL DISPATCHERS
17// ============================================================
18/// Internal search and discovery dispatcher retained behind public tools.
19pub const UNIFIED_SEARCH: &str = "search_dispatch_internal";
20/// Internal shell execution and code execution dispatcher retained behind public tools.
21pub const UNIFIED_EXEC: &str = "command_session_internal";
22/// Internal file operations dispatcher retained behind public tools.
23pub const UNIFIED_FILE: &str = "file_operation_internal";
24
25// ============================================================
26// TOOL IDS
27// ============================================================
28pub const THINK: &str = "think";
29pub const SEARCH_TOOLS: &str = "search_tools";
30/// Unified MCP tool (action: search_tools | get_tool_details | list_servers |
31/// connect | disconnect). `connect`/`disconnect` are config-gated lifecycle
32/// ops evaluated under the action-qualified policy keys `mcp:connect` /
33/// `mcp:disconnect` (default Prompt) so they keep their human-in-the-loop
34/// confirmation even though the base `mcp` tool is `ToolPolicy::Allow`.
35pub const MCP: &str = "mcp";
36pub const MCP_SEARCH_TOOLS: &str = "mcp_search_tools";
37pub const MCP_GET_TOOL_DETAILS: &str = "mcp_get_tool_details";
38pub const MCP_LIST_SERVERS: &str = "mcp_list_servers";
39pub const MCP_CONNECT_SERVER: &str = "mcp_connect_server";
40pub const MCP_DISCONNECT_SERVER: &str = "mcp_disconnect_server";
41pub const WEB_SEARCH: &str = "web_search";
42pub const WEB_FETCH: &str = "web_fetch";
43pub const FETCH_URL: &str = "fetch_url";
44/// Defuddle-backed markdown extraction for a single URL. The hosted
45/// `defuddle.md/{link}` service is rate-limited, so this tool is hard-capped
46/// at one call per tool instance (treat one tool instance as one session).
47pub const DEFUDDLE_FETCH: &str = "defuddle_fetch";
48pub const LIST: &str = "list";
49pub const GREP: &str = "grep";
50pub const FETCH: &str = "fetch";
51pub const EXEC_PTY_CMD: &str = "exec_pty_cmd";
52pub const SHELL: &str = "shell";
53pub const GREP_FILE: &str = "grep_file";
54pub const LIST_FILES: &str = "list_files";
55
56// ============================================================
57// SKILL MANAGEMENT TOOLS (Progressive Disclosure)
58// ============================================================
59/// List all available skills (local and dormant system utilities)
60pub const LIST_SKILLS: &str = "list_skills";
61/// Load a skill's instructions and activate its tools
62pub const LOAD_SKILL: &str = "load_skill";
63/// Load resources from a skill (scripts, templates, docs)
64pub const LOAD_SKILL_RESOURCE: &str = "load_skill_resource";
65
66// ============================================================
67// INTERNAL EXECUTION HELPERS
68// ============================================================
69pub const RUN_PTY_CMD: &str = "run_pty_cmd";
70pub const CREATE_PTY_SESSION: &str = "create_pty_session";
71pub const LIST_PTY_SESSIONS: &str = "list_pty_sessions";
72pub const CLOSE_PTY_SESSION: &str = "close_pty_session";
73pub const SEND_PTY_INPUT: &str = "send_pty_input";
74pub const READ_PTY_SESSION: &str = "read_pty_session";
75pub const RESIZE_PTY_SESSION: &str = "resize_pty_session";
76pub const EXECUTE_CODE: &str = "execute_code";
77
78// ============================================================
79// INTERNAL FILE OPERATION HELPERS
80// ============================================================
81pub const READ_FILE: &str = "read_file";
82pub const WRITE_FILE: &str = "write_file";
83pub const EDIT_FILE: &str = "edit_file";
84pub const DELETE_FILE: &str = "delete_file";
85pub const CREATE_FILE: &str = "create_file";
86pub const SEARCH_REPLACE: &str = "search_replace";
87pub const FILE_OP: &str = "file_op";
88pub const MOVE_FILE: &str = "move_file";
89pub const COPY_FILE: &str = "copy_file";
90
91// ============================================================
92// ERROR & DIAGNOSTICS
93// ============================================================
94pub const GET_ERRORS: &str = "get_errors";
95
96// ============================================================
97// HUMAN-IN-THE-LOOP (HITL)
98// ============================================================
99/// Canonical HITL tool name for structured user input.
100pub const REQUEST_USER_INPUT: &str = "request_user_input";
101/// Canonical memory tool name for Anthropic native memory sessions.
102pub const MEMORY: &str = "memory";
103/// Legacy alias routed to `request_user_input`.
104pub const ASK_QUESTIONS: &str = "ask_questions";
105/// Legacy alias routed to `request_user_input` (deprecated tabbed shape).
106pub const ASK_USER_QUESTION: &str = "ask_user_question";
107/// Durable scheduler control for coordinators and assignment-owned worker reports.
108pub const MATRIX: &str = "matrix";
109/// Unified subagent lifecycle tool (action: spawn | spawn_subprocess |
110/// send_input | resume | wait | close). `wait_agent`/`close_agent` are now
111/// aliases routed to `agent` (action='wait'/'close'); `LIFECYCLE_CLEANUP_TOOLS`
112/// still lists their names so the policy layer keeps treating them as
113/// always-allowed cleanup calls regardless of the active primary agent's
114/// restricted tool policy.
115pub const AGENT: &str = "agent";
116/// Unified scheduled-prompt tool (action: create | list | delete).
117pub const CRON: &str = "cron";
118/// Legacy alias for `cron` action=create.
119pub const CRON_CREATE: &str = "cron_create";
120/// List session-scoped scheduled tasks.
121pub const CRON_LIST: &str = "cron_list";
122/// Delete a session-scoped scheduled task by id.
123pub const CRON_DELETE: &str = "cron_delete";
124
125// ============================================================
126// PLANNING WORKFLOW
127// ============================================================
128/// Start planning - enables read-only tools and planning workflow.
129pub const START_PLANNING: &str = "start_planning";
130/// Task tracker / plan manager - tracks checklist progress during complex tasks.
131pub const TASK_TRACKER: &str = "task_tracker";
132
133// ============================================================
134// SUBAGENT COLLABORATION
135// ============================================================
136/// Spawn a delegated child agent.
137pub const SPAWN_AGENT: &str = "spawn_agent";
138/// Launch a managed background subprocess that hosts a background-enabled subagent.
139pub const SPAWN_BACKGROUND_SUBPROCESS: &str = "spawn_background_subprocess";
140/// Send follow-up input to a delegated child agent.
141pub const SEND_INPUT: &str = "send_input";
142/// Wait for one or more delegated child agents to finish.
143pub const WAIT_AGENT: &str = "wait_agent";
144/// Resume a delegated child agent without sending a message.
145pub const RESUME_AGENT: &str = "resume_agent";
146/// Close a delegated child agent.
147pub const CLOSE_AGENT: &str = "close_agent";
148/// Ask a peer CLI session in this workspace a question.
149pub const ASK_SESSION: &str = "ask_session";
150/// Answer a question received from a peer CLI session.
151pub const ANSWER_SESSION: &str = "answer_session";
152/// List live peer CLI sessions in this workspace.
153pub const LIST_SESSIONS: &str = "list_sessions";
154
155/// Cleanup-only child-agent tools that must remain available regardless of the
156/// active primary agent's tool policy, so restricted primaries can still join or
157/// close already-running child work. Add new lifecycle-only cleanup tools here.
158pub const LIFECYCLE_CLEANUP_TOOLS: &[&str] = &[WAIT_AGENT, CLOSE_AGENT];
159
160/// Workflow-coordination tools that must remain available regardless of the
161/// `[automation.full_auto].allowed_tools` allow-list, so planning, checklist,
162/// and interview coordination keep working in Auto mode and other full-auto
163/// runs. These are control-plane (not execution blast radius): `task_tracker`
164/// owns only its session tracker file, `start_planning` only flips the
165/// planning-workflow state, and `request_user_input` still resolves through
166/// the interactive-session gate at execution time. Callers must pass the
167/// canonical tool name (see `canonical_tool_name`); matching is exact.
168pub const ALWAYS_AVAILABLE_WORKFLOW_TOOLS: &[&str] = &[TASK_TRACKER, START_PLANNING, REQUEST_USER_INPUT, MATRIX];
169
170/// Returns `true` for workflow-coordination tools that bypass the full-auto
171/// allow-list (see [`ALWAYS_AVAILABLE_WORKFLOW_TOOLS`]).
172#[inline]
173pub fn is_workflow_coordination_tool(canonical_name: &str) -> bool {
174    ALWAYS_AVAILABLE_WORKFLOW_TOOLS.contains(&canonical_name)
175}
176
177// Special wildcard for full access
178pub const WILDCARD_ALL: &str = "*";
179
180// ===========================================================================
181// Compile-time validation
182//
183// All tool name constants are validated at compile time. These assertions
184// ensure every name is non-empty, uses only [a-z0-9_], and contains no
185// leading/trailing underscores (which would signal a naming convention
186// violation). The wildcard "*" is exempt from character checks.
187// ===========================================================================
188
189const _: () = {
190    /// Validate a tool name at compile time. Panics with a clear message
191    /// if the name is empty, contains invalid characters, or has leading/
192    /// trailing underscores (except for the wildcard "*").
193    const fn validate_tool_name(name: &str) {
194        assert!(!name.is_empty(), "tool name must not be empty");
195        let bytes = name.as_bytes();
196        // Wildcard "*" is the only name allowed to bypass character checks
197        if bytes.len() == 1 && bytes[0] == b'*' {
198            return;
199        }
200        assert!(
201            bytes[0] != b'_' && bytes[bytes.len() - 1] != b'_',
202            "tool name must not have leading/trailing underscores"
203        );
204        let mut i = 0;
205        while i < bytes.len() {
206            let b = bytes[i];
207            assert!(b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'_', "tool name must contain only [a-z0-9_]");
208            i += 1;
209        }
210    }
211
212    // Model-facing tools
213    validate_tool_name(EXEC_COMMAND);
214    validate_tool_name(WRITE_STDIN);
215    validate_tool_name(APPLY_PATCH);
216    validate_tool_name(CODE_SEARCH);
217
218    // Internal unified tools
219    validate_tool_name(UNIFIED_SEARCH);
220    validate_tool_name(UNIFIED_EXEC);
221    validate_tool_name(UNIFIED_FILE);
222
223    // Tool IDs
224    validate_tool_name(THINK);
225    validate_tool_name(SEARCH_TOOLS);
226    validate_tool_name(MCP);
227    validate_tool_name(MCP_SEARCH_TOOLS);
228    validate_tool_name(MCP_GET_TOOL_DETAILS);
229    validate_tool_name(MCP_LIST_SERVERS);
230    validate_tool_name(MCP_CONNECT_SERVER);
231    validate_tool_name(MCP_DISCONNECT_SERVER);
232    validate_tool_name(WEB_SEARCH);
233    validate_tool_name(WEB_FETCH);
234    validate_tool_name(FETCH_URL);
235    validate_tool_name(DEFUDDLE_FETCH);
236    validate_tool_name(LIST);
237    validate_tool_name(GREP);
238    validate_tool_name(FETCH);
239    validate_tool_name(EXEC_PTY_CMD);
240    validate_tool_name(SHELL);
241    validate_tool_name(GREP_FILE);
242    validate_tool_name(LIST_FILES);
243
244    // Skill management
245    validate_tool_name(LIST_SKILLS);
246    validate_tool_name(LOAD_SKILL);
247    validate_tool_name(LOAD_SKILL_RESOURCE);
248
249    // Internal execution helpers
250    validate_tool_name(RUN_PTY_CMD);
251    validate_tool_name(CREATE_PTY_SESSION);
252    validate_tool_name(LIST_PTY_SESSIONS);
253    validate_tool_name(CLOSE_PTY_SESSION);
254    validate_tool_name(SEND_PTY_INPUT);
255    validate_tool_name(READ_PTY_SESSION);
256    validate_tool_name(RESIZE_PTY_SESSION);
257    validate_tool_name(EXECUTE_CODE);
258
259    // Internal file operation helpers
260    validate_tool_name(READ_FILE);
261    validate_tool_name(WRITE_FILE);
262    validate_tool_name(EDIT_FILE);
263    validate_tool_name(DELETE_FILE);
264    validate_tool_name(CREATE_FILE);
265    validate_tool_name(SEARCH_REPLACE);
266    validate_tool_name(FILE_OP);
267    validate_tool_name(MOVE_FILE);
268    validate_tool_name(COPY_FILE);
269
270    // Error & diagnostics
271    validate_tool_name(GET_ERRORS);
272
273    // HITL
274    validate_tool_name(REQUEST_USER_INPUT);
275    validate_tool_name(MEMORY);
276    validate_tool_name(ASK_QUESTIONS);
277    validate_tool_name(ASK_USER_QUESTION);
278    validate_tool_name(AGENT);
279    validate_tool_name(CRON);
280    validate_tool_name(CRON_CREATE);
281    validate_tool_name(CRON_LIST);
282    validate_tool_name(CRON_DELETE);
283
284    // Planning workflow
285    validate_tool_name(START_PLANNING);
286    validate_tool_name(TASK_TRACKER);
287
288    // Subagent collaboration
289    validate_tool_name(SPAWN_AGENT);
290    validate_tool_name(SPAWN_BACKGROUND_SUBPROCESS);
291    validate_tool_name(SEND_INPUT);
292    validate_tool_name(WAIT_AGENT);
293    validate_tool_name(RESUME_AGENT);
294    validate_tool_name(CLOSE_AGENT);
295
296    // Wildcard
297    validate_tool_name(WILDCARD_ALL);
298};
299
300#[cfg(test)]
301mod tests {
302    use super::*;
303
304    #[test]
305    fn workflow_coordination_tools_bypass_the_full_auto_allow_list() {
306        for tool in [TASK_TRACKER, START_PLANNING, REQUEST_USER_INPUT] {
307            assert!(is_workflow_coordination_tool(tool), "{tool} must bypass the allow-list");
308        }
309    }
310
311    #[test]
312    fn execution_tools_do_not_bypass_the_full_auto_allow_list() {
313        for tool in [
314            EXEC_COMMAND,
315            WRITE_STDIN,
316            APPLY_PATCH,
317            CODE_SEARCH,
318            WEB_FETCH,
319            "not_a_tool",
320        ] {
321            assert!(!is_workflow_coordination_tool(tool), "{tool} must stay allow-list gated");
322        }
323    }
324}