feat: multi model and multi provider config and auto switching (#4035)
This commit is contained in:
@@ -55,6 +55,7 @@ use tokio_util::sync::CancellationToken;
|
|||||||
use tracing::{debug, error, info, instrument};
|
use tracing::{debug, error, info, instrument};
|
||||||
|
|
||||||
use super::final_output_tool::FinalOutputTool;
|
use super::final_output_tool::FinalOutputTool;
|
||||||
|
use super::model_selector::autopilot::AutoPilot;
|
||||||
use super::platform_tools;
|
use super::platform_tools;
|
||||||
use super::tool_execution::{ToolCallResult, CHAT_MODE_TOOL_SKIPPED_RESPONSE, DECLINED_RESPONSE};
|
use super::tool_execution::{ToolCallResult, CHAT_MODE_TOOL_SKIPPED_RESPONSE, DECLINED_RESPONSE};
|
||||||
use crate::agents::subagent_task_config::TaskConfig;
|
use crate::agents::subagent_task_config::TaskConfig;
|
||||||
@@ -102,6 +103,7 @@ pub struct Agent {
|
|||||||
pub(super) tool_route_manager: ToolRouteManager,
|
pub(super) tool_route_manager: ToolRouteManager,
|
||||||
pub(super) scheduler_service: Mutex<Option<Arc<dyn SchedulerTrait>>>,
|
pub(super) scheduler_service: Mutex<Option<Arc<dyn SchedulerTrait>>>,
|
||||||
pub(super) retry_manager: RetryManager,
|
pub(super) retry_manager: RetryManager,
|
||||||
|
pub(super) autopilot: Mutex<AutoPilot>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@@ -178,6 +180,7 @@ impl Agent {
|
|||||||
tool_route_manager: ToolRouteManager::new(),
|
tool_route_manager: ToolRouteManager::new(),
|
||||||
scheduler_service: Mutex::new(None),
|
scheduler_service: Mutex::new(None),
|
||||||
retry_manager,
|
retry_manager,
|
||||||
|
autopilot: Mutex::new(AutoPilot::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,6 +1044,20 @@ impl Agent {
|
|||||||
break;
|
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(
|
let mut stream = Self::stream_response_from_provider(
|
||||||
self.provider().await?,
|
self.provider().await?,
|
||||||
&system_prompt,
|
&system_prompt,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ pub mod extension_malware_check;
|
|||||||
pub mod extension_manager;
|
pub mod extension_manager;
|
||||||
pub mod final_output_tool;
|
pub mod final_output_tool;
|
||||||
mod large_response_handler;
|
mod large_response_handler;
|
||||||
|
pub mod model_selector;
|
||||||
pub mod platform_tools;
|
pub mod platform_tools;
|
||||||
pub mod prompt_manager;
|
pub mod prompt_manager;
|
||||||
pub mod recipe_tools;
|
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
|
||||||
|
|
||||||
Reference in New Issue
Block a user