From 82daa885a60dcf24b32b900787286738079bfd75 Mon Sep 17 00:00:00 2001 From: Greyforge Admin Date: Wed, 20 May 2026 00:15:26 -0400 Subject: [PATCH] Respect model option for agent create --- src/cortex-cli/src/agent_cmd/cli.rs | 7 +- .../src/agent_cmd/handlers/create.rs | 49 ++++++++----- .../src/agent_cmd/handlers/generate.rs | 2 +- src/cortex-cli/tests/agent_create_model.rs | 68 +++++++++++++++++++ 4 files changed, 104 insertions(+), 22 deletions(-) create mode 100644 src/cortex-cli/tests/agent_create_model.rs diff --git a/src/cortex-cli/src/agent_cmd/cli.rs b/src/cortex-cli/src/agent_cmd/cli.rs index c60b1a3ad..26300a1d3 100644 --- a/src/cortex-cli/src/agent_cmd/cli.rs +++ b/src/cortex-cli/src/agent_cmd/cli.rs @@ -130,9 +130,10 @@ pub struct CreateArgs { #[arg(short, long, value_name = "DESCRIPTION")] pub generate: Option, - /// Model to use for AI generation (default: gpt-4o). - #[arg(long, default_value = "gpt-4o")] - pub model: String, + /// Model to use for AI generation or as an agent override. + /// Defaults to gpt-4o when generating with --generate. + #[arg(long)] + pub model: Option, } /// Arguments for edit command. diff --git a/src/cortex-cli/src/agent_cmd/handlers/create.rs b/src/cortex-cli/src/agent_cmd/handlers/create.rs index 346dea0da..fb39b1579 100644 --- a/src/cortex-cli/src/agent_cmd/handlers/create.rs +++ b/src/cortex-cli/src/agent_cmd/handlers/create.rs @@ -45,6 +45,25 @@ pub async fn run_create(args: CreateArgs) -> Result<()> { } } + fn model_override_from_input(model_input: &str) -> Option { + let model_input = model_input.trim(); + if model_input.is_empty() { + return None; + } + + // Issue #2328: Validate model name if provided + match validate_model_name(model_input) { + Ok(valid_model) => Some(valid_model), + Err(e) => { + eprintln!("Warning: {}", e); + eprintln!( + "Using model name as-is. The agent may fail to run if the model doesn't exist." + ); + Some(model_input.to_string()) + } + } + } + // Only show banner in interactive mode if !args.non_interactive { println!("🤖 Cortex Agent Creator"); @@ -220,30 +239,24 @@ pub async fn run_create(args: CreateArgs) -> Result<()> { // Get optional settings let (temperature, model, color) = if args.non_interactive { - (None, None, None) + ( + None, + model_override_from_input(args.model.as_deref().unwrap_or("")), + None, + ) } else { println!("\nOptional Settings (press Enter to skip):"); let temp_input = prompt_input(&stdin, &mut stdout, " Temperature (0.0-2.0)", Some(""))?; let temperature = temp_input.parse::().ok(); - let model_input = prompt_input(&stdin, &mut stdout, " Model override", Some(""))?; - // Issue #2328: Validate model name if provided - let model = if model_input.is_empty() { - None - } else { - // Validate the model name to prevent typos from being accepted - match validate_model_name(&model_input) { - Ok(valid_model) => Some(valid_model), - Err(e) => { - eprintln!("Warning: {}", e); - eprintln!( - "Using model name as-is. The agent may fail to run if the model doesn't exist." - ); - Some(model_input) - } - } - }; + let model_input = prompt_input( + &stdin, + &mut stdout, + " Model override", + Some(args.model.as_deref().unwrap_or("")), + )?; + let model = model_override_from_input(&model_input); let color = prompt_input( &stdin, diff --git a/src/cortex-cli/src/agent_cmd/handlers/generate.rs b/src/cortex-cli/src/agent_cmd/handlers/generate.rs index b3bbabd60..1cf732169 100644 --- a/src/cortex-cli/src/agent_cmd/handlers/generate.rs +++ b/src/cortex-cli/src/agent_cmd/handlers/generate.rs @@ -67,7 +67,7 @@ pub async fn run_generate(args: CreateArgs) -> Result<()> { }; // Validate model argument - let model_arg = args.model.trim(); + let model_arg = args.model.as_deref().unwrap_or("gpt-4o").trim(); if model_arg.is_empty() { bail!("Error: Model name cannot be empty"); } diff --git a/src/cortex-cli/tests/agent_create_model.rs b/src/cortex-cli/tests/agent_create_model.rs new file mode 100644 index 000000000..d59c8e246 --- /dev/null +++ b/src/cortex-cli/tests/agent_create_model.rs @@ -0,0 +1,68 @@ +use std::fs; +use std::process::Command; + +use tempfile::tempdir; + +fn combined_output(output: &std::process::Output) -> String { + format!( + "{}{}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ) +} + +#[test] +fn agent_create_non_interactive_writes_requested_model() { + let home = tempdir().unwrap(); + let output = Command::new(env!("CARGO_BIN_EXE_Cortex")) + .args([ + "agent", + "create", + "--name", + "demo-agent", + "--non-interactive", + "--model", + "claude-sonnet-4-20250514", + ]) + .env("HOME", home.path()) + .env_remove("CORTEX_HOME") + .output() + .unwrap(); + + assert!( + output.status.success(), + "agent create failed:\n{}", + combined_output(&output) + ); + + let agent_path = home.path().join(".cortex/agents/demo-agent.md"); + let content = fs::read_to_string(&agent_path).unwrap(); + assert!(content.contains("model: claude-sonnet-4-20250514")); +} + +#[test] +fn agent_create_non_interactive_without_model_omits_model_override() { + let home = tempdir().unwrap(); + let output = Command::new(env!("CARGO_BIN_EXE_Cortex")) + .args([ + "agent", + "create", + "--name", + "default-agent", + "--non-interactive", + ]) + .env("HOME", home.path()) + .env_remove("CORTEX_HOME") + .output() + .unwrap(); + + assert!( + output.status.success(), + "agent create failed:\n{}", + combined_output(&output) + ); + + let agent_path = home.path().join(".cortex/agents/default-agent.md"); + let content = fs::read_to_string(&agent_path).unwrap(); + assert!(!content.contains("model:")); +}