Prewarm MCP runtime updates in the background (#35144)

## Why

Changes to MCP inputs can require rebuilding the runtime before the next model
step. Start that work eagerly so the step is less likely to wait for it.

## What changed

- Add a per-session worker that prewarms dirty MCP state after configuration,
  authentication, or explicit refresh changes.
- Coalesce queued refreshes and always rebuild from the latest session state,
  while keeping exact model-step refreshes as the correctness path.
- Stop and join the worker during session shutdown.

## Testing

- Verify rapid refreshes skip superseded configuration and publish the latest
  state.
- Verify MCP-relevant policy changes mark the runtime for refresh.

GitOrigin-RevId: 045ed406caff97dcbb483bc183fd16eae0c7d7ad
This commit is contained in:
jif authored and copyberry committed 2026-07-24 09:40:10 +00:00
1 parent 81da9deb06
commit ef2d3edb95
9 files changed
+306 -25

No files matched your search

+25 -17
View File
@@ -638,6 +638,7 @@ impl Session {
state.session_configuration = next.clone();
Ok((
next,
mcp_inputs_changed,
permission_profile_changed,
previous_config,
new_config,
@@ -647,23 +648,31 @@ impl Session {
}
};
let (session_configuration, permission_profile_changed, previous_config, new_config) =
match update_result {
Ok(update) => update,
Err(err) => {
let message = err.to_string();
self.send_event_raw(Event {
id: sub_id.clone(),
msg: EventMsg::Error(ErrorEvent {
message: message.clone(),
codex_error_info: Some(CodexErrorInfo::BadRequest),
}),
})
.await;
return Err(CodexErr::InvalidRequest(message));
}
};
let (
session_configuration,
mcp_inputs_changed,
permission_profile_changed,
previous_config,
new_config,
) = match update_result {
Ok(update) => update,
Err(err) => {
let message = err.to_string();
self.send_event_raw(Event {
id: sub_id.clone(),
msg: EventMsg::Error(ErrorEvent {
message: message.clone(),
codex_error_info: Some(CodexErrorInfo::BadRequest),
}),
})
.await;
return Err(CodexErr::InvalidRequest(message));
}
};
self.emit_config_changed_contributors(previous_config.as_ref(), new_config.as_ref());
if mcp_inputs_changed {
self.schedule_mcp_prewarm();
}
if permission_profile_changed {
self.refresh_managed_network_proxy_for_current_permission_profile()
@@ -727,7 +736,6 @@ impl Session {
.and_then(|turn_environment| turn_environment.cwd().to_abs_path().ok())
.unwrap_or_else(|| session_configuration.cwd().clone());
let per_turn_config = Self::build_per_turn_config(&session_configuration, cwd.clone());
let model_info = self
.services
.models_manager