feat: multi model and multi provider config and auto switching (#4035)

This commit is contained in:
Michael Neale
2025-09-04 11:24:14 +10:00
committed by GitHub
parent 3897345ca6
commit 439d293cae
6 changed files with 1594 additions and 0 deletions
+17
View File
@@ -55,6 +55,7 @@ use tokio_util::sync::CancellationToken;
use tracing::{debug, error, info, instrument};
use super::final_output_tool::FinalOutputTool;
use super::model_selector::autopilot::AutoPilot;
use super::platform_tools;
use super::tool_execution::{ToolCallResult, CHAT_MODE_TOOL_SKIPPED_RESPONSE, DECLINED_RESPONSE};
use crate::agents::subagent_task_config::TaskConfig;
@@ -102,6 +103,7 @@ pub struct Agent {
pub(super) tool_route_manager: ToolRouteManager,
pub(super) scheduler_service: Mutex<Option<Arc<dyn SchedulerTrait>>>,
pub(super) retry_manager: RetryManager,
pub(super) autopilot: Mutex<AutoPilot>,
}
#[derive(Clone, Debug)]
@@ -178,6 +180,7 @@ impl Agent {
tool_route_manager: ToolRouteManager::new(),
scheduler_service: Mutex::new(None),
retry_manager,
autopilot: Mutex::new(AutoPilot::new()),
}
}
@@ -1041,6 +1044,20 @@ impl Agent {
break;
}
{
let mut autopilot = self.autopilot.lock().await;
if let Some((new_provider, role, model)) = autopilot.check_for_switch(&messages, self.provider().await?).await? {
debug!("AutoPilot switching to {} role with model {}", role, model);
self.update_provider(new_provider).await?;
yield AgentEvent::ModelChange {
model: model.clone(),
mode: format!("autopilot:{}", role),
};
}
}
let mut stream = Self::stream_response_from_provider(
self.provider().await?,
&system_prompt,
+1
View File
@@ -5,6 +5,7 @@ pub mod extension_malware_check;
pub mod extension_manager;
pub mod final_output_tool;
mod large_response_handler;
pub mod model_selector;
pub mod platform_tools;
pub mod prompt_manager;
pub mod recipe_tools;
@@ -0,0 +1,28 @@
# Autopilot model selector
This is an advanced feature (config of which may change, use with caution for now)
which lets goose automatically rotate through many providers and models based on rules that trigger as part of its work.
Models can change at any time, and can help (similar to lead/worker) solve persistent issues, get an advanced plan, a second opinion or more.
`premade_roles.yaml` are the out of the box configurations, which can be used in the `~/.config/goose/config.yaml` like so:
```yaml
x-advanced-models:
- provider: databricks
model: goose-gpt-5
role: reviewer
- provider: anthropic
model: claude-opus-4-1-20250805
role: deep-thinker
```
in this case, when there is some complex activity or planning or thining required, it will automatically switch to opus for a while, likewise when code changes have been made, it will use the reviewer model.
## Use cases
You can do a lead/worker like combo, or you can default to a low cost model and only in some cases use a frontier model.
You could default to a local model, and only intermittently switch when needed.
use `--debug` flag if you want to see it logging when it changes.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
pub mod autopilot;
@@ -0,0 +1,181 @@
# Pre-made AutoPilot roles with default rules
# These define the default behaviors for common roles
# Users must specify the provider and model in their config.yaml
roles:
# Lead model - high-capability model for initial turns and failure recovery
- role: "lead"
rules:
triggers:
# Triggers at conversation start AND on consecutive failures
first_turn: true # Trigger on first turn
consecutive_failures: 2 # Same as GOOSE_LEAD_FAILURE_THRESHOLD default
source: "any" # Can trigger on both human (start) and machine (failures)
active_turns: 3 # Same as GOOSE_LEAD_TURNS default (initial) and GOOSE_LEAD_FALLBACK_TURNS for failures
priority: 30 # Highest priority to ensure it always triggers first
- role: "second-opinion"
rules:
triggers:
keywords: ["help"]
match_type: "any"
after_tool_use: true
source: "human"
active_turns: 5
priority: 5
# Deep reasoning and analysis
- role: "deep-thinker"
rules:
triggers:
keywords: ["think", "reason", "analyze", "explain why", "how does", "what if"]
match_type: "any"
complexity_threshold: "high"
source: "human" # Only trigger on human messages
active_turns: 3
priority: 10
# Consult the oracle
- role: "oracle"
rules:
triggers:
keywords: ["think", "reason", "analyze", "explain why", "what if"]
match_type: "any"
complexity_threshold: "medium"
source: "human" # Only trigger on human messages
active_turns: 5
priority: 15
# Consult the planner
- role: "planner"
rules:
triggers:
keywords: ["think", "plan", "help me", "look at", "consider"]
match_type: "any"
complexity_threshold: "low"
source: "any" # Only trigger on human messages
active_turns: 3
priority: 5
# Code debugging and error recovery
- role: "debugger"
rules:
triggers:
keywords: ["error", "bug", "broken", "failed", "exception"]
match_type: "any"
on_failure: true
source: "any" # Can trigger on both human and machine failures
active_turns: 2
priority: 15 # High priority for error handling
# Code implementation specialist
- role: "coder"
rules:
triggers:
keywords: ["implement", "code", "function", "class", "refactor", "optimize"]
match_type: "any"
after_tool_use: true
source: "human"
active_turns: 2
priority: 8
# Verification and review
- role: "reviewer"
rules:
triggers:
keywords: ["check", "verify", "review", "validate", "test", "correct"]
match_type: "any"
consecutive_tools: 12 # After many changes
source: "any" # Can be triggered by human request OR after lots of tool use
active_turns: 2
priority: 6
# Help and guidance specialist
- role: "helper"
rules:
triggers:
keywords: ["help", "assist", "guide", "explain", "teach", "how to"]
match_type: "any"
source: "human"
active_turns: 5
priority: 5
# Math and calculations
- role: "mathematician"
rules:
triggers:
keywords: ["calculate", "solve", "equation", "math", "formula", "compute"]
match_type: "any"
complexity_threshold: "medium"
source: "human"
active_turns: 1
priority: 7
# Creative brainstorming
- role: "creative"
rules:
triggers:
keywords: ["idea", "brainstorm", "creative", "innovate", "design", "imagine"]
match_type: "any"
source: "human"
active_turns: 5
priority: 4
# Quick responses for simple queries
- role: "quick-responder"
rules:
triggers:
complexity_threshold: "low"
source: "human"
active_turns: 0
priority: 2
# Research and fact-checking
- role: "researcher"
rules:
triggers:
keywords: ["research", "find", "search", "lookup", "fact", "source", "reference"]
match_type: "any"
source: "human"
active_turns: 3
priority: 6
# System recovery after multiple failures
- role: "recovery-specialist"
rules:
triggers:
consecutive_failures: 2 # After 2 consecutive tool failures
source: "machine" # Only triggers on machine-generated failures
active_turns: 10
priority: 20 # Very high priority
# Autonomous work reviewer - kicks in after lots of machine work
- role: "work-reviewer"
rules:
triggers:
tools_since_human: 5 # After 5+ tools used since last human input
source: "machine" # Only when machine is active
active_turns: 8
priority: 12
# Progress checker - ensures the machine isn't going off track
- role: "progress-checker"
rules:
triggers:
machine_messages_without_human: 4 # After 4+ consecutive machine messages
source: "machine"
active_turns: 5
priority: 11
# Intensive work monitor - for when lots of tool use is happening
- role: "intensive-work-monitor"
rules:
triggers:
consecutive_tools: 10 # 10+ tools in a row
messages_since_human: 6 # AND been working for 6+ messages
source: "machine"
active_turns: 10
priority: 14