vtcode_core/config/
constants.rs

1/// Prompt path constants to avoid hardcoding throughout the codebase
2pub mod prompts {
3    pub const DEFAULT_SYSTEM_PROMPT_PATH: &str = "prompts/system.md";
4    pub const CODER_SYSTEM_PROMPT_PATH: &str = "prompts/coder_system.md";
5}
6
7/// Model ID constants to sync with docs/models.json
8pub mod models {
9    // Google/Gemini models
10    pub mod google {
11        pub const DEFAULT_MODEL: &str = "gemini-2.5-flash-preview-05-20";
12        pub const SUPPORTED_MODELS: &[&str] = &[
13            "gemini-2.5-flash-preview-05-20",
14            "gemini-2.5-pro",
15            "gemini-2.5-flash",
16            "gemini-2.5-flash-lite",
17        ];
18
19        // Convenience constants for commonly used models
20        pub const GEMINI_2_5_FLASH_PREVIEW: &str = "gemini-2.5-flash-preview-05-20";
21        pub const GEMINI_2_5_PRO: &str = "gemini-2.5-pro";
22        pub const GEMINI_2_5_FLASH: &str = "gemini-2.5-flash";
23        pub const GEMINI_2_5_FLASH_LITE: &str = "gemini-2.5-flash-lite";
24    }
25
26    // OpenAI models (from docs/models.json)
27    pub mod openai {
28        pub const DEFAULT_MODEL: &str = "gpt-5";
29        pub const SUPPORTED_MODELS: &[&str] = &[
30            "gpt-5",
31            "gpt-5-codex",
32            "gpt-5-mini",
33            "gpt-5-nano",
34            "codex-mini-latest",
35        ];
36
37        /// Models that support the OpenAI reasoning API extensions
38        pub const REASONING_MODELS: &[&str] = &[GPT_5, GPT_5_CODEX, GPT_5_MINI, GPT_5_NANO];
39
40        // Convenience constants for commonly used models
41        pub const GPT_5: &str = "gpt-5";
42        pub const GPT_5_CODEX: &str = "gpt-5-codex";
43        pub const GPT_5_MINI: &str = "gpt-5-mini";
44        pub const GPT_5_NANO: &str = "gpt-5-nano";
45        pub const CODEX_MINI_LATEST: &str = "codex-mini-latest";
46        pub const CODEX_MINI: &str = "codex-mini";
47    }
48
49    // OpenRouter models (extensible via vtcode.toml)
50    pub mod openrouter {
51        pub const DEFAULT_MODEL: &str = "x-ai/grok-code-fast-1";
52        pub const SUPPORTED_MODELS: &[&str] = &[
53            "x-ai/grok-code-fast-1",
54            "x-ai/grok-4-fast:free",
55            "qwen/qwen3-coder",
56            "deepseek/deepseek-chat-v3.1",
57            "openai/gpt-5",
58            "openai/gpt-5-codex",
59            "anthropic/claude-sonnet-4",
60        ];
61
62        /// Models that expose reasoning traces via OpenRouter APIs
63        pub const REASONING_MODELS: &[&str] = &[
64            X_AI_GROK_4_FAST_FREE,
65            OPENAI_GPT_5,
66            OPENAI_GPT_5_CODEX,
67            ANTHROPIC_CLAUDE_SONNET_4,
68        ];
69
70        pub const X_AI_GROK_CODE_FAST_1: &str = "x-ai/grok-code-fast-1";
71        pub const X_AI_GROK_4_FAST_FREE: &str = "x-ai/grok-4-fast:free";
72        pub const QWEN3_CODER: &str = "qwen/qwen3-coder";
73        pub const DEEPSEEK_DEEPSEEK_CHAT_V3_1: &str = "deepseek/deepseek-chat-v3.1";
74        pub const OPENAI_GPT_5: &str = "openai/gpt-5";
75        pub const OPENAI_GPT_5_CODEX: &str = "openai/gpt-5-codex";
76        pub const ANTHROPIC_CLAUDE_SONNET_4: &str = "anthropic/claude-sonnet-4";
77    }
78
79    // Anthropic models (from docs/models.json) - Updated for tool use best practices
80    pub mod anthropic {
81        // Standard model for straightforward tools - Sonnet 4 preferred for most use cases
82        pub const DEFAULT_MODEL: &str = "claude-sonnet-4-20250514";
83        pub const SUPPORTED_MODELS: &[&str] = &[
84            "claude-opus-4-1-20250805", // Latest: Opus 4.1 (2025-08-05)
85            "claude-sonnet-4-20250514", // Latest: Sonnet 4 (2025-05-14)
86        ];
87
88        // Convenience constants for commonly used models
89        pub const CLAUDE_OPUS_4_1_20250805: &str = "claude-opus-4-1-20250805";
90        pub const CLAUDE_SONNET_4_20250514: &str = "claude-sonnet-4-20250514";
91    }
92
93    // xAI models
94    pub mod xai {
95        pub const DEFAULT_MODEL: &str = "grok-2-latest";
96        pub const SUPPORTED_MODELS: &[&str] = &[
97            "grok-2-latest",
98            "grok-2",
99            "grok-2-mini",
100            "grok-2-reasoning",
101            "grok-2-vision",
102        ];
103
104        pub const GROK_2_LATEST: &str = "grok-2-latest";
105        pub const GROK_2: &str = "grok-2";
106        pub const GROK_2_MINI: &str = "grok-2-mini";
107        pub const GROK_2_REASONING: &str = "grok-2-reasoning";
108        pub const GROK_2_VISION: &str = "grok-2-vision";
109    }
110
111    // Backwards compatibility - keep old constants working
112    pub const GEMINI_2_5_FLASH_PREVIEW: &str = google::GEMINI_2_5_FLASH_PREVIEW;
113    pub const GEMINI_2_5_FLASH: &str = google::GEMINI_2_5_FLASH;
114    pub const GEMINI_2_5_PRO: &str = google::GEMINI_2_5_PRO;
115    pub const GEMINI_2_5_FLASH_LITE: &str = google::GEMINI_2_5_FLASH_LITE;
116    pub const GPT_5: &str = openai::GPT_5;
117    pub const GPT_5_CODEX: &str = openai::GPT_5_CODEX;
118    pub const GPT_5_MINI: &str = openai::GPT_5_MINI;
119    pub const GPT_5_NANO: &str = openai::GPT_5_NANO;
120    pub const CODEX_MINI: &str = openai::CODEX_MINI;
121    pub const CODEX_MINI_LATEST: &str = openai::CODEX_MINI_LATEST;
122    pub const CLAUDE_OPUS_4_1_20250805: &str = anthropic::CLAUDE_OPUS_4_1_20250805;
123    pub const CLAUDE_SONNET_4_20250514: &str = anthropic::CLAUDE_SONNET_4_20250514;
124    pub const OPENROUTER_X_AI_GROK_CODE_FAST_1: &str = openrouter::X_AI_GROK_CODE_FAST_1;
125    pub const OPENROUTER_X_AI_GROK_4_FAST_FREE: &str = openrouter::X_AI_GROK_4_FAST_FREE;
126    pub const OPENROUTER_QWEN3_CODER: &str = openrouter::QWEN3_CODER;
127    pub const OPENROUTER_DEEPSEEK_CHAT_V3_1: &str = openrouter::DEEPSEEK_DEEPSEEK_CHAT_V3_1;
128    pub const OPENROUTER_OPENAI_GPT_5: &str = openrouter::OPENAI_GPT_5;
129    pub const OPENROUTER_OPENAI_GPT_5_CODEX: &str = openrouter::OPENAI_GPT_5_CODEX;
130    pub const OPENROUTER_ANTHROPIC_CLAUDE_SONNET_4: &str = openrouter::ANTHROPIC_CLAUDE_SONNET_4;
131    pub const XAI_GROK_2_LATEST: &str = xai::GROK_2_LATEST;
132    pub const XAI_GROK_2: &str = xai::GROK_2;
133    pub const XAI_GROK_2_MINI: &str = xai::GROK_2_MINI;
134    pub const XAI_GROK_2_REASONING: &str = xai::GROK_2_REASONING;
135    pub const XAI_GROK_2_VISION: &str = xai::GROK_2_VISION;
136}
137
138/// Model validation and helper functions
139pub mod model_helpers {
140    use super::models;
141
142    /// Get supported models for a provider
143    pub fn supported_for(provider: &str) -> Option<&'static [&'static str]> {
144        match provider {
145            "google" | "gemini" => Some(models::google::SUPPORTED_MODELS),
146            "openai" => Some(models::openai::SUPPORTED_MODELS),
147            "anthropic" => Some(models::anthropic::SUPPORTED_MODELS),
148            "openrouter" => Some(models::openrouter::SUPPORTED_MODELS),
149            "xai" => Some(models::xai::SUPPORTED_MODELS),
150            _ => None,
151        }
152    }
153
154    /// Get default model for a provider
155    pub fn default_for(provider: &str) -> Option<&'static str> {
156        match provider {
157            "google" | "gemini" => Some(models::google::DEFAULT_MODEL),
158            "openai" => Some(models::openai::DEFAULT_MODEL),
159            "anthropic" => Some(models::anthropic::DEFAULT_MODEL),
160            "openrouter" => Some(models::openrouter::DEFAULT_MODEL),
161            "xai" => Some(models::xai::DEFAULT_MODEL),
162            _ => None,
163        }
164    }
165
166    /// Validate if a model is supported by a provider
167    pub fn is_valid(provider: &str, model: &str) -> bool {
168        supported_for(provider)
169            .map(|list| list.iter().any(|m| *m == model))
170            .unwrap_or(false)
171    }
172}
173
174/// Default configuration values
175pub mod defaults {
176    use super::models;
177
178    pub const DEFAULT_MODEL: &str = models::google::GEMINI_2_5_FLASH_PREVIEW;
179    pub const DEFAULT_CLI_MODEL: &str = models::google::GEMINI_2_5_FLASH_PREVIEW;
180    pub const DEFAULT_PROVIDER: &str = "gemini";
181    pub const DEFAULT_API_KEY_ENV: &str = "GEMINI_API_KEY";
182    pub const DEFAULT_THEME: &str = "ciapre-dark";
183    pub const DEFAULT_MAX_TOOL_LOOPS: usize = 100;
184    pub const ANTHROPIC_DEFAULT_MAX_TOKENS: u32 = 4_096;
185}
186
187/// Reasoning effort configuration constants
188pub mod reasoning {
189    pub const LOW: &str = "low";
190    pub const MEDIUM: &str = "medium";
191    pub const HIGH: &str = "high";
192    pub const ALLOWED_LEVELS: &[&str] = &[LOW, MEDIUM, HIGH];
193}
194
195/// Message role constants to avoid hardcoding strings
196pub mod message_roles {
197    pub const SYSTEM: &str = "system";
198    pub const USER: &str = "user";
199    pub const ASSISTANT: &str = "assistant";
200    pub const TOOL: &str = "tool";
201}
202
203/// URL constants for API endpoints
204pub mod urls {
205    pub const GEMINI_API_BASE: &str = "https://generativelanguage.googleapis.com/v1beta";
206    pub const OPENAI_API_BASE: &str = "https://api.openai.com/v1";
207    pub const ANTHROPIC_API_BASE: &str = "https://api.anthropic.com/v1";
208    pub const ANTHROPIC_API_VERSION: &str = "2023-06-01";
209    pub const OPENROUTER_API_BASE: &str = "https://openrouter.ai/api/v1";
210    pub const XAI_API_BASE: &str = "https://api.x.ai/v1";
211}
212
213/// Tool name constants to avoid hardcoding strings throughout the codebase
214pub mod tools {
215    pub const GREP_SEARCH: &str = "grep_search";
216    pub const LIST_FILES: &str = "list_files";
217    pub const RUN_TERMINAL_CMD: &str = "run_terminal_cmd";
218    pub const READ_FILE: &str = "read_file";
219    pub const WRITE_FILE: &str = "write_file";
220    pub const EDIT_FILE: &str = "edit_file";
221    pub const DELETE_FILE: &str = "delete_file";
222    pub const CREATE_FILE: &str = "create_file";
223    pub const AST_GREP_SEARCH: &str = "ast_grep_search";
224    pub const SIMPLE_SEARCH: &str = "simple_search";
225    pub const BASH: &str = "bash";
226    pub const APPLY_PATCH: &str = "apply_patch";
227    pub const SRGN: &str = "srgn";
228    pub const CURL: &str = "curl";
229    pub const UPDATE_PLAN: &str = "update_plan";
230
231    // Explorer-specific tools
232    pub const FILE_METADATA: &str = "file_metadata";
233    pub const PROJECT_OVERVIEW: &str = "project_overview";
234    pub const TREE_SITTER_ANALYZE: &str = "tree_sitter_analyze";
235
236    // Special wildcard for full access
237    pub const WILDCARD_ALL: &str = "*";
238}
239
240pub mod project_doc {
241    pub const DEFAULT_MAX_BYTES: usize = 16 * 1024;
242}
243
244/// Context window management defaults
245pub mod context {
246    /// Approximate character count per token when estimating context size
247    pub const CHAR_PER_TOKEN_APPROX: usize = 3;
248
249    /// Default maximum context window (in approximate tokens)
250    pub const DEFAULT_MAX_TOKENS: usize = 90_000;
251
252    /// Trim target as a percentage of the maximum token budget
253    pub const DEFAULT_TRIM_TO_PERCENT: u8 = 80;
254
255    /// Minimum allowed trim percentage (prevents overly aggressive retention)
256    pub const MIN_TRIM_RATIO_PERCENT: u8 = 60;
257
258    /// Maximum allowed trim percentage (prevents minimal trimming)
259    pub const MAX_TRIM_RATIO_PERCENT: u8 = 90;
260
261    /// Default number of recent turns to preserve verbatim
262    pub const DEFAULT_PRESERVE_RECENT_TURNS: usize = 12;
263
264    /// Minimum number of recent turns that must remain after trimming
265    pub const MIN_PRESERVE_RECENT_TURNS: usize = 6;
266
267    /// Maximum number of recent turns to keep when aggressively reducing context
268    pub const AGGRESSIVE_PRESERVE_RECENT_TURNS: usize = 8;
269
270    /// Maximum number of retry attempts when the provider signals context overflow
271    pub const CONTEXT_ERROR_RETRY_LIMIT: usize = 2;
272}
273
274/// Chunking constants for large file handling
275pub mod chunking {
276    /// Maximum lines before triggering chunking for read_file
277    pub const MAX_LINES_THRESHOLD: usize = 2_000;
278
279    /// Number of lines to read from start of file when chunking
280    pub const CHUNK_START_LINES: usize = 800;
281
282    /// Number of lines to read from end of file when chunking
283    pub const CHUNK_END_LINES: usize = 800;
284
285    /// Maximum lines for terminal command output before truncation
286    pub const MAX_TERMINAL_OUTPUT_LINES: usize = 3_000;
287
288    /// Number of lines to show from start of terminal output when truncating
289    pub const TERMINAL_OUTPUT_START_LINES: usize = 1_000;
290
291    /// Number of lines to show from end of terminal output when truncating
292    pub const TERMINAL_OUTPUT_END_LINES: usize = 1_000;
293
294    /// Maximum content size for write_file before chunking (in bytes)
295    pub const MAX_WRITE_CONTENT_SIZE: usize = 500_000; // 500KB
296
297    /// Chunk size for write operations (in bytes)
298    pub const WRITE_CHUNK_SIZE: usize = 50_000; // 50KB chunks
299}