vtcode_config/core/agent/
approval.rs1use serde::{Deserialize, Serialize};
4
5#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
12#[derive(Debug, Clone, Deserialize, Serialize)]
13pub struct AsyncApprovalConfig {
14 #[serde(default = "default_async_approval_enabled")]
16 enabled: bool,
17
18 #[serde(default = "default_async_approval_timeout_secs")]
20 timeout_secs: u64,
21
22 #[serde(default)]
25 notify_command: Option<String>,
26
27 #[serde(default = "default_async_approval_auto_approve_below")]
30 auto_approve_below_usd: f64,
31
32 #[serde(default)]
35 auto_approve_timeout_secs: Option<u64>,
36}
37
38impl Default for AsyncApprovalConfig {
39 fn default() -> Self {
40 Self {
41 enabled: default_async_approval_enabled(),
42 timeout_secs: default_async_approval_timeout_secs(),
43 notify_command: None,
44 auto_approve_below_usd: default_async_approval_auto_approve_below(),
45 auto_approve_timeout_secs: None,
46 }
47 }
48}
49
50#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
56#[derive(Debug, Clone, Deserialize, Serialize)]
57pub struct SkepticPanelConfig {
58 #[serde(default = "default_skeptic_panel_enabled")]
60 pub enabled: bool,
61
62 #[serde(default)]
65 pub models: Vec<String>,
66}
67
68impl Default for SkepticPanelConfig {
69 fn default() -> Self {
70 Self {
71 enabled: default_skeptic_panel_enabled(),
72 models: Vec::new(),
73 }
74 }
75}
76
77const fn default_skeptic_panel_enabled() -> bool {
78 false
79}
80
81const fn default_async_approval_enabled() -> bool {
82 false
83}
84const fn default_async_approval_timeout_secs() -> u64 {
85 3600
86}
87const fn default_async_approval_auto_approve_below() -> f64 {
88 0.10
89}
90#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
98#[derive(Debug, Clone, Deserialize, Serialize)]
99pub struct ConfidenceEscalationConfig {
100 #[serde(default = "default_escalation_enabled")]
102 pub enabled: bool,
103
104 #[serde(default = "default_escalation_confidence_threshold")]
107 pub confidence_threshold: f64,
108
109 #[serde(default = "default_escalation_always_escalate_tools")]
112 pub always_escalate_tools: Vec<String>,
113
114 #[serde(default = "default_escalation_cost_threshold")]
117 pub cost_threshold_usd: f64,
118
119 #[serde(default = "default_escalation_llm_confidence")]
123 pub use_llm_confidence: bool,
124
125 #[serde(default)]
128 pub plan_mode_only: bool,
129
130 #[serde(default = "default_escalation_max_replan")]
134 pub max_replan_attempts: u32,
135
136 #[serde(default = "default_escalation_max_total")]
139 pub max_total_escalations: u32,
140
141 #[serde(default = "default_escalation_prompt_user")]
144 pub prompt_user_on_exhaust: bool,
145}
146
147impl ConfidenceEscalationConfig {
148 pub fn would_escalate(&self, tool_name: &str, estimated_cost_usd: Option<f64>) -> bool {
151 if self.always_escalate_tools.iter().any(|t| t == tool_name) {
152 return true;
153 }
154 if let Some(cost) = estimated_cost_usd
155 && cost > self.cost_threshold_usd
156 {
157 return true;
158 }
159 false
160 }
161}
162
163impl Default for ConfidenceEscalationConfig {
164 fn default() -> Self {
165 Self {
166 enabled: default_escalation_enabled(),
167 confidence_threshold: default_escalation_confidence_threshold(),
168 always_escalate_tools: default_escalation_always_escalate_tools(),
169 cost_threshold_usd: default_escalation_cost_threshold(),
170 use_llm_confidence: default_escalation_llm_confidence(),
171 plan_mode_only: false,
172 max_replan_attempts: default_escalation_max_replan(),
173 max_total_escalations: default_escalation_max_total(),
174 prompt_user_on_exhaust: default_escalation_prompt_user(),
175 }
176 }
177}
178
179const fn default_escalation_enabled() -> bool {
180 false
181}
182const fn default_escalation_confidence_threshold() -> f64 {
183 0.7
184}
185fn default_escalation_always_escalate_tools() -> Vec<String> {
186 vec!["delete_file".to_string(), "remove".to_string(), "rm".to_string()]
187}
188const fn default_escalation_cost_threshold() -> f64 {
189 0.05
190}
191const fn default_escalation_llm_confidence() -> bool {
192 false
193}
194const fn default_escalation_max_replan() -> u32 {
195 3
196}
197const fn default_escalation_max_total() -> u32 {
198 5
199}
200const fn default_escalation_prompt_user() -> bool {
201 true
202}