1use crate::constants::{defaults, instructions, llm_generation, project_doc};
2use crate::types::{
3 EditingMode, ReasoningEffortLevel, SystemPromptMode, ToolDocumentationMode,
4 UiSurfacePreference, VerbosityLevel,
5};
6use serde::{Deserialize, Serialize};
7use std::collections::BTreeMap;
8
9const DEFAULT_CHECKPOINTS_ENABLED: bool = true;
10const DEFAULT_MAX_SNAPSHOTS: usize = 50;
11const DEFAULT_MAX_AGE_DAYS: u64 = 30;
12
13#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
15#[derive(Debug, Clone, Deserialize, Serialize)]
16pub struct AgentConfig {
17 #[serde(default = "default_provider")]
19 pub provider: String,
20
21 #[serde(default = "default_api_key_env")]
23 pub api_key_env: String,
24
25 #[serde(default = "default_model")]
27 pub default_model: String,
28
29 #[serde(default = "default_theme")]
31 pub theme: String,
32
33 #[serde(default)]
37 pub system_prompt_mode: SystemPromptMode,
38
39 #[serde(default)]
45 pub tool_documentation_mode: ToolDocumentationMode,
46
47 #[serde(default = "default_enable_split_tool_results")]
54 pub enable_split_tool_results: bool,
55
56 #[serde(default = "default_todo_planning_mode")]
58 pub todo_planning_mode: bool,
59
60 #[serde(default)]
62 pub ui_surface: UiSurfacePreference,
63
64 #[serde(default = "default_max_conversation_turns")]
66 pub max_conversation_turns: usize,
67
68 #[serde(default = "default_reasoning_effort")]
71 pub reasoning_effort: ReasoningEffortLevel,
72
73 #[serde(default = "default_verbosity")]
76 pub verbosity: VerbosityLevel,
77
78 #[serde(default = "default_temperature")]
83 pub temperature: f32,
84
85 #[serde(default = "default_refine_temperature")]
89 pub refine_temperature: f32,
90
91 #[serde(default = "default_enable_self_review")]
93 pub enable_self_review: bool,
94
95 #[serde(default = "default_max_review_passes")]
97 pub max_review_passes: usize,
98
99 #[serde(default = "default_refine_prompts_enabled")]
101 pub refine_prompts_enabled: bool,
102
103 #[serde(default = "default_refine_max_passes")]
105 pub refine_prompts_max_passes: usize,
106
107 #[serde(default)]
109 pub refine_prompts_model: String,
110
111 #[serde(default)]
115 pub small_model: AgentSmallModelConfig,
116
117 #[serde(default)]
119 pub onboarding: AgentOnboardingConfig,
120
121 #[serde(default = "default_project_doc_max_bytes")]
123 pub project_doc_max_bytes: usize,
124
125 #[serde(
127 default = "default_instruction_max_bytes",
128 alias = "rule_doc_max_bytes"
129 )]
130 pub instruction_max_bytes: usize,
131
132 #[serde(default, alias = "instruction_paths", alias = "instructions")]
134 pub instruction_files: Vec<String>,
135
136 #[serde(default)]
138 pub custom_api_keys: BTreeMap<String, String>,
139
140 #[serde(default)]
147 pub credential_storage_mode: crate::auth::AuthCredentialsStoreMode,
148
149 #[serde(default)]
151 pub checkpointing: AgentCheckpointingConfig,
152
153 #[serde(default)]
155 pub vibe_coding: AgentVibeCodingConfig,
156
157 #[serde(default = "default_max_task_retries")]
161 pub max_task_retries: u32,
162
163 #[serde(default)]
165 pub harness: AgentHarnessConfig,
166
167 #[serde(default = "default_include_temporal_context")]
170 pub include_temporal_context: bool,
171
172 #[serde(default)]
174 pub temporal_context_use_utc: bool,
175
176 #[serde(default = "default_include_working_directory")]
178 pub include_working_directory: bool,
179
180 #[serde(default)]
182 pub user_instructions: Option<String>,
183
184 #[serde(default)]
187 pub default_editing_mode: EditingMode,
188
189 #[serde(default = "default_require_plan_confirmation")]
193 pub require_plan_confirmation: bool,
194
195 #[serde(default = "default_autonomous_mode")]
198 pub autonomous_mode: bool,
199
200 #[serde(default)]
203 pub circuit_breaker: CircuitBreakerConfig,
204
205 #[serde(default)]
208 pub open_responses: OpenResponsesConfig,
209}
210
211#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
212#[derive(Debug, Clone, Deserialize, Serialize)]
213pub struct AgentHarnessConfig {
214 #[serde(default = "default_harness_max_tool_calls_per_turn")]
216 pub max_tool_calls_per_turn: usize,
217 #[serde(default = "default_harness_max_tool_wall_clock_secs")]
219 pub max_tool_wall_clock_secs: u64,
220 #[serde(default = "default_harness_max_tool_retries")]
222 pub max_tool_retries: u32,
223 #[serde(default)]
225 pub event_log_path: Option<String>,
226}
227
228impl Default for AgentHarnessConfig {
229 fn default() -> Self {
230 Self {
231 max_tool_calls_per_turn: default_harness_max_tool_calls_per_turn(),
232 max_tool_wall_clock_secs: default_harness_max_tool_wall_clock_secs(),
233 max_tool_retries: default_harness_max_tool_retries(),
234 event_log_path: None,
235 }
236 }
237}
238
239#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
240#[derive(Debug, Clone, Deserialize, Serialize)]
241pub struct CircuitBreakerConfig {
242 #[serde(default = "default_circuit_breaker_enabled")]
244 pub enabled: bool,
245
246 #[serde(default = "default_failure_threshold")]
248 pub failure_threshold: u32,
249
250 #[serde(default = "default_pause_on_open")]
252 pub pause_on_open: bool,
253
254 #[serde(default = "default_max_open_circuits")]
256 pub max_open_circuits: usize,
257
258 #[serde(default = "default_recovery_cooldown")]
260 pub recovery_cooldown: u64,
261}
262
263impl Default for CircuitBreakerConfig {
264 fn default() -> Self {
265 Self {
266 enabled: default_circuit_breaker_enabled(),
267 failure_threshold: default_failure_threshold(),
268 pause_on_open: default_pause_on_open(),
269 max_open_circuits: default_max_open_circuits(),
270 recovery_cooldown: default_recovery_cooldown(),
271 }
272 }
273}
274
275#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
281#[derive(Debug, Clone, Deserialize, Serialize)]
282pub struct OpenResponsesConfig {
283 #[serde(default)]
287 pub enabled: bool,
288
289 #[serde(default = "default_open_responses_emit_events")]
293 pub emit_events: bool,
294
295 #[serde(default = "default_open_responses_include_extensions")]
298 pub include_extensions: bool,
299
300 #[serde(default = "default_open_responses_map_tool_calls")]
303 pub map_tool_calls: bool,
304
305 #[serde(default = "default_open_responses_include_reasoning")]
308 pub include_reasoning: bool,
309}
310
311impl Default for OpenResponsesConfig {
312 fn default() -> Self {
313 Self {
314 enabled: false, emit_events: default_open_responses_emit_events(),
316 include_extensions: default_open_responses_include_extensions(),
317 map_tool_calls: default_open_responses_map_tool_calls(),
318 include_reasoning: default_open_responses_include_reasoning(),
319 }
320 }
321}
322
323#[inline]
324const fn default_open_responses_emit_events() -> bool {
325 true }
327
328#[inline]
329const fn default_open_responses_include_extensions() -> bool {
330 true }
332
333#[inline]
334const fn default_open_responses_map_tool_calls() -> bool {
335 true }
337
338#[inline]
339const fn default_open_responses_include_reasoning() -> bool {
340 true }
342
343impl Default for AgentConfig {
344 fn default() -> Self {
345 Self {
346 provider: default_provider(),
347 api_key_env: default_api_key_env(),
348 default_model: default_model(),
349 theme: default_theme(),
350 system_prompt_mode: SystemPromptMode::default(),
351 tool_documentation_mode: ToolDocumentationMode::default(),
352 enable_split_tool_results: default_enable_split_tool_results(),
353 todo_planning_mode: default_todo_planning_mode(),
354 ui_surface: UiSurfacePreference::default(),
355 max_conversation_turns: default_max_conversation_turns(),
356 reasoning_effort: default_reasoning_effort(),
357 verbosity: default_verbosity(),
358 temperature: default_temperature(),
359 refine_temperature: default_refine_temperature(),
360 enable_self_review: default_enable_self_review(),
361 max_review_passes: default_max_review_passes(),
362 refine_prompts_enabled: default_refine_prompts_enabled(),
363 refine_prompts_max_passes: default_refine_max_passes(),
364 refine_prompts_model: String::new(),
365 small_model: AgentSmallModelConfig::default(),
366 onboarding: AgentOnboardingConfig::default(),
367 project_doc_max_bytes: default_project_doc_max_bytes(),
368 instruction_max_bytes: default_instruction_max_bytes(),
369 instruction_files: Vec::new(),
370 custom_api_keys: BTreeMap::new(),
371 credential_storage_mode: crate::auth::AuthCredentialsStoreMode::default(),
372 checkpointing: AgentCheckpointingConfig::default(),
373 vibe_coding: AgentVibeCodingConfig::default(),
374 max_task_retries: default_max_task_retries(),
375 harness: AgentHarnessConfig::default(),
376 include_temporal_context: default_include_temporal_context(),
377 temporal_context_use_utc: false, include_working_directory: default_include_working_directory(),
379 user_instructions: None,
380 default_editing_mode: EditingMode::default(),
381 require_plan_confirmation: default_require_plan_confirmation(),
382 autonomous_mode: default_autonomous_mode(),
383 circuit_breaker: CircuitBreakerConfig::default(),
384 open_responses: OpenResponsesConfig::default(),
385 }
386 }
387}
388
389impl AgentConfig {
390 pub fn validate_llm_params(&self) -> Result<(), String> {
392 if !(0.0..=1.0).contains(&self.temperature) {
394 return Err(format!(
395 "temperature must be between 0.0 and 1.0, got {}",
396 self.temperature
397 ));
398 }
399
400 if !(0.0..=1.0).contains(&self.refine_temperature) {
401 return Err(format!(
402 "refine_temperature must be between 0.0 and 1.0, got {}",
403 self.refine_temperature
404 ));
405 }
406
407 Ok(())
408 }
409}
410
411#[inline]
413fn default_provider() -> String {
414 defaults::DEFAULT_PROVIDER.into()
415}
416
417#[inline]
418fn default_api_key_env() -> String {
419 defaults::DEFAULT_API_KEY_ENV.into()
420}
421
422#[inline]
423fn default_model() -> String {
424 defaults::DEFAULT_MODEL.into()
425}
426
427#[inline]
428fn default_theme() -> String {
429 defaults::DEFAULT_THEME.into()
430}
431
432#[inline]
433const fn default_todo_planning_mode() -> bool {
434 true
435}
436
437#[inline]
438const fn default_enable_split_tool_results() -> bool {
439 true }
441
442#[inline]
443const fn default_max_conversation_turns() -> usize {
444 defaults::DEFAULT_MAX_CONVERSATION_TURNS
445}
446
447#[inline]
448fn default_reasoning_effort() -> ReasoningEffortLevel {
449 ReasoningEffortLevel::default()
450}
451
452#[inline]
453fn default_verbosity() -> VerbosityLevel {
454 VerbosityLevel::default()
455}
456
457#[inline]
458const fn default_temperature() -> f32 {
459 llm_generation::DEFAULT_TEMPERATURE
460}
461
462#[inline]
463const fn default_refine_temperature() -> f32 {
464 llm_generation::DEFAULT_REFINE_TEMPERATURE
465}
466
467#[inline]
468const fn default_enable_self_review() -> bool {
469 false
470}
471
472#[inline]
473const fn default_max_review_passes() -> usize {
474 1
475}
476
477#[inline]
478const fn default_refine_prompts_enabled() -> bool {
479 false
480}
481
482#[inline]
483const fn default_refine_max_passes() -> usize {
484 1
485}
486
487#[inline]
488const fn default_project_doc_max_bytes() -> usize {
489 project_doc::DEFAULT_MAX_BYTES
490}
491
492#[inline]
493const fn default_instruction_max_bytes() -> usize {
494 instructions::DEFAULT_MAX_BYTES
495}
496
497#[inline]
498const fn default_max_task_retries() -> u32 {
499 2 }
501
502#[inline]
503const fn default_harness_max_tool_calls_per_turn() -> usize {
504 defaults::DEFAULT_MAX_TOOL_CALLS_PER_TURN
505}
506
507#[inline]
508const fn default_harness_max_tool_wall_clock_secs() -> u64 {
509 defaults::DEFAULT_MAX_TOOL_WALL_CLOCK_SECS
510}
511
512#[inline]
513const fn default_harness_max_tool_retries() -> u32 {
514 defaults::DEFAULT_MAX_TOOL_RETRIES
515}
516
517#[inline]
518const fn default_include_temporal_context() -> bool {
519 true }
521
522#[inline]
523const fn default_include_working_directory() -> bool {
524 true }
526
527#[inline]
528const fn default_require_plan_confirmation() -> bool {
529 true }
531
532#[inline]
533const fn default_autonomous_mode() -> bool {
534 false }
536
537#[inline]
538const fn default_circuit_breaker_enabled() -> bool {
539 true }
541
542#[inline]
543const fn default_failure_threshold() -> u32 {
544 5 }
546
547#[inline]
548const fn default_pause_on_open() -> bool {
549 true }
551
552#[inline]
553const fn default_max_open_circuits() -> usize {
554 3 }
556
557#[inline]
558const fn default_recovery_cooldown() -> u64 {
559 60 }
561
562#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
563#[derive(Debug, Clone, Deserialize, Serialize)]
564pub struct AgentCheckpointingConfig {
565 #[serde(default = "default_checkpointing_enabled")]
567 pub enabled: bool,
568
569 #[serde(default)]
571 pub storage_dir: Option<String>,
572
573 #[serde(default = "default_checkpointing_max_snapshots")]
575 pub max_snapshots: usize,
576
577 #[serde(default = "default_checkpointing_max_age_days")]
579 pub max_age_days: Option<u64>,
580}
581
582impl Default for AgentCheckpointingConfig {
583 fn default() -> Self {
584 Self {
585 enabled: default_checkpointing_enabled(),
586 storage_dir: None,
587 max_snapshots: default_checkpointing_max_snapshots(),
588 max_age_days: default_checkpointing_max_age_days(),
589 }
590 }
591}
592
593#[inline]
594const fn default_checkpointing_enabled() -> bool {
595 DEFAULT_CHECKPOINTS_ENABLED
596}
597
598#[inline]
599const fn default_checkpointing_max_snapshots() -> usize {
600 DEFAULT_MAX_SNAPSHOTS
601}
602
603#[inline]
604const fn default_checkpointing_max_age_days() -> Option<u64> {
605 Some(DEFAULT_MAX_AGE_DAYS)
606}
607
608#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
609#[derive(Debug, Clone, Deserialize, Serialize)]
610pub struct AgentOnboardingConfig {
611 #[serde(default = "default_onboarding_enabled")]
613 pub enabled: bool,
614
615 #[serde(default = "default_intro_text")]
617 pub intro_text: String,
618
619 #[serde(default = "default_show_project_overview")]
621 pub include_project_overview: bool,
622
623 #[serde(default = "default_show_language_summary")]
625 pub include_language_summary: bool,
626
627 #[serde(default = "default_show_guideline_highlights")]
629 pub include_guideline_highlights: bool,
630
631 #[serde(default = "default_show_usage_tips_in_welcome")]
633 pub include_usage_tips_in_welcome: bool,
634
635 #[serde(default = "default_show_recommended_actions_in_welcome")]
637 pub include_recommended_actions_in_welcome: bool,
638
639 #[serde(default = "default_guideline_highlight_limit")]
641 pub guideline_highlight_limit: usize,
642
643 #[serde(default = "default_usage_tips")]
645 pub usage_tips: Vec<String>,
646
647 #[serde(default = "default_recommended_actions")]
649 pub recommended_actions: Vec<String>,
650
651 #[serde(default)]
653 pub chat_placeholder: Option<String>,
654}
655
656impl Default for AgentOnboardingConfig {
657 fn default() -> Self {
658 Self {
659 enabled: default_onboarding_enabled(),
660 intro_text: default_intro_text(),
661 include_project_overview: default_show_project_overview(),
662 include_language_summary: default_show_language_summary(),
663 include_guideline_highlights: default_show_guideline_highlights(),
664 include_usage_tips_in_welcome: default_show_usage_tips_in_welcome(),
665 include_recommended_actions_in_welcome: default_show_recommended_actions_in_welcome(),
666 guideline_highlight_limit: default_guideline_highlight_limit(),
667 usage_tips: default_usage_tips(),
668 recommended_actions: default_recommended_actions(),
669 chat_placeholder: None,
670 }
671 }
672}
673
674#[inline]
675const fn default_onboarding_enabled() -> bool {
676 true
677}
678
679const DEFAULT_INTRO_TEXT: &str =
680 "Let's get oriented. I preloaded workspace context so we can move fast.";
681
682#[inline]
683fn default_intro_text() -> String {
684 DEFAULT_INTRO_TEXT.into()
685}
686
687#[inline]
688const fn default_show_project_overview() -> bool {
689 true
690}
691
692#[inline]
693const fn default_show_language_summary() -> bool {
694 false
695}
696
697#[inline]
698const fn default_show_guideline_highlights() -> bool {
699 true
700}
701
702#[inline]
703const fn default_show_usage_tips_in_welcome() -> bool {
704 false
705}
706
707#[inline]
708const fn default_show_recommended_actions_in_welcome() -> bool {
709 false
710}
711
712#[inline]
713const fn default_guideline_highlight_limit() -> usize {
714 3
715}
716
717const DEFAULT_USAGE_TIPS: &[&str] = &[
718 "Describe your current coding goal or ask for a quick status overview.",
719 "Reference AGENTS.md guidelines when proposing changes.",
720 "Prefer asking for targeted file reads or diffs before editing.",
721];
722
723const DEFAULT_RECOMMENDED_ACTIONS: &[&str] = &[
724 "Review the highlighted guidelines and share the task you want to tackle.",
725 "Ask for a workspace tour if you need more context.",
726];
727
728fn default_usage_tips() -> Vec<String> {
729 DEFAULT_USAGE_TIPS.iter().map(|s| (*s).into()).collect()
730}
731
732fn default_recommended_actions() -> Vec<String> {
733 DEFAULT_RECOMMENDED_ACTIONS
734 .iter()
735 .map(|s| (*s).into())
736 .collect()
737}
738
739#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
749#[derive(Debug, Clone, Deserialize, Serialize)]
750pub struct AgentSmallModelConfig {
751 #[serde(default = "default_small_model_enabled")]
753 pub enabled: bool,
754
755 #[serde(default)]
758 pub model: String,
759
760 #[serde(default = "default_small_model_temperature")]
762 pub temperature: f32,
763
764 #[serde(default = "default_small_model_for_large_reads")]
766 pub use_for_large_reads: bool,
767
768 #[serde(default = "default_small_model_for_web_summary")]
770 pub use_for_web_summary: bool,
771
772 #[serde(default = "default_small_model_for_git_history")]
774 pub use_for_git_history: bool,
775}
776
777impl Default for AgentSmallModelConfig {
778 fn default() -> Self {
779 Self {
780 enabled: default_small_model_enabled(),
781 model: String::new(),
782 temperature: default_small_model_temperature(),
783 use_for_large_reads: default_small_model_for_large_reads(),
784 use_for_web_summary: default_small_model_for_web_summary(),
785 use_for_git_history: default_small_model_for_git_history(),
786 }
787 }
788}
789
790#[inline]
791const fn default_small_model_enabled() -> bool {
792 true }
794
795#[inline]
796const fn default_small_model_temperature() -> f32 {
797 0.3 }
799
800#[inline]
801const fn default_small_model_for_large_reads() -> bool {
802 true
803}
804
805#[inline]
806const fn default_small_model_for_web_summary() -> bool {
807 true
808}
809
810#[inline]
811const fn default_small_model_for_git_history() -> bool {
812 true
813}
814
815#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
820#[derive(Debug, Clone, Deserialize, Serialize)]
821pub struct AgentVibeCodingConfig {
822 #[serde(default = "default_vibe_coding_enabled")]
824 pub enabled: bool,
825
826 #[serde(default = "default_vibe_min_prompt_length")]
828 pub min_prompt_length: usize,
829
830 #[serde(default = "default_vibe_min_prompt_words")]
832 pub min_prompt_words: usize,
833
834 #[serde(default = "default_vibe_entity_resolution")]
836 pub enable_entity_resolution: bool,
837
838 #[serde(default = "default_vibe_entity_cache")]
840 pub entity_index_cache: String,
841
842 #[serde(default = "default_vibe_max_entity_matches")]
844 pub max_entity_matches: usize,
845
846 #[serde(default = "default_vibe_track_workspace")]
848 pub track_workspace_state: bool,
849
850 #[serde(default = "default_vibe_max_recent_files")]
852 pub max_recent_files: usize,
853
854 #[serde(default = "default_vibe_track_values")]
856 pub track_value_history: bool,
857
858 #[serde(default = "default_vibe_conversation_memory")]
860 pub enable_conversation_memory: bool,
861
862 #[serde(default = "default_vibe_max_memory_turns")]
864 pub max_memory_turns: usize,
865
866 #[serde(default = "default_vibe_pronoun_resolution")]
868 pub enable_pronoun_resolution: bool,
869
870 #[serde(default = "default_vibe_proactive_context")]
872 pub enable_proactive_context: bool,
873
874 #[serde(default = "default_vibe_max_context_files")]
876 pub max_context_files: usize,
877
878 #[serde(default = "default_vibe_max_snippets_per_file")]
880 pub max_context_snippets_per_file: usize,
881
882 #[serde(default = "default_vibe_max_search_results")]
884 pub max_search_results: usize,
885
886 #[serde(default = "default_vibe_value_inference")]
888 pub enable_relative_value_inference: bool,
889}
890
891impl Default for AgentVibeCodingConfig {
892 fn default() -> Self {
893 Self {
894 enabled: default_vibe_coding_enabled(),
895 min_prompt_length: default_vibe_min_prompt_length(),
896 min_prompt_words: default_vibe_min_prompt_words(),
897 enable_entity_resolution: default_vibe_entity_resolution(),
898 entity_index_cache: default_vibe_entity_cache(),
899 max_entity_matches: default_vibe_max_entity_matches(),
900 track_workspace_state: default_vibe_track_workspace(),
901 max_recent_files: default_vibe_max_recent_files(),
902 track_value_history: default_vibe_track_values(),
903 enable_conversation_memory: default_vibe_conversation_memory(),
904 max_memory_turns: default_vibe_max_memory_turns(),
905 enable_pronoun_resolution: default_vibe_pronoun_resolution(),
906 enable_proactive_context: default_vibe_proactive_context(),
907 max_context_files: default_vibe_max_context_files(),
908 max_context_snippets_per_file: default_vibe_max_snippets_per_file(),
909 max_search_results: default_vibe_max_search_results(),
910 enable_relative_value_inference: default_vibe_value_inference(),
911 }
912 }
913}
914
915#[inline]
917const fn default_vibe_coding_enabled() -> bool {
918 false }
920
921#[inline]
922const fn default_vibe_min_prompt_length() -> usize {
923 5
924}
925
926#[inline]
927const fn default_vibe_min_prompt_words() -> usize {
928 2
929}
930
931#[inline]
932const fn default_vibe_entity_resolution() -> bool {
933 true
934}
935
936#[inline]
937fn default_vibe_entity_cache() -> String {
938 ".vtcode/entity_index.json".into()
939}
940
941#[inline]
942const fn default_vibe_max_entity_matches() -> usize {
943 5
944}
945
946#[inline]
947const fn default_vibe_track_workspace() -> bool {
948 true
949}
950
951#[inline]
952const fn default_vibe_max_recent_files() -> usize {
953 20
954}
955
956#[inline]
957const fn default_vibe_track_values() -> bool {
958 true
959}
960
961#[inline]
962const fn default_vibe_conversation_memory() -> bool {
963 true
964}
965
966#[inline]
967const fn default_vibe_max_memory_turns() -> usize {
968 50
969}
970
971#[inline]
972const fn default_vibe_pronoun_resolution() -> bool {
973 true
974}
975
976#[inline]
977const fn default_vibe_proactive_context() -> bool {
978 true
979}
980
981#[inline]
982const fn default_vibe_max_context_files() -> usize {
983 3
984}
985
986#[inline]
987const fn default_vibe_max_snippets_per_file() -> usize {
988 20
989}
990
991#[inline]
992const fn default_vibe_max_search_results() -> usize {
993 5
994}
995
996#[inline]
997const fn default_vibe_value_inference() -> bool {
998 true
999}
1000
1001#[cfg(test)]
1002mod tests {
1003 use super::*;
1004
1005 #[test]
1006 fn test_editing_mode_config_default() {
1007 let config = AgentConfig::default();
1008 assert_eq!(config.default_editing_mode, EditingMode::Edit);
1009 assert!(config.require_plan_confirmation);
1010 assert!(!config.autonomous_mode);
1011 }
1012}