mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
dev
7919 Commits
-
Add environmentId to request_permissions (#25858)
## Stack 1. #25850 - Key request-permission grants by environment: stores and applies sticky permission grants per environment id. 2. This PR (#25858) - Add `environmentId` to `request_permissions`: lets the model target a selected environment and resolves relative permission paths against it. 3. #25862 - Propagate permission approval environment id: carries the selected environment id through approval events, app-server requests, TUI prompts, and delegate forwarding. 4. #25867 - Add remote request permissions integration coverage: verifies the selected remote environment across request, approval, grant reuse, and exec. This PR is stacked on #25850; #25862 and #25867 are stacked on this PR. ## Why PR1 made request-permission grants internally environment-keyed, but the model-facing `request_permissions` tool could still only target the primary environment. For CCA and multi-environment turns, the tool needs an explicit way to bind a permission request to a selected attached environment before resolving relative paths. ## What Changed - Added optional `environmentId` to `RequestPermissionsArgs`, with `environment_id` accepted as an alias. - Exposed `environmentId` in the `request_permissions` tool schema and description. - Resolve the selected environment before parsing filesystem permission paths, so relative paths bind to the selected environment cwd. - Route validated tool calls through `request_permissions_for_environment` directly instead of duplicating environment lookup in `Session::request_permissions`. - Reject unknown environment ids with a model-facing error. - Updated focused request-permissions and Guardian call sites for the new optional field. ## Testing Not run locally per instruction.
jif ·
2026-06-02 20:51:25 +02:00 -
[codex-analytics] Track CodexErr details in turn analytics (#25707)
## Summary - add analytics-only `CodexErr` telemetry to `codex_turn_event` while leaving existing `turn_error` unchanged - record terminal `CodexErr` facts from core immediately before the existing turn error event is sent - emit source-truth `codex_error_*` fields for downstream analytics, including the raw `CodexErr::InvalidRequest(String)` message as `codex_error_subreason` ## Validation - `just test -p codex-analytics` - attempted `just test -p codex-core`, but the local run timed out across unrelated integration suites in this environment and is not being used as validation
rhan-oai ·
2026-06-02 11:40:35 -07:00 -
Key request-permission grants by environment (#25850)
## Stack 1. This PR (#25850) - Key request-permission grants by environment: stores and applies sticky permission grants per environment id. 2. #25858 - Add `environmentId` to `request_permissions`: lets the model target a selected environment and resolves relative permission paths against it. 3. #25862 - Propagate permission approval environment id: carries the selected environment id through approval events, app-server requests, TUI prompts, and delegate forwarding. 4. #25867 - Add remote request permissions integration coverage: verifies the selected remote environment across request, approval, grant reuse, and exec. #25858, #25862, and #25867 are stacked on this PR and should be reviewed after it. ## Why Multi-environment CCA turns can attach both local and remote executors, but request-permission grants were still effectively cwd-only. Pending permission requests tracked a cwd, while stored turn/session grants had no environment identity, so sticky grants could be reused through the wrong executor context. This makes the first permission-grant step environment-aware without changing the external `request_permissions` payload shape: omitted environment targeting remains bound to the primary turn environment. ## What Changed - Store turn- and session-scoped request-permission grants by `environment_id`. - Keep the selected `TurnEnvironmentSelection` with pending `request_permissions` calls so approval responses normalize and record grants against the same environment. - Resolve relative `request_permissions` file paths against the primary turn environment cwd instead of deprecated `turn.cwd`. - Apply sticky grants in `shell`, `exec_command`, and `apply_patch` by selected environment id while still using the actual tool cwd for cwd-relative permission materialization. - Update Guardian and request-permissions coverage for the environment-keyed grant behavior. ## Testing Not run locally. Added or updated focused coverage for: - `request_permission_grants_are_environment_keyed` - `request_permissions_tool_resolves_relative_paths_against_primary_environment` - related Guardian/request-permissions sticky grant tests
jif ·
2026-06-02 20:16:57 +02:00 -
[codex] Revert shared BuildBuddy Bazel wrapper (#25909)
## Why PR #25905 intentionally adds a failing `codex-core` unit test, but its [Bazel test on Windows check](https://github.com/openai/codex/actions/runs/26837526950/job/79135369259) passed. That shows the Bazel configuration introduced by #25156 is not behaving as expected, so revert it while the configuration can be investigated separately. ## What changed Revert #25156 in full, restoring the previous Bazel remote configuration, CI scripts, workflows, `rusty_v8` handling, and documentation. This removes the shared BuildBuddy wrapper and its tests. ## Validation Not run locally; this exact revert was prioritized for a fast rollback.
Adam Perry @ OpenAI ·
2026-06-02 11:06:01 -07:00 -
core: derive built-in permission profiles from raw policies (#25739)
## Why Permission profiles that extend a built-in profile should behave like other TOML inheritance: parent entries provide defaults, and child keys override matching fields before the profile is compiled. That was not true for `:workspace`. Previously, a profile with `extends = ":workspace"` seeded the compiled runtime `PermissionProfile::workspace_write()` policy and then appended child filesystem entries. A child override such as `":tmpdir" = "read"` therefore left the inherited `":tmpdir" = "write"` entry in the final policy. Since same-target `write` wins over `read` during runtime resolution, the child override was ineffective. This also needs a clear source of truth for the built-in profiles. The protocol-level sandbox policy constructors now define the raw built-in filesystem entries, and both `PermissionProfile` presets and config-profile inheritance derive from those same values. ## What Changed - Add a canonical `FileSystemSandboxPolicy::read_only()` constructor while keeping the read-only and workspace-write raw filesystem entries explicit and independent. - Derive `PermissionProfile::read_only()` from `FileSystemSandboxPolicy::read_only()`; `PermissionProfile::workspace_write()` continues to derive from `FileSystemSandboxPolicy::workspace_write()`. - Build extensible `:read-only` and `:workspace` parent profiles by projecting those canonical sandbox policies into `PermissionProfileToml`, then merge user overrides at the TOML layer before compilation. - Add config parsing support for `:slash_tmp` so the built-in `:workspace` parent can be expressed in the same TOML-shaped filesystem table as user profiles. - Document that `PermissionsToml::resolve_profile()` returns an already-merged `PermissionProfileToml`, and return that profile directly after removing the resolved-profile wrapper. - Extend the config test for `extends = ":workspace"` to assert that inherited `":slash_tmp" = "write"` is preserved and that a child `":tmpdir" = "read"` entry replaces the inherited `write` entry. ## Verification - `just test -p codex-config` - `just test -p codex-protocol` - `just test -p codex-core permissions_profiles_resolve_extends_parent_first_with_child_overrides` - `just test -p codex-core default_permissions_profile_can_extend_builtin_workspace` - `just test -p codex-core` - Result: 2596 passed, 4 failed, 1 timed out. - The failures were existing sandbox/environment-sensitive tests unrelated to this permissions change: `suite::user_shell_cmd::user_shell_command_does_not_set_network_sandbox_env_var`, `suite::user_shell_cmd::user_shell_command_history_is_persisted_and_shared_with_model`, `suite::abort_tasks::interrupt_persists_turn_aborted_marker_in_next_request`, `suite::abort_tasks::interrupt_tool_records_history_entries`, and `thread_manager::tests::start_thread_uses_all_default_environments_from_codex_home`.Michael Bolin ·
2026-06-02 10:57:35 -07:00 -
Route Bazel CI through shared BuildBuddy remote config wrapper (#25156)
## Why Bazel remote configuration was selected in several CI scripts and workflow steps. That made the BuildBuddy tenant policy easy to duplicate and harder to audit, especially for fork pull requests that must not use the OpenAI tenant. This builds on [sluongng/buildbuddy-ci-host-routing](https://github.com/openai/codex/compare/main...sluongng:codex:sluongng/buildbuddy-ci-host-routing) and consolidates the policy in one place. ## What to do if this breaks you See `codex-rs/docs/bazel.md` for details. TLDR: 1. make a BuildBuddy API key and put it in `~/.bazelrc` 2. if you're an OpenAI employee, add `common --config=buildbuddy-openai-rbe` to `user.bazelrc` in the repo root Run `just bazel-test` to ensure it works. Note that `just bazel-remote-test` no longer exists, you need to select a remote configuration as documented to use RBE. ## What changed - Add `.github/scripts/run_bazel_with_buildbuddy.py` as the shared Bazel wrapper and Python library. It selects the OpenAI host only for trusted upstream GitHub Actions runs, routes keyed fork runs to the generic host, and falls back to local Bazel execution when no key is available. - Move endpoint selection into explicit `.bazelrc` configurations and update Bazel CI, query helpers, and `rusty_v8` staging to use the shared policy. Loading-phase target-discovery queries remain local. - Add wrapper and `rusty_v8` unit coverage, plus `just test-scripts` for the `.github/scripts` Python tests. - Document local Bazel usage, `user.bazelrc` setup, BuildBuddy configurations, and CI behavior in `codex-rs/docs/bazel.md`. ## Validation - `just test-scripts` - `bash -n .github/scripts/run-bazel-ci.sh .github/scripts/run-bazel-query-ci.sh .github/scripts/run-argument-comment-lint-bazel.sh scripts/list-bazel-clippy-targets.sh` - `python3 -m py_compile .github/scripts/run_bazel_with_buildbuddy.py .github/scripts/test_run_bazel_with_buildbuddy.py .github/scripts/test_rusty_v8_bazel.py .github/scripts/rusty_v8_bazel.py` - `ruff check .github/scripts/run_bazel_with_buildbuddy.py .github/scripts/test_run_bazel_with_buildbuddy.py .github/scripts/test_rusty_v8_bazel.py .github/scripts/rusty_v8_bazel.py`
Adam Perry @ OpenAI ·
2026-06-02 09:56:20 -07:00 -
Skip startup prewarm when websockets are disabled (#25868)
## Summary - skip startup websocket prewarm setup when the model client has Responses-over-WebSocket disabled - avoid making HTTP-only sessions build prewarm prompt/tool state that cannot produce a reusable websocket session ## Why Recent macOS timing flakes were timing out while waiting for first-turn events in HTTP-only core tests. Startup prewarm is only useful for websocket-capable providers, but it was scheduled for every session. For HTTP-only test providers this added unnecessary async startup work before the regular turn could reach the mocked response flow. ## Testing - bazel test //codex-rs/core:core-all-test --test_filter=suite::auto_review::remote_model_override_uses_catalog_model_for_strict_auto_review --test_output=errors - bazel test //codex-rs/core:core-all-test --test_filter=suite::request_permissions_tool::approved_folder_write_request_permissions_unblocks_later_apply_patch --test_output=errors
jif ·
2026-06-02 17:27:30 +02:00 -
[app-server][core] Add connector-level Guardian reviewer overrides (#25167)
Context: https://openai.slack.com/archives/C0B4JAF0Q2C/p1779912328647229 ``` approvals_reviewer = "auto_review" [apps.connector_5f3c8c41a1e54ad7a76272c89e2554fa] enabled = true approvals_reviewer = "user" default_tools_approval_mode = "prompt" ``` <img width="230" height="84" alt="Screenshot 2026-05-31 at 11 56 34 AM" src="https://github.com/user-attachments/assets/e319f8f7-0983-42a7-98cd-3302732fa406" /> <img width="841" height="233" alt="Screenshot 2026-05-31 at 11 52 42 AM" src="https://github.com/user-attachments/assets/7ac76645-4e90-4d00-8242-f031146a22a5" /> ------- ``` approvals_reviewer = "user" [apps.connector_5f3c8c41a1e54ad7a76272c89e2554fa] enabled = true approvals_reviewer = "auto_review" default_tools_approval_mode = "prompt" ``` <img width="195" height="83" alt="Screenshot 2026-05-31 at 12 02 27 PM" src="https://github.com/user-attachments/assets/3d374dc8-8aa2-466f-a13f-e4ed8567aa2e" /> <img width="771" height="207" alt="Screenshot 2026-05-31 at 12 05 42 PM" src="https://github.com/user-attachments/assets/105c2575-68d6-4ca6-8e69-dc8c82da36a2" /> ## Summary - add `apps.<connector_id>.approvals_reviewer` to override Guardian or user review routing per connected app - apply overrides across direct app MCP calls, delegated MCP prompts, and app-server MCP elicitation review while preserving global behavior for non-app MCP servers - expose and document the config through app-server v2 and generated schemas, while honoring global managed reviewer requirements --------- Co-authored-by: jif-oai <jif@openai.com>
Alex Zamoshchin ·
2026-06-02 17:04:11 +02:00 -
[codex] Use git CLI for Cargo fetches across Rust workflows (#25775)
## Why Cargo's libgit2 transport has intermittently failed while fetching git dependencies with nested submodules. [#25644](https://github.com/openai/codex/pull/25644) applied `CARGO_NET_GIT_FETCH_WITH_CLI=true` to the main Rust release build after macOS SecureTransport/libgit2 failures while cloning `libwebrtc`'s nested `libyuv` submodule. Similar flakes can affect other Cargo-bearing Rust jobs. ## What changed Configure `CARGO_NET_GIT_FETCH_WITH_CLI=true` at workflow scope for the remaining Cargo-bearing Rust workflows: - fast Rust CI and `cargo-deny` - reusable Windows and argument-comment-lint release workflows - `rusty-v8-release` and `v8-canary` Cargo builds and smoke tests The full Rust CI, reusable nextest workflow, and primary Rust release build already had the override. Bazel-only workflows are unchanged because they use a different dependency fetch path. ## Validation - Parsed all `.github/workflows/*.yml` files as YAML. - Scanned Cargo-bearing workflows to confirm they configure `CARGO_NET_GIT_FETCH_WITH_CLI`.
Adam Perry @ OpenAI ·
2026-06-02 07:39:41 -07:00 -
Run Codex async main on a sized stack (#25847)
## Why `Runtime::block_on` executes the top-level future on the caller's OS thread, not on one of Tokio's worker threads. That matters for the interactive CLI because the Tokio runtime already configures larger worker stacks, while the process main thread can still have a smaller platform default stack. This showed up as a `/clear` crash on macOS: starting a fresh TUI thread reloads config, and the stack-heavy TOML deserialization path can overflow before the new session is actually started. ## What Changed - Run the regular `arg0_dispatch_or_else` async entrypoint on a named `codex-main` thread. - Give that thread the same `TOKIO_WORKER_STACK_SIZE_BYTES` stack budget already used for Tokio worker threads. - Keep `Arg0DispatchPaths` and the arg0 alias guard lifetime behavior the same. - Resume panics from the spawned main thread so panic behavior is preserved. ## Verification - `cargo check -p codex-cli` currently fails because the top-level CLI/TUI future is not `Send` under the new thread boundary.
jif ·
2026-06-02 16:34:48 +02:00 -
flake: Keep plugin test homes alive (#25857)
## Summary Keep the full `TestCodex` harness alive in plugin integration tests instead of returning only the `CodexThread`. ## Why The helper was moving a temporary `codex_home` into `TestCodex`, then immediately dropping the harness and returning only the thread. For plugin MCP tests, the MCP server cwd is inside that temporary home. If the temp directory is removed while MCP startup is still racing, the server launch can fail with `No such file or directory`. Keeping the harness in scope keeps the temp home alive for the test duration and removes the lifetime race behind the recent `explicit_plugin_mentions_inject_plugin_guidance` flake. ## Validation - `just fmt` - `just test -p codex-core explicit_plugin_mentions_inject_plugin_guidance`
jif ·
2026-06-02 16:21:22 +02:00 -
Reduce stack pressure in session startup and config rebuilds (#25844)
## Why `/clear` starts a fresh thread with `InitialHistory::Cleared`, which re-enters the thread/session startup path. That path now builds large async futures through `ThreadManagerState::spawn_thread_with_source`, `Codex::spawn`, and `Session::new`. Separately, TUI config rebuilds for cwd and permission-profile changes build a similarly heavy `ConfigBuilder::build()` future inside the app task. In debug and Bazel runs, those call chains can put enough state on the caller stack to abort before startup or config refresh completes. This change keeps the behavior the same while moving the heaviest future frames off the caller stack. ## What changed - Box `Codex::spawn(...)` in `codex-rs/core/src/thread_manager.rs` before awaiting it from `spawn_thread_with_source`. - Box `Session::new(...)` in `codex-rs/core/src/session/mod.rs` before awaiting it from `Codex::spawn_internal`. - Route `ConfigBuilder::build()` through a small `tokio::spawn` helper in `codex-rs/tui/src/app/config_persistence.rs` so cwd and permission-profile config rebuilds run on a runtime worker stack while preserving error context. ## Verification CI is running on the PR. No new targeted tests were added. This is a mechanical stack-pressure reduction that keeps the existing behavior and error propagation intact.
jif-oai ·
2026-06-02 15:42:47 +02:00 -
Test runtime selector before first turn (#25724)
Stack split from #25708. Original PR intentionally left open. This fifth PR adds coverage that a remotely selected multi-agent runtime is applied when the model is selected before the first turn.
jif-oai ·
2026-06-02 15:01:10 +02:00 -
Test remote multi-agent runtime selector override (#25723)
Stack split from #25708. Original PR intentionally left open. This fourth PR adds coverage that remote model multi-agent runtime selectors override local feature flag defaults.
jif-oai ·
2026-06-02 14:48:13 +02:00 -
fix: main oops (#25840)
Fix main, comment is self-explainatory
jif-oai ·
2026-06-02 14:48:04 +02:00 -
session: keep startup prewarm aligned with resolved multi-agent runtime (#25841)
## Why Follow-up to #25722. Startup prewarm builds a preview `TurnContext` before the first real turn so it can precompute the initial prompt and tool surface. After the per-thread runtime work landed, that preview path still recomputed multi-agent mode from `model_info` and feature defaults instead of reusing the runtime the session had already resolved from persisted metadata or inheritance. That could leave the prewarmed session primed for a different multi-agent mode than the first real turn, which is especially risky because collaboration tool exposure depends on `turn_context.multi_agent_version`. ## What changed - In the `TurnMultiAgentRuntime::Preview` path, prefer `Session::multi_agent_version()` when it is already known. - Only fall back to `model_info.multi_agent_version` and feature defaults when the session has not resolved a runtime yet. - Keep preview mode read-only: this still avoids storing a runtime during startup prewarm. ## Testing - Not run (small runtime-selection follow-up)
jif-oai ·
2026-06-02 14:35:26 +02:00 -
Resolve per-thread multi-agent runtime (#25722)
Stack split from #25708. Original PR intentionally left open. This third PR resolves the effective per-thread multi-agent runtime from persisted metadata, inherited runtime, and current model selection.
jif-oai ·
2026-06-02 14:31:00 +02:00 -
Persist multi-agent runtime metadata (#25721)
Stack split from #25708. Original PR intentionally left open. This second PR persists multi-agent runtime metadata through thread creation, rollout recording, and thread storage.
jif-oai ·
2026-06-02 13:05:20 +02:00 -
Add multi-agent runtime metadata types (#25720)
Stack split from #25708. Original PR intentionally left open. This first PR adds the multi-agent runtime metadata types and catalog plumbing used by the rest of the stack.
jif-oai ·
2026-06-02 12:10:14 +02:00 -
feat: reuse compressed rollout search snippets (#25814)
## Summary - teach rollout search to return precomputed snippets for compressed rollouts - reuse those snippets in local thread search instead of reopening matching compressed files - keep the no-`rg` fallback single-pass and add regression coverage for the compressed path ## Why `thread/search` currently decodes matching compressed rollouts twice: once to discover the matching path and again to extract the snippet shown in results. That defeats a meaningful part of the compressed-read optimization work. ## Impact Compressed rollout hits now pay one decode pass on the search path while plain `.jsonl` hits keep the existing ripgrep-driven flow. ## Validation - `just test -p codex-rollout` - `just test -p codex-thread-store` - `just fix -p codex-rollout` - `just fix -p codex-thread-store` - `just fmt`
jif-oai ·
2026-06-02 11:32:36 +02:00 -
[codex] Validate plugin skill base names (#25782)
## Summary - Validate skill base name length before plugin namespacing. - Bound the composed `plugin:skill` qualified name to 128 characters. - Keep plugin skill runtime names in the existing `plugin:skill` form. - Add regression tests for the max qualified-name boundary and rejection path. ## Root Cause Plugin skills are represented as `plugin_name:skill_name`, but the loader previously applied the 64-character skill name limit after adding the plugin namespace. Moving that check to the base name fixes valid plugin skills with longer namespaces, and the separate 128-character qualified-name limit keeps model-visible skill names bounded. ## Validation - `just fmt` - `just test -p codex-core-skills plugin_skill_name_length_limit` - `git diff --check`
xl-openai ·
2026-06-02 06:33:02 +00:00 -
[codex] Move plugin discoverable logic into core-plugins (#25783)
## Summary - Move plugin discoverable recommendation filtering from `codex-core` into `codex-core-plugins` behind `ToolSuggestPluginDiscoveryInput`. - Keep `codex-core` as a thin adapter from `Config` to the core-plugins API and back to `DiscoverablePluginInfo`. - Keep the existing discoverable allowlist private to the core-plugins implementation. ## Validation - `just fmt` - `just test -p codex-core list_tool_suggest_discoverable_plugins` - `git diff --check` - Read-only subagent review: no findings
xl-openai ·
2026-06-01 23:25:37 -07:00 -
[codex] Cache remote plugin catalog for suggestions (#25457)
## Summary - cache the global remote plugin catalog when remote plugin listing runs and warm it during startup - use the cached remote catalog in plugin install recommendations with canonical `plugin@openai-curated-remote` ids - reuse the session `PluginsManager` for plugin recommendations so remote cache state is visible on the recommend path - skip core installed-state verification for remote plugin install suggestions while leaving local plugin and connector verification unchanged ## Testing - `just fmt` - `git diff --check` - `cargo test -p codex-core list_tool_suggest_discoverable_plugins_includes_cached_remote_global_plugins` - `cargo test -p codex-core remote_plugin_install_suggestions_skip_core_installed_verification` - `cargo test -p codex-app-server plugin_list_includes_remote_marketplaces_when_remote_plugin_enabled` Earlier focused checks during the same branch: codex-tools TUI filter test, request_plugin_install tests, and codex-app-server build.
xl-openai ·
2026-06-01 22:10:52 -07:00 -
[codex] Add plugin list JSON output (#25330)
## Summary - add `--json` output to `codex plugin list` with `installed` and `available` arrays - add `--available` for JSON output only; using it without `--json` is rejected - keep the existing non-JSON table output unchanged - add CLI coverage for JSON installed/available output and the `--available`/`--json` requirement ## Validation - `just test -p codex-cli plugin_list` - `just fix -p codex-cli` - `git diff --check` Note: `just fmt` ran Rust formatting first, then failed in the Python ruff step because `openai-codex-cli-bin==0.132.0` has no wheel for this Linux platform.
xl-openai ·
2026-06-01 21:27:06 -07:00 -
feat: show enterprise monthly credit limits in status (#24812)
## Summary Enterprise users can have an effective monthly credit limit, but Codex `/status` currently drops that metadata from the account-usage response. This change adds the optional `spend_control.individual_limit` projection to the existing rate-limit snapshot flow. The backend client reads the monthly limit, app-server exposes it as `individualLimit`, and the TUI renders a `Monthly credit limit` row through the existing progress-bar renderer. When the backend does not return an effective monthly limit, existing rate-limit behavior is unchanged. ## Existing backend state The account-usage backend already returns the effective monthly limit and current usage together: ```json { "spend_control": { "reached": false, "individual_limit": { "limit": "25000", "used": "8000", "remaining": "17000", "used_percent": 32, "remaining_percent": 68, "reset_after_seconds": 86400, "reset_at": 1778137680 } } } ``` Before this change, Codex projected rolling `primary` and `secondary` windows plus `credits`. It ignored `spend_control.individual_limit`, so app-server clients and `/status` could not render the monthly cap. The updated flow is: ```text account usage backend -> backend-client reads spend_control.individual_limit -> existing rate-limit snapshot carries optional individual_limit -> app-server exposes optional individualLimit -> TUI renders Monthly credit limit ``` ## App-server contract `account/rateLimits/read` and sparse `account/rateLimits/updated` notifications now include an additive nullable `rateLimits.individualLimit` field: ```json { "individualLimit": { "limit": "25000", "used": "8000", "remainingPercent": 68, "resetsAt": 1778137680 } } ``` In an `account/rateLimits/read` response, `null` means no monthly limit is available. `account/rateLimits/updated` remains a sparse rolling notification: clients merge available values into their most recent `account/rateLimits/read` snapshot or refetch. Nullable account metadata in a rolling notification does not clear a previously observed value. ## Design decisions - Extend the existing rate-limit snapshot instead of introducing a separate request or wire-level update protocol. - Keep the Codex projection narrow: `/status` needs the effective limit, current usage, remaining percentage, and reset timestamp. - Render the monthly row through the existing progress-bar renderer, with one optional detail line for `8,000 of 25,000 credits used`. - Keep the backend response optional so existing accounts and older usage states preserve their current behavior. - Preserve cached monthly metadata when sparse rolling notifications omit it. Live account-usage reads remain authoritative and can clear a removed limit. ## Visual evidence ```text Monthly credit limit: [██████████████░░░░░░] 68% left (resets 07:08 on 7 May) 8,000 of 25,000 credits used ``` Snapshot: `codex-rs/tui/src/status/snapshots/codex_tui__status__tests__status_snapshot_includes_enterprise_monthly_credit_limit.snap` ## Testing Tests: generated app-server schema verification, protocol tests, backend-client tests, app-server integration coverage, TUI snapshot coverage, formatting, and workspace lint cleanup.efrazer-oai ·
2026-06-01 21:25:42 -07:00 -
Move code review rules into AGENTS (#25738)
## Why Codex Review now supports repository-specific review rules in AGENTS.md. Adding the review prompts there makes the guidance available as repository review rules next to the code it governs while keeping the existing local review skills intact. ## What changed - Added a `## Code Review Rules` section to `AGENTS.md` with the existing review prompts for model context, breaking changes, test authoring, and change size. - Preserved the existing `.codex/skills/code-review*` skill files. ## Verification - `git diff --check origin/main...HEAD`
pakrym-oai ·
2026-06-02 01:41:04 +00:00 -
[codex] Add comprehensive root formatting check (#25683)
## Why The root formatting entrypoints could drift: `just fmt` did not format the Justfile itself, and the CI-facing check recipe only checked Python scripts instead of matching everything formatted by `just fmt`. ## What changed - Add a shared cross-platform Python formatter driver used by both `just fmt` and `just fmt-check`. - Run Justfile, Rust, Python SDK, and internal-script formatter groups concurrently while buffering each formatter group's output until it finishes. - Log formatter starts immediately, then print each formatter group's labeled output when it completes. - Keep the SDK lint-fix and Ruff formatting passes ordered, with source comments explaining their distinct roles and the check-mode equivalents. - Run Ruff through shared `uv run --no-sync --with ruff` overlays so formatting works on clean glibc Linux checkouts without installing the platform-specific SDK runtime wheel. - Show `fmt-check` help text in `just -l` and simplify CI to call the shared driver through `just fmt-check`. - Pin the general CI workflow to `just@1.51.0` so its formatter agrees with the checked-in Justfile. - Add regression coverage for the thin Just recipes and the driver's formatter graph. ## Validation - `just fmt` - `just fmt-check` - `python3 -m pytest sdk/python/tests/test_artifact_workflow_and_binaries.py -k 'root_fmt or root_format' -q` - `pnpm run format` - `git diff --check` - `just -l | rg -n '^ fmt|fmt-check'` - `uvx --from uv==0.7.22 uv run --frozen --project sdk/python --no-sync --with ruff ruff check --diff sdk/python`
Adam Perry @ OpenAI ·
2026-06-02 01:20:25 +00:00 -
feat(remote-control): add pairing start (#25675)
## Why Remote control enrollment authorizes a desktop server, but app-server v2 did not expose the follow-up pairing operation needed to mint a short-lived controller pairing artifact from that enrolled server. Clients need a narrow RPC that starts pairing without exposing the backend `serverId` or conflating pairing with websocket connection state. Issue: N/A; internal remote-control pairing API change. ## What Changed Added experimental app-server v2 `remoteControl/pairing/start` with `manualCode` input and `pairingCode`, nullable `manualPairingCode`, `environmentId`, and Unix-seconds `expiresAt` output. The method serializes under its own `global("remote-control-pairing")` scope and is documented in `app-server/README.md`. Extended the remote-control transport with private `/server/pair` request/response types and normalized `pair_url` handling. Pairing uses the current enrolled server bearer, refreshes that bearer when needed, keeps backend `server_id` private, validates returned `server_id` and `environment_id` against the current enrollment, and preserves backend status/header/body context for failures and malformed responses. Wired the request through `RemoteControlRequestProcessor` and `MessageProcessor`, mapping unavailable/disabled pairing to `invalid_request` and backend failures to internal errors. ## Verification - `just test -p codex-app-server-transport` - `just test -p codex-app-server remote_control_pairing_start_returns_pairing_artifacts`Anton Panasenko ·
2026-06-02 01:05:50 +00:00 -
Handle invalid plugin skills manifest field (#25717)
## Summary - Treat invalid `plugin.json` `skills` shapes as a field-level warning instead of rejecting the whole manifest - Keep valid string path behavior unchanged and continue falling back to the default `skills/` root - Add regression coverage for array-shaped `skills` ## Tests - `just fmt` - `cargo test -p codex-core-plugins`
xli-oai ·
2026-06-01 17:19:34 -07:00 -
Move cloud requirements crate to cloud config (#24621)
## Summary - Moves the existing `codex-cloud-requirements` crate to `codex-cloud-config`. - Updates workspace dependencies and imports to the new crate name. - Intentionally keeps runtime behavior unchanged: this still fetches the legacy cloud requirements endpoint. ## Details This PR exists to make the lineage obvious before the bundle migration. GitHub should show the old `codex-rs/cloud-requirements/src/lib.rs` implementation as moved to `codex-rs/cloud-config/src/lib.rs`, rather than as unrelated new code. The follow-up PR adapts this moved crate to the new config bundle API and switches runtime consumers over.
joeflorencio-openai ·
2026-06-01 16:43:52 -07:00 -
app-server: remove experimental persist_extended_history bool flag (#25712)
## Summary Remove the dead experimental `persistExtendedHistory` app-server flag and collapse rollout persistence to the single policy app-server already used. ## What Changed - Removed `persistExtendedHistory` from v2 thread start/resume/fork params and deleted its deprecation notice path. - Removed the persistence-mode enums and plumbing through core, rollout, and thread-store. - Made rollout filtering mode-free, keeping the existing limited persisted-history behavior. ## Test Plan - `just write-app-server-schema` - `cargo nextest run --no-fail-fast -p codex-app-server-protocol schema_fixtures` - `cargo nextest run --no-fail-fast -p codex-app-server thread_shell_command_history_responses_exclude_persisted_command_executions` - `cargo nextest run --no-fail-fast -p codex-rollout -p codex-thread-store` - final `rg` for removed flag/type names
Owen Lin ·
2026-06-01 23:33:42 +00:00 -
Wire managed MITM CA trust into child env (#22668)
## Stack 1. Parent PR: #18240 uses named MITM permissions config. 2. This PR wires managed MITM CA trust into spawned child processes. ## Why When Codex terminates HTTPS for limited mode or MITM hooks, child HTTPS clients need to trust Codex's managed MITM CA. Exporting proxy URLs alone is not enough, but blindly replacing user CA settings would be wrong: it can break custom enterprise/test roots, leak unreadable CA files into generated bundles, or make the child env disagree with its sandbox policy. ## Summary 1. Build immutable managed CA bundles under `$CODEX_HOME/proxy` that include native roots, the managed MITM CA, and only inherited or command-scoped CA bundles the child is allowed to read. 2. Export curated CA env vars alongside managed proxy env vars while preserving user CA override semantics, including nested Codex `SSL_CERT_FILE` precedence. 3. Thread generated CA bundle paths into child sandbox readable roots, including debug sandbox execution, so the exported env vars work inside sandboxed commands. 4. Remove only Codex-generated MITM CA bundle env when a child intentionally drops managed proxying for escalation or no-proxy retry. 5. Document the managed CA bundle behavior and cover env injection, per-child bundle generation, sandbox readable roots, and no-proxy cleanup in tests. ## Validation 1. Ran `just test -p codex-network-proxy`. 2. Ran `just test -p codex-protocol`. 3. Ran `just fix -p codex-network-proxy -p codex-protocol`. 4. Tried focused `codex-core` validation, but the crate currently fails to compile in `core/tests/suite/guardian_review.rs` because an existing `Op::UserInput` initializer is missing `additional_context`. --------- Co-authored-by: Eva Wong <evawong@openai.com>
Winston Howes ·
2026-06-01 23:23:59 +00:00 -
Reject directory rollout paths for pathless side chats (#25661)
## Why Fixes openai/codex#20944. Desktop side chats are intentionally ephemeral and pathless. They can still accept live turns while loaded, but after a reload there is no persisted rollout to resume. In the reported failure mode, Desktop could send `$CODEX_HOME` as the resume/fork path for one of these pathless side chats. `thread/resume` and `thread/fork` prefer an explicit `path` over `threadId`, and rollout path lookup only checked that a candidate existed. That let `$CODEX_HOME` pass as a rollout path, so the later rollout reader tried to open a directory and surfaced the low-level `Is a directory` error. ## What Changed - Reject explicit rollout paths that resolve to a directory or other non-file before attempting to read rollout history. - Make `codex_rollout::existing_rollout_path` return only plain or compressed rollout candidates that are actual files. - Add an app-server regression test that creates an ephemeral fork, runs a turn while the side thread is loaded, simulates reload, then verifies both `thread/resume` and `thread/fork` reject `$CODEX_HOME` with `path is a directory` instead of the OS-level directory-read error. - Rebase over the `TestAppServer` rename and update the remaining stale test harness call sites to use `TestAppServer` with `app_server` local variables. Relevant code: - `thread-store/src/local/read_thread.rs` validates explicit rollout paths before rollout reading: https://github.com/openai/codex/blob/25b47c8f425d351aaba4baa955a8092064a1707b/codex-rs/thread-store/src/local/read_thread.rs#L146-L165 - `rollout/src/compression.rs` now requires file metadata for plain and compressed rollout candidates: https://github.com/openai/codex/blob/25b47c8f425d351aaba4baa955a8092064a1707b/codex-rs/rollout/src/compression.rs#L940-L950 - The repro test covers the pathless ephemeral side-chat reload case: https://github.com/openai/codex/blob/25b47c8f425d351aaba4baa955a8092064a1707b/codex-rs/app-server/tests/suite/v2/thread_fork.rs#L774-L886 ## Verification - `just test -p codex-app-server pathless_ephemeral_thread_rejects_codex_home_path_after_reload`
Michael Bolin ·
2026-06-01 16:02:06 -07:00 -
[codex] Publish release symbol artifacts (#25649)
## Why Production Codex binaries are stripped for distribution, which leaves crashes and samples from released builds without the symbols needed for useful stack traces. Publish symbols as separate release assets so production artifacts stay small while released builds remain symbolicateable. ## What changed - Add `.github/scripts/archive-release-symbols-and-strip-binaries.sh` to package platform-native symbols into `codex-symbols-<artifact>.tar.gz` assets while stripping the corresponding Unix binaries before signing. - Build release binaries with full debug information before producing distribution artifacts. - Publish macOS `.dSYM` bundles, Linux `.debug` files with `.gnu_debuglink`, and Windows `.pdb` files. - Strip Linux `bwrap` before computing its packaged-resource digest, but intentionally omit `bwrap` from symbol archives. - Preserve symbols artifacts in the unsigned macOS promotion flow. ## Verification - Ran `shellcheck` and `bash -n` on `.github/scripts/archive-release-symbols-and-strip-binaries.sh`. - Parsed the modified workflow YAML files and ran `git diff --check`. - Built a macOS release smoke binary and verified that the archived `.dSYM` contains DWARF application source information and has the same UUID as the stripped production binary. - Built Linux smoke binaries and verified that the symbol archive contains `codex.debug`, excludes `bwrap.debug`, leaves the expected `.gnu_debuglink` in `codex`, and does not mutate the separately stripped `bwrap` digest. - Staged a Windows smoke archive and verified that it contains the expected `.pdb` file.
Jeremy Rose ·
2026-06-01 15:49:54 -07:00 -
fix(tui): clarify footer shortcut overlay hints (#25625)
## Why The TUI shortcut overlay used static labels for `Tab` and `Ctrl+C`, even though both keys change behavior while a task is running. That made the visible help misleading: idle `Tab` submits rather than queues, and active-turn `Ctrl+C` interrupts rather than exits. Closes #25531. Closes #25564. ## What Changed - Pass task-running state into the shortcut overlay renderer. - Render `Tab` as `submit message` while idle and `queue message` while work is running. - Render `Ctrl+C` as `exit` while idle and `interrupt` while work is running. - Add snapshot coverage for the active-work shortcut overlay and update idle overlay snapshots. ## How to Test 1. Start Codex and open the shortcut overlay with `?` while no task is running. 2. Confirm the overlay shows `tab to submit message` and `ctrl + c to exit`. 3. Start a task, then open or keep the shortcut overlay visible while work is running. 4. Confirm the overlay shows `tab to queue message` and `ctrl + c to interrupt`. 5. Type a follow-up prompt during active work and press `Tab`; confirm it queues rather than submitting immediately. Targeted tests: - `just test -p codex-tui footer_snapshots` - `just test -p codex-tui footer_mode_snapshots` ## Validation Notes `just test -p codex-tui` currently has two unrelated guardian feature-flag test failures on this base: - `app::tests::update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history` - `app::tests::update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default` `just argument-comment-lint codex-rs/tui/src/bottom_pane/footer.rs` could not run locally because the prebuilt wrapper requires `dotslash`; the touched Rust diff was manually inspected for opaque positional literals.
Felipe Coury ·
2026-06-01 19:41:22 -03:00 -
Move tool search metadata onto ToolExecutor (#25684)
Deferred tools need to be searchable even when they are not implemented inside `codex-core`. Extension-provided tools can be registered for later discovery, but the search metadata path was still owned by core-specific runtime hooks, which meant the shared `ToolExecutor` abstraction could not describe how a deferred extension tool should appear in `tool_search`. ## Changes - Move `ToolSearchEntry` and `ToolSearchInfo` into `codex-tools` and re-export them from the shared tools crate. - Add a default `ToolExecutor::search_info` implementation that derives loadable tool-search metadata from function and namespace specs. - Forward search metadata through extension adapters and exposure overrides while keeping custom search text/source metadata for dynamic, MCP, and multi-agent tools. - Remove the old core-local `tool_search_entry` module now that search metadata lives with the shared executor APIs. ## Testing - Added `deferred_extension_tools_are_discoverable_with_tool_search` coverage in `core/src/tools/spec_plan_tests.rs`.
jif-oai ·
2026-06-02 00:24:41 +02:00 -
Fix stale TestAppServer rename in plugin_list test (#25705)
## Why #25701 renamed the app-server test harness to `TestAppServer`, but it raced with #25681, which added a new `plugin_list` test call site still using the old `McpProcess` name. Once both changes met on `main`, app-server test builds failed before running the suite because `McpProcess` no longer exists in that scope. This PR fixes that CI break by updating the remaining stale call site to the renamed helper. ## What Changed - Replaced the `McpProcess::new(...)` use in `codex-rs/app-server/tests/suite/v2/plugin_list.rs` with `TestAppServer::new(...)`. - Renamed the local variable from `mcp` to `app_server` at the same call site to match the helper rename. Relevant code: https://github.com/openai/codex/blob/aadd9c999b4e0789f7afb2b9b8cc43000bb47e86/codex-rs/app-server/tests/suite/v2/plugin_list.rs#L234-L246 ## Verification Not run locally; this is a compile fix for the app-server test harness rename.
Michael Bolin ·
2026-06-01 15:14:03 -07:00 -
[codex] enable parallel standalone web search calls (#25702)
## Summary - opt the extension-backed standalone `web.run` tool into parallel tool execution - update the existing extension registration test to assert that the tool advertises parallel-call support ## Why The standalone web-search API endpoint now supports parallel requests. The extension executor still inherited the shared serial default, causing multiple `web.run` calls to acquire the exclusive runtime lock. ## Impact Models that emit multiple standalone web-search calls can now execute them concurrently when model-level parallel tool calls are enabled. ## Validation - `just fmt` - `just test -p codex-web-search-extension` - `git diff --check origin/main...HEAD`
sayan-oai ·
2026-06-01 15:04:11 -07:00 -
fix: rename McpServer to TestAppServer (#25701)
This PR brought to you via VS Code rather than Codex... - opened `codex-rs/app-server/tests/common/mcp_process.rs` - put the cursor on `McpServer` - hit `F2` and renamed the symbol to `TestAppServer` - went to the file tree - hit enter and renamed `mcp_process.rs` to `test_app_server.rs` - ran **Save All Files** from the Command Palette - ran `just fmt` The End (Admittedly, most of the local variables for `TestAppServer` are still named `mcp`, though.)
Michael Bolin ·
2026-06-01 21:49:38 +00:00 -
fix: Deduplicate installed local and remote curated plugins (#25681)
## Summary - Deduplicate installed `openai-curated` and `openai-curated-remote` plugin conflicts by feature flag. - Prefer remote when remote plugins are enabled; otherwise prefer local, while preserving one-sided installs. ## Testing - `just fmt` - `git diff --check` - Targeted `just test` was blocked locally because `cargo-nextest` is not installed.
xl-openai ·
2026-06-01 14:27:18 -07:00 -
Add Python version compatibility guidance (#25690)
## Why Python contributions in this repository should target the declared Python 3 runtime instead of carrying Python 2 compatibility patterns forward. When compatibility across Python 3 point releases matters, contributors need a consistent source of truth for the minimum supported version. ## What changed - Added Python development guidance to `AGENTS.md` stating that the repository uses Python 3+ and should not use the `__future__` module. - Documented that contributors should check the nearest `pyproject.toml` `requires-python` field when evaluating Python 3 point-release compatibility. ## Testing Not run (guidance-only change).
Adam Perry @ OpenAI ·
2026-06-01 14:05:54 -07:00 -
[codex] Generalize deferred nested tool guidance (#25689)
## Summary - describe omitted code-mode tools as deferred nested tools instead of MCP/app tools - update the prompt-description assertion to match ## Why Deferred dynamic tools are also callable through `tools` and discoverable in `ALL_TOOLS`, so the previous MCP/app-specific wording was too narrow. ## Validation - `just fmt` - `just test -p codex-code-mode` - `git diff --check`
sayan-oai ·
2026-06-01 21:01:30 +00:00 -
Add rollout compression histograms (#25680)
## Summary Stacked on #25679. Add histogram telemetry for rollout compression runtime, per-file compression time, byte sizes, and compression ratio. ## Changes - Emit `codex.rollout_compression.run.duration_ms` tagged by final run status. - Emit `codex.rollout_compression.file.duration_ms` tagged by file outcome. - Emit source and compressed byte histograms for compression candidates/results. - Emit `codex.rollout_compression.file.compression_ratio` for successful compressions, recorded as integer basis points. ## Validation - `just fmt` - `just test -p codex-rollout` - `just fix -p codex-rollout`
jif-oai ·
2026-06-01 22:54:25 +02:00 -
[codex] document out-of-line test module convention (#25682)
## Why New unit test modules should follow one consistent layout so implementation files stay focused and test suites remain easy to locate, without creating cleanup churn in existing inline test modules. ## What changed - Added `AGENTS.md` guidance requiring new test modules to use separate sibling `*_tests.rs` files with an explicit `#[path = "..._tests.rs"]` attribute. - Clarified that existing inline `#[cfg(test)] mod tests { ... }` modules should not be moved solely to follow the new convention. ## Validation - Ran `git diff --check`.Adam Perry @ OpenAI ·
2026-06-01 13:36:16 -07:00 -
Add rollout compression counters (#25679)
## Summary Add counter telemetry for the local rollout compression worker so we can see when it runs, why it skips, and how individual file/materialization paths resolve. ## Changes - Emit `codex.rollout_compression.run` with statuses for start, completion, failure, duplicate-run skip, and missing runtime skip. - Emit `codex.rollout_compression.file` outcomes for scanned, compressed, skipped, and failed compression candidates. - Emit `codex.rollout_compression.temp_cleanup` and `codex.rollout_compression.materialize` counters for cleanup and decompression paths. ## Validation - `just fmt` - `just test -p codex-rollout` - `just fix -p codex-rollout`
jif-oai ·
2026-06-01 22:26:32 +02:00 -
refactor: hide shell override for zsh fork unified exec (#24980)
## Why When unified exec is configured to launch through the zsh fork, local commands should not let the model override the shell binary with the `shell` parameter. The configured zsh fork is the mechanism that makes `execv(2)` interception reliable, so exposing `shell` for local zsh-fork execution would create a confusing API surface and undermine the composition. Remote environments are different: zsh-fork interception is local-only, so remote unified-exec calls must keep direct unified-exec behavior and still expose `shell` when a remote environment can be selected. ## What Changed - Taught the `exec_command` schema builder to omit the `shell` parameter when requested. - Hid `shell` from the unified-exec tool schema only when zsh-fork unified exec applies to all selectable environments. - Kept `shell` visible when any remote environment can be targeted, because those calls run through direct unified exec. - Made unified exec choose the effective shell mode per selected environment: local environments keep zsh-fork mode, remote environments use direct mode. - Left direct unified-exec behavior unchanged, including support for model-specified shells there. ## Verification - Added schema coverage showing `exec_command` can hide `shell`. - Added planner coverage showing zsh-fork unified exec hides `shell` for local-only execution while direct unified exec still exposes it. - Added planner coverage showing `shell` remains visible when a remote environment is available. - Added handler coverage showing remote environments use direct unified-exec shell mode instead of zsh-fork mode. - Ran the focused `codex-core` shell-parameter and zsh-fork tests. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/24980). * #24982 * #24981 * __->__ #24980
Michael Bolin ·
2026-06-01 20:22:28 +00:00 -
feat: gate unified exec zsh fork composition (#24979)
## Why `shell_zsh_fork` and unified exec need to remain independently controllable for enterprise rollouts, but we also need a third mode that composes them. That composed mode is intended to preserve unified exec command lifecycle support while letting the zsh fork provide more accurate `execv(2)` interception. Enabling `unified_exec_zsh_fork` by itself is intentionally not sufficient. It is a composition gate, not a dependency-enabling shortcut: - `unified_exec` selects the PTY-backed unified exec tool. - `shell_zsh_fork` opts into the zsh fork backend. - `unified_exec_zsh_fork` only allows those two already-enabled modes to be composed so local zsh unified exec commands can launch through the zsh fork. This separation is deliberate. Enterprises and staged rollouts must be able to enable or disable unified exec and zsh-fork independently. If `unified_exec_zsh_fork` implied either dependency, then enabling one under-development composition flag would silently activate a shell backend that the configured feature set left disabled. This PR introduces only the configuration and planning gate for that composition. Existing `shell_zsh_fork` behavior continues to use the standalone shell tool unless the new composition feature is explicitly enabled alongside both dependencies. ## What Changed - Added the under-development feature flag `unified_exec_zsh_fork`. - Added `UnifiedExecFeatureMode` so the three input feature flags collapse into `Disabled`, `Direct`, or `ZshFork` mode before tool planning. - Updated tool selection so zsh-fork composition requires `unified_exec`, `shell_zsh_fork`, and `unified_exec_zsh_fork`. - Kept the existing standalone zsh-fork shell tool behavior when only `shell_zsh_fork` is enabled. - Updated config schema output for the new feature flag. ## Verification - Added feature and tool-config coverage for the new gate. - Added planner coverage proving `shell_zsh_fork` remains standalone until composition is explicitly enabled. - Ran focused tests for `codex-features`, `codex-tools`, and the affected `codex-core` planner case. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/24979). * #24982 * #24981 * #24980 * __->__ #24979
Michael Bolin ·
2026-06-01 13:01:36 -07:00 -
fix: deflake zsh-fork approval test (#25669)
Fixes this flake: https://github.com/openai/codex/actions/runs/26773809591/job/78919970410?pr=25659 This test is about zsh-fork subcommand approval behavior, not workspace sandboxing, so it now runs with `DangerFullAccess` to avoid macOS sandbox setup failures before the second subcommand approval.
jif-oai ·
2026-06-01 21:55:44 +02:00 -
exec-server: canonicalize bound filesystem paths (#25149)
## Summary - add executor filesystem canonicalization as a bound-path operation - route remote canonicalization through the exec-server filesystem RPC surface - keep path normalization attached to the filesystem that owns the path ## Stack - 2/5 in the skills path authority stack extracted from https://github.com/openai/codex/pull/25098 - follows merged https://github.com/openai/codex/pull/25121 ## Validation - `cd /Users/starr/code/codex-worktrees/pr-25098-restack-review-pr1b/codex-rs && just fmt` - Not run: tests/checks (not requested) - GitHub CI pending on rewritten head
starr-openai ·
2026-06-01 11:53:31 -07:00 -
[codex-rs] auto-review model override (#23767)
## Why Guardian auto-review normally uses the provider-preferred review model when one is available. Some parent models need model-catalog metadata to select a different review model while keeping older `/models` payloads compatible when that metadata is absent. ## What changed - Added optional `ModelInfo::auto_review_model_override` metadata to the public model payload as a review-model slug. - Updated Guardian review model selection to prefer the catalog override when present, while preserving the existing provider preferred-model path and parent-model fallback when it is omitted. - Added focused Guardian coverage for override and no-override model selection. - Added an `auto_review` core integration suite test that loads override metadata from a remote model catalog path and asserts the strict auto-review `/responses` request uses the catalog-selected review model. - Updated existing `ModelInfo` fixtures and local catalog constructors for the new optional field. ## Validation - `cargo test -p codex-protocol model_info_defaults_availability_nux_to_none_when_omitted` - `cargo test -p codex-core guardian_review_uses_` - `cargo test -p codex-core remote_model_override_uses_catalog_model_for_strict_auto_review --test all` - `just fix -p codex-protocol` - `just fix -p codex-core` - `just fmt` - `git diff --check`
Won Park ·
2026-06-01 11:51:15 -07:00