vtcode_core/ui/
user_confirmation.rs1use crate::utils::colors::style;
7use anyhow::Result;
8use dialoguer::{Confirm, Input, Select};
9pub struct UserConfirmation;
13
14#[derive(Debug, Clone, PartialEq)]
16pub enum ToolConfirmationResult {
17 Yes,
19 YesAutoAccept,
21 No,
23 Feedback(String),
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum ProModelConfirmationResult {
30 Yes,
32 YesAutoAccept,
34 No,
36}
37
38impl UserConfirmation {
39 pub fn confirm_pro_model_usage(current_model: &str) -> Result<ProModelConfirmationResult> {
42 use crate::config::constants::models;
43 println!("{}", style("Model Upgrade Required").red().bold());
44 println!("Current model: {}", style(current_model).cyan());
45 println!(
46 "Requested model: {}",
47 style(models::google::GEMINI_3_1_PRO_PREVIEW).cyan().bold()
48 );
49 println!();
50 println!("The Gemini 3 Pro model is the most capable but also:");
51 println!("• More expensive per token");
52 println!("• Slower response times");
53 println!("• Higher resource usage");
54 println!();
55
56 let options = vec![
57 "Yes - Use Pro model for this task",
58 "Yes - Always use Pro model (Auto-accept)",
59 "No - Use default model instead",
60 ];
61
62 let selection = Select::new()
63 .with_prompt("How would you like to proceed?")
64 .default(0)
65 .items(&options)
66 .interact()?;
67
68 match selection {
69 0 => {
70 println!(
71 "{}",
72 style("✓ Using Gemini 3 Pro model for this task").green()
73 );
74 Ok(ProModelConfirmationResult::Yes)
75 }
76 1 => {
77 println!(
78 "{}",
79 style("✓ Using Gemini 3 Pro model (will auto-accept in future)").green()
80 );
81 Ok(ProModelConfirmationResult::YesAutoAccept)
82 }
83 2 => {
84 println!("{}", style("✗ Keeping current model").red());
85 Ok(ProModelConfirmationResult::No)
86 }
87 _ => Ok(ProModelConfirmationResult::No),
88 }
89 }
90
91 pub fn select_agent_mode() -> Result<AgentMode> {
93 println!("{}", style("Agent Mode Selection").cyan().bold());
94 println!(
95 "VT Code now uses single-agent mode with Decision Ledger for reliable task execution."
96 );
97
98 Ok(AgentMode::SingleCoder)
99 }
100
101 pub fn assess_task_complexity(task_description: &str) -> Result<TaskComplexity> {
103 println!("{}", style("Task Complexity Assessment").cyan().bold());
104 println!("Task: {}", style(task_description).cyan());
105 println!();
106
107 let options = vec![
108 "Simple (single file edit, basic question, straightforward task)",
109 "Moderate (multiple files, refactoring, testing)",
110 "Complex (architecture changes, cross-cutting concerns, large refactoring)",
111 ];
112
113 let selection = Select::new()
114 .with_prompt("How would you classify this task's complexity?")
115 .default(0)
116 .items(&options)
117 .interact()?;
118
119 let complexity = match selection {
120 0 => TaskComplexity::Simple,
121 1 => TaskComplexity::Moderate,
122 2 => TaskComplexity::Complex,
123 _ => TaskComplexity::Simple, };
125
126 match complexity {
127 TaskComplexity::Simple => {
128 println!(
129 "{}",
130 style("Simple task - Single agent recommended").green()
131 );
132 }
133 TaskComplexity::Moderate => {
134 println!(
135 "{}",
136 style("Moderate task - Single agent usually sufficient").cyan()
137 );
138 }
139 TaskComplexity::Complex => {
140 println!(
141 "{}",
142 style("Complex task detected - proceeding with single-agent mode").cyan()
143 );
144 }
145 }
146
147 Ok(complexity)
148 }
149
150 #[must_use = "confirmation action failure is silently ignored"]
152 pub fn confirm_action(message: &str, default: bool) -> Result<bool> {
153 Confirm::new()
154 .with_prompt(message)
155 .default(default)
156 .interact()
157 .map_err(Into::into)
158 }
159
160 #[cold]
162 pub fn show_warning(message: &str) -> Result<()> {
163 println!("{}", style(" Warning").red().bold());
164 println!("{}", message);
165 println!();
166
167 Confirm::new()
168 .with_prompt("Press Enter to continue or Ctrl+C to cancel")
169 .default(true)
170 .interact()?;
171
172 Ok(())
173 }
174
175 pub fn confirm_tool_usage(
177 tool_name: &str,
178 tool_args: Option<&str>,
179 ) -> Result<ToolConfirmationResult> {
180 println!("{}", style("Tool Execution Confirmation").cyan().bold());
181 println!("Tool: {}", style(tool_name).cyan().bold());
182 if let Some(args) = tool_args {
183 println!("Args: {}", style(args).dim());
184 }
185 println!();
186
187 let options = vec![
188 "Yes - Allow this execution",
189 "Yes - Always allow this tool (Auto-accept)",
190 "No - Deny this execution",
191 "No - Deny and provide feedback to agent",
192 ];
193
194 let selection = Select::new()
195 .with_prompt("How would you like to proceed?")
196 .default(0)
197 .items(&options)
198 .interact()?;
199
200 match selection {
201 0 => Ok(ToolConfirmationResult::Yes),
202 1 => Ok(ToolConfirmationResult::YesAutoAccept),
203 2 => Ok(ToolConfirmationResult::No),
204 3 => {
205 let feedback: String = Input::new()
206 .with_prompt("Enter feedback for the agent")
207 .allow_empty(false)
208 .interact_text()?;
209 Ok(ToolConfirmationResult::Feedback(feedback))
210 }
211 _ => Ok(ToolConfirmationResult::No),
212 }
213 }
214}
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
218pub enum AgentMode {
219 SingleCoder,
221}
222
223#[derive(Debug, Clone, Copy, PartialEq, Eq)]
225pub enum TaskComplexity {
226 Simple,
228 Moderate,
230 Complex,
232}
233
234impl TaskComplexity {
235 pub fn recommended_agent_mode(&self) -> AgentMode {
237 match self {
238 TaskComplexity::Simple | TaskComplexity::Moderate => AgentMode::SingleCoder,
239 TaskComplexity::Complex => AgentMode::SingleCoder, }
241 }
242}