fix: use default provider and model when provider in session no longer exists (#8035)

This commit is contained in:
Lifei Zhou
2026-03-21 09:48:30 +11:00
committed by GitHub
parent 1f7f234326
commit 0ace570e28
4 changed files with 85 additions and 11 deletions
+17 -4
View File
@@ -385,7 +385,7 @@ async fn resume_agent(
}
})?;
let extension_results = if payload.load_model_and_extensions {
let (extension_results, session) = if payload.load_model_and_extensions {
let agent = state
.get_agent_for_route(payload.session_id.clone())
.await
@@ -394,7 +394,7 @@ async fn resume_agent(
status: code,
})?;
agent
let provider_changed = agent
.restore_provider_from_session(&session)
.await
.map_err(|e| ErrorResponse {
@@ -402,6 +402,19 @@ async fn resume_agent(
status: StatusCode::INTERNAL_SERVER_ERROR,
})?;
let session = if provider_changed {
state
.session_manager()
.get_session(&payload.session_id, true)
.await
.map_err(|err| ErrorResponse {
message: format!("Failed to re-fetch session: {}", err),
status: StatusCode::INTERNAL_SERVER_ERROR,
})?
} else {
session
};
let extension_results =
if let Some(results) = state.take_extension_loading_task(&payload.session_id).await {
tracing::debug!(
@@ -420,9 +433,9 @@ async fn resume_agent(
agent.load_extensions_from_session(&session).await
};
Some(extension_results)
(Some(extension_results), session)
} else {
None
(None, session)
};
Ok(Json(ResumeAgentResponse {
+65 -4
View File
@@ -1759,7 +1759,8 @@ impl Agent {
/// Restore the provider from session data or fall back to global config
/// This is used when resuming a session to restore the provider state
pub async fn restore_provider_from_session(&self, session: &Session) -> Result<()> {
/// Returns true if the session's provider was replaced with a fallback.
pub async fn restore_provider_from_session(&self, session: &Session) -> Result<bool> {
let config = Config::global();
let provider_name = session
@@ -1784,9 +1785,69 @@ impl Agent {
let extensions =
EnabledExtensionsState::extensions_or_default(Some(&session.extension_data), config);
let provider = crate::providers::create(&provider_name, model_config, extensions)
let (provider, provider_changed) = if crate::providers::get_from_registry(&provider_name)
.await
.map_err(|e| anyhow!("Could not create provider: {}", e))?;
.is_ok()
{
let p = crate::providers::create(&provider_name, model_config, extensions)
.await
.map_err(|e| anyhow!("Could not create provider: {}", e))?;
(p, false)
} else {
let fallback_provider_name = config
.get_goose_provider()
.ok()
.filter(|name| name != &provider_name)
.ok_or_else(|| {
anyhow!(
"Could not create provider: provider '{}' not found",
provider_name
)
})?;
tracing::warn!(
"Session provider '{}' unavailable, falling back to '{}'",
provider_name,
fallback_provider_name
);
let fallback_model_name = config
.get_goose_model()
.ok()
.ok_or_else(|| anyhow!("Could not configure fallback provider: missing model"))?;
let fallback_model_config = crate::model::ModelConfig::new(&fallback_model_name)
.map_err(|e| anyhow!("Could not configure fallback provider: invalid model {}", e))?
.with_canonical_limits(&fallback_provider_name);
let fallback_provider = crate::providers::create(
&fallback_provider_name,
fallback_model_config.clone(),
extensions,
)
.await
.map_err(|e| {
anyhow!(
"Could not create provider '{}' or fallback '{}': {}",
provider_name,
fallback_provider_name,
e
)
})?;
if let Err(e) = self
.config
.session_manager
.update(&session.id)
.provider_name(&fallback_provider_name)
.model_config(fallback_model_config)
.apply()
.await
{
tracing::warn!("Failed to update session provider: {}", e);
}
(fallback_provider, true)
};
self.update_provider(provider, &session.id).await?;
// Propagate session mode to the new provider
@@ -1797,7 +1858,7 @@ impl Agent {
.map_err(|e| anyhow!("Failed to propagate mode to provider: {}", e))?;
}
*self.current_goose_mode.lock().await = session.goose_mode;
Ok(())
Ok(provider_changed)
}
/// Override the system prompt with a custom template
+1 -1
View File
@@ -118,7 +118,7 @@ pub async fn refresh_custom_providers() -> Result<()> {
Ok(())
}
async fn get_from_registry(name: &str) -> Result<ProviderEntry> {
pub async fn get_from_registry(name: &str) -> Result<ProviderEntry> {
let guard = get_registry().await.read().unwrap();
guard
.entries
+2 -2
View File
@@ -48,7 +48,7 @@ pub mod venice;
pub mod xai;
pub use init::{
cleanup_provider, create, create_with_default_model, create_with_named_model, providers,
refresh_custom_providers,
cleanup_provider, create, create_with_default_model, create_with_named_model,
get_from_registry, providers, refresh_custom_providers,
};
pub use retry::{retry_operation, RetryConfig};