move global config access out of ModelConfig, and move ModelConfig into goose_providers (#9769)

This commit is contained in:
Jack Amadeo
2026-06-18 12:33:19 -04:00
committed by GitHub
parent 4c64375de7
commit 80eaf8fa44
92 changed files with 843 additions and 1027 deletions
+22 -16
View File
@@ -6,6 +6,7 @@ use console::style;
use goose::agents::{Agent, Container, ExtensionError};
use goose::config::resolve_extensions_for_new_session;
use goose::config::{Config, ExtensionConfig, GooseMode};
use goose::model_config::model_config_from_user_config;
use goose::providers::create;
use goose::recipe::Recipe;
use goose::session::session_manager::SessionType;
@@ -229,14 +230,14 @@ async fn load_extensions(
struct ResolvedProviderConfig {
provider_name: String,
model_name: String,
model_config: goose::model::ModelConfig,
model_config: goose_providers::model::ModelConfig,
}
fn resolve_provider_and_model(
session_config: &SessionBuilderConfig,
config: &Config,
saved_provider: Option<String>,
saved_model_config: Option<goose::model::ModelConfig>,
saved_model_config: Option<goose_providers::model::ModelConfig>,
) -> ResolvedProviderConfig {
let recipe_settings = session_config
.recipe
@@ -277,14 +278,16 @@ fn resolve_provider_and_model(
}
config
} else {
let temperature = recipe_settings.and_then(|s| s.temperature);
goose::model::ModelConfig::new(&model_name)
.unwrap_or_else(|e| {
output::render_error(&format!("Failed to create model configuration: {}", e));
process::exit(1);
})
.with_canonical_limits(&provider_name)
.with_temperature(temperature)
let mut config =
goose::model_config::model_config_from_user_config(&provider_name, &model_name)
.unwrap_or_else(|e| {
output::render_error(&format!("Failed to create model configuration: {}", e));
process::exit(1);
});
if let Some(temp) = recipe_settings.and_then(|s| s.temperature) {
config = config.with_temperature(Some(temp));
}
config
};
ResolvedProviderConfig {
@@ -575,12 +578,15 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
))
.yellow()
);
let fallback_model_config = goose::model::ModelConfig::new(&fallback_model)
.unwrap_or_else(|e| {
output::render_error(&format!("Failed to create model configuration: {}", e));
process::exit(1);
})
.with_canonical_limits(&fallback_provider);
let fallback_model_config =
model_config_from_user_config(fallback_provider.as_str(), &fallback_model)
.unwrap_or_else(|e| {
output::render_error(&format!(
"Failed to create model configuration: {}",
e
));
process::exit(1);
});
match create(
&fallback_provider,
fallback_model_config,
+26 -11
View File
@@ -13,6 +13,7 @@ use crate::session::task_execution_display::{
format_task_execution_notification, TASK_EXECUTION_NOTIFICATION_TYPE,
};
use goose::conversation::Conversation;
use std::env;
use std::io::Write;
use std::str::FromStr;
use tokio::signal::ctrl_c;
@@ -57,6 +58,8 @@ use tokio;
use tokio_util::sync::CancellationToken;
use tracing::warn;
const GOOSE_PLANNER_CONTEXT_LIMIT: &str = "GOOSE_PLANNER_CONTEXT_LIMIT";
#[derive(Serialize, Deserialize, Debug)]
struct JsonOutput {
messages: Vec<Message>,
@@ -842,8 +845,11 @@ impl CliSession {
let new_model_config =
build_switched_model_config(&current_provider_name, model_name, &current_model_config)?;
let configured_effort = Config::global().get_goose_thinking_effort();
let new_effort = new_model_config.thinking_effort().or(configured_effort);
let current_effort = current_model_config.thinking_effort().or(configured_effort);
if new_model_config.model_name == current_model_config.model_name
&& new_model_config.thinking_effort() == current_model_config.thinking_effort()
&& new_effort == current_effort
{
output::goose_mode_message(&format!(
"Session already using model '{}' for provider '{}'",
@@ -2200,7 +2206,6 @@ fn handle_agent_error(e: &anyhow::Error, is_stream_json_mode: bool) {
}
async fn get_reasoner() -> Result<Arc<dyn Provider>, anyhow::Error> {
use goose::model::ModelConfig;
use goose::providers::create;
let config = Config::global();
@@ -2225,8 +2230,19 @@ async fn get_reasoner() -> Result<Arc<dyn Provider>, anyhow::Error> {
.expect("No model configured. Run 'goose configure' first")
};
let planner_context_limit = match env::var(GOOSE_PLANNER_CONTEXT_LIMIT)
.ok()
.map(|v| v.parse::<usize>())
{
Some(Ok(n)) if n >= 4096 => Some(n),
Some(Ok(_)) => anyhow::bail!("{} must be at least 4096", GOOSE_PLANNER_CONTEXT_LIMIT),
Some(Err(e)) => anyhow::bail!("{}: {}", GOOSE_PLANNER_CONTEXT_LIMIT, e),
None => None,
};
let model_config =
ModelConfig::new_with_context_env(model, &provider, Some("GOOSE_PLANNER_CONTEXT_LIMIT"))?;
goose::model_config::model_config_from_user_config(&provider, model.as_str())?
.with_context_limit(planner_context_limit);
let extensions = goose::config::extensions::get_enabled_extensions_with_config(config);
let reasoner = create(&provider, model_config, extensions).await?;
@@ -2249,12 +2265,11 @@ fn format_elapsed_time(duration: std::time::Duration) -> String {
fn build_switched_model_config(
provider_name: &str,
model_name: &str,
current_model_config: &goose::model::ModelConfig,
) -> Result<goose::model::ModelConfig> {
goose::model::ModelConfig::new(model_name)
current_model_config: &goose_providers::model::ModelConfig,
) -> Result<goose_providers::model::ModelConfig> {
goose::model_config::model_config_from_user_config(provider_name, model_name)
.map(|config| {
config
.with_canonical_limits(provider_name)
.with_temperature(current_model_config.temperature)
.with_toolshim(current_model_config.toolshim)
.with_toolshim_model(current_model_config.toolshim_model.clone())
@@ -2404,7 +2419,7 @@ mod tests {
("GOOSE_TOOLSHIM_OLLAMA_MODEL", None::<&str>),
]);
let current_model_config = goose::model::ModelConfig {
let current_model_config = goose_providers::model::ModelConfig {
model_name: "gpt-4o".to_string(),
context_limit: Some(128_000),
temperature: Some(0.25),
@@ -2421,7 +2436,7 @@ mod tests {
let switched =
build_switched_model_config("openai", "gpt-5.4", &current_model_config).unwrap();
let expected = goose::model::ModelConfig::new_or_fail("gpt-5.4")
let expected = goose_providers::model::ModelConfig::new_or_fail("gpt-5.4")
.with_canonical_limits("openai")
.with_temperature(Some(0.25))
.with_toolshim(true)
@@ -2448,8 +2463,8 @@ mod tests {
("GOOSE_THINKING_EFFORT", None::<&str>),
]);
let current =
goose::model::ModelConfig::new_or_fail("gpt-5.4-high").with_canonical_limits("openai");
let current = goose_providers::model::ModelConfig::new_or_fail("gpt-5.4-high")
.with_canonical_limits("openai");
assert_eq!(current.model_name, "gpt-5.4");
assert_eq!(
current.thinking_effort(),