vtcode_core/config/core/
agent.rs

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