vtcode_core/config/core/
agent.rs

1use crate::config::constants::{defaults, project_doc};
2use crate::config::types::ReasoningEffortLevel;
3use serde::{Deserialize, Serialize};
4
5/// Agent-wide configuration
6#[derive(Debug, Clone, Deserialize, Serialize)]
7pub struct AgentConfig {
8    /// AI provider for single agent mode (gemini, openai, anthropic, openrouter, xai)
9    #[serde(default = "default_provider")]
10    pub provider: String,
11
12    /// Default model to use
13    #[serde(default = "default_model")]
14    pub default_model: String,
15
16    /// UI theme identifier controlling ANSI styling
17    #[serde(default = "default_theme")]
18    pub theme: String,
19
20    /// Maximum number of conversation turns before auto-termination
21    #[serde(default = "default_max_conversation_turns")]
22    pub max_conversation_turns: usize,
23
24    /// Reasoning effort level for models that support it (low, medium, high)
25    /// Applies to: Claude, GPT-5, Gemini, Qwen3, DeepSeek with reasoning capability
26    #[serde(default = "default_reasoning_effort")]
27    pub reasoning_effort: ReasoningEffortLevel,
28
29    /// Enable an extra self-review pass to refine final responses
30    #[serde(default = "default_enable_self_review")]
31    pub enable_self_review: bool,
32
33    /// Maximum number of self-review passes
34    #[serde(default = "default_max_review_passes")]
35    pub max_review_passes: usize,
36
37    /// Enable prompt refinement pass before sending to LLM
38    #[serde(default = "default_refine_prompts_enabled")]
39    pub refine_prompts_enabled: bool,
40
41    /// Max refinement passes for prompt writing
42    #[serde(default = "default_refine_max_passes")]
43    pub refine_prompts_max_passes: usize,
44
45    /// Optional model override for the refiner (empty = auto pick efficient sibling)
46    #[serde(default)]
47    pub refine_prompts_model: String,
48
49    /// Session onboarding and welcome message configuration
50    #[serde(default)]
51    pub onboarding: AgentOnboardingConfig,
52
53    /// Maximum bytes of AGENTS.md content to load from project hierarchy
54    #[serde(default = "default_project_doc_max_bytes")]
55    pub project_doc_max_bytes: usize,
56}
57
58impl Default for AgentConfig {
59    fn default() -> Self {
60        Self {
61            provider: default_provider(),
62            default_model: default_model(),
63            theme: default_theme(),
64            max_conversation_turns: default_max_conversation_turns(),
65            reasoning_effort: default_reasoning_effort(),
66            enable_self_review: default_enable_self_review(),
67            max_review_passes: default_max_review_passes(),
68            refine_prompts_enabled: default_refine_prompts_enabled(),
69            refine_prompts_max_passes: default_refine_max_passes(),
70            refine_prompts_model: String::new(),
71            onboarding: AgentOnboardingConfig::default(),
72            project_doc_max_bytes: default_project_doc_max_bytes(),
73        }
74    }
75}
76
77fn default_provider() -> String {
78    defaults::DEFAULT_PROVIDER.to_string()
79}
80fn default_model() -> String {
81    defaults::DEFAULT_MODEL.to_string()
82}
83fn default_theme() -> String {
84    defaults::DEFAULT_THEME.to_string()
85}
86fn default_max_conversation_turns() -> usize {
87    150
88}
89fn default_reasoning_effort() -> ReasoningEffortLevel {
90    ReasoningEffortLevel::default()
91}
92
93fn default_enable_self_review() -> bool {
94    false
95}
96
97fn default_max_review_passes() -> usize {
98    1
99}
100
101fn default_refine_prompts_enabled() -> bool {
102    false
103}
104
105fn default_refine_max_passes() -> usize {
106    1
107}
108
109fn default_project_doc_max_bytes() -> usize {
110    project_doc::DEFAULT_MAX_BYTES
111}
112
113#[derive(Debug, Clone, Deserialize, Serialize)]
114pub struct AgentOnboardingConfig {
115    /// Toggle onboarding message rendering
116    #[serde(default = "default_onboarding_enabled")]
117    pub enabled: bool,
118
119    /// Introductory text shown at session start
120    #[serde(default = "default_intro_text")]
121    pub intro_text: String,
122
123    /// Whether to include project overview in onboarding message
124    #[serde(default = "default_show_project_overview")]
125    pub include_project_overview: bool,
126
127    /// Whether to include language summary in onboarding message
128    #[serde(default = "default_show_language_summary")]
129    pub include_language_summary: bool,
130
131    /// Whether to include AGENTS.md highlights in onboarding message
132    #[serde(default = "default_show_guideline_highlights")]
133    pub include_guideline_highlights: bool,
134
135    /// Maximum number of guideline bullets to surface
136    #[serde(default = "default_guideline_highlight_limit")]
137    pub guideline_highlight_limit: usize,
138
139    /// Tips for collaborating with the agent effectively
140    #[serde(default = "default_usage_tips")]
141    pub usage_tips: Vec<String>,
142
143    /// Recommended follow-up actions to display
144    #[serde(default = "default_recommended_actions")]
145    pub recommended_actions: Vec<String>,
146
147    /// Placeholder suggestion for the chat input bar
148    #[serde(default = "default_chat_placeholder")]
149    pub chat_placeholder: String,
150}
151
152impl Default for AgentOnboardingConfig {
153    fn default() -> Self {
154        Self {
155            enabled: default_onboarding_enabled(),
156            intro_text: default_intro_text(),
157            include_project_overview: default_show_project_overview(),
158            include_language_summary: default_show_language_summary(),
159            include_guideline_highlights: default_show_guideline_highlights(),
160            guideline_highlight_limit: default_guideline_highlight_limit(),
161            usage_tips: default_usage_tips(),
162            recommended_actions: default_recommended_actions(),
163            chat_placeholder: default_chat_placeholder(),
164        }
165    }
166}
167
168fn default_onboarding_enabled() -> bool {
169    true
170}
171
172fn default_intro_text() -> String {
173    "Let's get oriented. I preloaded workspace context so we can move fast.".to_string()
174}
175
176fn default_show_project_overview() -> bool {
177    true
178}
179
180fn default_show_language_summary() -> bool {
181    false
182}
183
184fn default_show_guideline_highlights() -> bool {
185    true
186}
187
188fn default_guideline_highlight_limit() -> usize {
189    3
190}
191
192fn default_usage_tips() -> Vec<String> {
193    vec![
194        "Describe your current coding goal or ask for a quick status overview.".to_string(),
195        "Reference AGENTS.md guidelines when proposing changes.".to_string(),
196        "Prefer asking for targeted file reads or diffs before editing.".to_string(),
197    ]
198}
199
200fn default_recommended_actions() -> Vec<String> {
201    vec![
202        "Review the highlighted guidelines and share the task you want to tackle.".to_string(),
203        "Ask for a workspace tour if you need more context.".to_string(),
204    ]
205}
206
207fn default_chat_placeholder() -> String {
208    "Implement {feature}...".to_string()
209}