vtcode_core/config/mod.rs
1//! # Configuration Management System
2//!
3//! This module provides a comprehensive configuration management system for VTCode,
4//! handling TOML-based configuration files with support for policies, security settings,
5//! and runtime customization.
6//!
7//! ## Architecture Overview
8//!
9//! The configuration system is built around several key components:
10//!
11//! - **TOML Configuration**: Human-readable configuration files
12//! - **Layered Defaults**: Sensible defaults with user overrides
13//! - **Runtime Validation**: Configuration validation and error handling
14//! - **Hot Reloading**: Configuration changes without restart (where applicable)
15//! - **Security Controls**: Policy-based access control and restrictions
16//!
17//! ## Configuration Structure
18//!
19//! ```toml
20//! [agent]
21//! max_iterations = 50
22//! timeout_seconds = 300
23//! enable_decision_ledger = true
24//!
25//! [tools]
26//! max_tool_loops = 25
27//! default_policy = "prompt"
28//!
29//! [llm.providers.gemini]
30//! api_key = "your-key"
31//! model = "gemini-2.5-flash"
32//!
33//! [security]
34//! workspace_root = "/path/to/project"
35//! allow_network_access = false
36//! ```
37//!
38//! ## Basic Usage
39//!
40//! ```rust,no_run
41//! use vtcode_core::{VTCodeConfig, AgentConfig};
42//!
43//! #[tokio::main]
44//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
45//! // Load configuration from vtcode.toml
46//! let config = VTCodeConfig::load()?;
47//!
48//! // Access specific sections
49//! println!("Max iterations: {}", config.agent.max_iterations);
50//! println!("Default tool policy: {}", config.tools.default_policy);
51//!
52//! // Create agent with configuration
53//! let agent = vtcode_core::core::agent::core::Agent::new(config).await?;
54//!
55//! Ok(())
56//! }
57//! ```
58//!
59//! ## Configuration Sections
60//!
61//! ### Agent Configuration
62//! ```rust,no_run
63//! use vtcode_core::config::core::AgentConfig;
64//!
65//! let agent_config = AgentConfig {
66//! max_iterations: 100,
67//! timeout_seconds: 600,
68//! enable_decision_ledger: true,
69//! enable_conversation_summarization: true,
70//! ..Default::default()
71//! };
72//! ```
73//!
74//! ### Tool Configuration
75//! ```rust,no_run
76//! use vtcode_core::config::core::{ToolsConfig, ToolPolicy};
77//!
78//! let tools_config = ToolsConfig {
79//! max_tool_loops: 50,
80//! default_policy: ToolPolicy::Prompt,
81//! enable_file_operations: true,
82//! enable_terminal_commands: true,
83//! ..Default::default()
84//! };
85//! ```
86//!
87//! ### Security Configuration
88//! ```rust,no_run
89//! use vtcode_core::config::core::SecurityConfig;
90//!
91//! let security_config = SecurityConfig {
92//! workspace_root: "/path/to/secure/workspace".into(),
93//! allow_network_access: false,
94//! command_allowlist: vec!["git".to_string(), "cargo".to_string()],
95//! path_restrictions: vec!["*.secret".to_string()],
96//! ..Default::default()
97//! };
98//! ```
99//!
100//! ## Runtime Configuration Management
101//!
102//! ```rust,no_run
103//! use vtcode_core::config::loader::ConfigManager;
104//!
105//! #[tokio::main]
106//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
107//! let mut config_manager = ConfigManager::new()?;
108//!
109//! // Load configuration
110//! let config = config_manager.load_config().await?;
111//!
112//! // Modify configuration at runtime
113//! config.agent.max_iterations = 75;
114//!
115//! // Save changes
116//! config_manager.save_config(&config).await?;
117//!
118//! Ok(())
119//! }
120//! ```
121//!
122//! ## Environment Variables
123//!
124//! VTCode supports configuration through environment variables:
125//!
126//! ```bash
127//! # API Keys
128//! export GEMINI_API_KEY="your-gemini-key"
129//! export OPENAI_API_KEY="your-openai-key"
130//! export ANTHROPIC_API_KEY="your-anthropic-key"
131//!
132//! # Configuration
133//! export VTCode_WORKSPACE_DIR="/path/to/project"
134//! export VTCode_CONFIG_PATH="/path/to/vtcode.toml"
135//! ```
136//!
137//! ## Validation and Error Handling
138//!
139//! The configuration system provides comprehensive validation:
140//!
141//! ```rust,no_run
142//! use vtcode_core::VTCodeConfig;
143//!
144//! match VTCodeConfig::load() {
145//! Ok(config) => {
146//! // Configuration loaded successfully
147//! println!("Configuration valid");
148//! }
149//! Err(e) => {
150//! // Handle configuration errors
151//! eprintln!("Configuration error: {}", e);
152//! // Provide helpful error messages
153//! if e.to_string().contains("missing field") {
154//! eprintln!("Hint: Check your vtcode.toml file for required fields");
155//! }
156//! }
157//! }
158//! ```
159//!
160//! ## Security Best Practices
161//!
162//! - **Never commit API keys** to version control
163//! - **Use environment variables** for sensitive configuration
164//! - **Validate workspace paths** to prevent directory traversal
165//! - **Restrict command execution** to approved commands only
166//! - **Enable audit logging** for security monitoring
167
168//! VTCode Configuration Module
169//!
170//! This module handles loading and managing configuration from vtcode.toml files.
171//! It provides a centralized way to manage agent policies, tool permissions, and
172//! command allow lists.
173
174pub mod api_keys;
175pub mod constants;
176pub mod context;
177pub mod core;
178pub mod defaults;
179pub mod loader;
180pub mod mcp;
181pub mod models;
182pub mod router;
183pub mod telemetry;
184pub mod types;
185
186// Re-export main types for backward compatibility
187pub use context::{ContextFeaturesConfig, LedgerConfig};
188pub use core::{
189 AgentConfig, AutomationConfig, CommandsConfig, FullAutoConfig, SecurityConfig, ToolPolicy,
190 ToolsConfig,
191};
192pub use defaults::{ContextStoreDefaults, PerformanceDefaults, ScenarioDefaults};
193pub use loader::{ConfigManager, VTCodeConfig};
194pub use mcp::{
195 McpAllowListConfig, McpAllowListRules, McpClientConfig, McpHttpServerConfig, McpProviderConfig,
196 McpStdioServerConfig, McpTransportConfig, McpUiConfig, McpUiMode,
197};
198pub use router::{ComplexityModelMap, ResourceBudget, RouterConfig};
199pub use telemetry::TelemetryConfig;
200pub use types::ReasoningEffortLevel;
201
202use serde::{Deserialize, Serialize};
203
204#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
205#[serde(rename_all = "snake_case")]
206pub enum ToolOutputMode {
207 Compact,
208 Full,
209}
210
211impl Default for ToolOutputMode {
212 fn default() -> Self {
213 Self::Compact
214 }
215}
216
217#[derive(Debug, Clone, Deserialize, Serialize)]
218pub struct UiConfig {
219 #[serde(default = "default_tool_output_mode")]
220 pub tool_output_mode: ToolOutputMode,
221 #[serde(default = "default_inline_viewport_rows")]
222 pub inline_viewport_rows: u16,
223}
224
225impl Default for UiConfig {
226 fn default() -> Self {
227 Self {
228 tool_output_mode: default_tool_output_mode(),
229 inline_viewport_rows: default_inline_viewport_rows(),
230 }
231 }
232}
233
234/// PTY configuration
235#[derive(Debug, Clone, Deserialize, Serialize)]
236pub struct PtyConfig {
237 /// Enable PTY functionality
238 #[serde(default = "default_pty_enabled")]
239 pub enabled: bool,
240
241 /// Default terminal rows
242 #[serde(default = "default_pty_rows")]
243 pub default_rows: u16,
244
245 /// Default terminal columns
246 #[serde(default = "default_pty_cols")]
247 pub default_cols: u16,
248
249 /// Maximum number of concurrent PTY sessions
250 #[serde(default = "default_max_pty_sessions")]
251 pub max_sessions: usize,
252
253 /// Command timeout in seconds
254 #[serde(default = "default_pty_timeout")]
255 pub command_timeout_seconds: u64,
256
257 /// Number of PTY stdout lines to display in chat output
258 #[serde(default = "default_stdout_tail_lines")]
259 pub stdout_tail_lines: usize,
260}
261
262impl Default for PtyConfig {
263 fn default() -> Self {
264 Self {
265 enabled: default_pty_enabled(),
266 default_rows: default_pty_rows(),
267 default_cols: default_pty_cols(),
268 max_sessions: default_max_pty_sessions(),
269 command_timeout_seconds: default_pty_timeout(),
270 stdout_tail_lines: default_stdout_tail_lines(),
271 }
272 }
273}
274
275fn default_pty_enabled() -> bool {
276 true
277}
278fn default_pty_rows() -> u16 {
279 24
280}
281fn default_pty_cols() -> u16 {
282 80
283}
284fn default_max_pty_sessions() -> usize {
285 10
286}
287fn default_pty_timeout() -> u64 {
288 300
289}
290fn default_stdout_tail_lines() -> usize {
291 crate::config::constants::defaults::DEFAULT_PTY_STDOUT_TAIL_LINES
292}
293fn default_tool_output_mode() -> ToolOutputMode {
294 ToolOutputMode::Compact
295}
296fn default_inline_viewport_rows() -> u16 {
297 crate::config::constants::ui::DEFAULT_INLINE_VIEWPORT_ROWS
298}