Preserve model providers when reloading v2 agents (#36906)

## Why

Reloading an unloaded v2 agent could inherit the model provider from the
agent that triggered the reload, even though the worker's model was restored
from its persisted thread state.

## What changed

- Restore both the model and model provider from the stored thread when
  reloading a v2 agent.
- Return an invalid-request error if the stored provider is no longer present
  in the configured provider map.

## Testing

Extend the v2 agent reload test to trigger the reload with a different sender
provider and verify that the worker retains its stored provider.

GitOrigin-RevId: 6401d9f0d1c116e9954e3bd193d016f04da5f223
This commit is contained in:
jif
2026-08-04 15:01:28 +00:00
committed by copyberry
parent d98eb72e18
commit d1f14e31a7
2 changed files with 39 additions and 1 deletions
+13
View File
@@ -269,6 +269,7 @@ impl AgentControl {
})
.await?;
let stored_model = stored_thread.model.clone();
let stored_model_provider = stored_thread.model_provider.clone();
let stored_source = stored_thread.source.clone();
let stored_parent_thread_id = stored_thread.parent_thread_id;
let history = load_agent_model_context(&state, thread_id, stored_thread.history_mode)
@@ -324,6 +325,18 @@ impl AgentControl {
if let Some(model) = stored_model {
config.model = Some(model);
}
if config.model_provider_id != stored_model_provider {
config.model_provider = config
.model_providers
.get(&stored_model_provider)
.cloned()
.ok_or_else(|| {
CodexErr::InvalidRequest(format!(
"Model provider `{stored_model_provider}` not found"
))
})?;
config.model_provider_id = stored_model_provider;
}
let residency_slot = self
.reserve_v2_residency_slot(&state, &config, Some(thread_id))
.await?;
+26 -1
View File
@@ -713,9 +713,17 @@ async fn ensure_v2_agent_loaded_reloads_registered_unloaded_agent() {
Ok(_) => panic!("expected thread to be removed"),
}
let mut sender_config = harness.config.clone();
sender_config.model_provider_id = "ollama".to_string();
sender_config.model_provider = sender_config
.model_providers
.get("ollama")
.cloned()
.expect("ollama provider should be configured");
harness
.control
.ensure_v2_agent_loaded(harness.config.clone(), spawned_agent.thread_id)
.ensure_v2_agent_loaded(sender_config, spawned_agent.thread_id)
.await
.expect("known v2 agent should reload");
let reloaded_child = harness
@@ -728,6 +736,23 @@ async fn ensure_v2_agent_loaded_reloads_registered_unloaded_agent() {
"gpt-5.6-luna",
"residency reload must preserve the worker model instead of inheriting its parent model",
);
assert_eq!(
(
reloaded_child.config_snapshot().await.model_provider_id,
reloaded_child
.session
.new_default_turn()
.await
.provider
.info()
.clone(),
),
(
stored_child.model_provider,
harness.config.model_provider.clone()
),
"residency reload must preserve the worker provider instead of inheriting its sender's provider",
);
let communication = InterAgentCommunication::new(
AgentPath::root(),