mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
7d47056ea42636271ac020b86347fbbef49490aa
6799 Commits
-
fix: plugin bundle archive handling for upload and install (#23983)
Move plugin tar.gz packing and unpacking into a shared core-plugins archive helper so uploaded bundles are decoded through the same tar handling used for installs. This removes duplicate archive logic, supports GNU long-name entries on extraction, and keeps size, traversal, link, and entry-type checks in one place.
xl-openai ·
2026-05-22 19:31:39 -07:00 -
code-mode: merge stored values by key (#24159)
## Summary Change code-mode stored value updates to merge writes by key instead of replacing the session's complete stored-value map after each cell completes. Previously, each cell received a snapshot of stored values and returned the complete resulting map. When multiple cells ran concurrently, a later completion could overwrite values written by another cell because it committed an older snapshot. This change moves stored-value ownership into `CodeModeService`: - Each runtime starts from the service's current stored values. - Runtime completion reports only keys written by that cell. - The service merges those writes into the current stored-value map on successful completion. - Core no longer replaces its stored-value state from a cell result. As a result, concurrently executing cells can update different stored keys without clobbering one another. The move into CodeModeService is motivated by a desire to have this lifetime tied to a new lifetime object on that side in a subsequent PR.
Channing Conger ·
2026-05-22 19:09:02 -07:00 -
Michael Bolin ·
2026-05-22 18:42:19 -07:00 -
Default function tools into tool hooks (#23757)
# Why `PreToolUse`, `PostToolUse`, and `updatedInput` coverage for local function tools currently depends on each handler remembering to wire up the hook contract itself. That makes coverage easy to miss as new function tools are added, even though most of them share the same basic shape: a model-facing function call with JSON arguments. # What This makes `CoreToolRuntime` provide the default hook contract for ordinary local function tools: - build generic `PreToolUse` and `PostToolUse` payloads from the function tool name and arguments - apply `updatedInput` rewrites back into function-tool arguments through the same default path - let tool outputs override the post-hook input or response when they have a more stable hook-facing contract The exceptions stay explicit: - hosted tools remain outside the generic local function path - code-mode `wait` and `write_stdin` opt out for now - `PostToolUse` feedback replaces only the model-visible response, so code mode keeps its typed tool result With the generic path in place, the MCP and extension-tool adapters no longer need their own duplicate pre/post hook plumbing. The new coverage exercises the registry default plus end-to-end local function behavior for pre-hook blocking, `updatedInput` rewriting, and post-hook context.
Abhinav ·
2026-05-23 00:56:58 +00:00 -
package: include zsh fork in Codex package (#23756)
## Why The package layout gives Codex a stable place for runtime helpers that should travel with the entrypoint. `shell_zsh_fork` still required users to configure `zsh_path` manually, even though we already publish prebuilt zsh fork artifacts. This PR builds on #24129 and uses the shared DotSlash artifact fetcher to include the zsh fork in Codex packages when a matching target artifact exists. Packaged Codex builds can then discover the bundled fork automatically; the user/profile `zsh_path` override is removed so the feature uses the package-managed artifact instead of a legacy path knob. ## What Changed - Added `scripts/codex_package/codex-zsh`, a checked-in DotSlash manifest for the current macOS arm64 and Linux zsh fork artifacts. - Taught `scripts/build_codex_package.py` to fetch the matching zsh fork artifact and install it at `codex-resources/zsh/bin/zsh` when available for the selected target. - Added package layout validation for the optional bundled zsh resource. - Added `InstallContext::bundled_zsh_path()` and `InstallContext::bundled_zsh_bin_dir()` for package-layout resource discovery. - Threaded the packaged zsh path through config loading as the runtime `zsh_path` for packaged installs, and removed the config/profile/CLI override path. - Kept the packaged default zsh override typed as `AbsolutePathBuf` until the existing runtime `Config::zsh_path` boundary. - Updated app-server zsh-fork integration tests to spawn `codex-app-server` from a temporary package layout with `codex-resources/zsh/bin/zsh`, matching the new packaged discovery path instead of setting `zsh_path` in config. - Switched package executable copying from metadata-preserving `copy2()` to `copyfile()` plus explicit executable bits, which avoids macOS file-flag failures when local smoke tests use system binaries as inputs. ## Testing To verify that the `zsh` executable from the Codex package is picked up correctly, first I ran: ```shell ./scripts/build_codex_package.py ``` which created: ``` /private/var/folders/vw/x2knqmks50sfhfpy27nftl900000gp/T/codex-package-pms94kdp/ ``` so then I ran: ``` /private/var/folders/vw/x2knqmks50sfhfpy27nftl900000gp/T/codex-package-pms94kdp/bin/codex exec --enable shell_zsh_fork 'run `echo $0`' ``` which reported the following, as expected: ``` /private/var/folders/vw/x2knqmks50sfhfpy27nftl900000gp/T/codex-package-pms94kdp/codex-resources/zsh/bin/zsh ``` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23756). * #23768 * __->__ #23756
Michael Bolin ·
2026-05-22 17:54:07 -07:00 -
fix(remote-control): cap reconnect backoff (#24164)
## Why Remote-control websocket reconnects currently use the shared exponential backoff helper without a local ceiling, so a long failure streak can stretch retries out indefinitely and leave the runtime behavior hard to inspect from logs. ## What Changed Cap the remote-control reconnect delay at 30 seconds, then reset the reconnect attempt counter once that capped delay is emitted so the next failure starts from the initial jittered delay again. The reconnect failure log now records the attempt number, chosen delay, and whether the cap triggered a reset, with a separate info log when the backoff counter is reset after the cap. ## Verification `just test -p codex-app-server-transport` Related issue: N/A
Anton Panasenko ·
2026-05-23 00:38:22 +00:00 -
release: build macOS x64 zsh artifact (#24165)
## Why The zsh release workflow currently publishes macOS arm64 and Linux zsh fork artifacts, but no macOS x64 artifact. The Codex package builder therefore cannot include codex-resources/zsh/bin/zsh for x86_64-apple-darwin packages. ## What Changed - Added an x86_64-apple-darwin row to the macOS zsh release matrix. - Runs that row on macos-15-large, the Intel macOS runner appropriate for the native zsh build. - Added the matching macos-x86_64 platform to the zsh DotSlash publish config so the generated release manifest can reference the new tarball.
Michael Bolin ·
2026-05-22 17:08:59 -07:00 -
Display workspace usage limit error copy from response header (#24114)
## Why `openai/openai#947613` adds `X-Codex-Rate-Limit-Reached-Type` for Codex workspace credit-depletion and spend-cap responses. The CLI currently reads the adjacent promo header but otherwise renders generic usage-limit copy, so those responses do not explain the workspace-specific action the user needs to take. Backend dependency: https://github.com/openai/openai/pull/947613 ## What Changed - Parse `X-Codex-Rate-Limit-Reached-Type` in the usage-limit error handling path alongside `x-codex-promo-message`. - Keep the header value parsing with the shared `RateLimitReachedType` enum. - Carry the parsed type on `UsageLimitReachedError` and render client-owned copy for the four workspace owner/member credit and spend-cap values. - Preserve existing promo and plan-based text for absent, generic, or unknown header values. - Keep the existing TUI workspace-owner nudge state path unchanged; the response header only selects the displayed error string. - Add focused display coverage for all specific type values and the generic fallback case. ## Test Plan - Added `usage_limit_reached_error_formats_rate_limit_reached_types` coverage. - Not run manually, per request; CI runs validation on the pushed commit.
dhruvgupta-oai ·
2026-05-22 23:58:49 +00:00 -
[codex] Remove external client session reset plumbing (#24157)
## Why The turn loop no longer needs to decide when a `ModelClientSession` should reset its websocket state after compaction. That reset behavior belongs inside the model client, where the websocket cache and retry state are owned. The repo guidance now calls this out explicitly so future changes let the incremental request logic decide whether the previous request can be reused. ## What Changed - Removed the `reset_client_session` return value from pre-sampling and auto-compact helpers in `core/src/session/turn.rs`. - Changed compaction helpers to return `CodexResult<()>` so callers only handle success or failure. - Made `ModelClientSession::reset_websocket_session` private to `core/src/client.rs`, leaving it callable only from model-client internals. - Added `AGENTS.md` guidance not to call `reset_client_session` unnecessarily. ## Validation - `just test -p codex-core session::turn`
pakrym-oai ·
2026-05-22 16:46:25 -07:00 -
chore: add JSON schema policy fixture coverage (#24152)
## Why Before changing the Codex Bridge JSON schema policy, add integration coverage around real connector-like MCP tool schemas. The existing unit tests cover individual sanitizer behaviors, but they do not make it easy to see whether full fixture schemas keep model-visible guidance, prune only unreachable definitions, drop unsupported JSON Schema fields, and stay within the Responses API schema budget. ## What Changed - Added `tools/tests/json_schema_policy_fixtures.rs`, which converts MCP tool fixtures through `mcp_tool_to_responses_api_tool` and validates the resulting Responses tool parameters. - Added connector-style fixtures for Slack, Google Calendar, Google Drive, Notion, and Microsoft Outlook Email under `tools/tests/fixtures/json_schema_policy/`. - Added fixture assertions for preserved guidance, pruned definitions, expected field drops after `JsonSchema` conversion, marker count baselines, and dangling local `$ref` prevention. - Added a real oversized golden Notion `create_page` input schema fixture to exercise the compaction path that strips descriptions, drops root `$defs`, rewrites local refs, and fits the compacted schema under the budget.
Celia Chen ·
2026-05-22 16:31:33 -07:00 -
[codex] Add image re-encoding benchmarks (#23935)
## Summary - add Divan benchmarks for prompt image re-encoding paths - wire the image benchmark smoke test into Rust CI workflows ## Why Image prompt handling includes re-encoding work that benefits from repeatable benchmark coverage so changes can be measured in CI and locally. This already helped identify a potential regression from changing compiler flags. ## Impact Developers can run and compare the new image re-encoding benchmarks, and CI exercises the benchmark target via the Rust benchmark smoke test.
Adam Perry @ OpenAI ·
2026-05-22 22:38:40 +00:00 -
[codex] Use TurnInput for session task input (#24151)
## Why The idea here is to erase the difference between initial and followup inputs to a turn. Followup inputs are already represented as TurnInput. Eventual goal is not to have explicit on task input at all and pull everything from input Q. ## What Changed - Changes `SessionTask::run` and the erased `AnySessionTask::run` path to accept `Vec<TurnInput>`. - Wraps user-submitted spawn input as `TurnInput::UserInput` at the session task start boundary. - Updates `run_turn` to record initial `TurnInput` using the same hook and recording path used for pending input. - Keeps review-specific conversion local to `ReviewTask`, where the sub-Codex one-shot API still expects `Vec<UserInput>`. - Moves the synthetic compact prompt into `CompactTask` and starts compact tasks with empty task input. ## Validation - `cargo check -p codex-core` - `just test -p codex-core -E 'test(task_finish_emits_turn_item_lifecycle_for_leftover_pending_user_input) | test(queued_response_items_for_next_turn_move_into_next_active_turn) | test(steered_input_reopens_mailbox_delivery_for_current_turn)'`
pakrym-oai ·
2026-05-22 15:21:08 -07:00 -
package: factor DotSlash executable fetching (#24129)
## Why The package builder already fetches `rg` from a checked-in DotSlash manifest. The zsh packaging work needs the same fetch/cache/size-check/SHA-256/extract path for another manifest, but keeping that refactor inside the zsh PR makes the review harder to follow. This PR factors the existing `rg`-specific implementation into a reusable helper with no intended behavior change for `rg` packaging. ## What Changed - Added `scripts/codex_package/dotslash.py` for checked-in DotSlash manifest parsing, archive download, cache reuse, size validation, SHA-256 validation, and member extraction. - Updated `scripts/codex_package/ripgrep.py` to delegate to the shared helper. - Preserved the existing `rg` manifest path, cache key, destination filename, and executable-bit behavior. ## Testing - `python3 -m py_compile scripts/codex_package/dotslash.py scripts/codex_package/ripgrep.py scripts/codex_package/cli.py scripts/codex_package/layout.py scripts/codex_package/zsh.py` - `python3 -m unittest discover scripts/codex_package` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/24129). * #23768 * #23756 * __->__ #24129
Michael Bolin ·
2026-05-22 14:38:44 -07:00 -
[codex-analytics] split compaction v2 analytics implementation (#24146)
## What changed - Add a distinct `responses_compaction_v2` value for `CodexCompactionEvent.implementation`. - Emit that value from the remote compaction v2 path. - Keep local compaction as `responses` and legacy `/responses/compact` as `responses_compact`. ## Why Remote compaction v2 and local prompt-based compaction were both reported as `responses`, which made the analytics table collapse two different compaction mechanisms into one implementation bucket. ## Validation - `just fmt` - `just test -p codex-analytics` `just test -p codex-core` was started locally, but this PR is intentionally being pushed for CI to finish the remaining validation.
rhan-oai ·
2026-05-22 21:34:22 +00:00 -
Add typed Images client to codex-api (#23989)
## Why Standalone image generation needs a typed `codex-api` client surface for the Codex image proxy routes before the harness and model-facing tool layers are wired in. ## What changed - Added `ImagesClient` support for JSON `images/generations` and `images/edits` requests. - Added typed request and response shapes for generation, JSON edit image URLs, image metadata, and base64 image outputs. - Kept generation model slugs open-ended while requiring the generation model field that the downstream endpoint expects. - Exported the new client and image types from `codex-api`. - Added coverage for generation and edit wire shapes, extra response metadata that the client ignores, and malformed image responses missing `data`. ## Validation - `cargo test -p codex-api` - `just fix -p codex-api` - `just fmt` - `git diff --check main`
Won Park ·
2026-05-22 14:10:55 -07:00 -
Support OAuth options in codex mcp add (#24120)
## Summary - add `--oauth-client-id` and `--oauth-resource` options for streamable HTTP `codex mcp add` registrations - persist those options in MCP server config and use them during the immediate OAuth login flow - cover add-time serialization of both OAuth options in the CLI integration tests ## Testing - `just fmt` - `cargo test -p codex-cli` - `just fix -p codex-cli`
Matthew Zeng ·
2026-05-22 13:21:01 -07:00 -
Add trace_id to TurnStartedEvent (#23980)
## Why [Recent PR](https://github.com/openai/codex/pull/22709) removed `trace_id` from `TurnContextItem`. ## What changed - Add to `TurnStartedEvent` so rollout consumers can correlate turns with telemetry traces. - Note that the branch name is out of date because I originally re-added to `TurnContextItem`, but we decided to move it to `TurnStartedEvent`. ## Verification - `cargo test -p codex-protocol` - `cargo test -p codex-core --lib regular_turn_emits_turn_started_without_waiting_for_startup_prewarm` - `cargo test -p codex-core --test all emits_warning_when_resumed_model_differs` - `cargo test -p codex-rollout` - `cargo test -p codex-state`
mchen-oai ·
2026-05-22 13:10:56 -07:00 -
cli: support --profile for codex sandbox (#24110)
## Why `codex sandbox` now always runs the host sandbox backend, so it should accept the same profile selection mechanism as the rest of the runtime CLI surface. Without `--profile`, sandbox debugging can exercise only the default config stack unless users manually translate profile config into ad hoc `-c` overrides. Supporting `--profile` lets sandbox invocations load `$CODEX_HOME/<name>.config.toml`, including permission profile configuration, before resolving the sandbox policy for the command being run. ## What Changed - Added `--profile NAME` / `-p NAME` to the host-specific `codex sandbox` argument structs as `config_profile`. - Allowed root-level `codex --profile NAME sandbox ...` and made a sandbox-local `codex sandbox --profile NAME ...` override the root selection. - Threaded `LoaderOverrides` through sandbox config loading so selected config profile files participate in permission resolution before the legacy read-only fallback. - Documented the new sandbox flag in `codex-rs/README.md`. ## Verification - Added parser coverage for `codex sandbox --profile`. - Added sandbox config-loader coverage that verifies selected config profile loader overrides select the profile config rather than falling back to read-only. - Ran `cargo test -p codex-cli`.
Michael Bolin ·
2026-05-22 13:00:53 -07:00 -
fix(tui): restore Windows VT before TUI renders (#24082)
## Why Older Git for Windows versions can leave the Windows console output mode without virtual terminal processing after Codex runs git metadata commands in a repository. When the TUI later emits ANSI control sequences for redraws, restore, or image rendering, Windows Terminal can show raw escape bytes or leave the prompt/status area corrupted. This is a targeted mitigation for the repo-conditioned Windows rendering corruption reported in #23888 and related reports #23512 and #23628. Updating Git avoids the trigger for affected users, but Codex should also reassert the terminal mode before it writes TUI control sequences. | Before | After | |---|---| | <img width="2100" height="1359" alt="CleanShot 2026-05-22 at 11 23 21" src="https://github.com/user-attachments/assets/3218c379-5f97-4c71-ab25-805c9d20578a" /> | <img width="2100" height="1359" alt="CleanShot 2026-05-22 at 11 23 58" src="https://github.com/user-attachments/assets/55ac72bb-37d0-400e-99bc-12dd5ea4092d" /> | ## What Changed - Re-enable Windows virtual terminal processing for stdout and stderr before TUI mode setup, restore, redraw, resume, and pet image render paths. - Treat invalid, null, or non-console handles as no-ops so redirected or non-console output is unaffected. - Keep the helper as a no-op on non-Windows platforms. ## How to Test 1. On Windows Terminal with a Git 2.28.0 for Windows install, start Codex inside a valid Git repository. 2. Start a new Codex CLI session. 3. Confirm the prompt, working indicator, and bottom status line remain readable instead of showing raw ANSI escape sequences. 4. Repeat outside a Git repository to confirm the ordinary non-repo startup path is unchanged. Targeted tests: - Not run locally; the behavior depends on Windows console mode APIs and the current worktree is on macOS.
Felipe Coury ·
2026-05-22 16:20:09 -03:00 -
docs: update README.md to mention curl-based installer (#24106)
Now that users can install via `curl` (or `irm`), we should tell them about it so they no longer need to use `npm`! Note that on one Windows machine I tested on, when I ran: ``` irm https://chatgpt.com/codex/install.ps1 | iex ``` I got this error: ``` iex : The property 'OSArchitecture' cannot be found on this object. Verify that the property exists. At line:1 char:45 + irm https://chatgpt.com/codex/install.ps1 | iex + ~~~ + CategoryInfo : NotSpecified: (:) [Invoke-Expression], PropertyNotFoundException + FullyQualifiedErrorId : PropertyNotFoundStrict,Microsoft.PowerShell.Commands.InvokeExpressionCommand ``` so we'll recommend the following that works from both `cmd.exe` and PowerShell: ``` powershell -ExecutionPolicy ByPass -c "irm https://chatgpt.com/codex/install.ps1 | iex" ``` This PR makes a slight update to `codex-rs/tui/src/update_action.rs` to match.
Michael Bolin ·
2026-05-22 18:39:08 +00:00 -
[codex] Use rolling files for Windows sandbox logs (#24117)
## Why Windows sandbox diagnostics currently append to a single `sandbox.log` under `CODEX_HOME/.sandbox`. That file never rolls over, which makes it hard to safely include sandbox diagnostics in future feedback reports without risking unbounded growth. ## What changed - Replaced direct append-open sandbox logging with `tracing_appender::rolling::RollingFileAppender`. - Configured sandbox logs to rotate daily using names like `sandbox.YYYY-MM-DD.log`. - Added a conservative `MAX_LOG_FILES` cap of 90 retained matching log files. - Routed the Windows sandbox setup helper through the same rolling writer. - Added helpers for resolving the current daily sandbox log path so future feedback upload work can use the same filename logic. - Updated tests and test diagnostics to read the dated daily log file. This intentionally does not include sandbox logs in `/feedback` yet; scrubbing and attachment behavior can happen in a follow-up. ## Testing - `cargo fmt -p codex-windows-sandbox` - `cargo check -p codex-windows-sandbox` - `cargo test -p codex-windows-sandbox` - `cargo test -p codex-windows-sandbox logging::tests` - `cargo clippy -p codex-windows-sandbox --all-targets -- -D warnings`
iceweasel-oai ·
2026-05-22 11:37:01 -07:00 -
Add new enterprise requirement gate (#23736)
Add new enterprise requirement gate. Validation: - `cargo test -p codex-config --lib` - `cargo test -p codex-app-server-protocol --lib` - `cargo test -p codex-tui --lib debug_config` - `cargo test -p codex-app-server --lib` *(fails: stack overflow in `in_process::tests::in_process_start_initializes_and_handles_typed_v2_request`; reproduces when run alone)*
adams-oai ·
2026-05-22 11:33:44 -07:00 -
app-server: drop legacy profile config surface (#24067)
## Why Legacy `[profiles.<name>]` config tables and the legacy `profile` selector are being retired in favor of profile files selected with `--profile <name>`. After #23886 removed the CLI-side legacy profile plumbing, the app-server config surface still exposed those fields and still carried conversion code for the old protocol shape. ## What changed - Remove `profile`, `profiles`, and `ProfileV2` from the app-server config protocol/schema output so `config/read` no longer returns legacy profile config. - Drop the old v1 `UserSavedConfig` profile conversion path from `config`. - Reject new app-server config writes under `profiles.*` with the same migration direction used for `profile`, while still allowing callers to clear existing legacy profile tables. - Refresh app-server config coverage and the experimental API README example around the remaining `Config` nesting path. ## Verification - Added config-manager coverage that `config/read` omits legacy profile config, `profiles.*` writes are rejected, and existing legacy profile tables can still be cleared. - Updated the v2 config RPC test to cover the rejected `profiles.*` batch-write path.
jif-oai ·
2026-05-22 19:41:39 +02:00 -
cli: infer host sandbox backend (#24102)
## Why `codex sandbox` previously required an OS subcommand like `linux`, `macos`, or `windows`, even though the command can only run the sandbox backend available on the current host. That made the CLI imply a cross-OS choice that does not exist. ## What changed - Collapse `codex sandbox <os>` into `codex sandbox [COMMAND]...` by wiring the `sandbox` parser directly to the host-specific backend args with `cfg`. - Keep the existing backend runners for Seatbelt, Linux sandbox, and Windows restricted token. - Rename the public Windows debug sandbox runner to `run_command_under_windows_sandbox` for clarity. - Update the Rust sandbox docs and related README references to describe host OS selection and avoid pointing readers at legacy `sandbox_mode` config. ## Arg0 compatibility The `codex-linux-sandbox` helper path is still handled before normal CLI parsing. `arg0_dispatch()` checks whether the executable basename is `codex-linux-sandbox` and directly calls `codex_linux_sandbox::run_main()`, so removing the `sandbox linux` parser branch does not affect the arg0 helper flow. ## Verification - `cargo test -p codex-cli` - `cargo test -p codex-arg0` - `just fix -p codex-cli`
Michael Bolin ·
2026-05-22 10:23:59 -07:00 -
tui: make
codex-tui.logopt-in (#24081)## Why The TUI currently creates a shared plaintext `codex-tui.log` under the default log directory. That append-only file can keep growing across runs even though the TUI already records diagnostics in bounded local stores. Make the plaintext file log an explicit troubleshooting choice instead of a default side effect. This is possible because logs are also stored in the DB with proper rotation ## What changed - Only install the TUI file logging layer when `log_dir` is explicitly set. - Remove the prior `codex-tui.log` at startup before an opt-in file layer is created. - Clarify the `log_dir` config/schema text and `docs/install.md` example so users opt in with `codex -c log_dir=...` when they need a plaintext log.
jif-oai ·
2026-05-22 17:19:51 +00:00 -
retry remote compaction v2 requests (#23951)
## Why Remote compaction v2 sends a normal `/responses` request with a compaction trigger. It should follow the retry semantics used by normal Responses streaming calls for transient stream/request failures, while keeping a smaller per-transport retry budget because compact attempts can run much longer than normal turns. ## What changed - Add a v2 compaction retry loop that uses `stream_max_retries`, matching normal Responses turn retry mechanics. - Cap the compact v2 retry budget at 2 retries per transport with `min(stream_max_retries, 2)`. - Retry retryable request-open and post-open stream collection failures through the same loop. - Use the existing 200ms exponential backoff and requested retry delay handling used by normal turn retries. - Emit the same `Reconnecting... n/max` stream-error notification pattern. - Fall back from WebSockets to HTTPS after the compact v2 stream retry budget is exhausted, then reset the retry counter for HTTPS. - Keep final remote-compaction failure logging after retries/fallback are exhausted. - Treat compact stream EOF before `response.completed` as a retryable stream failure. - Add compact v2 regression coverage with `request_max_retries = 0` and `stream_max_retries = 2`, covering both request-open failure and opened-stream EOF in one end-to-end test. ## Tests - `just fmt` - `cargo test -p codex-core remote_compact_v2` - `just fix -p codex-core`
rhan-oai ·
2026-05-22 10:14:14 -07:00 -
Prefer
just testovercargo testin docs (#23910)`cargo test` for the core and other crates fails on a fresh macOS checkout without the right stack size variable. This change encourages using the just test command that sets the environment up correctly. As a bonus, this should encourage agents to get more benefit out of nextest's parallel execution.
anp-oai ·
2026-05-22 16:58:14 +00:00 -
fix(app-server): fix optional bool annotations (#24099)
`#[serde(default)]` wasn't sufficient for our generated TS types to reflect that clients didn't have to set them. We also need `skip_serializing_if = "std::ops::Not::not"`. This is already a rule in our agents.md file.
Owen Lin ·
2026-05-22 16:52:53 +00:00 -
ci: Use codex produced v8 artifacts for release builds (#23934)
Updates our build script to pull down the artifacts like we do in CI for building v8 into our targets. This changes the flow so that we now pre-install rusty v8 assets for all of our release targets from pre-built in workflow. Secondarily if running it locally we now optionally pull the assets down on python run assuming the user hasn't set the proper values, it then provides them. Sorry for the miss here.
Channing Conger ·
2026-05-22 09:42:08 -07:00 -
fix: reject legacy profile selectors (#24059)
## Why `--profile` now selects `<name>.config.toml`, so the legacy `profile` selector should not be reintroduced through config write or MCP tool paths. A matching legacy selector in base user config also needs the same migration guard as a matching legacy `[profiles.<name>]` table so profile loading fails with one clear migration error instead of mixing the old and new profile models. ## What - reject non-null app-server config writes to the top-level legacy `profile` selector - make `--profile <name>` reject base user config that still selects the same legacy `profile = "<name>"` value, alongside the existing matching legacy profile-table guard - reject removed MCP `codex` tool fields such as `profile` by denying unknown tool-call parameters and exposing that restriction in the generated schema - add regression coverage for the app-server write paths, config loader guard, and MCP tool input/schema behavior ## Verification - targeted regression tests cover the new app-server, config loader, and MCP rejection paths
jif-oai ·
2026-05-22 13:19:47 +02:00 -
otel: drop legacy profile usage telemetry (#24061)
## Summary - drop the dead legacy profile usage metric and active-profile conversation-start fields - update role comments so they describe provider and service-tier preservation without legacy config-profile wording - pair the code cleanup with the file-backed profile docs update in openai/developers-website#1476 ## Testing - `just fmt` - `cargo test -p codex-otel` - `cargo test -p codex-core` *(fails: existing stack overflow in `mcp_tool_call::tests::guardian_mode_mcp_denial_returns_rationale_message`)* - `cargo test -p codex-core --lib mcp_tool_call::tests::guardian_mode_mcp_denial_returns_rationale_message` *(fails with the same stack overflow)*
jif-oai ·
2026-05-22 13:14:44 +02:00 -
Avoid config snapshots in live agent subtree traversal (#24057)
## Why `/feedback` asks `ThreadManager` for the selected agent subtree before it uploads logs. The previous live subtree path reconstructed parent-child links by iterating every loaded thread and awaiting each thread config snapshot, so unrelated loaded-thread state could stall feedback subtree enumeration. The loaded-thread set already belongs to [`ThreadManagerState`](https://github.com/openai/codex/blob/50e6644c9425df2dcbfe52f65fd60bd7f15a8ea2/codex-rs/core/src/thread_manager.rs). Reading thread-spawn parents from the captured `CodexThread` session sources at that boundary keeps unload and resume behavior manager-owned while avoiding per-session config inspection. ## What Changed - expose parent-child thread-spawn edges for loaded, non-internal threads from `ThreadManagerState` - build the live child map from those edges while keeping agent metadata lookup and ordering in `AgentControl` - add regression coverage for live subtree enumeration when no state DB is available ## Validation - `git diff --check` - local Rust tests not run per request
jif-oai ·
2026-05-22 13:06:40 +02:00 -
config: remove legacy profile write paths (#24055)
## Why [#23883](https://github.com/openai/codex/pull/23883) moved the user-facing `--profile` flag onto profile v2 and [#23886](https://github.com/openai/codex/pull/23886) removed CLI forwarding for the legacy profile-v1 path. Core and TUI config persistence still carried `active_profile` and `ConfigEditsBuilder::with_profile`, which let later writes continue targeting legacy `[profiles.<name>]` tables after profile selection moved to profile-v2 config files. ## What - Remove legacy profile routing from [`ConfigEditsBuilder`](https://github.com/openai/codex/blob/4b38e9c22e762261d7f7eef49d8a21792e241a06/codex-rs/core/src/config/edit.rs#L1064-L1294), so core config edits no longer carry `with_profile` or infer `[profiles.*]` write targets from a `profile` key. - Drop `active_profile` plumbing from runtime `Config`, TUI startup/state, app-server config override forwarding, and Windows sandbox setup persistence. - Make app-server-backed TUI config edits use unscoped model, service-tier, feature, Auto-review, plan-mode, and Windows sandbox paths through [`tui/src/config_update.rs`](https://github.com/openai/codex/blob/4b38e9c22e762261d7f7eef49d8a21792e241a06/codex-rs/tui/src/config_update.rs#L43-L112). - Update config edit coverage so legacy `profile` state stays untouched by direct model writes, and remove tests whose only contract was the deleted profile-scoped persistence path. ## Testing - Not run locally.
jif-oai ·
2026-05-22 12:50:42 +02:00 -
config: remove legacy profile v1 resolution (#24051)
## Why [#23883](https://github.com/openai/codex/pull/23883) moved user-facing `--profile` selection onto profile v2, and [#23886](https://github.com/openai/codex/pull/23886) removed the old CLI `config_profile` override path. Core still had a second legacy path: `profile = "..."` could select `[profiles.*]` values while runtime config was built. Keeping that resolver alive preserves the old precedence model and profile-carrying surfaces even though profile selection now points at `$CODEX_HOME/<name>.config.toml`. ## What - Reject legacy top-level `profile = "..."` config while loading runtime config, with an error that points callers at `--profile <name>` and `<name>.config.toml` in the [core load path](https://github.com/openai/codex/blob/3d923366eca10a29143623124c6c6e538f058269/codex-rs/core/src/config/mod.rs#L2524-L2531). - Remove the remaining profile-v1 merge points from runtime config resolution, including features, permissions, model/provider selection, web search, Windows sandbox settings, TUI settings, role reloads, and OSS provider lookup. - Drop the leftover profile override surface from [`ConfigOverrides`](https://github.com/openai/codex/blob/3d923366eca10a29143623124c6c6e538f058269/codex-rs/core/src/config/mod.rs#L2118-L2148) and from the MCP server `codex` tool schema. - Prune profile-precedence tests that only exercised the removed resolver and replace them with rejection coverage for the legacy selector. ## Testing - Not run in this metadata pass. - Added [`legacy_profile_selection_is_rejected`](https://github.com/openai/codex/blob/3d923366eca10a29143623124c6c6e538f058269/codex-rs/core/src/config/config_tests.rs#L7942-L7965) coverage for the new runtime guard.
jif-oai ·
2026-05-22 12:13:52 +02:00 -
mcp: surface profile migration guidance under --profile (#23890)
## Why `codex --profile <name> mcp ...` should reach the same profile-v2 migration guard as runtime commands. Otherwise legacy `[profiles.<name>]` users see the generic command-scope rejection instead of the existing guidance to move settings into `$CODEX_HOME/<name>.config.toml`. ## What - Allow `codex mcp` through the `--profile` subcommand gate. - Pass profile loader overrides into the MCP entry point only to validate profile-v2 migration when a profile is present. - Keep MCP add/remove/list/get/login/logout behavior otherwise unchanged; this does not add profile-scoped MCP server management. - Cover the legacy profile migration error for `codex --profile work mcp list`. ## Testing - `cargo test -p codex-cli`
jif-oai ·
2026-05-22 10:40:33 +02:00 -
[codex] Enable Node env proxy for managed network proxy (#23905)
## Summary - set `NODE_USE_ENV_PROXY=1` when Codex applies managed network proxy environment overrides - keep the Node opt-in in the proxy environment key set used by shell/runtime env handling - cover the new env var in the focused network proxy env test ## Why Codex already sets HTTP proxy environment variables for child processes when the managed network proxy is active. Node's built-in network behavior needs the `NODE_USE_ENV_PROXY` opt-in to honor those env vars, so Node-based skill scripts can otherwise skip the managed proxy path and fail under restricted network access. ## Validation - `just fmt` in `codex-rs` - `cargo test -p codex-network-proxy` in `codex-rs`
rreichel3-oai ·
2026-05-22 01:27:25 -04:00 -
Allow parallel MCP tool calls when annotated readOnly (#23750)
## Summary - Treat MCP tools with `readOnlyHint: true` as parallel-safe even when `supports_parallel_tool_calls` is unset or `false`. - Keep server-level `supports_parallel_tool_calls` as an additive override for non-read-only tools. - Add focused unit coverage for the MCP handler eligibility decision. - Update RMCP integration coverage to keep the serial baseline on a mutable tool, verify read-only concurrency without server opt-in, and preserve the server opt-in concurrency path separately. ## Testing - `just fmt` - `cargo test -p codex-core --lib tools::handlers::mcp::tests::` - `cargo test -p codex-core --test all stdio_mcp_read_only_tool_calls_run_concurrently_without_server_opt_in` - `cargo test -p codex-core --test all stdio_mcp_parallel_tool_calls_opt_in_runs_concurrently` - `cargo test -p codex-rmcp-client`
anp-oai ·
2026-05-21 20:40:34 -07:00 -
feat: best-effort compact large tool schemas (#23904)
## Why The `dev/cc/ref-def` branch preserves richer JSON Schema detail for connector tools, including `$defs` and nested shapes. That improves fidelity, but it pushes the largest connector schemas well past the intended tool-schema budget. This PR adds a best-effort compaction pass for unusually large tool input schemas so the p99 and max tails stay small while ordinary schemas are left alone. ## What Changed - Added best-effort large-schema compaction in `codex-rs/tools/src/json_schema.rs` after schema sanitization and definition pruning. - Compaction runs as a waterfall only while the compact JSON budget proxy is exceeded: 1. Strip schema `description` metadata. 2. Drop root `$defs` / `definitions`. 3. Collapse deep nested complex schema objects to `{}`. - Kept top-level argument names and immediate schema shape where possible. ## Corpus Results Scope: 2,025 schemas under `golden_schemas`, all parsed successfully. Token count is `o200k_base` over compact JSON from `parse_tool_input_schema`. | Percentile | Before `origin/main` `4dbca61e20` | After branch `dev/cc/ref-def` `f9bf071758` | After this PR | |---|---:|---:|---:| | p0 | 9 | 9 | 9 | | p10 | 59 | 63 | 63 | | p25 | 81 | 86 | 86 | | p50 | 114 | 127 | 125 | | p75 | 174 | 205 | 202 | | p90 | 295 | 335 | 322 | | p95 | 391 | 526 | 422 | | p99 | 794 | 1,303 | 689 | | max | 2,836 | 3,337 | 887 | After this PR, `0 / 2,025` schemas are over 1k tokens. ### Compaction Savings These are cumulative waterfall stages over the same corpus. Later passes only run for schemas that are still over the compact JSON budget proxy. | Stage | Total tokens | Step savings | Schemas changed by step | |---|---:|---:|---:| | No compaction | 391,862 | - | - | | Strip schema `description` metadata | 350,961 | 40,901 | 66 | | Drop root `$defs` / `definitions` | 340,683 | 10,278 | 13 | | Collapse deep complex schemas to `{}` | 335,875 | 4,808 | 6 |Celia Chen ·
2026-05-22 01:26:17 +00:00 -
Expose conversation history to extension tools (#23963)
## Why Extension tools that need conversation context should be able to read it from the live tool invocation instead of reaching into thread persistence themselves. ## What changed - Add a `ConversationHistory` snapshot to extension `ToolCall`s and populate it from the current raw in-memory response history. - Expose all history items at this boundary so each extension can filter and bound the subset it needs before consuming or forwarding it. - Cover the adapter and registry dispatch paths and update existing extension tests that construct `ToolCall` literals. ## Test plan - `cargo test -p codex-tools` - `cargo test -p codex-extension-api` - `cargo test -p codex-goal-extension` - `cargo test -p codex-memories-extension` - `cargo test -p codex-core passes_turn_fields_to_extension_call` - `cargo test -p codex-core extension_tool_executors_are_model_visible_and_dispatchable`
sayan-oai ·
2026-05-22 01:11:47 +00:00 -
feat: support local refs and defs in tool input schemas (#23357)
# Why Some connector tool input schemas use local JSON Schema references and definition tables to avoid duplicating large nested shapes. Codex previously lowered these schemas into the supported subset in a way that could discard `$ref`-only schema objects and lose the corresponding definitions, which made non-strict tool registration less faithful than the original connector schema. This keeps the existing minimal-lowering policy: Codex still does not raw-pass through arbitrary JSON Schema, but it now preserves local reference structure that fits the Responses-compatible subset and prunes definition entries that cannot be reached by following `$ref`s from the root schema after sanitization, including refs found transitively inside other reachable definitions. The pruning matters because Responses parses definition tables even when entries are unused, so keeping dead definitions wastes prompt tokens. # What changed - Added `$ref`, `$defs`, and legacy `definitions` fields to the tool `JsonSchema` representation. - Updated `parse_tool_input_schema` lowering so `$ref`-only schema objects survive sanitization instead of becoming `{}`. - Sanitized definition tables recursively and dropped malformed definition tables so non-strict registration degrades gracefully. - Added reachability pruning for root definition tables by starting from refs outside definition tables, then following refs inside reachable definitions. - Added JSON Pointer decoding for local definition refs such as `#/$defs/Foo~1Bar`. # Verification ran local golden-schema probes against representative connector schemas to validate behavior on real generated schemas: | Golden schema | Before bytes | After bytes | `$defs` before -> after | `$ref` before -> after | Result | |---|---:|---:|---:|---:|---| | `google_calendar/create_space` | 7111 | 4526 | 7 -> 7 | 7 -> 7 | all definitions preserved because all are reachable | | `figma/apply_file_variable_changes` | 4609 | 999 | 8 -> 5 | 8 -> 5 | unused defs pruned after unsupported `oneOf` shapes lower away | | `snowflake/list_catalog_integrations` | 1380 | 404 | 3 -> 0 | 0 -> 0 | all defs pruned because none are referenced | | `dropbox/create_shared_link` | 8894 | 1836 | 14 -> 4 | 9 -> 4 | only defs reachable from the root schema after sanitization are retained, including transitively through other retained defs | Token increase across golden schema due to this change: <img width="817" height="366" alt="Screenshot 2026-05-19 at 1 47 04 PM" src="https://github.com/user-attachments/assets/d5c80fe9-da85-41e6-8ac7-a01d1e0b0f71" />Celia Chen ·
2026-05-22 00:32:14 +00:00 -
Fix auto-review permission profile override (#23956)
## Summary The auto-review runtime sync path was assigning a raw `PermissionProfile` into `runtime_permission_profile_override`, whose field now expects `RuntimePermissionProfileOverride`. That broke the TUI Bazel build. This changes the assignment to store `RuntimePermissionProfileOverride::from_config(&self.config)`, matching the other runtime override paths and preserving the active profile and network metadata with the permission profile.
Eric Traut ·
2026-05-21 16:52:36 -07:00 -
Add Bedrock Mantle GovCloud region (#23860)
## Summary - Add us-gov-west-1 to the Bedrock Mantle supported region list - Cover the GovCloud endpoint URL in the existing base_url unit test ## Test - cargo test -p codex-model-provider
CHARLESPALEN-OAI ·
2026-05-21 19:19:26 -04:00 -
fix: Allow plugin skills to share plugin-level icon assets (#23776)
Thread the plugin root through plugin skill loading so skill interface icons can reference shared plugin assets, such as ../../assets/logo.svg.
xl-openai ·
2026-05-21 16:11:59 -07:00 -
[3 of 4] tui: route feature and memory toggles through app server (#22915)
## Why Experimental feature toggles and memory settings can update several related config values in one interaction. Keeping those writes local in a remote TUI session is especially dangerous because the UI can diverge from the app-server config while also leaving behind partially stale supporting keys. This is **[3 of 4]** in a stacked series that moves TUI-owned config mutations onto app-server APIs. ## What changed - Routed feature flag persistence through app-server batch writes, including the supporting reviewer and permission updates used by guardian approval. - Routed Windows sandbox mode persistence and legacy Windows feature cleanup through app-server writes. - Routed memory settings through app-server batch writes and updated the TUI tests to exercise the embedded app-server path. ## Config keys affected - `features.<feature_key>` - `profiles.<profile>.features.<feature_key>` - `approval_policy` - `sandbox_mode` - `approvals_reviewer` - `windows.sandbox` - `features.experimental_windows_sandbox` - `features.elevated_windows_sandbox` - `features.enable_experimental_windows_sandbox` - Profile-scoped Windows legacy feature variants under `profiles.<profile>.features.*` - `memories.use_memories` - `memories.generate_memories` - Profile-scoped memory variants under `profiles.<profile>.memories.*` ## Suggested manual validation - Connect the TUI to a remote app server, toggle guardian approval on and off, and confirm the remote config updates `features.guardian_approval`, reviewer state, approval policy, and sandbox mode coherently. - Toggle a default-false experimental feature at the root level, disable it again, and confirm the key clears instead of lingering as an unnecessary explicit `false`. - Change memory settings and confirm the remote config updates both memory keys while the running TUI reflects the new state. - On Windows, switch sandbox mode through the TUI and confirm `windows.sandbox` is updated while the legacy Windows feature keys are cleared. ## Stack 1. [#22913](https://github.com/openai/codex/pull/22913) `[1 of 4]` primary settings writes 2. [#22914](https://github.com/openai/codex/pull/22914) `[2 of 4]` app and skill enablement 3. [#22915](https://github.com/openai/codex/pull/22915) `[3 of 4]` feature and memory toggles 4. [#22916](https://github.com/openai/codex/pull/22916) `[4 of 4]` startup and onboarding bookkeeping
Eric Traut ·
2026-05-21 16:03:11 -07:00 -
Add subagent identity to hook inputs (#22882)
# What When a normal hook fires inside a thread-spawned subagent, Codex now includes these optional top-level fields in the hook input: - `agent_id`: the child thread id - `agent_type`: the subagent role Root-agent hook inputs omit these fields. `SubagentStart` and `SubagentStop` keep their existing required `agent_id` and `agent_type` fields because those events are inherently subagent-scoped. This does not change matcher behavior. Tool hooks still match on tool name, compact hooks still match on trigger, and `UserPromptSubmit` still ignores matchers. Only `SubagentStart` and `SubagentStop` match on `agent_type`.
Abhinav ·
2026-05-21 14:54:01 -07:00 -
fix(remote-control): retry after auth recovery (#23775)
## Why When remote control hits an auth failure such as a revoked or reused refresh token, the websocket loop falls into reconnect backoff. If the user fixes auth while that loop is sleeping, remote control can stay offline until the old retry timer expires because nothing wakes the loop or resets its exhausted auth recovery state. ## What Changed Added an auth-change watch on `AuthManager` for refresh-relevant cached auth updates. The remote-control websocket loop now subscribes to that signal, resets `UnauthorizedRecovery` and reconnect backoff when auth changes, and retries immediately instead of waiting for the previous delay. Updated the remote-control transport test to verify that reloading auth with the now-available account id wakes enrollment before the prior retry delay. ## Verification `cargo test -p codex-app-server-transport remote_control_waits_for_account_id_before_enrolling`
Anton Panasenko ·
2026-05-21 14:38:30 -07:00 -
[codex] Make thread search case-insensitive (#23921)
## Summary - make rollout content search prefilter rollout files case-insensitively - keep the no-ripgrep fallback scan and visible snippet matcher aligned with that behavior - cover a lowercase `thread/search` query matching mixed-case conversation content ## Why The rollout-backed `thread/search` path used exact string matching in both its `rg` prefilter and semantic snippet generation. A content result could be missed solely because the query casing did not match the stored conversation text. ## Validation - `just fmt` - `cargo test -p codex-app-server thread_search_returns_content_matches` - `cargo test -p codex-rollout` - `just bazel-lock-update` - `just bazel-lock-check` - `cargo build -p codex-cli` - launched a local Electron dev instance with the rebuilt CLI binary
Francis Chalissery ·
2026-05-21 14:14:01 -07:00 -
npm: remove legacy package artifact synthesis (#23836)
## Why `rust-release` now publishes `codex-package-<target>.tar.gz` as the canonical native package payload. npm staging should consume those archives directly instead of keeping legacy synthesis code that fetched `rg`, copied standalone binaries, and rebuilt an approximate package layout. That also means the package builder should not know the internal shape of `codex-package`. It should extract and copy the target payload wholesale so future layout changes stay localized to the archive producer. The release job stages `codex`, `codex-responses-api-proxy`, and `codex-sdk` together, so native artifact download should be filtered, observable, and shared across component installs. Since that native hydration is now only used by release staging, keeping a separate `install_native_deps.py` CLI adds an extra wrapper without a real caller. ## What Changed - Removed legacy `codex-package` synthesis and related compatibility flags from npm staging. - Folded the remaining native artifact hydration code into `scripts/stage_npm_packages.py` and deleted `codex-cli/scripts/install_native_deps.py`. - Made platform package staging copy the full extracted target directory instead of enumerating package entries. - Kept non-`codex-package` native components under their component directory name instead of using a legacy destination map. - Split native staging by component set while sharing one workflow-artifact cache across the invocation. - Changed workflow artifact download to select target artifacts by name, print sizes/progress, and reuse cached artifacts. - Removed the implicit `CI=true` default from `build_npm_package.py`; local CI-shaped runs should set that environment explicitly. - Kept `npm pack` cache/log output in its temporary directory so packing does not write to the user npm cache. ## Verification - `python3 -m py_compile scripts/stage_npm_packages.py codex-cli/scripts/build_npm_package.py` - `python3 -m unittest discover -s scripts/codex_package -p "test_*.py"` - `scripts/stage_npm_packages.py --help` - `codex-cli/scripts/build_npm_package.py --help` - Ran the release-shaped staging command from `rust-release.yml` against workflow run https://github.com/openai/codex/actions/runs/26240748758 with `CI=true` set locally to match GitHub Actions: ```sh CI=true python3 ./scripts/stage_npm_packages.py \ --release-version 0.133.0 \ --workflow-url https://github.com/openai/codex/actions/runs/26240748758 \ --package codex \ --package codex-responses-api-proxy \ --package codex-sdk ``` That completed successfully, downloaded only the six target artifacts once, reused the cache for `codex-responses-api-proxy`, and produced all nine npm tarballs. Generated tarballs and staging/artifact temp dirs were cleaned afterward.
Michael Bolin ·
2026-05-21 20:43:48 +00:00 -
Remove plugin hooks feature flag (#22552)
# Why This is a follow-up stacked on top of the `plugin_hooks` default-on change. Once we are comfortable making plugin hooks part of the normal plugin behavior, the separate feature flag stops buying us much and leaves extra branching/cache state behind. # What - remove the `PluginHooks` feature and generated config-schema entries - make plugin hook loading/listing follow plugin enablement directly - drop plugin-manager cache/state that only existed to distinguish hook-flag toggles - remove tests and fixtures that modeled `plugin_hooks = true/false`
Abhinav ·
2026-05-21 19:15:18 +00:00 -
[codex] Add rollout-backed thread content search (#23519)
## Summary - add experimental `thread/search` for local rollout-backed thread search using `rg` over JSONL rollouts - return search-specific result rows with optional previews instead of storing preview data on `StoredThread` or ordinary `Thread` responses - keep `thread/list` separate from full-content search and document the new app-server surface ## Testing - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-app-server thread_search_returns_content_and_title_matches -- --nocapture`
Francis Chalissery ·
2026-05-21 11:52:24 -07:00