Wire incremental exec tool updates into Code Mode sessions (#60163)

## Why

Changes to nested tools should update the model's catalog without repeating the full `functions.exec` declaration or rewriting retained context.

## What changed

Pass structured exec definitions through the tool router into the session's tool world state. Enable granular updates for Responses Lite in `CodeModeOnly` when both `IncrementalTools` and `IncrementalExecTools` are enabled.

Append changed tool definitions, namespace instructions, and removals as developer messages. Keep common exec instructions and shared types frozen until compaction, then install the latest full catalog.

## Testing

Add feature-gating coverage and a scenario snapshot covering tool additions and removals, namespace instruction changes, eager/deferred transitions, re-enabling tools, retained context, and catalog restoration after compaction.

GitOrigin-RevId: bbf850d4e5018388eeb4c09345d885d776962e09
This commit is contained in:
Alex Kira
2026-11-07 19:26:20 +00:00
committed by copyberry
parent 2bc8e7f545
commit 33b3f80a09
13 changed files with 882 additions and 21 deletions
+1
View File
@@ -328,6 +328,7 @@ impl StepContext {
Vec::new(),
ToolMode::Direct,
BTreeMap::new(),
/*exec_definitions*/ None,
/*tool_namespaces_info*/ None,
&[],
)),
+6 -2
View File
@@ -208,11 +208,15 @@ impl Session {
.cloned()
.collect::<Vec<_>>();
let definitions = codex_tools::create_tools_json_for_responses_lite(&specs)?;
world_state.add_section(TopLevelToolsState::new(
let mut top_level = TopLevelToolsState::new(
model_messages.incremental_tools(),
definitions,
Some(Arc::clone(&extension_metrics)),
)?);
)?;
if let Some(entries) = step_context.tool_router.exec_definitions() {
top_level = top_level.with_incremental_exec_tools(Some(entries));
}
world_state.add_section(top_level);
}
world_state.add_section(model_state);
let token_budget_enabled = turn_context.config.features.enabled(Feature::TokenBudget)