use crate::utils::colors::style;
use anyhow::Result;
use dialoguer::{Confirm, Input, Select};
pub struct UserConfirmation;
#[derive(Debug, Clone, PartialEq)]
pub enum ToolConfirmationResult {
Yes,
YesAutoAccept,
No,
Feedback(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProModelConfirmationResult {
Yes,
YesAutoAccept,
No,
}
impl UserConfirmation {
pub fn confirm_pro_model_usage(current_model: &str) -> Result<ProModelConfirmationResult> {
use crate::config::constants::models;
println!("{}", style("Model Upgrade Required").red().bold());
println!("Current model: {}", style(current_model).cyan());
println!(
"Requested model: {}",
style(models::google::GEMINI_3_1_PRO_PREVIEW).cyan().bold()
);
println!();
println!("The Gemini 3 Pro model is the most capable but also:");
println!("• More expensive per token");
println!("• Slower response times");
println!("• Higher resource usage");
println!();
let options = vec![
"Yes - Use Pro model for this task",
"Yes - Always use Pro model (Auto-accept)",
"No - Use default model instead",
];
let selection = Select::new()
.with_prompt("How would you like to proceed?")
.default(0)
.items(&options)
.interact()?;
match selection {
0 => {
println!(
"{}",
style("✓ Using Gemini 3 Pro model for this task").green()
);
Ok(ProModelConfirmationResult::Yes)
}
1 => {
println!(
"{}",
style("✓ Using Gemini 3 Pro model (will auto-accept in future)").green()
);
Ok(ProModelConfirmationResult::YesAutoAccept)
}
2 => {
println!("{}", style("✗ Keeping current model").red());
Ok(ProModelConfirmationResult::No)
}
_ => Ok(ProModelConfirmationResult::No),
}
}
pub fn select_agent_mode() -> Result<AgentMode> {
println!("{}", style("Agent Mode Selection").cyan().bold());
println!(
"VT Code now uses single-agent mode with Decision Ledger for reliable task execution."
);
Ok(AgentMode::SingleCoder)
}
pub fn assess_task_complexity(task_description: &str) -> Result<TaskComplexity> {
println!("{}", style("Task Complexity Assessment").cyan().bold());
println!("Task: {}", style(task_description).cyan());
println!();
let options = vec![
"Simple (single file edit, basic question, straightforward task)",
"Moderate (multiple files, refactoring, testing)",
"Complex (architecture changes, cross-cutting concerns, large refactoring)",
];
let selection = Select::new()
.with_prompt("How would you classify this task's complexity?")
.default(0)
.items(&options)
.interact()?;
let complexity = match selection {
0 => TaskComplexity::Simple,
1 => TaskComplexity::Moderate,
2 => TaskComplexity::Complex,
_ => TaskComplexity::Simple, };
match complexity {
TaskComplexity::Simple => {
println!(
"{}",
style("Simple task - Single agent recommended").green()
);
}
TaskComplexity::Moderate => {
println!(
"{}",
style("Moderate task - Single agent usually sufficient").cyan()
);
}
TaskComplexity::Complex => {
println!(
"{}",
style("Complex task detected - proceeding with single-agent mode").cyan()
);
}
}
Ok(complexity)
}
pub fn confirm_action(message: &str, default: bool) -> Result<bool> {
Confirm::new()
.with_prompt(message)
.default(default)
.interact()
.map_err(Into::into)
}
pub fn show_warning(message: &str) -> Result<()> {
println!("{}", style(" Warning").red().bold());
println!("{}", message);
println!();
Confirm::new()
.with_prompt("Press Enter to continue or Ctrl+C to cancel")
.default(true)
.interact()?;
Ok(())
}
pub fn confirm_tool_usage(
tool_name: &str,
tool_args: Option<&str>,
) -> Result<ToolConfirmationResult> {
println!("{}", style("Tool Execution Confirmation").cyan().bold());
println!("Tool: {}", style(tool_name).cyan().bold());
if let Some(args) = tool_args {
println!("Args: {}", style(args).dim());
}
println!();
let options = vec![
"Yes - Allow this execution",
"Yes - Always allow this tool (Auto-accept)",
"No - Deny this execution",
"No - Deny and provide feedback to agent",
];
let selection = Select::new()
.with_prompt("How would you like to proceed?")
.default(0)
.items(&options)
.interact()?;
match selection {
0 => Ok(ToolConfirmationResult::Yes),
1 => Ok(ToolConfirmationResult::YesAutoAccept),
2 => Ok(ToolConfirmationResult::No),
3 => {
let feedback: String = Input::new()
.with_prompt("Enter feedback for the agent")
.allow_empty(false)
.interact_text()?;
Ok(ToolConfirmationResult::Feedback(feedback))
}
_ => Ok(ToolConfirmationResult::No),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum AgentMode {
SingleCoder,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TaskComplexity {
Simple,
Moderate,
Complex,
}
impl TaskComplexity {
pub fn recommended_agent_mode(&self) -> AgentMode {
match self {
TaskComplexity::Simple | TaskComplexity::Moderate => AgentMode::SingleCoder,
TaskComplexity::Complex => AgentMode::SingleCoder, }
}
}