## Why
MCP tool calls reported every aborted approval as "user cancelled MCP tool call", including interrupted requests and automatic cancellations in `exec` mode.
## What changed
Carry `user`, `interrupted`, or `non_interactive` cancellation reasons through MCP approval metadata and resolution. Mark explicit TUI cancellations as user actions, interrupted requests as interruptions, and automatic `exec` cancellations as non-interactive.
Use the reason to report when a call was cancelled before approval or because interactive approval is unavailable in `exec` mode. Preserve the existing cancellation message for clients that omit the reason.
## Testing
Update tests to verify that a closed approval response carries the interruption reason and that `exec` cancellation responses include the non-interactive reason.
GitOrigin-RevId: be2a5f7fef539b5db2add53b46aea27e2b8a66fc
## Why
Dynamic tool calls should remain independent while waiting for client responses, so one pending call does not block another from reaching the client.
## What changed
Enable parallel execution in `DynamicToolHandler`, allowing code mode programs to issue concurrent dynamic tool calls with `Promise.all`.
## Testing
Add a code mode regression test that waits for two dynamic tool requests before responding, resolves them in reverse order, and verifies that `Promise.all` preserves the expected result order.
GitOrigin-RevId: c93c1fea720f76c772b0e3452ddc8c01fb1a08d8
## Why
Remote credential masking previously supported only Bash commands without login startup or shell snapshots, leaving Zsh commands with unmasked credentials.
## What changed
- Enable masking for Zsh login commands using shell snapshots on Linux and macOS.
- Capture trusted startup profiles per launch, bind the credential broker to the resulting environment, and replace credentials and supported aliases with placeholders before snapshot replay.
- Preserve explicit environment overrides, credential unsets, and launcher-managed proxy settings during replay.
- Warn and fall back to unmasked startup when a snapshot cannot safely replay credentials; stop execution if protected snapshot restoration fails.
## Testing
Extend remote execution tests for inherited and profile-defined credentials, overrides, destination changes, and unsupported-profile fallback. Add a Zsh scenario snapshot showing a credential placeholder in command output.
GitOrigin-RevId: 83193d6cbc05f3deb0d6d0b9ae80974b353ce900
## What changed
Add optional `inputImages` metadata containing each referenced local image's path and SHA-256 hash of the bytes read before normalization. Compute the hash from the same bytes used to prepare the edit request.
Preserve this metadata through completion events, persisted thread history, resume, and legacy rollout migration. Update app-server schemas and generated TypeScript and Python types; older items continue to deserialize without the field.
## Testing
Add coverage for input ordering, changed contents at the same path, unreadable or invalid references, serialization, persisted history and resume, and legacy migration.
GitOrigin-RevId: 522be8ec1e39c9b2bbe5b9ccb37ea67d17f0e21a
## What changed
- Upload generated images to the attachment store and expose `fileId` in image-generation items when available, with inline `result` fallback on upload or decoding failure.
- Preserve file references through legacy events, persisted rollouts, thread history, and task output summaries. Keep model-facing image preparation separate.
- Add attachment request tags and mark generated-image uploads with `usage=image_gen`, preserving the thread's ephemeral setting.
- Update public schemas and SDK types to accept either image representation, retain the Python `ImageGenerationThreadItem` alias, and prefer `fileId` when reading records containing both fields.
## Testing
Add coverage for file-backed generation and rollout persistence, legacy history replay, inline and transitional serialization, task output visibility, and Python SDK alias compatibility.
GitOrigin-RevId: f7a2bb5707e2f277348a547a988bc33c8e96d891
## What changed
Negotiate executor support for `credential_masking` and enable built-in credential brokerage in executor-local network proxies. Supported non-login Bash commands on Linux and macOS receive credential placeholders, with real credentials injected by the proxy for matching destinations.
Retain credential mappings across process launches within the same executor session, scoped by environment, conversation, and broker configuration. Keep credentials and destination context on the executor.
Fall back to unmasked execution for unsupported shells or shell startup, and for configured credential providers. Emit warnings when masking is unavailable, preserving shell profiles and snapshots.
## Testing
Add coverage for capability negotiation, fallback behavior, mapping reuse and isolation, proxy credential injection, and keeping executor credentials out of model-visible request history. Test warning, removal, and rejection modes for credentials left unmasked during preparation.
GitOrigin-RevId: f64e916a5de8350fa0d289d3440ec29761accd75
## Why
Guardian approval covers the permissions of the reviewed action. A retry outside the sandbox needs a fresh review of its broader permissions.
## What changed
- Track the initial approval source so Guardian approval does not preapprove an escalated retry, while preserving existing user and hook approval behavior.
- For exec retries that can run without the sandbox, set the approval action to `RequireEscalated` and clear `additional_permissions` so review and caching reflect the retry's actual permissions.
GitOrigin-RevId: 06f8d53745a7bcfe9fdb5628ff9e85da6060547d
## Why
With granular sandbox approvals disabled, `write_stdin` rejected input to terminals retaining additional permissions even when those permissions were still granted.
## What changed
Let input reach approval review when the terminal's retained permissions match active grants for its environment. Require identical filesystem grants, including entry order, and an active network grant when retained permissions enable network access. Each input still requires review.
Keep rejecting input when retained authority is no longer covered or the approval policy changes to `Never`.
## Testing
Add regression coverage for user and Guardian review, turn grant expiry, session grants, and switching to `Never`. Cover filesystem restrictions, protected metadata, symlinks, and ordered denials, and verify that rejected input never reaches the terminal.
GitOrigin-RevId: 9abf7da8d03b1526d26ca2a718e36349a255330b
## Why
Environment tool availability and selectors should remain stable as selected environments become ready.
## What changed
- Keep configured environment tools advertised even when no execution environment is ready, and derive `environment_id` selectors from all selected environments.
- Return guidance to wait when an environment is unavailable, while preserving errors for unknown environment IDs. Require a usable primary environment for `write_stdin`.
- Always include `shell` and `login` in the `exec_command` schema and mark `stable_environment_tools` as removed.
## Testing
Update integration tests to expect environment tools with empty or starting environments, and remove explicit feature opt-ins from affected scenarios.
GitOrigin-RevId: 1590c1b5be16a39e4a370663c552b881602545b5
## Why
Native extensions need configured Responses metadata for request attribution, but extension calls used the MCP metadata template, which omits it. Image requests also did not forward the turn metadata to the backend.
## What changed
Use the Responses metadata template for native extension calls while continuing to exclude tool inventory. Forward the resulting metadata in the `x-codex-turn-metadata` header on image generation and edit requests.
## Testing
Extend metadata tests to cover configured values in extension calls and app-server tests to verify `display_name` and `turn_trigger` on image generation and edit requests, including a Unicode display name.
GitOrigin-RevId: a2ffaa4d15259c662917612391b8717ee34b9c6c
## What changed
- Preserve approval resolution sources through tool errors and tag cancelled MCP approvals with `error_type=approval`, `error_code=cancelled`, and `approval_source` (`guardian`, `user`, `hook`, or `unknown`). The source identifies the reviewer, not who caused cancellation.
- Record `context_changed` when validating a Guardian allow against changed authorization or review context, even when a concurrent stop or history reset determines the outcome. Retain the flag across retries and fresh-checkpoint recovery, and include it in the Guardian review counter.
GitOrigin-RevId: a19a986a7565f9a78a9bb2eaabdb5651834d28b8
## Why
Prediction forks need to retain their parent's context even when it exceeds the automatic compaction threshold. Compaction or context resets can otherwise replace the history used for the prediction.
## What changed
- Apply a thread-local `AutoCompactionDisabled` policy to experimental prediction forks without changing model or skill budgets.
- Skip automatic compaction before, during, and after turns, including context-limit recovery, and suppress new token-budget reminders.
- Reject `new_context` requests for these threads and report context-limit failures without compacting their history.
## Testing
Add regression tests for legacy and paginated prediction forks across compaction thresholds, unchanged parent compaction and skill/tool inputs, context-limit failures, and rejected context resets. Add a request-history snapshot verifying inherited context and reminders survive without compaction or additional reminders after a tool call.
GitOrigin-RevId: 7df374287f4142f776981bb6c22e5caa564d74a5
## What changed
Move child configuration, task path construction, fork usage hints, and backend spawning into `core::thread_spawn`. Add request, result, and error types that distinguish preparation failures from backend errors.
Route the v2 `spawn_agent` handler through the shared helper while retaining tool-specific telemetry, activity events, and response formatting in the handler.
GitOrigin-RevId: a09a8f66beb41c1403220750d236a12717dbfc6c
## What changed
Add `features.multi_agent_v2.disable_native_tools` to hide native multi-agent tools while keeping the V2 runtime and its instructions enabled for host-provided tools. The option defaults to `false`, preserving existing tool exposure.
## Testing
Extend configuration parsing tests for the new option and parameterize the multi-agent catalog scenario to cover both settings. Add a snapshot showing native tools are absent while the V2 runtime and instructions remain enabled.
GitOrigin-RevId: 21a53584d2395bb678813c876a8b7927bea61c90
## Why
With `multi_agent_v2.disable_direct_message` enabled, an unavailable agent message board could cause tool router construction to reject the turn.
## What changed
Remove the requirement that the router expose the board's `post` tool. Unavailable board calls return an unsupported-call error to the model, allowing the turn to continue.
## Testing
Update scenario coverage for a disabled board feature, legacy agents, and ephemeral sessions. Assert that unavailable board calls return an error to the model, that `post`, `send_message`, and `followup_task` are not advertised, and that no board database is created.
GitOrigin-RevId: cb9571459c128d84c3c96f185e70c404e0463473
## What changed
- Add the disabled-by-default `output_token_replay` feature to request `output.encrypted_content` from OpenAI providers.
- Preserve encrypted message and tool-call output, message and function-call status, and output-text `annotations` and `logprobs` through history and replay. Update the generated protocol schemas and SDK types.
- Strip output ciphertext from requests to other providers while retaining it in stored history, including after replay is disabled. Remove encrypted content from memory extraction inputs.
## Testing
Add integration coverage for the feature/provider combinations, metadata replay across follow-up requests, and history preservation when resuming with replay disabled.
GitOrigin-RevId: 77729a021b6771933402aebe74ece8eb39c057e2
## Why
Fixed argument limits truncated recorded tool calls even when their metadata fit within the available message budget.
## What changed
- Remove the 8 KiB per-call and 32 KiB per-output argument limits for direct calls and Code Mode.
- Preserve full recorded arguments while retaining message metadata budgets, pending-call limits, and the direct metadata retention limit.
- Rename the normalization helper to `normalize_executed_tool_call_completeness`; it now only clears completeness when calls or tool names were lost.
## Testing
Update regression coverage for large arguments, escaped inputs, reserved-key wrappers, and argument and result metadata preservation across Code Mode waits.
GitOrigin-RevId: 8c199ccf39191d5d44eef02d28b1773654735b43
## Why
Tools that do not opt into parallel execution acquire an exclusive scheduler lock, serializing independent reads.
## What changed
Allow skill listing and reading, memory listing, reading and searching, conversation history search and reading, plugin listing, agent listing, current time, remaining context, and `get_goal` to run in parallel. Keep goal creation and updates serialized.
## Testing
Add `cloud_skill_reads_run_in_parallel`, which uses a barrier to require two cloud skill reads to overlap and verifies that each returns the expected resource contents.
GitOrigin-RevId: 97b5634f1f84be2ba092be89e6e9c634ca75c07b
## Why
Subagents should retain the spawning turn's selected skills and plugin choices whether `fork_turns` is `none` or `all`. Capability selection should not depend on copied conversation metadata.
## What changed
- Use a shared child startup path for fresh and history-forked agents, inheriting selected capability roots from the spawning environment snapshot.
- Pass the spawning turn's `disabled_plugin_ids` through both spawn handlers. When omitted, inherit the parent's current choices; explicit lists, including an empty list, override them.
- Resolve the parent before startup so inherited client MCP settings apply even when only the session source identifies the parent.
- Carry plugin choices into delegates with inherited isolation and preserve saved capability roots when resuming a child.
## Testing
Add regression coverage for executor skill listing and reading, plugin MCP registration with both history modes, plugin overrides, capability-root precedence and isolation, and restoring saved child settings after parent settings change.
GitOrigin-RevId: 2a6891a9bc6372fd2d1f30add2b5611f96b60594
## What changed
- Use the standard shell executor and remove the zsh fork escalation runtime, `codex-execve-wrapper`, and `shell-escalation` crate.
- Ignore `shell_zsh_fork` and `unified_exec_zsh_fork`, emit migration notices for legacy configuration, and warn when ignoring managed requirements for these flags.
- Keep the active session's `apply_patch` alias directory readable under restricted filesystem permissions.
## Testing
Add coverage for legacy configuration startup and shell execution, migration notice rendering, active alias directory selection, and nested `apply_patch` execution while other files in `CODEX_HOME` remain unreadable.
GitOrigin-RevId: 43af461fea32b4980550ee7237effd2bc0646ed8
## Why
Command processes need thread and tool call labels for correlation, without stale values from inherited environments or cached shell snapshots.
## What changed
- Export the originating `exec_command` call ID as `CODEX_TOOL_CALL_ID`; later `write_stdin` calls leave it unchanged.
- Apply executor metadata as `CODEX_THREAD_ID` and `CODEX_TOOL_CALL_ID` after environment policies, overlays, and snapshot replay. Clear omitted fields when metadata is present; without metadata, preserve thread context and remove the call ID.
- Exclude both IDs from newly captured snapshots and omit the call ID from capture and validation helpers.
- Preserve empty call IDs, omit NUL-containing IDs, and handle case-insensitive environment names on Windows. Document that these labels support correlation, not authorization.
## Testing
Add regression coverage for metadata precedence, missing and invalid IDs, snapshot capture and replay, local and remote execution with pipes and TTYs, sandboxed remote execution, and preservation of the originating call ID across later input.
GitOrigin-RevId: 1027212b5d495d8e7cfac0f498c3134e060aa897
## What changed
- Route app-server idle unloading of multi-agent v2 children through local eviction that preserves unread mail and environment selections for reload.
- Hold residency pins through input submission so newly reloaded children cannot be evicted before receiving their work.
- Guard listener cleanup against replacement runtimes and subscriptions, and reject local eviction of host-controlled threads.
## Testing
Add coverage for unsubscribe-driven eviction followed by `followup_task`, verifying restored conversation context and exactly-once delivery of queued mail. Extend tests to check that residency pins block eviction and that rejected host eviction preserves the thread and mailbox.
GitOrigin-RevId: e36723730af683d2081e495e637f0e6d23548b8d
## What changed
Add `functions_namespace_functions_description_prefixes` to model tool messages, keyed by unqualified tool name. Prepend this guidance to descriptions in the `functions` namespace across direct declarations, Code Mode documentation, and tool-search results, including custom tools.
Trim prefixes, ignore empty values and unavailable functions, and enforce a combined 256-byte UTF-8 limit including separators for reachable tools. Keep overrides local to each step, preserve search ranking text, and retain runtime caches for unaffected tools.
## Testing
Extend coverage for direct and indirect descriptions, clearing prefixes when switching models, namespace scoping for deferred dynamic tools, and tool-search cache reuse and reset.
GitOrigin-RevId: f434e37cec010764fe3e09fb12c339e933b3c21c
## Why
Disabling `experimental_request_user_input_enabled` previously left `request_user_input_async` available when the model advertised support for it.
## What changed
Require the user input setting to be enabled before registering `request_user_input_async`, while preserving the root-agent restriction and support for both current and legacy model capability names.
## Testing
Add parameterized tests covering enabled and disabled settings, current and legacy capability names, missing capabilities, and subagents. Also verify that `send_message_to_user_async` remains available to root agents independently of the user input setting.
GitOrigin-RevId: 27156a3fe7da38d10fccb6384f28e755c39abc39
## Why
Truncating recorded arguments does not lose the call inventory. Clearing `tool_calls_complete` in that case incorrectly treats retained calls and tool names as incomplete.
## What changed
Define `tool_calls_complete` as completeness of the ordered call inventory, independent of recorded arguments. Preserve it for direct tool outputs and Code Mode cells when argument limits or message budgets truncate arguments, including across later waits. Continue clearing completeness when calls are omitted or tool names are truncated.
## Testing
Update protocol, recorder, and integration tests to verify completeness survives argument truncation and message budgeting. Add coverage confirming that omitted calls and truncated tool names still clear completeness.
GitOrigin-RevId: 1534dbfabbd1291b840dd6fb6738ed51bcd4c0c4
## What changed
Add the `codex.tools.registered` histogram to count finalized tool registrations by `exposure` and `tool_mode`, including zero counts for empty exposure categories. Record it once per sampling request before transport retries, excluding hosted tools. These counts describe the registered inventory, not model visibility or tool reachability.
## Testing
Add an integration test covering a stream retry, direct and deferred namespace tools, a model-only tool, and hosted web search. Verify that registrations are recorded once, hosted tools are excluded, and metric labels contain no tool names or descriptions.
GitOrigin-RevId: 02b450743886e3d487d6c3bcda12eb65f6d1104b
## What changed
Wire existing sandbox integrity checks into local command preparation, exec-server process preparation, and sandboxed filesystem helper and file-open operations. Make execution request preparation asynchronous so callers can await the checks.
The checks remain observational: failures and timeouts do not prevent command execution.
## Testing
Add regression tests that launch a real command after checker preparation fails or exceeds its timeout, verifying successful output and exit status.
GitOrigin-RevId: a82399f8aeb8b08f9965e6121b4c7f460552af3f
## What changed
Move `SandboxOverride` into the shared protocol and carry the controller's selection through tool attempts, execution requests, and exec-server process and filesystem sandbox preparation. Include it as `sandboxOverride` in filesystem sandbox contexts for observation without granting broader permissions or altering sandbox commands.
Default missing values to `NoOverride` and omit that value when serializing to preserve compatibility with existing requests.
## Testing
Extend tests to cover override propagation, wire round-trips for all three variants, and deserialization of requests without `sandboxOverride`.
GitOrigin-RevId: 2f438cf4aef1134e3149959d14aa731682168ae5
## What changed
Remove the duplicate tool metadata stored in `CachedMcpHandler` and compare incoming metadata directly with `McpHandler::tool_info()`.
Preserve complete agent plugin namespace descriptions in the handler, applying the existing 1,000-byte limit when building tool specs and search metadata. Truncation continues to respect UTF-8 character boundaries.
## Testing
Extend the agent plugin namespace description test to verify that the handler retains the full description while search output remains bounded.
GitOrigin-RevId: d0a9d5f6796143315235e658e77e059657e85f13
## What changed
Apply `code_mode_tool_description_first` when preparing nested tool definitions for Code Mode execution and tool search. When enabled, place each tool's description before its namespace description; otherwise, preserve namespace-first ordering.
Reuse cached MCP definitions only when both the input schema budget and description-order setting match.
## Testing
Extend deferred app tool integration tests to cover both description orders with and without ranked search, including consistency between search results and `ALL_TOOLS`. Extend the MCP cache test to reject reuse when the description-order setting changes.
GitOrigin-RevId: 1e3f84d2d95c200aef21ad710d367274b2169b4b
## What changed
Increment `codex.agents_md.edit` for committed `apply_patch` changes to `AGENTS.md` and `AGENTS.override.md`, matching filenames case-insensitively and tagging the counter with the normalized filename.
Count additions, deletions, updates, and distinct move destinations, including changes committed before a later patch failure.
GitOrigin-RevId: bcbfa671acb37a2a24fe7e4effc9318981a22ec7
## Why
Interrupting a turn or terminating a Code Mode cell can drop a pending dynamic tool handler before it publishes its completion. Cancellation needs to settle the call in live events and persisted history without allowing a late response into model context.
## What changed
- Let dynamic tool handlers observe cancellation and publish their terminal item before dispatch finishes. Calls cancelled while awaiting a response complete with a failed item and a cancellation error.
- Keep readiness, dispatch admission, registry lock waits, hooks, and output processing cancellable so cancellation can finish even when a hook is blocked.
- Report an aborted tool lifecycle outcome when cancellation interrupts dispatch, including before handler execution.
## Testing
Add regression tests for turn interruption with pending calls or blocked hooks, cell termination with persisted failure and late-response exclusion, cancellation before dispatch admission, and exactly one completion when a response races cancellation.
GitOrigin-RevId: 0112fc74c8652c91503ed5bbfb334ae2e26930ef
## Why
Capability discovery needs the roots captured with each environment snapshot. Threads sharing an executor can select different roots, and changing environment order must preserve executor skill aliases.
## What changed
- Attach the receiving thread's capability roots when constructing `TurnEnvironmentSelection` at startup and settings updates, including roots loaded from saved history.
- Resolve capability roots from environment snapshots while preserving their original order. Retain startup roots so deselecting and reselecting an environment restores its capabilities.
- Match inherited configuration by environment and workspace so differences in capability root metadata do not interrupt configuration propagation.
## Testing
Add regression coverage for root ordering across environment states and configuration changes, independent root selections on a shared executor, reselection with startup or saved roots, active turn updates, and pending configuration failures reaching child and grandchild threads.
GitOrigin-RevId: 4f2e4bb414d27195a6752406117a6050718a1198
## Why
Changing the incremental tools setting on resume should not move tool declarations and base instructions within an existing context window.
## What changed
- Determine the current window's tool declaration mode from its history, and apply the incremental tools setting when building a new window after compaction or a context reset.
- Use that mode consistently for sampling, remote compaction, startup prewarm, prompt debugging, and Guardian input budgeting.
- Preserve tool declarations alongside their comparison baseline in full-history agent forks, including compacted histories; remove them together when rebuilding context.
## Testing
Add request snapshots covering legacy resume, migration after remote compaction or a context reset, disabling incremental tools, and tool updates after restart. Extend agent fork and WebSocket startup prewarm tests to cover retained declarations and incremental tools.
GitOrigin-RevId: 7c46849a1788027a8435082e4d1f7e7f48d2700c
## What changed
Add `model` and `reasoningEffort` to `subAgentActivity` items for multi-agent v2 spawns. Capture startup settings before the child begins its turn and resolve the reported effort against model metadata, including model defaults, while preserving the child's configured effort.
Carry these fields through live notifications, persisted activity, thread history, and legacy rollout migration. Update the JSON schemas and generated TypeScript and Python types. Older records and other activity kinds retain null values.
## Testing
Add coverage for resolved spawn settings matching the child's request across legacy and paginated history, preserving configured effort, forwarding metadata through events and history, and reading and migrating older records without the new fields.
GitOrigin-RevId: a9e4241ae21bb8db1ead293f78ffba8257cca0ae
## Why
Clients starting delegated work need to attribute descendant turns to the original turn and retain that attribution through completion and history reads.
## What changed
- Accept optional `parentTurnId` and `rootTurnId` in `turn/start`, and expose `rootTurnId` on returned turns and lifecycle notifications.
- Default new turns to their own root when none is supplied. Preserve the active turn's root when steering, ignoring incoming lineage fields.
- Carry root IDs through completion, interruption, recovery, and fork boundaries, and persist them for paginated history reads. Leave unknown roots null in older history.
- Update protocol schemas and generated TypeScript and Python bindings.
## Testing
Extend coverage for default and explicit roots, steering without changing lineage, interrupted and recovered turns, history reads after restart in both history modes, nested fork pagination, and compatibility with older database writers.
GitOrigin-RevId: f1a570a12bd11742929fd2e8b017e5d35aa07dcb
## Why
Spawn failures can share an error kind and message despite different causes, such as execution and residency capacity limits. Telemetry needs enough detail to distinguish these failures without using error messages or correlation IDs as metric labels.
## What changed
- Add `AgentErrorContext` annotations for capacity limits, registry rejections, runtime availability, and spawn stages. Preserve the first annotation so outer stages retain the more precise failure origin.
- Add bounded `detail` and `error_kind` labels to spawn failure metrics, using `unknown` when no context is available.
- Emit spawn failure trace events with these classifications and the call and turn IDs for both multi-agent versions.
## Testing
Add tests for distinct capacity and registry failure contexts, preservation of manager, fork, and shutdown errors, and metric aggregation across different error messages and correlation IDs. Verify that annotations preserve existing error kinds and user-visible messages.
GitOrigin-RevId: 5bbe3d32f6ce408622f38e559fddeab05b8ccb65
## What changed
Add `codex.shell_snapshot.command` and `codex.shell_snapshot.wait_ms` metrics for eligible command preparations in the unified exec runtime and exec server. Tag observations with snapshot version, availability state, and whether replay was selected (`used`) or normal shell startup was used (`fallback`). Exclude background prewarming from command observations; `used` measures replay selection, not successful restoration or command completion.
## Testing
Extend snapshot retry tests to verify command counts and wait observations across fallback and recovery, excluding prewarm captures. Extend credential-broker approval tests to verify one `protected` snapshot observation for login-shell commands.
GitOrigin-RevId: d3d9f370b6bbba6dfc930a44044ce09373841799
## What changed
Record elapsed time for completed `wait_agent` waits in `codex.multi_agent.wait.duration_ms`, with an `outcome` tag of `mailbox`, `steered`, or `timed_out`. Exclude dropped waits because they have no observed outcome.
GitOrigin-RevId: 6378b98bfadab69d47aa2e9c93fa9d720f9cd0ef
## What changed
- Limit multi-agent V2 `fork_turns` guidance to `all` and `none`. Accept legacy positive integer strings as full-history forks instead of truncating parent history.
- Remove partial-history fork handling and telemetry, and direct model override usage to `fork_turns: "none"`.
- Strip inherited `multi_agent.role_instructions` and `multi_agent.usage_hint` content by kind, including persisted hints whose wording predates the current bundled instructions.
## Testing
Update regression coverage for legacy `"1"` and `"3"` values inheriting full history, invalid and zero values being rejected, and stale parent hints being removed from compacted history with both marked and unmarked instructions.
GitOrigin-RevId: 8f6017dc66ad8deefd7745399ef76e1bb1435bb2
## What changed
- Add the default-disabled `code_mode_tool_search` feature to expose `await tools.tool_search({query: "...", limit: 8})` in code mode when the model supports tool search.
- Return BM25-ranked deferred tools as `{tools: [{name, description}]}`, including callable names and TypeScript declarations for use in later code cells.
- Filter results through the current step's nested-tool policy before applying the limit, preserving namespace restrictions, normalized identities, description prefixes, and schema budgets.
- Add ranked-search guidance while retaining `ALL_TOOLS` catalog discovery and description overrides.
## Testing
Add coverage for feature and model-capability gating, namespace restrictions, argument validation, schema budgets, and discovery followed by deferred MCP and dynamic tool calls. Extend the scenario snapshot to cover search, invocation, yielding, and completion through `wait`.
GitOrigin-RevId: 092a29dd5f0773c518f53a001b9cafb917422f13
## Why
Updating a CRLF file with `apply_patch` previously normalized its line endings to LF unless preservation was explicitly enabled. Preserve the file's existing line endings without requiring an opt-in.
## What changed
- Use line-ending-preserving updates for both tool calls and standalone `apply_patch` invocations, removing the legacy normalization mode.
- Mark `apply_patch_preserve_line_endings` as removed.
- Always set `CODEX_APPLY_PATCH_PRESERVE_LINE_ENDINGS=1` in child environments for compatibility with older patch executables, overriding stale values.
## Testing
Update CLI, tool-call, shell-heredoc, and app-server tests to check CRLF preservation by default. Keep coverage for overriding stale compatibility environment values.
GitOrigin-RevId: 96d0b0e5350faa3fc7a45d63627a132657b44523
## What changed
- Accept per-environment `skills.required` lists through `environment/add` and `environments.toml`.
- Before inference, require each named skill to be enabled and supplied by the selected environment. Missing skills fail the turn before a model request, including when environment setup fails.
- Stop applying an environment's requirements after it is deselected. Exempt isolated Guardian reviewers, which have no skill catalog.
## Testing
Add tests for available, missing, disabled, and wrong-environment skills, failed environment setup, recovery after deselection, and propagation of TOML requirements to the correct environment.
GitOrigin-RevId: 302ced4774697d2f414f745fe0535e71f747eda2
## Why
The warning assertions need tracing callsite interest to remain independent of untraced parallel tests, even when the test runner already owns the global subscriber.
## What changed
Run the test on a current-thread Tokio runtime and capture warnings with a thread-local subscriber and an explicit buffer. Keep a `NoSubscriber` dispatch alive to stabilize callsite interest, and assert the deferral warning and `client_echo` directly against the captured logs.
GitOrigin-RevId: 5bf22b2cbfefcf8f65016d2cc1444112d9f6a6c7
## What changed
Add the default-off `stable_environment_tools` feature flag. When enabled, advertise environment-backed tools before an executor is ready, keep environment selectors stable as readiness changes, and include the `shell` and `login` parameters. Execution still requires a usable environment and its policy.
When disabled, expose environment-backed tools only when a usable environment exists, derive selectors from usable environments, and condition shell parameters on the execution configuration. Restore tool-specific unavailable-environment errors and skip the environment readiness check for `write_stdin`.
## Testing
Parameterize the empty-environment tool availability test for both flag states, check that commands require a ready transport by default, and explicitly opt tests that rely on stable tool exposure into the feature.
GitOrigin-RevId: 68c6240fb3adf85d7f9b407804d4823c515abfdc
## Why
Environment readiness previously changed which tools and command parameters were advertised to the model, even when the selected environments stayed the same.
## What changed
- Keep enabled command, patch, image, and permission tools exposed when environments are absent, starting, or failed.
- Return a consistent message asking the model to wait when no usable execution environment is available, while preserving distinct errors for unknown environment IDs.
- Derive environment selectors from all selected environments rather than only ready ones.
- Always advertise `exec_command`'s `shell` and `login` parameters while continuing to enforce login policy at execution time.
## Testing
Expand integration coverage for empty, pending, failed, ready, and recovered environments, including stable command parameters and login-policy rejection. Update subagent and skill-catalog snapshots, with separate Windows expectations.
GitOrigin-RevId: bb08084066896a9f14b3b568c081c3eaac981db7
## Why
Third-party exposure settings can eagerly expose tool schemas or exclude tools from `exec`. Keeping eligible tools deferred lets MCP catalogs change between turns without changing the model's eager tool prefix.
## What changed
Add the disabled-by-default `code_mode_only_strict_3p_tools` feature, applied only when the effective model tool mode is Code Mode Only.
- Defer eligible MCP, app, and client-supplied dynamic tools while keeping them discoverable and callable through `exec`.
- Override `deferLoading`, MCP/app `omit_tools_from`, and direct-only or excluded namespace settings. Log conflicts without adding prompt warnings.
- Preserve disabled, app-only, policy-denied, and over-budget tool restrictions. Keep built-in tool exposure unchanged, including when a dynamic tool has the same name.
## Testing
Add unit and integration coverage for exposure overrides, effective model modes, tool eligibility, and app discovery and dispatch. Add an MCP refresh scenario that verifies the eager tool prefix stays unchanged as tools are added, replaced, and removed while `exec` tracks the current catalog.
GitOrigin-RevId: a6a8e401214119bb02ea4711473c8fa3ec85c81a
## Why
Tool availability can change between calls. Conditioning discovery guidance on whether deferred tools are currently present changes the `exec` description when the catalog changes.
## What changed
Always include the configured discovery guidance in the Code Mode `exec` description, even when no deferred tools are present. The default guidance explains how to find tools in `ALL_TOOLS` and notes that availability can change between calls. Custom guidance and explicit empty overrides remain supported.
## Testing
Add regression coverage for stable guidance with empty and populated deferred tool catalogs in both Code Mode configurations, including custom and empty overrides. Update tool-description assertions and request snapshots.
GitOrigin-RevId: 086ea19a48e3c51ec8c429a619676a936d658721
## Why
In `CodeModeOnly`, MCP resource helper definitions changed when the first server was added or the last server was removed.
## What changed
Always register `list_mcp_resources`, `list_mcp_resource_templates`, and `read_mcp_resource` in `CodeModeOnly`, even without configured MCP servers. This keeps their definitions stable across server configuration changes.
## Testing
Add a regression scenario that calls all three helpers before adding a server, with a server registered, and after removing it. Assert identical tool definitions across requests, empty resource and template lists, and the expected error when reading from an unknown server.
GitOrigin-RevId: c5777efac250b83dd4bb1c9100a6b6169470556f
## What changed
- Remove `namespace_tools` from `ProviderCapabilities` and `namespaceTools` from `ModelProviderCapabilitiesReadResponse`, updating generated schemas and SDK types.
- Preserve tool namespaces and configured collaboration tool namespaces without a provider capability check, and always use Responses Lite tool serialization for Responses Lite requests.
- Gate tool search on `supports_search_tool` and retain the existing image generation and web search checks without requiring a namespace capability.
GitOrigin-RevId: ae1843563736765a40e03a02c41ff5e470018a93