mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
dev
7919 Commits
-
core: surface terminal subagent errors to parent agents (#28375)
## Why When a subagent exhausts its retries, it emits an `Error`, but the generic task lifecycle then emits `TurnComplete(None)`. That completion used to overwrite the subagent's `Errored` status with `Completed(None)`, so the parent received an empty completion notification. This made a failed child look indistinguishable from a child that completed without an answer. In unattended or long-running multi-agent work, the root could silently continue without knowing that delegated work failed or how to restart it. ## Behavior Before, a terminal stream failure was reduced to an empty completion: ```text <subagent_notification> {"agent_path":"/root/worker","status":{"completed":null}} </subagent_notification> ``` Now the parent receives the actual terminal error, bounded to 1,000 tokens, together with an actionable recovery hint: ```text <subagent_notification> { "agent_path": "/root/worker", "status": { "errored": "stream disconnected before completion: stream closed before response.completed" }, "next_action": "This agent's turn failed. If you still need this agent, use `followup_task` to give it another task." } </subagent_notification> ``` The notification remains queue-only: it does not wake the root or replay the failed request. The root sees it at the next sampling boundary and can use `followup_task` to start a new turn for that agent. ## What changed - Added terminal-error precedence to the [agent status reducer](https://github.com/openai/codex/blob/e95fcfe2bb6a02f1a75650afa20048859f556511/codex-rs/core/src/agent/status.rs#L23-L34), so a closing `TurnComplete` cannot erase an immediately preceding `Errored` status. - Made MultiAgentV2 completion forwarding use the retained session status instead of re-deriving `Completed(None)` from the final event. - Extended the [subagent notification fragment](https://github.com/openai/codex/blob/e95fcfe2bb6a02f1a75650afa20048859f556511/codex-rs/core/src/context/subagent_notification.rs#L6-L60) with a `next_action` for terminal errors and a hard cap on model-visible error text. - Kept successful completions and interrupted turns unchanged. ## Verification - Added a status-reducer test proving that `Errored` survives the trailing `TurnComplete`. - Added an integration test that exhausts a subagent's stream retries and verifies the exact `agent_message` delivered to the parent, including the error and `followup_task` guidance. - Re-ran the existing successful-completion and interrupted-turn notification tests.jif ·
2026-06-16 14:34:54 +02:00 -
[codex] Clarify plugin load and runtime capability stages (#28472)
## Summary Plugin loading and auth projection both previously produced `PluginLoadOutcome`. That made an unfiltered load result look like runtime-ready capabilities and generated capability summaries before auth routing had run. This change keeps loaded plugin records in the cache, applies the current auth policy in `PluginsManager`, and only then builds `PluginLoadOutcome` and its summaries. Auth changes still reuse the cached disk load and re-resolve apps and MCP servers without reloading plugins. The updated tests cover cached auth changes and verify that capability summaries match the effective app/MCP surface. ## Testing - `just test -p codex-core-plugins` - `just test -p codex-plugin` - `just fix -p codex-core-plugins`
xl-openai ·
2026-06-16 12:57:21 +01:00 -
[tests] Keep Apps out of generic core test harness (#28508)
## Summary - disable the stable Apps feature in the generic `test_codex()` integration-test harness - keep Apps-specific tests explicit: their builders re-enable Apps and point it at a local mock server ## Why Generic tests that use dummy ChatGPT auth were also enabling the host-owned `codex_apps` MCP server. That made unrelated tests contact `chatgpt.com` and wait for MCP startup, causing the Bazel timeouts observed on #28368. The generic harness should be hermetic and should not start an external service that the test did not request. This is test-only; production Apps behavior is unchanged. The broader optional-MCP startup behavior is being handled separately in #28407. ## Testing - `just test -p codex-core -E 'test(pre_sampling_compact_runs_when_comp_hash_changes) | test(model_switch_to_smaller_model_updates_token_context_window) | test(codex_apps_file_params_upload_local_paths_before_mcp_tool_call)'` - `just fix -p codex-core` - `just fmt`
jif ·
2026-06-16 13:07:43 +02:00 -
feat: render typed envelopes for multi-agent v2 messages (#28368)
## Why Multi-agent v2 messages need a consistent, model-visible envelope that identifies what kind of interaction occurred, who sent it, and which agent it targets. Previously, encrypted deliveries exposed only `encrypted_content`, while child completion used the legacy `<subagent_notification>` shape. That meant the client could not consistently present `NEW_TASK`, `MESSAGE`, and `FINAL_ANSWER` using the same format. This change adds the routing envelope as plaintext while keeping task and message payloads encrypted. No new Responses API field is required: an encrypted delivery is represented as an `input_text` header immediately followed by its existing `encrypted_content` item. Every envelope now follows this shape: ```text Message Type: <NEW_TASK | MESSAGE | FINAL_ANSWER> Task name: <recipient agent path> Sender: <author agent path> Payload: <message payload> ``` ## Message types ### `NEW_TASK` `NEW_TASK` is used when the recipient should begin a new turn, including an initial `spawn_agent` task and a later `followup_task`. For a root agent spawning `/root/worker`, the request contains a plaintext envelope followed by the encrypted task: ```json { "type": "agent_message", "author": "/root", "recipient": "/root/worker", "content": [ { "type": "input_text", "text": "Message Type: NEW_TASK\nTask name: /root/worker\nSender: /root\nPayload:\n" }, { "type": "encrypted_content", "encrypted_content": "<encrypted task payload>" } ] } ``` Conceptually, the model receives: ```text Message Type: NEW_TASK Task name: /root/worker Sender: /root Payload: Review the authentication changes and report any regressions. ``` ### `MESSAGE` `MESSAGE` is used for a queued `send_message` delivery. It communicates with an existing agent without starting a new turn. For `/root/worker` reporting progress to the root agent, the request contains: ```json { "type": "agent_message", "author": "/root/worker", "recipient": "/root", "content": [ { "type": "input_text", "text": "Message Type: MESSAGE\nTask name: /root\nSender: /root/worker\nPayload:\n" }, { "type": "encrypted_content", "encrypted_content": "<encrypted message payload>" } ] } ``` Conceptually, the model receives: ```text Message Type: MESSAGE Task name: /root Sender: /root/worker Payload: The protocol tests pass; I am checking the resume path now. ``` ### `FINAL_ANSWER` `FINAL_ANSWER` is emitted when a child agent reaches a terminal state and reports its result to its parent. Completion payloads are already available locally, so the complete envelope is represented as plaintext rather than as a plaintext header plus encrypted content. For `/root/worker` completing work for the root agent, the request contains: ```json { "type": "agent_message", "author": "/root/worker", "recipient": "/root", "content": [ { "type": "input_text", "text": "Message Type: FINAL_ANSWER\nTask name: /root\nSender: /root/worker\nPayload:\nNo regressions found." } ] } ``` The model-visible form is: ```text Message Type: FINAL_ANSWER Task name: /root Sender: /root/worker Payload: No regressions found. ``` Errored, shut down, and missing agents also use `FINAL_ANSWER`, with a terminal-status description in the payload. ## What changed - Render `NEW_TASK` or `MESSAGE` in `InterAgentCommunication::to_model_input_item`, based on whether the encrypted delivery starts a turn. - Replace the multi-agent v2 `<subagent_notification>` completion payload with a model-visible `FINAL_ANSWER` envelope. - Document `Task name`, `Sender`, and `Payload` consistently in the multi-agent developer instructions. - Prevent local-only history projections from treating an encrypted message's plaintext header as the complete assistant message. - Preserve rollout-trace interaction edges when an agent message contains both plaintext and encrypted content. Legacy multi-agent behavior remains unchanged. ## Verification - `just test -p codex-protocol` - `just test -p codex-rollout-trace` - `just test -p codex-web-search-extension` - `just test -p codex-core encrypted_multi_agent_v2_spawn_sends_agent_message_to_child` - `just test -p codex-core plaintext_multi_agent_v2_completion_sends_agent_message` - `just test -p codex-core multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn` - `just test -p codex-core multi_agent_v2_completion_queues_message_for_direct_parent`jif ·
2026-06-16 11:46:59 +02:00 -
[codex] Compress cold active rollouts (#28338)
## Why The local rollout compression worker currently scans only `archived_sessions`, so cold unarchived thread history remains expanded indefinitely. ## What changed - Scan `sessions` after `archived_sessions` within the existing worker runtime budget. - Update rollout compression coverage to require both cold active and archived rollouts to be compressed while fresh active rollouts remain plain. The worker remains behind the disabled-by-default `local_thread_store_compression` feature, and the existing seven-day cold-file threshold is unchanged. ## Validation - `just test -p codex-rollout` (69 passed) - `just fmt` - `git diff --check`
jif ·
2026-06-16 10:52:21 +02:00 -
[codex] expose Bedrock credential source in account/read (#27751)
## Why `account/read` currently reports only `type: "amazonBedrock"`, so clients cannot distinguish a Codex-managed Bedrock API key from credentials supplied by AWS. The app UI needs that distinction to render the appropriate account state without duplicating provider-auth logic. Credential-source selection belongs to the Bedrock model provider because it already owns the precedence between managed Bedrock auth and the external AWS credential path. This builds on #27443 and #27689. ## What changed - Added `AmazonBedrockCredentialSource` with `codexManaged` and `awsManaged` values. - Included the selected credential source in `ProviderAccount::AmazonBedrock` and the app-server `Account` response. - Made `AmazonBedrockModelProvider::account_state()` classify the source from its managed-auth state. - Regenerated the app-server JSON and TypeScript schemas. - Updated app-server account documentation and downstream TUI matches. `codexManaged` means the provider found a managed Bedrock API key. `awsManaged` identifies the provider's external AWS credential path; it does not assert that the AWS credential chain has been validated. ## Testing - Added model-provider coverage for Codex-managed precedence and AWS-managed fallback. - Added app-server protocol serialization coverage for both wire values. - Added app-server integration coverage for both `account/read` responses. - `just test -p codex-protocol -p codex-model-provider -p codex-app-server-protocol` (497 tests passed). After rebasing onto #27711, the `codex-app-server` test target compiled past the image-generation `PathUri` migration. Local linking was then interrupted by disk exhaustion (`No space left on device`).
Celia Chen ·
2026-06-16 07:14:53 +00:00 -
[codex] Record external agent import results (#28396)
## Summary - restore `externalAgentConfig/import/progress` notifications while keeping `externalAgentConfig/import/completed` as the must-deliver event - persist completed external-agent config imports in state DB by `importId`, including concrete success/failure details for config, AGENTS.md, skills, plugins, MCP servers, subagents, hooks, commands, and sessions - add `externalAgentConfig/import/readHistories` so clients can recover persisted import results after missing the live completion notification - include `errorType` on import failures in protocol responses/notifications and persisted DB JSON so future code can classify failures without another wire/storage shape change ## Validation - `git diff --check` - `just test -p codex-state external_agent_config_imports` - `just test -p codex-app-server-protocol` - `CODEX_SQLITE_HOME=/private/tmp/codex-app-server-sqlite-read-details just test -p codex-app-server external_agent_config_import_sends_completion_notification_for_sync_only_import` Also ran earlier broader checks before publishing: - `just test -p codex-state` - `CODEX_SQLITE_HOME=/private/tmp/codex-app-server-external-agent-test-sqlite just test -p codex-app-server external_agent_config` - `just test -p codex-external-agent-migration`
charlesgong-openai ·
2026-06-15 23:17:24 -07:00 -
[codex] Use local environment for user shell commands (#28163)
## Why User shell commands still read the legacy turn cwd and session shell even though execution context is now owned by selected turn environments. App-server also defines `thread/shellCommand` as a local-host escape hatch, so it must use an available local environment even when a remote environment is primary. ## What changed - Add `ResolvedTurnEnvironments::local()` to find the selected local environment. - Resolve the user shell command cwd and shell from that local `TurnEnvironment`. - Emit the standard `shell is unavailable in this session` error when no selected local environment or resolved local shell is available. - Add an integration test covering `/shell` without a local environment. ## Test plan - `just test -p codex-core user_shell_command_without_local_environment_emits_error`
pakrym-oai ·
2026-06-16 04:55:20 +00:00 -
[codex] Use expect in integration tests (#28441)
The workspace denies `clippy::expect_used` in production. Although `clippy.toml` allows `expect` in tests, Bazel Clippy compiles integration-test helper code in a way that does not receive that exemption, which encouraged verbose `unwrap_or_else(... panic!(...))` and equivalent `match`/`let else` forms. This allows `clippy::expect_used` once at each integration-test crate root (including aggregated suites and test-support libraries), then replaces manual panic-based Result and Option unwraps with `expect`/`expect_err`. Standalone `tests/*.rs` files remain their own crate roots. Intentional assertion and unexpected-variant panics remain unchanged, and the production `expect_used = "deny"` lint remains in place. The cleanup is mechanical and net-negative in line count.
pakrym-oai ·
2026-06-15 21:53:47 -07:00 -
[codex] Add interruptible sleep tool (#28429)
## Why Models sometimes need to pause briefly while waiting for external work, but using a shell command for that delay ties the wait to a process and does not naturally resume when new turn input arrives. ## What changed - add a built-in `sleep` tool behind the under-development `sleep_tool` feature - accept a bounded `duration_ms` argument, matching the millisecond convention used by unified exec - end the sleep early when either steered user input or mailbox input arrives - include elapsed wall-clock time in completed and interrupted outputs - emit a dedicated core `SleepItem` through `item/started` and `item/completed` - expose the sleep item as app-server v2 `ThreadItem::Sleep` and retain it in reconstructed thread history - regenerate the configuration schema for the new feature flag - regenerate app-server JSON and TypeScript schema fixtures ## Test plan - `just test -p codex-core sleep_tool_follows_feature_gate` - `just test -p codex-core any_new_input_interrupts_sleep` - `just test -p codex-app-server-protocol` - `just test -p codex-app-server sleep_emits_started_and_completed_items`
pakrym-oai ·
2026-06-15 21:39:21 -07:00 -
[codex] Bind shell snapshots to retained thread environments (#28421)
## Why Shell snapshots are currently session-scoped even though shell and cwd are properties of a selected turn environment. That makes snapshot refresh depend on separate session-cwd plumbing, prevents retained environments from retaining their snapshot work, and can make snapshot construction use a different shell than command execution. This follows #27955 by making the retained thread-environment service own environment snapshot lifecycles. Session configuration remains the requested selection state, while `ThreadEnvironments` remains the source of successfully resolved environments. ## What changed - Configure the shell-snapshot builder before initial environment resolution. - Start each local environment snapshot task when its `TurnEnvironment` is built and retain that shared task while environment ID and cwd still match. - Inherit retained environment snapshots into spawned child threads. - Carry the selected `TurnEnvironment` through shell runtimes so snapshot construction and command execution use the same environment-specific shell and cwd. - Load project instructions and warm plugins/skills after initial environment resolution. - Continue decoding invalid UTF-8 instruction files lossily without emitting a startup warning. - Keep requested selections in `SessionConfiguration`; failed or duplicate resolutions only affect the resolved environment snapshot. ## Validation - `cargo check -p codex-core --tests` - `just test -p codex-home instructions` (6 passed) - Focused environment, instruction, shell-snapshot, and user-shell tests (84 passed) - Focused shell-snapshot, user-shell, and unified-exec tests (126 passed; two event-timing tests passed on retry)
pakrym-oai ·
2026-06-15 20:10:53 -07:00 -
Use ApiPathString in app-server filesystem permission paths (#28367)
## Why Clients running an app-server on one OS and an exec-server on another OS need to be able to pass sandbox config to app-server that refers to resources on the executor's foreign OS. ## What `AbsolutePathBuf` can't represent these paths and we don't want users to be exposed to `PathUri` yet, so this moves the public app-server API to be expressed in terms of `ApiPathString`. Stacked on #28165. - change app-server v2 filesystem permission paths, including legacy read/write roots, to `ApiPathString` - localize API paths through `PathUri` when converting into the current native core permission types - make path-bearing permission conversions fallible and surface localization failures instead of silently treating malformed grants as ordinary denials - propagate conversion failures through app-server and TUI approval handling - regenerate the app-server JSON and TypeScript schemas - leave migration TODOs on native-path conversions so they can be removed once core permission paths use `PathUri`
Adam Perry @ OpenAI ·
2026-06-15 19:25:54 -07:00 -
[codex] Make plugin details capability aware (#27958)
## Summary Makes plugin details/read flows capability-aware so auth-filtered plugin surfaces report the same usable app/MCP/skill shape as the marketplace and install flows. ## Validation Not run; this change was rebased onto the current plugin auth stack and pushed as a draft PR. **Manual test** 1. set up a local marketplace with a plugin that has both app and mcp declarations ``` // .app.json { "apps": { "linear": { "id": "some_id" } } } ``` ``` // .mcp.json { "mcpServers": { "linear": { "type": "http", "url": "https://mcp.linear.app/mcp", "oauth_resource": "https://mcp.linear.app/mcp" }, "linear2": { "type": "http", "url": "https://mcp.linear2.app/mcp", "oauth_resource": "https://mcp.linear2.app/mcp" } } } ``` 2a. **login in with api key** and observe plugin details page which shows no apps (note we don't show "app not available due to api key log in as there's no way to differentiate between no apps and app without substitute mcp exists" without significantly more code changes, i've separated this to a follow up if we want that behaviour. <img width="1170" height="279" alt="Screenshot 2026-06-15 at 23 45 40" src="https://github.com/user-attachments/assets/d36cb160-fbec-461e-9643-9c761dbae7bb" /> <img width="975" height="640" alt="Screenshot 2026-06-15 at 18 40 30" src="https://github.com/user-attachments/assets/90ec0bc8-7506-4b90-bbd3-070720de799e" /> 2b. **log in with chat** and observe intended conflict resolution logic <img width="1165" height="224" alt="Screenshot 2026-06-15 at 17 17 30" src="https://github.com/user-attachments/assets/80adfbf2-7dac-4f08-8b76-8eeeab6c95e7" /> <img width="968" height="567" alt="Screenshot 2026-06-15 at 18 38 59" src="https://github.com/user-attachments/assets/9ea92c5e-535b-4aa4-8ad0-ee513b57bc3c" />felixxia-oai ·
2026-06-16 01:25:22 +00:00 -
[codex] Load API curated marketplace by auth (#28383)
## Summary - choose the local OpenAI curated marketplace manifest based on auth: Codex backend auth gets the existing marketplace, direct provider auth gets `api_marketplace.json` - include Bedrock API key auth in the direct-provider API marketplace path - safely skip the API marketplace when `api_marketplace.json` is absent ## Validation - `just fmt` - `git diff --check origin/main...HEAD` - CI should run the full validation ## Manual Testing ### - New api marketplace not available for API key sign 1. Safely not display anything from api marketplace <img width="1161" height="289" alt="Screenshot 2026-06-15 at 21 37 43" src="https://github.com/user-attachments/assets/a5f16642-8a20-4ac1-a0de-1274a4c7b5b2" /> ### - New api marketplace for API key sign in 1. Setup api_marketplace.json ``` { "name": "openai-curated", "interface": { "displayName": "Codex official" }, "plugins": [ { "name": "linear", "source": { "source": "local", "path": "./plugins/linear" }, "policy": { "installation": "AVAILABLE", "authentication": "ON_INSTALL" }, "category": "Productivity" } ] } ``` 2. Log in with API key, observe that only the defined plugin from api_marketplace.json is available from "Codex Official" (outside of local testing marketplaces) <img width="1167" height="446" alt="Screenshot 2026-06-15 at 21 16 53" src="https://github.com/user-attachments/assets/7cf61477-d826-4ef6-bc05-0a23ac1c0259" /> also checked functionality on codex app ### - SiWC users Still uses 'default' marketplace.json and renders all plugins <img width="1171" height="502" alt="Screenshot 2026-06-15 at 21 40 25" src="https://github.com/user-attachments/assets/d212ea9b-0aa5-470b-8ea4-450efe65bb2b" /> also checked functionality on codex app ## Notes - `just test -p codex-core-plugins` was started locally before splitting branches, but I stopped relying on local tests per follow-up and left final validation to PR CI.
felixxia-oai ·
2026-06-16 01:16:11 +00:00 -
exec-server: default remote transport to Noise (#26245)
## Why The transport in [openai/codex#26242](https://github.com/openai/codex/pull/26242) needs to be used by every remote orchestrator-to-executor connection before JSON-RPC traffic starts. ## Changes - Generates one executor Noise identity when remote exec-server starts and registers its public key. - Creates a harness identity for each physical remote environment connection. - Fetches a fresh registry bundle before connecting and validates the authenticated harness key before completing the executor handshake. - Multiplexes encrypted logical streams over the existing executor WebSocket. - Adds bounded stream, handshake-failure, and reassembly state. - Adds safe lifecycle diagnostics without logging keys, authorizations, plaintext, or ciphertext. - Covers reconnects, replay rejection, validation failure, framing limits, and encrypted JSON-RPC tool traffic. ## Stack 1. [openai/codex#26242](https://github.com/openai/codex/pull/26242): Noise channel and relay transport 2. **[openai/codex#26245](https://github.com/openai/codex/pull/26245)**: remote registration and runtime activation ## Verification - `just test -p codex-exec-server` - `just fix -p codex-exec-server` - `just bazel-lock-check` - `cargo shear` --------- Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-06-15 17:39:00 -07:00 -
Run core integration tests against a Wine-backed Windows executor (#28401)
## Why We want to exercise a linux app-server against a windows exec-server without having to repeat every test case. This approach has slight precedent in the remote docker test setup. ## What Run the shared `codex-core` integration suite against Windows exec-server behavior from Linux. This makes cross-OS path and shell regressions visible while keeping unsupported cases owned by individual tests. - Add `local`, `docker`, and `wine-exec` test environment selection with legacy Docker compatibility. - Extend `codex_rust_crate` to generate a sharded Wine-exec variant using a cross-built Windows server and pinned Bazel Wine/PowerShell runtimes. - Teach remote-aware helpers about Windows paths and track temporary incompatibilities with source-local `skip_if_wine_exec!` calls and follow-up reasons.
Adam Perry @ OpenAI ·
2026-06-16 00:38:41 +00:00 -
Preserve hook trust bypass in codex exec threads (#26434)
Addresses #26383 and #26452 ## Summary `codex exec --dangerously-bypass-hook-trust` printed the bypass warning, but valid untrusted hooks still did not run. Exec applied the flag to its initial config, then lost it when app-server reloaded config for the new or resumed thread. ## Fix Forward `bypass_hook_trust: true` through the existing thread request config override for both start and resume. The override is omitted when the flag is not enabled, preserving normal trust behavior. ## Testing Added: - A test confirming start and resume preserve the override. - An end-to-end exec test confirming a `SessionStart` hook runs and creates a marker file.
Abhinav ·
2026-06-15 17:36:21 -07:00 -
Add a toggle for realtime startup context (#28405)
## Summary - Add `includeStartupContext` to realtime start requests so callers can explicitly skip Codex startup context while keeping the backend prompt - Thread the new flag through protocol types, request processing, and realtime session config - Update app-server docs and coverage for the new default and opt-out behavior ## Testing - Added protocol serialization coverage for `includeStartupContext` - Added realtime integration coverage for starting a session with startup context disabled
guinness-oai ·
2026-06-15 17:14:22 -07:00 -
[codex] Centralize plugin auth capability filtering (#27902)
## Summary This is the first step in making plugin auth routing consistent. The rule should not live as one-off checks in every place that loads or displays plugin capabilities. This PR introduces a small resolver for the auth-level policy: given a plugin's declared apps, MCP servers, current auth mode, and active state, return the capabilities that are actually usable in that context. ## Why Product rule: - SiWC auth can use app connectors, so app declarations stay available. - API-key/direct auth cannot use app connectors, so app declarations are removed. - When an active plugin has both an app and an MCP server with the same name, the app route wins for Codex-backed auth and the conflicting MCP server is hidden. Putting that rule in `capabilities.rs` gives the rest of the stack one place to ask instead of duplicating auth checks in loader, manager, marketplace, and details code. ## Validation - `cargo fmt` - `cargo test -p codex-core-plugins`
felixxia-oai ·
2026-06-16 00:13:27 +00:00 -
[codex] Add second-based OTEL duration histograms (#27058)
## Why Exec-server request and connection latencies need fractional-second histograms. The existing duration API records integer milliseconds and uses millisecond-scale buckets. ## What changed - Adds a described duration API that records `Duration` values as fractional seconds. - Uses second-scale explicit histogram boundaries. - Caches duration histograms by name, unit, and description, matching the existing instrument caching model. - Covers exact boundaries, representative bucket placement, fractional sums, and exported metadata. This PR only adds the duration primitive. It does not add exec-server adoption. ## Stack 1. #26091: counter descriptions 2. #27057: gauge instruments 3. **#27058: second-based duration histograms** 4. #25019: initialize exec-server OpenTelemetry at startup Related independent coverage: #27059 tests OTLP HTTP log and trace event export. ## Validation - `just test -p codex-otel`
richardopenai ·
2026-06-15 17:10:52 -07:00 -
[codex] Fix missing response item metadata in tests (#28415)
Summary - Add the two missing `metadata: None` initializers after #28355 made response-item metadata required. - Restore test compilation for `codex-core` and `codex-api` on main. Validation - `git diff --check` - `just fmt` (Rust formatting passed; unrelated Python formatter steps could not use the sandboxed shared `uv` cache) - Focused crate tests are running after PR creation.
Alex Daley ·
2026-06-16 00:08:39 +00:00 -
Use PathUri in filesystem permission paths for exec-server (#28165)
## Why Progress towards letting app-server and exec-server run on different platforms, specifically for sandbox configuration. ## What - Make the filesystem path containment hierarchy generic, defaulting to `AbsolutePathBuf` for now. - Have clients specify `AbsolutePathBuf` or `PathUri` directly where needed. - Use `PathUri` throughout exec-server filesystem protocol and trait boundaries. - Implement `From` for conversion to path URIs and `TryFrom` for fallible conversion to absolute paths through the generic type hierarchy.
Adam Perry @ OpenAI ·
2026-06-15 23:55:23 +00:00 -
exec-server: add Noise relay transport (#26242)
## Why Rendezvous forwards traffic between the orchestrator and exec-server. The endpoints need to authenticate each other and encrypt that traffic without trusting Rendezvous with plaintext or endpoint keys. ## Changes - Adds a hybrid Noise IK channel through Clatter using X25519, ML-KEM-768, AES-256-GCM, and SHA-256. - Binds each handshake to `environment_id`, `executor_registration_id`, and `stream_id`. - Pins the registry-provided executor key and carries the harness authorization inside the encrypted handshake. - Orders relay frames before consuming Noise nonces and fragments large JSON-RPC messages into bounded records. - Bounds handshake payloads, frames, streams, and message reassembly. Runtime activation is in [openai/codex#26245](https://github.com/openai/codex/pull/26245). ## Stack 1. **[openai/codex#26242](https://github.com/openai/codex/pull/26242)**: Noise channel and relay transport 2. [openai/codex#26245](https://github.com/openai/codex/pull/26245): remote registration and runtime activation ## Verification - `just test -p codex-exec-server` - Oversized initiator payload regression coverage - `just fix -p codex-exec-server` - `just bazel-lock-check` - `cargo shear` --------- Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-06-15 16:39:41 -07:00 -
[codex-analytics] Analytics Capture to File in Debug Builds (#27093)
## This PR The original [combined remote plugin analytics PR #26281](https://github.com/openai/codex/pull/26281) mixed reusable analytics test infrastructure, two manual smoke workflows, a metadata refactor, and the final identity behavior. This PR isolates the generic capture mechanism so it can be reviewed and landed before any plugin-specific behavior. - Add a debug-only analytics destination that writes final request payloads as JSONL. - Suppress HTTP delivery whenever capture mode is selected, including after capture write failures. - Keep release behavior unchanged even when the capture environment variable is present. - Keep the mechanism generic; this PR contains no plugin-specific behavior. Set `CODEX_ANALYTICS_EVENTS_CAPTURE_FILE=/path/events.jsonl` when running a debug Codex binary to inspect the exact batched payload that would otherwise be sent to the analytics endpoint. ## Testing - `just test -p codex-analytics` (76 passed) - `just test --release -p codex-analytics` (73 passed) - CI is green across the required platform matrix. ## Split Overview ```text main ├── #27093 Debug analytics capture ← you are here │ └── #27099 Non-mutating plugin smoke │ └── #27100 Remote install/uninstall smoke └── #27102 Plugin telemetry metadata refactor After #27093, #27099, #27100, and #27102 merge: └── Final PR: add remote_plugin_id to plugin analytics ``` Review order and dependencies: 1. [#27093 Add debug-only analytics event capture](https://github.com/openai/codex/pull/27093) **(this PR, based on `main`)** 2. [#27099 Add a plugin analytics smoke workflow](https://github.com/openai/codex/pull/27099) (stacked on #27093) 3. [#27100 Add a remote plugin analytics mutation smoke workflow](https://github.com/openai/codex/pull/27100) (stacked on #27099) 4. [#27102 Centralize plugin telemetry metadata construction](https://github.com/openai/codex/pull/27102) (independent, based on `main`) 5. Final remote-ID behavior PR (created after PRs 1-4 merge) The original [#26281](https://github.com/openai/codex/pull/26281) remains open as the green aggregate reference until the final PR is published.
jameswt-oai ·
2026-06-15 16:32:38 -07:00 -
Add realtime speech append control (#27917)
## Why Realtime voice harness tuning needs app-side control over what backend Codex text is spoken. Backend orchestrator text is written for a reading UI, so automatically speaking every preamble, progress update, or final assistant message can make the realtime voice model too chatty. For experimentation, clients need two simple controls: keep app/client text-item injection on the existing item-create path, and add an explicit speakable path that app code can call only when it wants realtime to speak. Automatic Codex output also needs an opt-in way to switch from the protocol's default speakable path to regular realtime items, with a caller-provided prefix so prompt wording can be tuned outside core. The default remains unchanged: if a client omits the new start fields and never calls `appendSpeech`, automatic backend output continues down the existing speakable path for the selected realtime protocol. ## What Changed - Adds experimental `thread/realtime/appendSpeech` for app-provided speakable text. - Keeps existing `thread/realtime/appendText` as the item-create API for app-provided realtime text items. - Adds `codexResponsesAsItems` / `codex_responses_as_items` on `thread/realtime/start` to send automatic Codex responses with `conversation.item.create` instead of the protocol's default speakable output path. - Adds `codexResponseItemPrefix` / `codex_response_item_prefix` so clients can prepend experiment instructions to those automatic Codex response items. - Keeps literal `conversation.handoff.append` routing scoped to the v1 speakable path; v2 default speech uses its item/function-output plus `response.create` behavior. - Removes the earlier public silent-context API and hardcoded silent-context prefix. - Updates realtime tests to cover default automatic speakable behavior, opt-in automatic item-create behavior, and explicit `appendSpeech` behavior. ## Validation - `cargo check -p codex-core -p codex-app-server -p codex-api` - `just test -p codex-app-server realtime_conversation` - `just test -p codex-core realtime_conversation` (50/51 passed in the filtered parallel run; the lone failure passed when rerun in isolation) - `just test -p codex-core conversation_mirrors_assistant_message_text_to_realtime_handoff` - `just test -p codex-api e2e_connect_and_exchange_events_against_mock_ws_server` - `just fix -p codex-core` - `just fix -p codex-app-server` - `cargo build -p codex-cli`
guinness-oai ·
2026-06-15 16:15:58 -07:00 -
[codex] retain resolved environments across turns (#27955)
## Why Selected execution environments are thread-scoped resources, but startup and turn construction repeatedly resolved their IDs and working directories. That discarded existing environment handles and shell metadata even when a selection had not changed. Session configuration updates also need to affect future turns without changing the resolved environment set already captured by a running turn. ## What changed - Create a `ThreadEnvironments` service inside `Codex` from the spawned `EnvironmentManager` and raw environment selections, then store it on `SessionServices`. - Split service construction from `update_selections`, allowing session configuration updates to mutate the resolved set in place. - Retain an existing `TurnEnvironment` when its environment ID and working directory match; resolve only added or changed selections and remove selections that are no longer present. - Normalize duplicate IDs by keeping the first selection and skip individual selections that fail to resolve instead of rejecting the entire update. - Give each `TurnContext` a cloned `TurnEnvironmentSnapshot`, so later session configuration updates affect future turns without rewriting an active turn. - Reuse the service-owned environment manager and resolved snapshot for startup work, MCP initialization, and child-thread spawning instead of flowing resolved environments through spawn arguments. ## Test plan - `cargo check -p codex-core --tests` - `just test -p codex-core environment_selection` - `just test -p codex-core turn_environments` - `just test -p codex-core session_update_settings_does_not_rewrite_sticky_environment_cwds` - `just test -p codex-core default_turn_does_not_overlay_legacy_fallback_cwd_onto_stored_thread_environments`
pakrym-oai ·
2026-06-15 16:15:07 -07:00 -
[codex] Preserve remote plugin directory order (#28395)
## Summary - preserve the plugin directory endpoint's response order while merging installed state - append unmatched installed-only plugins afterward when requested - add focused coverage for directory order and installed-only placement ## Why The remote marketplace merge currently reconstructs plugins through ordered maps and sets, then sorts the result alphabetically by display name. That discards any ordering supplied by the plugin directory endpoint before the list reaches Desktop. ## Implementation Directory plugin IDs are unique, so the merge now iterates the directory vector directly in response order. For each directory plugin, it removes matching installed state from an ID-indexed map and builds the summary. Any entries left in the installed map are installed-only plugins and are appended when `include_installed_only` is enabled. There is no separate rank field, rank map, or final sort. Desktop therefore receives directory order—including any backend ranking—and can preserve it within its existing stable UI state tiers. ## Testing - `just test -p codex-core-plugins` (225 passed)
jameswt-oai ·
2026-06-15 16:09:43 -07:00 -
Deflake realtime handoff steering test (#28300)
## Summary - keep the realtime mock websocket open for the handoff steering test after scripted responses - avoid racing the mock server close before the standalone handoff append is observed, which was showing up as a Windows timeout in CI __Details__: Failures in samples seem to be caused by: 1. The mock websocket sends conversation.handoff.requested. 2. The mock immediately closes the websocket because start_websocket_server(...) defaults to close_after_requests: true. 3. On Windows, that close often surfaces as os error 10053 / 10054. 4. The realtime stream shuts down before the routed handoff finishes creating/steering the follow-up request. 5. The test waits for the expected follow-up event and times out. The PR changes only step 2: for this test, the mock websocket stays open after sending the scripted handoff event. The same handoff event is still sent, and the test still asserts the important steering behavior: 1. first Responses request has the original prompt 2. first request does not contain realtime delegation 3. second Responses request does contain the realtime delegation ## Validation - `just fmt` - `just test -p codex-core --test all suite::realtime_conversation::inbound_handoff_request_steers_active_turn` ## Recent CI failures with the same signature - https://github.com/openai/codex/actions/runs/27538033492/job/81392362858 - 2026-06-15, `[codex] update multi-agent v2 prompts` - same test failed after `conversation.handoff.requested`; websocket read failed with `os error 10053` - https://github.com/openai/codex/actions/runs/27543877820/job/81412200651 - 2026-06-15, `feat: dispatch queued user messages through core idle extensions` - same test failed; websocket read failed with `os error 10054` - https://github.com/openai/codex/actions/runs/27544342375/job/81413801641 - 2026-06-15, `[codex] Make marketplace loading capability aware` - same test failed; websocket read failed with `os error 10053`
felixxia-oai ·
2026-06-15 23:50:11 +01:00 -
[codex] Reuse Apps policy evaluation across MCP tool exposure (#27813)
## Summary - move `AppToolPolicyEvaluator` and the Apps config/requirements policy logic from `codex-core` into `codex-connectors` - resolve one immutable policy snapshot per exposure build and reuse it across every Codex Apps MCP tool - keep core as a thin adapter from MCP metadata to connector-owned policy input while preserving the call-time defense-in-depth check ## Why `build_mcp_tool_exposure` evaluates every Codex Apps tool on each sampling request. The old path rebuilt effective Apps configuration for every tool, and the policy implementation lived in the already-large core crate even though it is connector-specific. The connector-owned evaluator keeps the expensive config merge/decode out of the loop and gives core only the effective policy result it needs. ## Performance With the real 557-tool Apps corpus, `build_mcp_tool_exposure` measured 3.74 ms and 3.33 ms after the extraction (3.54 ms mean). The original path measured 807 ms mean, so the final result retains the 99.6% reduction. ## Validation - `cargo check -p codex-connectors -p codex-core` - `just test -p codex-connectors` — 15 passed - `just test -p codex-core --lib connectors` — 35 passed - `just test -p codex-core --lib mcp_tool_exposure` — 5 passed - `just test -p codex-core --lib mcp_tool_call` — 72 passed - `just bazel-lock-update` - `just bazel-lock-check` - `just fix -p codex-connectors` - `just fix -p codex-core` - `just fmt`
Matthew Zeng ·
2026-06-15 15:24:33 -07:00 -
Respect blocking PostToolUse hooks in code mode (#28365)
## Summary Make blocking hook behavior reliable for tools invoked from code mode. Previously, a `PostToolUse` hook could block a completed tool result, but code mode would still return the original typed result to JavaScript. The hook appeared blocked in hook telemetry while the running script continued with the result. This change: - rejects the nested JavaScript tool promise when `PostToolUse` blocks - normalizes `decision: "block"` and exit code 2 to the same blocking behavior - surfaces the hook feedback as the rejected promise's error - adds end-to-end coverage for the relevant PreToolUse and PostToolUse interactions ## Hook semantics in code mode | Hook behavior | Code-mode result | |---|---| | PreToolUse block | Reject the promise before the tool executes | | PreToolUse `updatedInput` | Execute the rewritten invocation and return its result | | PostToolUse `decision: "block"` | Execute the tool, then reject the promise with the hook reason | | PostToolUse exit code 2 | Same behavior as `decision: "block"` | | PostToolUse `continue: false` | Preserve the existing feedback-only behavior; do not reject the promise | ## Test coverage Added or strengthened end-to-end coverage proving that: - a PreToolUse block rejects the JavaScript promise before execution - a PreToolUse input rewrite executes only the rewritten command - JavaScript receives the rewritten command's result - PostToolUse `decision: "block"` rejects after the command executes - PostToolUse exit code 2 has the same behavior - the hook observes the original completed tool response - the blocked original result does not reach JavaScript - existing direct-mode replacement behavior remains intact - `continue: false` without a reason produces deterministic fallback feedback
Abhinav ·
2026-06-15 15:12:26 -07:00 -
[codex] Add created-by-me remote plugin marketplace (#28203)
## Summary - add the `created-by-me-remote` marketplace backed by paginated `scope=USER` plugin directory and installed-plugin requests - include USER plugins in installed-plugin caching, bundle sync, and stale-cache cleanup without client-side discoverability filtering - expose the marketplace through app-server v2 and regenerate the protocol schemas ## Testing - `cargo build -p codex-app-server --bin codex-app-server` - production-auth `plugin/list` smoke test for `created-by-me-remote` (returned the expected USER plugin as installed and enabled) - `just test -p codex-core-plugins` (221 passed) - `just test -p codex-app-server-protocol` (231 passed) - `just test -p codex-app-server suite::v2::plugin_list::` (37 passed) - `just fix -p codex-core-plugins -p codex-app-server-protocol -p codex-app-server` - `just fmt`
Eric Ning ·
2026-06-15 22:07:07 +00:00 -
feat(core): add metadata field to ResponseItem (#28355)
## Description This PR adds an optional `metadata` field to `ResponseItem` for Responses API calls. Only mechanical plumbing, no actual values populated and sent yet. Turns out just adding a new field to `ResponseItem` has quite a large blast radius already. This change is backwards compatible because `metadata` is optional and omitted when absent, so existing response items and rollout history without it still deserialize and requests that do not set it keep the same wire shape. For provider compatibility, we strip out `metadata` before non-OpenAI Responses requests so Azure and AWS Bedrock never see this field. My followup PR here will actually make use of it to start storing and passing along `turn_id`: https://github.com/openai/codex/pull/28360 ## What changed - Added `ResponseItemMetadata` with optional `turn_id`, plus optional `metadata` on Responses API item variants and inter-agent communication. - Preserved item metadata through response-item rewrites such as truncation, missing tool-output synthesis, compaction history rebuilding, visible-history conversion, rollout/resume, and generated app-server schemas/types. - Strip item metadata from non-OpenAI Responses requests while preserving it for OpenAI-shaped requests. - Updated the mechanical fixture/test construction churn required by the new optional field.
Owen Lin ·
2026-06-15 15:05:28 -07:00 -
feat(app-server): expose rate-limit reset credits (#28143)
## Why Codex users can earn personal rate-limit reset credits, but app-server clients do not currently have an API for reading or redeeming them. This adds the backend and protocol foundation used by the `/usage` TUI flow in #28154. ## What changed - Extend `account/rateLimits/read` with a nullable `rateLimitResetCredits` summary sourced from the existing usage response. - Add backend-client and app-server support for consuming a reset with a caller-generated idempotency key. A UUID is recommended, and clients reuse the same key when retrying the same logical reset. - Return only the consume `outcome`; clients refetch `account/rateLimits/read` for updated window state. - Document the response field and each consume outcome, and regenerate the JSON and TypeScript schema fixtures. - Clarify in `AGENTS.md` that new app-server string enum values use camelCase on the wire. - Update the existing TUI response fixture for the expanded protocol shape. - Add coverage for authentication, response mapping, backend failures, consume outcomes, and request timeout behavior. ## Validation - `just test -p codex-app-server-protocol` — 231 passed. - `just test -p codex-backend-client` — 14 passed. - Focused `codex-app-server` reset-credit tests — 5 passed. - Focused `codex-tui` protocol response fixture test — passed. - `just fix -p codex-backend-client -p codex-app-server-protocol -p codex-app-server` — passed. - `just fmt` — passed.
jay ·
2026-06-15 21:54:01 +00:00 -
core: cache the tool search handler per session (#27258)
## Why Tool router construction rebuilds the deferred-tool BM25 index during session initialization and before each sampling continuation, even when the searchable tool metadata is unchanged. Local profiling measured `append_tool_search_executor` at roughly 113 ms per continuation, making repeated index construction the largest measured router-building cost. ## What changed - Add a session-scoped `ToolSearchHandlerCache` so continuations and user turns can reuse the existing handler. - Key reuse on the complete ordered `Vec<ToolSearchInfo>`, rebuilding when searchable text, loadable tool specs, source metadata, or ordering changes. - Build handlers outside the cache lock and recheck before publishing them, avoiding holding the mutex during index construction. ## Verification - `cache_reuses_identical_search_infos_and_rebuilds_changed_inputs` covers exact cache reuse and invalidation when the ordered search metadata changes. - Local rollout profiling showed the initial router build populating the cache and unchanged later continuations reusing it: - uncached: 118 ms median across 14 spans from 3 rollouts - cached: 4 ms median across 12 spans from 3 rollouts
mchen-oai ·
2026-06-15 14:48:30 -07:00 -
Add hidden Windows sandbox wrapper entrypoint (#28358)
## Why This is the second PR in the Windows fs-helper sandbox stack. The fs-helper path needs a Windows sandbox launcher that has the same argv-shaped contract as macOS `sandbox-exec` and `codex-linux-sandbox`, but this PR only introduces that hidden launcher. It does not route fs-helper through it yet. The hidden launcher still needs to be policy-complete before later direct-spawn callers use it. In particular, it has to carry the same Windows sandbox policy details that the existing spawn paths already understand: proxy enforcement, read/write root overrides, and deny-read/deny-write overrides. ## What Changed - Added the hidden `codex.exe --run-as-windows-sandbox` arg1 dispatch path. - Added `windows-sandbox-rs/src/wrapper.rs`, which parses the wrapper argv, launches the requested command through the shared Windows sandbox session runner from PR1, and forwards stdio. - Added `create_windows_sandbox_command_args_for_permission_profile()` so later direct-spawn callers can build the wrapper argv consistently. - Made the wrapper argv round-trip the full Windows sandbox policy surface it needs later: workspace roots, environment, permission profile, sandbox level, private desktop, proxy enforcement, read/write root overrides, and deny-read/deny-write overrides. - Carried `proxy_enforced` through the shared Windows session request so proxy-managed executions continue to use the offline/elevated sandbox identity. - Added wrapper argument round-trip coverage for the full policy fields. ## Verification - `just test -p codex-windows-sandbox windows_wrapper_args_round_trip` - `just test -p codex-arg0` - `just test -p codex-core exec::tests::windows_` - `just fix -p codex-windows-sandbox -p codex-core -p codex-cli` Local note: the full `just fmt` command still fails on this workstation in non-Rust formatter setup (`uv` cache access denied and missing `dotslash`/buildifier), but the Rust formatter phase completed.
iceweasel-oai ·
2026-06-15 21:30:32 +00:00 -
Add Windows unified exec yield floor (#27086)
## Why The Windows `unified_exec` experiment regressed at the turn level in a way that points to premature backgrounding / extra command cycles rather than individual responses getting heavier: - `codex_local_tool_calls_per_turn` was up about 20.7%. - `codex_local_blended_tokens_per_turn` was up about 4.1%, and `codex_local_output_tokens_per_turn` was up about 4.0%. - `codex_local_response_latency_per_turn` was up about 8.3%. - The primary activity metrics also moved down: `codex_turns` about -6.6%, `codex_dau` about -1.0%, and `codex_local_hourly_active_users` about -3.0%. At the same time, the per-response metrics moved in the other direction: blended tokens per response, output tokens per response, and latency per response were all lower in test. That suggests the bad turn-level shape is largely about extra tool/model cycles, not each response being slower or more expensive on its own. Local Windows benchmarking showed the likely mechanism: shell-wrapped commands pay a large PowerShell startup/teardown tax before the actual command has much time to run. In the benchmark, the PowerShell wrapper added roughly 0.7-1.0s versus direct exec: - Windows PowerShell: about 740ms p50 / 800ms p90 overhead versus direct exec. - PowerShell 7 (`pwsh`): about 930ms p50 / 980ms p90 overhead versus direct exec. The model commonly asks for a 1s initial yield. On Windows, that can spend nearly the whole window waiting on PowerShell machinery, so otherwise-short commands are more likely to return as background sessions and require follow-up polling/tool calls. This is intentionally a temporary unlock. It gives Windows closer to the same useful post-shell command window as other platforms while we work on reducing the PowerShell tax directly, for example with persistent PowerShell workers or conservative direct-exec paths for commands that do not need shell semantics. ## What changed - Adds a Windows-only 2s floor to `unified_exec`'s initial `yield_time_ms` clamp. - Keeps larger model-requested waits unchanged, including the existing 10s default. - Keeps the existing 30s max clamp. - Leaves non-Windows behavior unchanged. - Adds platform-gated tests for both the Windows floor and the non-Windows clamp behavior. ## Verification - `just test -p codex-core unified_exec`
iceweasel-oai ·
2026-06-15 13:56:18 -07:00 -
recover stale Windows sandbox credentials (#27944)
## Why The elevated Windows sandbox persists dedicated sandbox account credentials so later commands can launch without reprovisioning. If those persisted credentials drift from the actual Windows account password, `CreateProcessWithLogonW` fails with `ERROR_LOGON_FAILURE` and Codex currently surfaces that as a hard runner launch failure. This change makes that failure self-healing. When Windows specifically rejects the sandbox login, Codex now treats the persisted sandbox credentials as stale, regenerates them through the existing setup path, and retries the runner launch once. ## What Changed - Preserve `CreateProcessWithLogonW` failures as a typed runner logon error so callers can distinguish `ERROR_LOGON_FAILURE` from unrelated launch failures. - Add a sandbox credential refresh helper that deletes the persisted `sandbox_users.json` record and reuses `require_logon_sandbox_creds()` to reprovision credentials through the established setup flow. - Retry elevated runner startup after stale-credential failures in both the legacy elevated capture path and unified exec elevated backend. - Add focused tests for stale logon failure detection and persisted sandbox user file removal. ## Validation - `git diff --check` - `cargo test -p codex-windows-sandbox`
iceweasel-oai ·
2026-06-15 13:54:24 -07:00 -
[codex] Add external agent import result accounting (#28008)
## Why External-agent imports can complete synchronously or continue in the background for plugins/sessions. Clients need a stable import id to correlate the immediate response with the eventual completion notification, and the completion payload needs enough accounting to show which artifact types succeeded or failed without hiding partial failures. ## What Changed - `externalAgentConfig/import` now returns an `importId`; `externalAgentConfig/import/completed` includes the same `importId` plus type-level `itemResults`. - Completed `itemResults` report `successCount`, `errorCount`, `successes`, and `rawErrors` for each migrated item type. - Added protocol/schema/TypeScript types for import successes, raw errors, and type-level results. No progress notification is included in the final PR. - `ExternalAgentConfigService::import` now returns an outcome object with synchronous item results and pending plugin imports. - Plugin import outcomes track succeeded/failed marketplaces, plugin ids, and raw errors. Plugin failures can be reported in completed accounting while later migration items continue. - Non-plugin synchronous import failures still fail the request, so invalid config/skills-style failures are not reported as a successful import response. - Session imports now return item results. Successful imports include the source session path and imported thread id; prepare, persist, ledger, and source-validation failures become raw errors in completion accounting where the import can continue. - The request processor generates the `importId`, aggregates synchronous results with background plugin/session results, and sends a single completed notification when all selected work is done. - App-server docs and generated schema fixtures were updated for the new response/completed payload shapes. ## Validation - `just test -p codex-app-server-protocol` - `just test -p codex-app-server-client event_requires_delivery` - `CODEX_SQLITE_HOME=/private/tmp/codex-app-server-review-sync-error just test -p codex-app-server external_agent_config_import_returns_error_for_failed_sync_import` - `CODEX_SQLITE_HOME=/private/tmp/codex-app-server-review-external-agent just test -p codex-app-server external_agent_config` Note: local sandbox validation used `CODEX_SQLITE_HOME` because the default sqlite state path is read-only in this environment.
charlesgong-openai ·
2026-06-15 13:25:42 -07:00 -
[mcp] Increase default tool timeout to 300 seconds (#28234)
Summary - Increase the default MCP tool-call timeout from 120 to 300 seconds. Validation - `just test -p codex-mcp` - `just fmt`
Alex Daley ·
2026-06-15 16:07:01 -04:00 -
Add request user input auto-resolution timer (#28235)
## Summary - Add TUI auto-resolution handling for `request_user_input` prompts when `autoResolutionMs` is present. - Use a 60s hidden grace period followed by a 60s visible countdown, then submit an empty answer response if the user does not interact. - Snooze auto-resolution on key or paste interaction and add snapshot/test coverage for the countdown UI. ## Notes - The TUI currently treats `autoResolutionMs` as an enable signal and intentionally does not use the provided duration value for the countdown policy. ### Auto resolution https://github.com/user-attachments/assets/5323152f-2ece-4aba-b75d-c32aa776f544 ### Snooze after interaction https://github.com/user-attachments/assets/100d54c4-3a41-4c6c-9c07-cd28075a0d62
Shijie Rao ·
2026-06-15 11:49:19 -07:00 -
[codex] add path-types skill (#28347)
## Why Codex contributors and agents need repository-scoped guidance for choosing compatible Rust types for operating system paths during the ongoing URI migration. Keeping the guidance in the repository makes the app-server and exec-server rules available consistently without relying on a personal skill installation. ## What - Add the `path-types` skill at `.codex/skills/path-types/SKILL.md`. - Document the intended uses of `ApiPathString`, `PathUri`, `AbsolutePathBuf`, and `PathBuf` across protocol, internal, and shared dependency boundaries. - Keep migrations of existing types limited to explicit requests and proportional edits. ## Validation - Validated the skill structure with skill-creator's `quick_validate.py`.
Adam Perry @ OpenAI ·
2026-06-15 11:48:31 -07:00 -
Use aws-lc-rs for rustls crypto provider (#27706)
## Why Some enterprise TLS proxies issue certificate chains signed with `ecdsa_secp521r1_sha512` / `ECDSA_NISTP521_SHA512`. Custom CA configuration such as `SSL_CERT_FILE` can add the right trust root, but it cannot make `rustls`'s `ring` verifier support a certificate signature algorithm it does not advertise. That can still break TLS after the CA bundle is configured, including on Rust websocket paths that call the shared `ensure_rustls_crypto_provider()` helper, such as the Responses websocket connector and remote app-server client: - [`codex-api/src/endpoint/responses_websocket.rs`](https://github.com/openai/codex/blob/eddc5c75ed527a8348bfcaa85692e53189600833/codex-rs/codex-api/src/endpoint/responses_websocket.rs#L441) - [`app-server-client/src/remote.rs`](https://github.com/openai/codex/blob/eddc5c75ed527a8348bfcaa85692e53189600833/codex-rs/app-server-client/src/remote.rs#L718) The `aws-lc-rs` `rustls` provider supports this P-521/SHA-512 certificate signature scheme, so use it as Codex's process-wide `rustls` provider. ## What Changed - Switch the workspace `rustls` feature from `ring` to `aws_lc_rs`. - Update `codex-utils-rustls-provider` to install `rustls::crypto::aws_lc_rs::default_provider()`. - Add an assertion and integration test that the installed provider supports `ECDSA_NISTP521_SHA512`. ## Verification ```shell just fmt just test -p codex-utils-rustls-provider just bazel-lock-update just bazel-lock-check ```
malsamiri-oai ·
2026-06-15 11:32:13 -07:00 -
Extract shared Windows sandbox session runner (#28357)
## Why This is the first PR in a stack for the Windows fs-helper sandbox fix. Before changing fs-helper behavior, this pulls the reusable Windows sandbox session launch pieces out of the debug CLI path so later PRs can call the same backend selection and stdio forwarding logic. Keeping this as a pure refactor makes the later security fix easier to review: `codex sandbox windows` should continue to launch the same elevated or restricted-token backend, just through shared APIs in `windows-sandbox-rs` instead of code local to `cli/src/debug_sandbox.rs`. ## What Changed - Added `WindowsSandboxSessionRequest` and `spawn_windows_sandbox_session_for_level()` in `windows-sandbox-rs` to share the elevated-vs-legacy session launch decision. - Moved the Windows sandbox stdio forwarding helpers from `cli/src/debug_sandbox.rs` into `windows-sandbox-rs/src/stdio_bridge.rs`. - Updated `codex sandbox windows` to call the shared session launcher and stdio bridge. - Added unit coverage for the moved stdio forwarding helpers. ## Verification - `just bazel-lock-update` - `just bazel-lock-check` - `just test -p codex-windows-sandbox stdio_bridge::tests` - `just fix -p codex-windows-sandbox -p codex-sandboxing -p codex-exec-server -p codex-arg0 -p codex-core -p codex-file-system` - The new `stdio_bridge` tests also passed as part of `just test -p codex-windows-sandbox` on the stack tip. That full local run still fails in pre-existing legacy session integration tests with `CreateRestrictedToken failed: 87` on this workstation.
iceweasel-oai ·
2026-06-15 18:30:48 +00:00 -
skills: cache orchestrator resources per thread (#28336)
## Why Hosted orchestrator skills are read through the remote MCP resource server. Within one thread, the same catalog or skill resource can be requested multiple times by prompt injection and the `skills.list` / `skills.read` tools. Re-fetching adds latency and can make those surfaces observe different remote contents during the same thread. This is a follow-up to #28333: orchestrator skills remain limited to threads without a local executor, and those threads now get a stable per-thread view of the remote skill data they use. ## What changed - Reuse the existing per-thread orchestrator catalog snapshot for `skills.list` and `skills.read` availability checks. - Cache successful orchestrator resource reads by authority, package, and resource so prompt injection and tool calls share the same contents. - Keep the cache memory-only and bounded to 100 resources and 8 MiB per thread. - Leave host and executor skill reads unchanged, and do not cache failed remote reads. ## Verification - Extended the app-server MCP resource integration test to read the same hosted skill resource twice and verify that the remote server receives one read. - The same test verifies that catalog discovery and the selected skill's main prompt are each fetched only once per thread.
jif ·
2026-06-15 20:20:19 +02:00 -
core: let steer interrupt wait_agent (#28341)
## Why `wait_agent` can block for a long timeout while waiting for sub-agent mailbox activity. Although same-turn user steer is accepted during that tool call, the input remains pending until the wait returns, so an explicit request to change direction can appear unresponsive. ## What changed - Notify active `wait_agent` calls when user input is steered into the current turn. - Check for already-pending steer input when subscribing so input that races with tool startup is not missed. - Distinguish mailbox activity, steered input, and timeout outcomes, returning `Wait interrupted by new input.` for the steer path. - Update the `wait_agent` tool description to document the early-return behavior. ## Testing - `just test -p codex-core input_queue_` - `just test -p codex-core wait_agent` The coverage includes steer notification before and after subscription, plus an end-to-end test that verifies the interrupted wait result and steered user input are both included exactly once in the follow-up model request.
jif ·
2026-06-15 20:08:15 +02:00 -
Support staging OAuth client ID overrides (#28257)
## Summary - allow app-server ChatGPT login to use a configured OAuth client ID - reuse the same client ID for refresh and revoke requests - cover staging login, refresh, and revoke request payloads ## Tests - `just test -p codex-login` - `just test -p codex-app-server login_account_chatgpt_uses_debug_oauth_overrides` - `just test -p codex-login logout_with_revoke_revokes_refresh_token_then_removes_auth` - `just fix -p codex-login` - `just fix -p codex-app-server` - `just fmt`
Anton Panasenko ·
2026-06-15 10:56:53 -07:00 -
bound prompt image cache retention (#28294)
## Why The prompt image cache was bounded to 32 entries, but not by the size of those entries. A set of large encoded images could therefore retain substantially more memory than intended. Cache hits also cloned the full encoded payload. ## What changed - cap the cache at 64 MiB of encoded image data while preserving its existing 32-entry limit - skip caching an image that exceeds the entire byte budget - evict least-recently-used entries until the cache is back within its byte budget - share cached encoded bytes with `Arc<[u8]>` so cache hits do not deep-clone image payloads ## Validation - `just test -p codex-utils-image`
jif ·
2026-06-15 19:52:30 +02:00 -
TUI Plugin Sharing 2 - add remote plugin section plumbing (#26702)
This adds the background plumbing for remote-backed plugin catalog sections while leaving the fuller directory presentation to the next PR. The TUI can fetch section-specific remote marketplace results, keep local plugin data available, and carry section errors forward for later rendering. - Fetches explicit remote marketplace kinds for curated, workspace, and shared-with-me sections. - Gates shared-with-me loading on the plugin sharing feature flag. - Adds section-level error state and user-actionable error copy. - Merges remote marketplace results into the cached plugin list without discarding local results.
canvrno-oai ·
2026-06-15 10:25:37 -07:00 -
guardian: isolate review context from skills and memories (#28285)
## Why Guardian reviews embed the parent session transcript as untrusted evidence. Skill or plugin mentions in that transcript must not be interpreted as requests to inject more instructions into the Guardian request, and memory context adds unrelated model-visible context to an approval decision. Keeping those sources out of the nested review session makes the request smaller and preserves the trust boundary around the transcript being assessed. ## What changed - Skip skill and plugin discovery when building turns for Guardian reviewer sessions. - Disable memory context and dedicated memory tools in the derived Guardian configuration. - Extend the Guardian request-layout coverage to verify that a `$skill` mention remains visible only as transcript evidence while neither the skill body nor memory context is injected. - Expand the Guardian configuration test to cover the disabled memory settings. ## Testing - Updated the Guardian review request snapshot and assertions for skill and memory isolation. - Extended the Guardian session configuration test to cover memories.
jif ·
2026-06-15 19:24:50 +02:00 -
[codex] preserve explicit environment cwd (#27995)
## Why `TurnEnvironmentSelections::new` rewrote the primary environment's explicit `cwd` to the legacy fallback cwd. For a remote-first selection, this could replace the remote working directory with a local fallback path and made the legacy cwd overlay authoritative over environment-owned state. ## What changed - Preserve every explicit environment cwd when constructing turn environment selections. - Keep `cwd`-only app-server updates compatible by rebuilding the default environment selections at the requested cwd. - Cover both explicit primary cwd preservation and cwd-only updates reaching the model-visible execution environment. ## Testing - `just test -p codex-core session_update_settings_does_not_rewrite_sticky_environment_cwds` - `just test -p codex-core environment_settings_preserve_explicit_primary_cwd` - `just test -p codex-app-server thread_settings_update_cwd_retargets_default_environment`
pakrym-oai ·
2026-06-15 17:17:34 +00:00