1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3
4use crate::constants::{defaults, tools};
5use crate::core::plugins::PluginRuntimeConfig;
6
7#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
9#[derive(Debug, Clone, Deserialize, Serialize)]
10pub struct ToolsConfig {
11 #[serde(default = "default_tool_policy")]
13 pub default_policy: ToolPolicy,
14
15 #[serde(default)]
17 #[cfg_attr(
18 feature = "schema",
19 schemars(with = "std::collections::BTreeMap<String, ToolPolicy>")
20 )]
21 pub policies: IndexMap<String, ToolPolicy>,
22
23 #[serde(default = "default_max_tool_loops")]
30 pub max_tool_loops: usize,
31
32 #[serde(default = "default_max_repeated_tool_calls")]
35 pub max_repeated_tool_calls: usize,
36
37 #[serde(default = "default_max_tool_rate_per_second")]
40 pub max_tool_rate_per_second: Option<usize>,
41
42 #[serde(default)]
44 pub web_fetch: WebFetchConfig,
45
46 #[serde(default)]
48 pub plugins: PluginRuntimeConfig,
49}
50
51#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
53#[derive(Debug, Clone, Deserialize, Serialize)]
54pub struct WebFetchConfig {
55 #[serde(default = "default_web_fetch_mode")]
57 pub mode: String,
58
59 #[serde(default)]
61 pub dynamic_blocklist_enabled: bool,
62
63 #[serde(default)]
65 pub dynamic_blocklist_path: String,
66
67 #[serde(default)]
69 pub dynamic_whitelist_enabled: bool,
70
71 #[serde(default)]
73 pub dynamic_whitelist_path: String,
74
75 #[serde(default)]
77 pub blocked_domains: Vec<String>,
78
79 #[serde(default)]
81 pub allowed_domains: Vec<String>,
82
83 #[serde(default)]
85 pub blocked_patterns: Vec<String>,
86
87 #[serde(default)]
89 pub enable_audit_logging: bool,
90
91 #[serde(default)]
93 pub audit_log_path: String,
94
95 #[serde(default = "default_strict_https")]
97 pub strict_https_only: bool,
98}
99
100impl Default for ToolsConfig {
101 fn default() -> Self {
102 let policies = DEFAULT_TOOL_POLICIES
103 .iter()
104 .map(|(tool, policy)| ((*tool).into(), *policy))
105 .collect::<IndexMap<_, _>>();
106 Self {
107 default_policy: default_tool_policy(),
108 policies,
109 max_tool_loops: default_max_tool_loops(),
110 max_repeated_tool_calls: default_max_repeated_tool_calls(),
111 max_tool_rate_per_second: default_max_tool_rate_per_second(),
112 web_fetch: WebFetchConfig::default(),
113 plugins: PluginRuntimeConfig::default(),
114 }
115 }
116}
117
118const DEFAULT_BLOCKLIST_PATH: &str = "~/.vtcode/web_fetch_blocklist.json";
119const DEFAULT_WHITELIST_PATH: &str = "~/.vtcode/web_fetch_whitelist.json";
120const DEFAULT_AUDIT_LOG_PATH: &str = "~/.vtcode/web_fetch_audit.log";
121
122impl Default for WebFetchConfig {
123 fn default() -> Self {
124 Self {
125 mode: default_web_fetch_mode(),
126 dynamic_blocklist_enabled: false,
127 dynamic_blocklist_path: DEFAULT_BLOCKLIST_PATH.into(),
128 dynamic_whitelist_enabled: false,
129 dynamic_whitelist_path: DEFAULT_WHITELIST_PATH.into(),
130 blocked_domains: Vec::new(),
131 allowed_domains: Vec::new(),
132 blocked_patterns: Vec::new(),
133 enable_audit_logging: false,
134 audit_log_path: DEFAULT_AUDIT_LOG_PATH.into(),
135 strict_https_only: true,
136 }
137 }
138}
139
140#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
142#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
143#[serde(rename_all = "lowercase")]
144pub enum ToolPolicy {
145 Allow,
147 Prompt,
149 Deny,
151}
152
153#[inline]
154const fn default_tool_policy() -> ToolPolicy {
155 ToolPolicy::Prompt
156}
157
158#[inline]
159const fn default_max_tool_loops() -> usize {
160 defaults::DEFAULT_MAX_TOOL_LOOPS
161}
162
163#[inline]
164const fn default_max_repeated_tool_calls() -> usize {
165 defaults::DEFAULT_MAX_REPEATED_TOOL_CALLS
166}
167
168#[inline]
169const fn default_max_tool_rate_per_second() -> Option<usize> {
170 None
171}
172
173#[inline]
174fn default_web_fetch_mode() -> String {
175 "restricted".into()
176}
177
178fn default_strict_https() -> bool {
179 true
180}
181
182const DEFAULT_TOOL_POLICIES: &[(&str, ToolPolicy)] = &[
183 (tools::LIST_FILES, ToolPolicy::Allow),
185 (tools::GREP_FILE, ToolPolicy::Allow),
186 (tools::READ_FILE, ToolPolicy::Allow),
187 (tools::WRITE_FILE, ToolPolicy::Allow),
189 (tools::EDIT_FILE, ToolPolicy::Allow),
190 (tools::CREATE_FILE, ToolPolicy::Allow),
191 (tools::DELETE_FILE, ToolPolicy::Prompt),
193 (tools::APPLY_PATCH, ToolPolicy::Prompt),
194 (tools::SEARCH_REPLACE, ToolPolicy::Prompt),
195 (tools::RUN_PTY_CMD, ToolPolicy::Prompt),
197 (tools::CREATE_PTY_SESSION, ToolPolicy::Allow),
198 (tools::READ_PTY_SESSION, ToolPolicy::Allow),
199 (tools::LIST_PTY_SESSIONS, ToolPolicy::Allow),
200 (tools::RESIZE_PTY_SESSION, ToolPolicy::Allow),
201 (tools::SEND_PTY_INPUT, ToolPolicy::Prompt),
202 (tools::CLOSE_PTY_SESSION, ToolPolicy::Allow),
203 (tools::EXECUTE_CODE, ToolPolicy::Prompt),
205 (tools::SEARCH_TOOLS, ToolPolicy::Allow),
207 (tools::SKILL, ToolPolicy::Allow),
208 (tools::WEB_FETCH, ToolPolicy::Prompt),
211];