diff --git a/crates/tui/src/tools/subagent/mod.rs b/crates/tui/src/tools/subagent/mod.rs index af204a07..bcc977cb 100644 --- a/crates/tui/src/tools/subagent/mod.rs +++ b/crates/tui/src/tools/subagent/mod.rs @@ -3390,7 +3390,7 @@ pub(crate) async fn resolve_subagent_assignment_route( let explicit_model = configured_model.is_some(); let mut route = fallback_subagent_assignment_route(runtime, configured_model, prompt); - if (runtime.auto_model || runtime.reasoning_effort_auto) + if should_use_subagent_flash_router(runtime) && let Ok(Some(recommendation)) = subagent_flash_router(runtime, prompt).await { if runtime.auto_model && !explicit_model { @@ -3407,6 +3407,10 @@ pub(crate) async fn resolve_subagent_assignment_route( route } +fn should_use_subagent_flash_router(runtime: &SubAgentRuntime) -> bool { + runtime.auto_model +} + fn fallback_subagent_assignment_route( runtime: &SubAgentRuntime, configured_model: Option, diff --git a/crates/tui/src/tools/subagent/tests.rs b/crates/tui/src/tools/subagent/tests.rs index 0295b567..bd8f29bb 100644 --- a/crates/tui/src/tools/subagent/tests.rs +++ b/crates/tui/src/tools/subagent/tests.rs @@ -442,6 +442,26 @@ fn subagent_auto_reasoning_resolves_to_distinct_v4_tiers() { ); } +#[test] +fn fixed_model_subagent_auto_reasoning_skips_flash_router() { + let runtime = stub_runtime().with_reasoning_effort(Some("high".to_string()), true); + + assert!( + !should_use_subagent_flash_router(&runtime), + "fixed-model auto thinking should resolve locally without a hidden router request" + ); +} + +#[test] +fn auto_model_subagent_assignments_still_use_flash_router() { + let runtime = stub_runtime().with_auto_model(true); + + assert!( + should_use_subagent_flash_router(&runtime), + "auto-model sub-agent assignments still need router guidance" + ); +} + #[test] fn subagent_router_prompt_frames_assignment_as_auto_routing() { let runtime = stub_runtime() diff --git a/crates/tui/src/tui/ui.rs b/crates/tui/src/tui/ui.rs index 0fb83fed..0de2de7d 100644 --- a/crates/tui/src/tui/ui.rs +++ b/crates/tui/src/tui/ui.rs @@ -3628,7 +3628,7 @@ async fn dispatch_user_message( persistence_actor::persist(PersistRequest::Checkpoint(session)); } - let auto_selection = if app.auto_model || app.reasoning_effort == ReasoningEffort::Auto { + let auto_selection = if should_resolve_auto_model_selection(app) { Some(resolve_auto_model_selection(app, config, &message, &content).await) } else { None @@ -3698,6 +3698,10 @@ async fn dispatch_user_message( Ok(()) } +fn should_resolve_auto_model_selection(app: &App) -> bool { + app.auto_model +} + async fn resolve_auto_model_selection( app: &App, config: &Config, diff --git a/crates/tui/src/tui/ui/tests.rs b/crates/tui/src/tui/ui/tests.rs index bfe61bf2..915b261e 100644 --- a/crates/tui/src/tui/ui/tests.rs +++ b/crates/tui/src/tui/ui/tests.rs @@ -787,6 +787,31 @@ async fn dispatch_user_message_failed_send_clears_loading_state() { assert!(app.last_send_at.is_none()); } +#[test] +fn fixed_model_auto_thinking_skips_auto_model_router() { + let mut app = create_test_app(); + app.auto_model = false; + app.model = "deepseek-v4-pro".to_string(); + app.reasoning_effort = ReasoningEffort::Auto; + + assert!( + !should_resolve_auto_model_selection(&app), + "fixed-model auto thinking must stay local instead of starting a hidden router request" + ); +} + +#[test] +fn auto_model_still_uses_auto_model_router() { + let mut app = create_test_app(); + app.auto_model = true; + app.reasoning_effort = ReasoningEffort::Auto; + + assert!( + should_resolve_auto_model_selection(&app), + "auto model still needs the router to choose the concrete model" + ); +} + fn init_git_repo() -> TempDir { let dir = tempfile::tempdir().expect("tempdir");