1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3
4use crate::constants::{defaults, tools};
5
6#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
8#[derive(Debug, Clone, Deserialize, Serialize)]
9pub struct ToolsConfig {
10 #[serde(default = "default_tool_policy")]
12 pub default_policy: ToolPolicy,
13
14 #[serde(default)]
16 #[cfg_attr(
17 feature = "schema",
18 schemars(with = "std::collections::BTreeMap<String, ToolPolicy>")
19 )]
20 pub policies: IndexMap<String, ToolPolicy>,
21
22 #[serde(default = "default_max_tool_loops")]
29 pub max_tool_loops: usize,
30
31 #[serde(default = "default_max_repeated_tool_calls")]
34 pub max_repeated_tool_calls: usize,
35
36 #[serde(default)]
38 pub web_fetch: WebFetchConfig,
39}
40
41#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
43#[derive(Debug, Clone, Deserialize, Serialize)]
44pub struct WebFetchConfig {
45 #[serde(default = "default_web_fetch_mode")]
47 pub mode: String,
48
49 #[serde(default)]
51 pub dynamic_blocklist_enabled: bool,
52
53 #[serde(default)]
55 pub dynamic_blocklist_path: String,
56
57 #[serde(default)]
59 pub dynamic_whitelist_enabled: bool,
60
61 #[serde(default)]
63 pub dynamic_whitelist_path: String,
64
65 #[serde(default)]
67 pub blocked_domains: Vec<String>,
68
69 #[serde(default)]
71 pub allowed_domains: Vec<String>,
72
73 #[serde(default)]
75 pub blocked_patterns: Vec<String>,
76
77 #[serde(default)]
79 pub enable_audit_logging: bool,
80
81 #[serde(default)]
83 pub audit_log_path: String,
84
85 #[serde(default = "default_strict_https")]
87 pub strict_https_only: bool,
88}
89
90impl Default for ToolsConfig {
91 fn default() -> Self {
92 let policies = DEFAULT_TOOL_POLICIES
93 .iter()
94 .map(|(tool, policy)| ((*tool).into(), *policy))
95 .collect::<IndexMap<_, _>>();
96 Self {
97 default_policy: default_tool_policy(),
98 policies,
99 max_tool_loops: default_max_tool_loops(),
100 max_repeated_tool_calls: default_max_repeated_tool_calls(),
101 web_fetch: WebFetchConfig::default(),
102 }
103 }
104}
105
106const DEFAULT_BLOCKLIST_PATH: &str = "~/.vtcode/web_fetch_blocklist.json";
107const DEFAULT_WHITELIST_PATH: &str = "~/.vtcode/web_fetch_whitelist.json";
108const DEFAULT_AUDIT_LOG_PATH: &str = "~/.vtcode/web_fetch_audit.log";
109
110impl Default for WebFetchConfig {
111 fn default() -> Self {
112 Self {
113 mode: default_web_fetch_mode(),
114 dynamic_blocklist_enabled: false,
115 dynamic_blocklist_path: DEFAULT_BLOCKLIST_PATH.into(),
116 dynamic_whitelist_enabled: false,
117 dynamic_whitelist_path: DEFAULT_WHITELIST_PATH.into(),
118 blocked_domains: Vec::new(),
119 allowed_domains: Vec::new(),
120 blocked_patterns: Vec::new(),
121 enable_audit_logging: false,
122 audit_log_path: DEFAULT_AUDIT_LOG_PATH.into(),
123 strict_https_only: true,
124 }
125 }
126}
127
128#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
130#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
131#[serde(rename_all = "lowercase")]
132pub enum ToolPolicy {
133 Allow,
135 Prompt,
137 Deny,
139}
140
141#[inline]
142const fn default_tool_policy() -> ToolPolicy {
143 ToolPolicy::Prompt
144}
145
146#[inline]
147const fn default_max_tool_loops() -> usize {
148 defaults::DEFAULT_MAX_TOOL_LOOPS
149}
150
151#[inline]
152const fn default_max_repeated_tool_calls() -> usize {
153 defaults::DEFAULT_MAX_REPEATED_TOOL_CALLS
154}
155
156#[inline]
157fn default_web_fetch_mode() -> String {
158 "restricted".into()
159}
160
161fn default_strict_https() -> bool {
162 true
163}
164
165const DEFAULT_TOOL_POLICIES: &[(&str, ToolPolicy)] = &[
166 (tools::LIST_FILES, ToolPolicy::Allow),
168 (tools::GREP_FILE, ToolPolicy::Allow),
169 (tools::READ_FILE, ToolPolicy::Allow),
170 (tools::WRITE_FILE, ToolPolicy::Allow),
172 (tools::EDIT_FILE, ToolPolicy::Allow),
173 (tools::CREATE_FILE, ToolPolicy::Allow),
174 (tools::DELETE_FILE, ToolPolicy::Prompt),
176 (tools::APPLY_PATCH, ToolPolicy::Prompt),
177 (tools::RUN_PTY_CMD, ToolPolicy::Allow),
179 (tools::CREATE_PTY_SESSION, ToolPolicy::Allow),
180 (tools::READ_PTY_SESSION, ToolPolicy::Allow),
181 (tools::LIST_PTY_SESSIONS, ToolPolicy::Allow),
182 (tools::RESIZE_PTY_SESSION, ToolPolicy::Allow),
183 (tools::SEND_PTY_INPUT, ToolPolicy::Prompt),
184 (tools::CLOSE_PTY_SESSION, ToolPolicy::Allow),
185 (tools::EXECUTE_CODE, ToolPolicy::Prompt),
187 (tools::UPDATE_PLAN, ToolPolicy::Allow),
189 (tools::SEARCH_TOOLS, ToolPolicy::Allow),
190 (tools::SAVE_SKILL, ToolPolicy::Allow),
192 (tools::LOAD_SKILL, ToolPolicy::Allow),
193 (tools::LIST_SKILLS, ToolPolicy::Allow),
194 (tools::SEARCH_SKILLS, ToolPolicy::Allow),
195 (tools::GET_ERRORS, ToolPolicy::Allow),
198 (tools::DEBUG_AGENT, ToolPolicy::Allow),
200 (tools::ANALYZE_AGENT, ToolPolicy::Allow),
202 (tools::WEB_FETCH, ToolPolicy::Prompt),
204];