mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
rust-v0.143.0
6993
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c4d748f586 |
## New Features
- Remote plugins are now enabled by default, with richer catalog rows, npm marketplace sources, and visible remote/local versions. (#30297, #26705, #29375, #30981) - Codex can route authentication and Responses API traffic through macOS and Windows system proxies, including PAC and WPAD configurations. (#26708, #26709, #31335) - Added `codex remote-control pair` for generating manual pairing codes from a running daemon. (#29913) - Added Amazon Bedrock GPT-5.6 Sol, Terra, and Luna models, with first-class support for `max` reasoning effort. (#30285, #30467) - MCP tools now use tool search by default, and ChatGPT-hosted MCP servers can explicitly use session authentication. (#29486, #29733) - App-server clients can inspect environments, list descendant threads, and fork history through a specific turn. (#30291, #29591, #30277) ## Bug Fixes - Fixed Windows ConPTY input handling for line endings and backspace, plus sandbox credential retry edge cases. (#29734, #29624, #29637) - Fixed stale TUI safety prompts and cancelled reviews that could leave MCP startup appearing busy. (#30490, #31189) - Improved recovery when exec servers are temporarily offline and prevented remote-control token refresh retry storms. (#30098, #30201) - Preserved trailing realtime transcript text and terminal rollout events during shutdown. (#29918, #30144) - Improved incremental WebSocket request success by ignoring response metadata during comparisons. (#30770) - Reduced installer failures from GitHub API rate limits by reusing release metadata. (#31056) ## Documentation - Documented UUID7 thread and turn IDs, plus recommended remote-executor integration-test workflows. (#27714, #29790) ## Chores - Updated OpenSSL, Hono, fast-uri, quick-xml, and crossbeam-epoch to address security advisories. (#29487, #29650, #30941, #31308) ## Changelog Full Changelog: https://github.com/openai/codex/compare/rust-v0.142.0...rust-v0.143.0 - #26708 PAC 3 - Add Windows system proxy resolver @canvrno-oai - #28769 Register full CDP requirements feature @syuan-oai - #29485 [codex] fetch featured IDs for remote plugins @ericning-o - #29487 Upgrade bundled OpenSSL to 3.6.3 @jif-oai - #29489 [codex] Update esbuild to 0.28.1 @pakrym-oai - #29488 [plugins] Add dark-mode logo metadata @drewschuster-openai - #29249 [codex] migrate environment context to model world state @pakrym-oai - #29494 core: wrap token budget window context @bolinfest - #29417 [codex] replace remote images with model-visible error text @rka-oai - #28360 feat(core): store turn_id on ResponseItem metadata @owenlin0 - #29486 [codex] Use tool search for MCP tools by default @sayan-oai - #29501 path-uri: clarify host-native path conversion @anp-oai - #29504 fix: world state response item test @celia-oai - #26704 TUI Plugin Sharing 4 - cover remote plugin catalog flows @canvrno-oai - #29419 [codex] reject remote images at app-server ingress @rka-oai - #28992 chore: improve expired Bedrock credential errors @celia-oai - #29467 Make formatter output quiet on success @anp-oai - #26709 PAC 4 - Add macOS system proxy resolver @canvrno-oai - #29490 chore: warn when Code Mode lacks model metadata @celia-oai - #29493 mcp: accept foreign absolute cwd for remote stdio @anp-oai - #29473 Propagate safety buffering treatment metadata @fc-oai - #24092 [codex] Reject unlowered PowerShell AST regions @bookholt-oai - #29155 [codex] Expose service tier and reasoning effort in OTEL @daniel-oai - #29068 [codex] stylistic changes @rka-oai - #29518 Remove redundant Codex Apps manager flag @aibrahim-oai - #27946 [codex] Use input items for Responses Lite tools @rka-oai - #29528 Centralize Codex Apps client handling @aibrahim-oai - #29577 Handle additional tools in image URL validation @aibrahim-oai - #29575 Remove redundant Codex Apps cache guard @aibrahim-oai - #29583 Group Codex Apps client setup @aibrahim-oai - #29358 Allow codex sandbox to consume MCP sandbox state @jif-oai - #29599 Stop persisting bridged log events @jif-oai - #29615 Fix Codex Apps auth elicitation hang @jif-oai - #29067 Namespace multi-agent v2 tools under collaboration @jif-oai - #29614 path-uri: add lexical containment @jif-oai - #28426 Share resumed rollout history @charliemarsh-oai - #29634 Update rmcp to 1.8.0 @jif-oai - #29650 Update vulnerable Hono and fast-uri dependencies @jif-oai - #29498 [codex] Instrument rollout persistence bytes @wiltzius-openai - #29659 [core] debounce current-time reminders by elapsed time @rka-oai - #29608 Shut down superseded MCP managers on refresh @jif-oai - #29527 core: use turn-owned world state for inline compaction @sayan-oai - #29672 [codex] Handle additional tools in rollout persistence metrics @rka-oai - #29669 Handle additional tools in rollout persistence metrics @winston-openai - #29680 Revert "Handle additional tools in rollout persistence metrics" @rasmusrygaard - #27714 app-server: document thread and turn IDs are UUID7 @owenlin0 - #29456 Prepare managed network sandbox context @jif-oai - #28418 chore(core) rm AskForApproval::OnFailure @dylan-hurd-oai - #29675 core: add extra metadata field to Thread struct @kumquatexpress - #29013 Keep managed MITM CA private keys in proxy memory @winston-openai - #29495 Separate local and remote plugin analytics IDs @jameswt-oai - #29671 [codex] Preserve proxy state for filesystem sandbox helpers @iceweasel-oai - #29513 [codex] allow image generation with provider auth @richardopenai - #29526 core: resolve view_image paths in selected environment @anp-oai - #29696 [codex] Fix stale approval policy in MCP test @sayan-oai - #29704 [codex] Fix stale approval policy in MCP test @kumquatexpress - #29547 core: use current step environments for tools @sayan-oai - #28976 Add MCP tool call error metrics @stevenlee-oai - #27045 feat(guardian): include connected account email in app reviews @viyatb-oai - #29620 Decouple plugin manifest path resolution @jif-oai - #29666 [codex] Report the exec-server working directory @rasmusrygaard - #29705 feat(app-server): thread/turns/items/list -> thread/items/list @owenlin0 - #29716 code-mode: Rename codex_code_mode::CodeModeService @cconger - #29712 test: branch on target OS instead of runner flavor @anp-oai - #29728 core tests: rename automatic environment builder @anp-oai - #29158 path-uri: remove legacy path deserialization @anp-oai - #29519 core: persist initial context window metadata @bolinfest - #28918 Make selected plugin roots URI-native @jif-oai - #29515 [codex] define code mode host handshake protocol @cconger - #29715 [codex] surface rollout budget exhaustion @rka-oai - #29732 code-mode: Remove Session::is_alive() @cconger - #29626 Load executor skills without host path conversion @jif-oai - #29714 protocol: separate app and exec RPC ownership @anp-oai - #29664 refactor: extract context window token status @bolinfest - #29665 fix: scope context remaining to body window @bolinfest - #29744 [codex] rename rollout budget error to session budget error @rka-oai - #29739 Update new_context_window instructions @andmis - #29743 core: reset context for token budget compaction @bolinfest - #29477 Support thread-level originator overrides @alexsong-oai - #29745 core: add wait_for_environment for starting environments @sayan-oai - #28630 [codex] trace MCP startup latency @rphilizaire-openai - #29750 chore: assign `amsg_` IDs to agent messages @bolinfest - #29746 test: add app-server auto environment helper @anp-oai - #29711 Let image generation extension hosts control output persistence @won-openai - #29762 [codex] Reuse compacted history replacement for new context windows @pakrym-oai - #29768 [codex] Update bundled skill installer guidance @sayan-oai - #29690 [plugins] Add marketplace source requirements @xl-openai - #29765 [codex] Ignore local curated plugins when remote catalog is active @xl-openai - #29767 [codex] Assign response item IDs in forked history @pakrym-oai - #29721 auth: move domain mode below app wire types @anp-oai - #29753 [plugins] Enforce marketplace source admission requirements @xl-openai - #29722 config: own layer provenance types @anp-oai - #29723 connectors: own app metadata types @anp-oai - #29788 test: run app-server integration tests under Wine @anp-oai - #29789 test: use automatic environments in app-server integration tests @anp-oai - #29790 docs: document remote executor integration testing @anp-oai - #29815 [codex] Remove auto-compaction opt-out @rhan-oai - #29628 Keep executor plugin MCP paths URI-native @jif-oai - #29731 [codex] Emit implicit skill usage for support reads @alexsong-oai - #29829 Persist agent messages as response items @jif-oai - #29841 Add a bounded filesystem walk RPC @jif-oai - #29842 Use fs/walk for environment skill discovery @jif-oai - #29567 [codex] show external import result counts @charlesgong-openai - #29831 Cache plugin namespace during executor skill discovery @jif-oai - #29720 ci: fail jobs that dirty the worktree @anp-oai - #29887 Fix environment skill discovery after merge @jif-oai - #29734 [codex] fix Windows ConPTY input handling @iceweasel-oai - #28593 [codex] suppress low usage remaining warnings when credits are available @brooks-oai - #29624 Preserve Windows sandbox identity during credential retry @jif-oai - #27466 [codex] Trace exec-server JSON-RPC requests @richardopenai - #29844 Follow directory symlinks in filesystem walks @jif-oai - #29637 Skip credential refresh for WindowsApps launch failures @jif-oai - #29591 feat(app-server): list descendant threads by ancestor @btraut-openai - #28034 feat(network-proxy): experimental local credential broker @winston-openai - #29736 [codex] Inject agent graph store into ThreadManager @wiltzius-openai - #29889 [apps] Thread structured icon assets through app list @drewschuster-openai - #29724 mcp: keep elicitation requests below app wire types @anp-oai - #29684 [plugins] Track plugin install requests by ID @adaley-openai - #29870 Pipeline bounded AGENTS.md and Git root probes @jif-oai - #29893 [codex] dedupe remote control account header @shuo-openai - #29851 Add a connector declaration snapshot @jif-oai - #29903 path-uri: normalize parent segments in absolute joins @anp-oai - #29852 Read connector declarations from executor plugins @jif-oai - #29785 Isolate curated plugin sync Git environment @etraut-openai - #29907 [codex] namespace sleep under clock @rka-oai - #29910 [codex] nest sleep config under current time reminder @rka-oai - #29913 feat(remote-control): add daemon pairing command @apanasenko-oai - #29936 core: add configurable <context_window_guidance> message @bolinfest - #26705 TUI Plugin Sharing 5 - polish remote plugin catalog rows @canvrno-oai - #29733 Allow ChatGPT-hosted MCP servers to use session auth @aibrahim-oai - #29833 [1/3] core: make world state snapshots serializable @sayan-oai - #29919 TUI support for buffer experience @etraut-openai - #29924 Represent MCP authentication with an enum @aibrahim-oai - #29804 code-mode: define process host wire protocol @cconger - #29956 [codex] Populate remote plugin local versions @abhinav-oai - #29835 [2/3] core: persist world state in rollouts @sayan-oai - #29899 [codex] Update reasoning effort @shijie-oai - #29837 [3/3] core: replay persisted world state @sayan-oai - #29969 Report MCP error codes with server attribution @aibrahim-oai - #29970 core: raise token budget message limits @bolinfest - #29973 [codex] route sleep through time providers @rka-oai - #19051 feat: use run agent task auth for inference @adrian-openai - #29810 core: make AGENTS.md react to environment changes @sayan-oai - #29997 core: reconcile legacy WorldState sections @sayan-oai - #29990 Parallelize environment skill loading @anp-oai - #28522 Support HTTP MCP servers from selected executor plugins @jif-oai - #28529 Support OAuth for HTTP MCP servers from selected executor plugins @jif-oai - #29656 Test executor-routed MCP OAuth token exchange @jif-oai - #29928 chore(app-server): mark thread/rollback as deprecated @owenlin0 - #29856 Persist selected capability roots and resolve availability per model step @jif-oai - #27467 [codex] Record exec-server lifecycle metrics @richardopenai - #29942 feat: add provider-aware model fallback to thread start @celia-oai - #30095 cli: rename sandbox permission profile flag @bolinfest - #30029 [codex] current time reminder interval to be set to 0 @rka-oai - #29941 core: expose permission profile to shell tools @bolinfest - #30031 [codex] add current time reminder delivery mode config @rka-oai - #30098 [codex] Retry temporarily offline exec-server recovery @richardopenai - #30033 [codex] impl delivery_mode: current time reminders on response boundaries @rka-oai - #30108 [codex] extend code-mode host IPC transport @cconger - #27470 [codex] Observe remote exec-server lifecycle @richardopenai - #30113 [codex] poll external clock during sleep @rka-oai - #29003 feat(core, mcp): cache codex_apps tools in memory @owenlin0 - #30114 release: publish standalone zsh artifacts @bolinfest - #30116 release: consume standalone zsh artifacts @bolinfest - #29648 [codex] Add managed MCP server matchers @felixxia-oai - #30100 Let extensions contribute World State sections @jif-oai - #30124 fix(app-server): suppress TUI rollback warning @fcoury-oai - #29877 [codex] Surface MCP reauthentication-required startup failures @felixxia-oai - #29988 Recognize Work web and mobile thread originators @chiam-oai - #30110 [codex] add code-mode host failure supervision hooks @cconger - #30088 Project executor skills through World State @jif-oai - #30117 [codex] Propagate traces through exec-server HTTP @wiltzius-openai - #30101 Pin MCP runtimes to model steps @jif-oai - #30134 ci: narrow Windows test skips @anp-oai - #30093 Project selected plugin runtime by environment availability @jif-oai - #30145 Reuse walk inventory for environment skill metadata @jif-oai - #30111 [codex] implement standalone code-mode process host @cconger - #29935 [codex] Attribute app-server analytics by thread originator @alexsong-oai - #30152 Reinject missing World State fragments on resume @jif-oai - #30127 Keep MCP elicitation routable across runtime refreshes @jif-oai - #29934 Expose MCP app identity in app context @martinauyeung-oai - #29909 [codex] allow CCA image generation and web search extensions @won-openai - #30157 Test selected capabilities across availability and resume @jif-oai - #30144 [codex] fix terminal rollout event durability @wiltzius-openai - #29920 Retry failed Codex Apps MCP startup @kbazzi - #29516 Persist Cloudflare affinity cookies for MCP HTTP @stevenlee-oai - #30112 [codex] add process-owned code-mode session client @cconger - #30142 [codex] wire process-owned code mode host into core @cconger - #30198 [codex] fix CreateThreadParams test initializer @anp-oai - #30148 Reuse MCP runtimes when selected availability changes nothing @jif-oai - #30215 Test selected capabilities across unavailable resume @jif-oai - #29991 [codex] narrow unused skills intro export @aibrahim-oai - #30229 Relax hooks.json top-level metadata validation @charlesgong-openai - #29927 feat(app-server): add history_mode to thread @owenlin0 - #30276 fix main @owenlin0 - #29683 [codex] Add managed new-thread model settings @hefuc-oai - #30225 Overlap executor skill reads with namespace discovery @jif-oai - #30274 [codex] allow AGENTS.md and skills to authorize delegation @charlesdu-openai - #30147 [codex] Use managed defaults for TUI threads @hefuc-oai - #30261 ensure thread.history_mode is immutable @owenlin0 - #30277 feat(app-server): add optional turn_id to thread/fork @owenlin0 - #30143 Let Codex consult user-level code-review-* skills. @anp-oai - #30285 feat: add GPT-5.6 variants to Bedrock catalog @celia-oai - #30173 Close thread persistence when submission channel closes @alfozan - #30257 [codex] Classify nested MCP authentication startup errors @felixxia-oai - #29375 [codex] Support npm marketplace plugin sources @charlesgong-openai - #30146 [codex] group blocking and postmerge CI workflows @anp-oai - #30282 feat(protocol): define missing rollout turn items @owenlin0 - #30201 fix(remote-control): avoid server token refresh retry storms @apanasenko-oai - #30273 [codex] consume pushed exec-server process events @richardopenai - #30286 core: overlap diff root discovery with world state @anp-oai - #30314 app-server: structure and test JSON shutdown logs @bolinfest - #30317 Update security check wording @etraut-openai - #30302 Preserve namespaces on custom tool calls @nhamidi-oai - #30327 core: stabilize synthesized call output IDs @bolinfest - #30291 [app-server] expose environment info RPC @maxj-oai - #29691 [plugins] Enforce marketplace source policy at runtime @xl-openai - #30384 [app-server] increase currentTime/read timeout @rka-oai - #30297 [codex] Enable remote plugins by default @xl-openai - #30490 fix(tui): clear completed safety buffering prompt @fcoury-oai - #29740 [codex] Use model metadata for skills usage instructions @ani-oai - #30511 [codex] Restore v1 delegation guidance @aibrahim-oai - #30508 Revert "Make auto-review on-request prompt more proactive" @dylan-hurd-oai - #30467 [codex] Treat max as a first-class reasoning effort @shijie-oai - #30491 Update safety check links @etraut-openai - #30607 [codex] auto-label AWS Bedrock issues @etraut-openai - #30269 [codex] disable Nagle on Rendezvous WebSockets @richardopenai - #30645 [codex] Update safety notice wording @etraut-openai - #30757 fix(core) Remove full text websocket trace @dylan-hurd-oai - #30851 docs: add tag to fenced code block @bolinfest - #30643 [codex] bound Rendezvous WebSocket liveness @richardopenai - #30867 Consolidate multi-agent v2 communication sends @bolinfest - #30872 Log multi-agent communication lifecycle @bolinfest - #30883 [codex] emit per-request TTFT completion telemetry @xli-oai - #30897 Fix inherited availability metadata for Bedrock models @shijie-oai - #30941 fix: address quick-xml security advisories @bolinfest - #30770 fix(websockets) ignore metadata for incremental requests @dylan-hurd-oai - #30334 telemetry: log structured direct tool-call timing @bolinfest - #30493 [codex] Add configurable multi-agent mode hint text @shijie-oai - #30796 Fix MIME types for path-backed feedback attachments @btraut-openai - #31056 fix(install): reuse GitHub release metadata @bolinfest - #30981 [codex] expose remote plugin versions @ericning-o - #31066 chore: remove unused git-cliff configuration @bolinfest - #31064 [codex] Read buffering metadata from response events @fc-oai - #30223 Make plugin guidance react to environment readiness @sayan-oai - #31189 Fix cancelled review leaving MCP startup busy @charliemarsh-oai - #30876 [core] Support interleaved response items @alexi-openai - #31262 [codex] Read retry model from buffering events @fc-oai - #31261 Revert "[core] Support interleaved response items" @alexi-openai - #31253 Emit exec-policy warnings for freshly loaded thread config @etraut-openai - #31179 Remove TUI exec-policy core exports @etraut-openai - #29959 Conditional codex_home dotenv @canvrno-oai - #30627 elicitations: Move to shared ElicitationService @cconger - #30318 core: trace executor skill discovery @anp-oai - #31276 Revert "Conditional codex_home dotenv" @canvrno-oai - #30956 refactor(protocol): isolate legacy item fanout @owenlin0 - #30395 [app-server] Include reset-credit details in rate limits @jayp-oai - #31267 chore(approvals) consolidate guardian calls for shell tools @dylan-hurd-oai - #31252 [tui] Truncate hook context in conversation history @abhinav-oai - #29918 [codex] Flush trailing realtime transcript tail @guinness-oai - #30226 Make Apps guidance react to MCP availability @sayan-oai - #31190 Use popup token ranges for autocomplete insertion @charliemarsh-oai - #29697 fix: attribut network requests to the exact exec on linux @jif-oai - #31303 feat(code-mode): allow disabling V8 JIT @cconger - #31271 chore: use .worktreeinclude for user Bazel config @anp-oai - #31308 fix: update crossbeam-epoch for RUSTSEC-2026-0204 @cconger - #30202 [codex] bundle code mode host in release packages @cconger - #31293 [codex] app-server: expose plugin install policy source @ericning-o - #31318 ci: share common workflow setup @anp-oai - #29992 app-server: cover selected environments in integration tests @anp-oai - #31284 Warn when configured service tiers are unsupported @etraut-openai - #31323 Extract shared HTTP transport into codex-http-client @bolinfest - #31331 Migrate direct HTTP consumers to codex-http-client @bolinfest - #31337 fix: restore Codex environment setup table @anp-oai - #31188 Preserve managed exec policy after rules parse errors @etraut-openai - #31306 [codex] Support sequential cutoff reasoning summaries @ashwinnathan-openai - #31344 exec-server: use virtual time in Noise relay test @bolinfest - #31296 refactor(protocol): map canonical tool items to legacy events @owenlin0 - #31335 core: route Responses API through system proxy @bolinfest |
||
|
|
6afcf26d5d |
core: route Responses API through system proxy (#31335)
## Why `features.respect_system_proxy` already routes authentication traffic through the OS proxy APIs, but it does not affect the primary inference path. That leaves users behind OS-managed proxies unable to send normal Responses API requests even after login succeeds. This PR is the first product-path migration onto the route-aware transport introduced in #31323 and refined in #31331. It also establishes the construction pattern for later migrations: the effective feature state is resolved once into a required HTTP client factory rather than represented by an optional per-call setting. The scope remains limited to the two HTTP Responses endpoints; WebSockets, model discovery, memories, realtime, and file uploads remain follow-up migrations. ## What changed - Replace the optional proxy marker with an explicit `OutboundProxyPolicy::{ReqwestDefault, RespectSystemProxy}` and a required `HttpClientFactory`. The policy has no default, and the lower-level route-aware reqwest builder is now private. - Have `Config` construct the factory from the effective feature state and require every `ModelClient` constructor to receive it. There is no optional setter or implicit `None` fallback. - Build HTTP clients for `/responses` and `/responses/compact` with `ClientRouteClass::Api`, using the complete destination URL so PAC rules can make URL-specific decisions. - Layer route-aware selection onto Codex's existing default headers, Cloudflare cookie store, custom CA handling, and sandbox no-proxy behavior. - Add an integration test that loads `features.respect_system_proxy` through `config.toml`, creates a real Codex session, and verifies that both a normal Responses turn and remote compaction reach an isolated local proxy. ## Review guide 1. `http-client/src/outbound_proxy.rs` defines the mandatory policy/factory boundary and keeps route resolution private. 2. `core/src/config/mod.rs`, `core/src/session/session.rs`, and `core/src/client.rs` show the compile-time invariant: effective config creates the factory, and `ModelClient` cannot be constructed without one. 3. `login/src/auth/default_client.rs` preserves existing default-client behavior while accepting the required factory for migrated routes. 4. `core/src/client.rs` switches only streaming Responses and remote compaction HTTP transports to the API route class. 5. `core/tests/suite/responses_api_system_proxy.rs` is the behavioral regression boundary. Its Linux subprocess deliberately sets the CGI marker that disables reqwest's implicit environment-proxy handling, so the test fails if session wiring or either Responses call site falls back to the default client. ## Test plan - `cargo check --tests -p codex-http-client -p codex-login -p codex-core` - `just test -p codex-login` - `just test -p codex-core respect_system_proxy_feature_resolves_enabled` - Existing `compact_uses_bearer_after_agent_identity_session_fallback` coverage passes with the new transport construction. - New Linux integration coverage: `responses_and_compact_use_enabled_system_proxy` - `just bazel-lock-check` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/31335). * #31342 * __->__ #31335 |
||
|
|
b9b934e99b |
refactor(protocol): map canonical tool items to legacy events (#31296)
## Description This PR adds legacy `EventMsg` mappings for the `TurnItem` types introduced in [#30282](https://github.com/openai/codex/pull/30282): - `CommandExecution` - `DynamicToolCall` - `CollabAgentToolCall` - `SubAgentActivity` When their producers move to canonical `ItemStarted` / `ItemCompleted`, raw core event consumers can still receive the existing begin/end-style events. The canonical item lifecycle remains the live source of truth. We also record the mapped legacy events in rollout trace so the producer migration preserves the existing tool-runtime trace entries. ## Why This is the compatibility layer for the follow-up producer migrations. Splitting it out first keeps each producer PR small and keeps the legacy mapping in one place. ## What changed - Added `TurnItem` → legacy `EventMsg` mappings in `protocol/src/legacy_events.rs`. - Added the command execution status conversion used by the exec mapping. - Added focused coverage for command execution and dynamic tool mappings. |
||
|
|
9365b08467 |
exec-server: use virtual time in Noise relay test (#31344)
## Why `fragmented_writes_yield_to_keepalive_and_queued_pong` deliberately blocks WebSocket writes while exercising keepalive and queued-Pong scheduling. It previously advanced those states with wall-clock sleeps. Under a sufficiently delayed CI worker, those sleeps and scheduling gaps could consume the test-only 100 ms Pong-watchdog budget, causing the relay to exit and the next write-permit send to fail with `TrySendError::Disconnected`. The failure was therefore a timing flake in the harness test, not evidence that the production relay mishandled a Pong. ## What changed - Run this test with Tokio time paused. - Advance the virtual clock through its two keepalive transitions instead of sleeping in wall-clock time. - Enable Tokio's `test-util` feature only for `codex-exec-server` dev dependencies. No production code or timeout values change. ## Review guide The behavioral change is confined to `noise_relay/harness_tests.rs`; the `Cargo.toml` change only exposes Tokio's paused-clock test APIs. ## Validation - `just test -p codex-exec-server fragmented_writes_yield_to_keepalive_and_queued_pong` - `just fix -p codex-exec-server` - `just bazel-lock-update` (no lockfile changes) |
||
|
|
775ef7dcc7 |
[codex] Support sequential cutoff reasoning summaries (#31306)
## Summary When enabled for the OpenAI provider, Codex sends `stream_options.reasoning_summary_delivery = "sequential_cutoff"` on HTTP and WebSocket requests, including prewarm, and renders completed summary sections from `reasoning_summary_text.done`. Flag-off and non-OpenAI behavior is unchanged. ## Expected rollout ```text reasoning 0 added summary 0 done summary 1 done summary 2 starts summary 2 cancelled / incomplete reasoning 0 done <-- cancel summary 2 work and mark it incomplete message 1 added message 1 text streams message 1 completed ``` Depends on [openai/openai#1096660](https://github.com/openai/openai/pull/1096660). |
||
|
|
831c14fc39 |
Preserve managed exec policy after rules parse errors (#31188)
## Why Cleanup for #31179 exposed a core fallback bug that the TUI had been handling locally. When a custom `.rules` file fails to parse, nonfatal clients warn and continue, but `load_exec_policy_with_warning` replaced the entire policy with `Policy::empty()` before managed requirements were merged. App-server and desktop clients could therefore silently lose required prompt and forbidden rules. This fix is intentionally separate from #31179 so the TUI cleanup does not depend on it. ## What changed - Preserve the managed requirements exec policy when custom file rules fail to parse, while returning the existing warning and discarding the file-based policy. - Use the same nonfatal fallback when loading network proxy policy. - Keep parse errors fatal for strict clients such as `codex exec`. |
||
|
|
641aa1b619 |
Migrate direct HTTP consumers to codex-http-client (#31331)
## Why #31323 introduces `codex-http-client` and leaves compatibility re-exports in `codex-client`. Low-level HTTP consumers should depend on the crate that now owns those APIs rather than continuing through the transitional compatibility layer. This stacked follow-up makes that ownership explicit and moves the repository toward enforcing the abstraction without mixing call-site churn into the extraction itself. ## What changed - Switched `codex-backend-client`, `codex-cloud-tasks`, `codex-exec-server`, `codex-login`, and `codex-model-provider` from `codex-client` to `codex-http-client` where they only use low-level HTTP APIs. - Added the direct dependency to `codex-api` for its custom-CA request and websocket paths while retaining `codex-client` for higher-level retry and transport policy. - Updated imports and normalized login's internal client type name from `CodexHttpClient` to `HttpClient`, while preserving its existing `CodexRequestBuilder` re-export. - Updated `Cargo.lock` to reflect the new direct dependency edges. ## Review guide This PR is intentionally mechanical: 20 files and 92 changed lines, with no runtime logic changes. The largest diff is `codex-rs/login/src/auth/default_client.rs`, where the only semantic-looking changes are type and import renames. The remaining source changes replace `codex_client` import paths with `codex_http_client`; the manifest and lockfile changes mirror those imports. ## Test plan - Compile-checked `codex-api`, `codex-backend-client`, `codex-cloud-tasks`, `codex-exec-server`, `codex-login`, and `codex-model-provider` together. |
||
|
|
9acfe8965d |
Extract shared HTTP transport into codex-http-client (#31323)
## Why Codex-owned HTTP construction currently lives in `codex-client` alongside higher-level retry, SSE, and request-telemetry policy. That makes it difficult to apply shared network behavior consistently across crates, particularly system proxy/PAC resolution, custom CA handling, and the ChatGPT Cloudflare cookie policy. It also leaves no clear crate boundary for migrating direct `reqwest` usage behind a single Codex abstraction. This change establishes that low-level ownership boundary without changing request behavior. It builds on the system proxy support introduced in #26706, #26707, #26708, and #26709. ## What changed - Added `codex-rs/http-client` as the `codex-http-client` crate. - Moved request/response types, the concrete `reqwest` transport, custom CA handling, Cloudflare cookie policy, and macOS/Windows proxy resolution into the new crate. - Kept retry, SSE, and request-telemetry policy in `codex-client`. - Re-exported the moved API from `codex-client`, including compatibility aliases for `CodexHttpClient` and `CodexRequestBuilder`, so existing consumers do not change in this PR. - Moved the existing proxy and custom-CA tests with their implementation. ## Scope boundary This PR deliberately stops at the crate extraction. Stacked follow-up #31331 migrates downstream imports from `codex-client` to `codex-http-client`, keeping this change focused on ownership and compatibility rather than mixing in repository-wide call-site churn. ## Review guide GitHub reports 30 changed files, of which 17 are detected renames. A useful review order is: 1. Review the new boundary in `codex-rs/http-client/Cargo.toml` and `codex-rs/http-client/src/lib.rs`. 2. Review `codex-rs/codex-client/Cargo.toml` and `codex-rs/codex-client/src/lib.rs` for what remains in the higher-level crate and how compatibility is preserved. 3. Treat the renamed implementation and test files as moves. Their meaningful edits are limited to crate paths and normalizing the new crate's type names to `HttpClient` and `RequestBuilder`. 4. Review `codex-rs/Cargo.toml`, `codex-rs/Cargo.lock`, and the two `BUILD.bazel` files as mechanical workspace integration. ## Test plan - `just test -p codex-http-client -p codex-client` (38 tests) - Compile-checked the unchanged `codex-api`, `codex-backend-client`, `codex-cloud-tasks`, `codex-exec-server`, `codex-login`, and `codex-model-provider` consumers against the compatibility re-exports. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/31323). * #31331 * __->__ #31323 |
||
|
|
45be435135 |
Warn when configured service tiers are unsupported (#31284)
## Why Codex currently omits a configured `service_tier` when the selected model's catalog entry does not advertise support for it. That fallback is silent, so users can unknowingly send requests at the default tier instead. This makes cases such as #26604 difficult to diagnose. ## What changed - Emit the shared core `Warning` event during session startup when a configured service tier will be omitted because the initial model does not advertise support for it. - Do not warn on later model or service-tier changes, which keeps warning emission stateless and avoids client-specific handling. - Keep the existing request filtering behavior unchanged. ## Validation - `just test -p codex-core unsupported_service_tier` - `just test -p codex-core unsupported_configured_service_tier_warns_at_session_start` ### Manual validation - Launched the real TUI with the bundled catalog, where `gpt-5.5` advertises the `priority` tier but not `flex`, and configured `service_tier = "flex"`. - Confirmed the unsupported-tier warning appeared exactly once during startup. - Submitted two turns through a local Responses API SSE stub; both received mock replies and neither emitted another warning. - Inspected both captured `/v1/responses` request bodies and confirmed that neither contained a `service_tier` field. - Repeated the two-turn TUI flow against the live Responses API; both turns completed and the warning was not repeated. |
||
|
|
8a18312ee5 |
app-server: cover selected environments in integration tests (#29992)
## Why Now that basic cross-OS app/exec support is wired up, it's time to clean up the tech debt of the remote_env_windows test and make sure its test logic is covered in more maintainable feature-specific tests. ## What - Add focused app-server tests for target-native `AGENTS.md` sources and content, plus shell and cwd context, while preserving explicit TODO baselines for the remaining host-scoped metadata. - Add a `TestAppServer` helper that waits for and returns the matching typed turn completion. - Remove redundant app-server coverage and dependencies from `remote_env_windows` while retaining its exec and apply-patch smoke coverage. A follow-up will remove these. ## Validation - `just test -p codex-app-server` - `bazel test //codex-rs/app-server:app-server-all-wine-exec-test --test_output=errors` - `bazel test //codex-rs/core/tests/remote_env_windows:smoke-test --test_output=errors` |
||
|
|
c71895f63b |
[codex] app-server: expose plugin install policy source (#31293)
## Summary - Add `PluginInstallPolicySource` to the app-server v2 `PluginSummary` payload. - Propagate remote `installation_policy_source` through plugin summaries, details, installed-plugin caching, and app-server responses. - Preserve the supported source values and map unrecognized backend values to `null`. - Return `null` for local plugins and expose the field in generated JSON and TypeScript schemas. - Update app-server API documentation and plugin list/read coverage. ## Testing - `just test -p codex-app-server-protocol` (251 passed) - Targeted `codex-app-server` plugin list, installed, and read tests (4 passed) - Targeted `codex-core-plugins` known and unknown policy source tests (2 passed) - `just fmt` - `git diff --check` |
||
|
|
9732b406e7 |
fix: update crossbeam-epoch for RUSTSEC-2026-0204 (#31308)
Bump our crossbeam-epoch dep to fix cargo-deny. |
||
|
|
d61ad78abc |
feat(code-mode): allow disabling V8 JIT (#31303)
We want the option to be able to run code-mode in jitless mode. |
||
|
|
1013295c2d |
fix: attribut network requests to the exact exec on linux (#29697)
## Why Managed-network commands within one Codex conversation share the same HTTP and SOCKS proxy ingress. When several exec calls run concurrently, the proxy sees the requested destination but cannot tell which exec opened the connection. For example: ```text exec A: curl https://example.com/a ─┐ ├─> conversation proxy ─> Guardian exec B: curl https://example.com/b ─┘ host: example.com trigger: unknown ```. Three parallel network execs reached Guardian without their triggering call IDs or commands. Guardian denied the requests, but Codex could not safely associate those outcomes with the individual tool calls. ## What changes Keep the shared proxy ingress and tag each connection at the existing trusted Linux bridge: ```text exec A ─> existing Linux bridge ─> [token A][proxy bytes] ─┐ ├─> shared HTTP/SOCKS ingress exec B ─> existing Linux bridge ─> [token B][proxy bytes] ─┘ │ token A ─> exec A ─────┤ token B ─> exec B ─────┘ ``` The complete path is: ```text active exec registration │ ├─ registers its UUID as a short-lived attribution token ├─ passes the token to the Linux sandbox helper ├─ helper removes the token before launching the user command ├─ existing host bridge prepends the token to each proxy connection ├─ shared proxy consumes the bounded attribution frame └─ proxy attaches the matching execution-scoped state ├─ Guardian receives the exact call ID and command └─ a denial finishes/cancels the matching tool call ``` Dropping the active or deferred exec registration removes the token. Connections that were already accepted retain their resolved attribution; new connections using an expired token fail closed. ## Before and after Before, Guardian could receive only the network destination: ```json { "tool": "network_access", "host": "www.17track.net", "port": 443, "protocol": "https" } ``` After, the same request includes the action that caused it: ```json { "tool": "network_access", "host": "www.17track.net", "port": 443, "protocol": "https", "trigger": { "callId": "exec-network-first", "command": ["/bin/sh", "-c", "curl https://www.17track.net"] } } ``` ## Listener accounting This PR does **not** create proxy listeners per exec. ```text Existing topology: one conversation -> one HTTP listener + optional one SOCKS listener Discarded per-exec approach: one conversation -> existing listener pair + up to one additional listener pair per active exec This PR: one conversation -> existing listener pair only + one small token-map entry per active exec ``` The Linux sandbox already creates a trusted routing bridge for each sandboxed command. This PR adds a short frame write to that bridge rather than introducing another listener, task, or proxy process. The existing conversation-scoped listener pair remains. Making a single proxy service shared across multiple conversations would be a separate multi-tenant architecture change involving per-conversation policy, configuration, audit, and Guardian routing. ## Keeping the implementation small The attribution is bound once, when the TCP connection enters the proxy. The ingress installs an execution-scoped clone of the existing `NetworkProxyState`, so the established HTTP, SOCKS, MITM, policy, audit, and blocked-request paths continue using their existing state lookup. This avoids plumbing a new request-context type through every protocol handler. Outside the two ingress wrappers, protocol-specific request handling is unchanged. ## Security behavior - Tokens are generated from the existing random execution registration IDs. - The trusted Linux helper consumes and removes the token before executing user code. - Attribution frames have a fixed magic prefix, bounded token length, and bounded read timeout. - Unknown or expired tokens close the connection. - A token presented to a proxy for another environment closes the connection. - Existing unframed callers preserve the current conservative attribution behavior. ## Platform scope Exact bridge attribution is enabled on Linux. macOS and Windows retain their current shared-proxy behavior. ## Test coverage The concurrent end-to-end test starts two managed-network execs together and synchronizes them so both are active before either connects. It then inspects the two Guardian requests and compares the complete attribution pairs: ```text (exec-network-first, exact first command) (exec-network-second, exact second command) ``` Focused proxy coverage verifies the bounded frame and that a registered framed connection receives the matching execution and environment state. ## Scope This fixes the Linux network-to-exec attribution path and records a denial against the exact matching tool call. It intentionally does not change: - delivery of an entirely unattributed denial to the parent turn; - how parallel denials count toward the Guardian circuit breaker; - how the UI displays the rejection reason or completed-turn state. Those remain separate concerns from attribution. ## Relationship to #29456 and #29668 #29456 made the proxy environment and sandbox policy come from the same prepared network context. This PR adds the execution token to that prepared launch and consumes it at the shared ingress. This follows #29668's shared-ingress framing direction, but completes the production registration, Linux bridge, core call mapping, denial mapping, and concurrent end-to-end path. It also keeps attribution in the existing per-connection proxy state instead of introducing request-context plumbing through every HTTP, SOCKS, and MITM handler. This PR is intended to supersede #29668 for the Linux attribution fix. --------- Co-authored-by: viyatb-oai <viyatb@openai.com> Co-authored-by: Codex <noreply@openai.com> |
||
|
|
d847857f80 |
Use popup token ranges for autocomplete insertion (#31190)
## Summary Autocomplete popup synchronization already identifies the active token's range and query, but accepting a result previously discarded that range and independently recomputed token boundaries around the cursor. Those calculations could disagree at ambiguous cursor positions. For example, in `@first| @second` (with `|` marking the cursor at the intervening space), the popup targets `@second`, while the old acceptance path replaces `@first`. This threads the active range through legacy file search, skill mentions, and mentions-v2 completion. File, image, and mention insertion now replace the same token that supplied the popup query, and image completion reuses the shared file insertion path. ## Stack This is PR 1 of 3. #31191 builds separator and dismissal behavior on these explicit replacement ranges, and #30463 then fixes token affinity between adjacent mentions. |
||
|
|
3c2bfe7c5d |
Make Apps guidance react to MCP availability (#30226)
## Why Generic Apps guidance is emitted only while building static initial context. If the Apps MCP is unavailable then and recovers later in the same turn, its tools can become usable without the model receiving the guidance for using them. ## What - move generic Apps guidance into a persisted `apps_instructions` World State section - derive availability from the request's MCP runtime while preserving the existing feature, auth, orchestrator-MCP, and config gates - recognize legacy and retained Apps fragments so resume and compaction do not duplicate guidance - register Apps guidance as rollback-trimmable context - remove the old static injection path and its now-unused connector helper - keep tool construction on its existing independent `list_all_tools()` read rather than adding a request-wide cache; a reconnect between the two reads can differ for one request and reconciles on the next request Apps and plugin guidance now render after the remaining static host-skills block, with Apps before Plugins. ## Testing - `just fmt` - `just test -p codex-core apps_instructions` - `just test -p codex-core apps_guidance_appears_after_background_recovery_within_a_turn` - `just test -p codex-core drop_last_n_user_turns_trims_context_updates_above_rolled_back_turn` |
||
|
|
c976741124 |
[codex] Flush trailing realtime transcript tail (#29918)
## Why A realtime session can end after more transcript has accumulated than was included in its last handoff. That tail already lives in core's active transcript state, but the stop path aborted the realtime input/fanout tasks before routing it, so the final bit of the conversation could disappear before `thread/realtime/closed`. This behavior is still being evaluated, so clients must opt in per realtime session. Omitted or false leaves shutdown behavior unchanged. ## What changed - Add optional `flushTranscriptTailOnSessionEnd` to `thread/realtime/start`, defaulting to false in app-server. - Expose an idempotent `take_transcript_tail()` from the existing active transcript state using `last_handoff_entry_count`. - When enabled, let shutdown cancel the input owner cleanly and publish at most one final existing `<realtime_delegation>` with the remaining text in `<transcript_delta>`. - Have the existing fanout drain already-parsed events before routing that final delegation, so a queued handoff wins first and is not duplicated in the tail. - Flush realtime shutdown before ordinary session task abort during core cleanup. ## Validation - `just test -p codex-app-server-protocol` - `just test -p codex-app-server realtime_conversation_stop_emits_closed_notification` - `just test -p codex-core conversation_transport_close_` - `just test -p codex-core conversation_close_routes_only_remaining_transcript_tail_once` - scoped `just fix` for `codex-app-server-protocol`, `codex-app-server`, `codex-protocol`, and `codex-core` - `just fmt` |
||
|
|
02868b9019 | [tui] Truncate hook context in conversation history (#31252) | ||
|
|
aa94ea1397 |
chore(approvals) consolidate guardian calls for shell tools (#31267)
## Summary As part of our effort to start simplifying approvals code, this PR extracts Guardian approvals logic from shell tool calls, and replaces it with the ApprovalAction abstraction instead. This way, tools don't need to know about Guardian at all. ## Testing - [x] Adds integration test |
||
|
|
58ec528315 |
[app-server] Include reset-credit details in rate limits (#30395)
## Why Supported clients currently receive only a reset-credit count from `account/rateLimits/read`. The redemption UI and other app-server clients need each available credit's expiry and ID so they can explain what will expire and consume the credit a user selected. This information belongs on the existing rate-limit read surface rather than a second app-server list RPC that clients would need to coordinate. ## What changed - extend `rateLimitResetCredits` on `account/rateLimits/read` with nullable `credits` detail rows - fetch usage and reset-credit details concurrently; if the detail request fails, times out, or cannot be parsed, preserve the usage response and return `credits: null` - expose each credit's ID, reset type, status, grant time, expiry time, title, and description - add an optional nullable `creditId` to `account/rateLimitResetCredit/consume`; omitting it preserves the existing automatic-selection behavior - forward a selected credit ID to the Codex backend and update the app-server documentation and generated schemas The TUI consumer is stacked in #30488. ## Validation - `just test -p codex-app-server-protocol` (251 passed) - `just test -p codex-backend-client` (16 passed) - `just test -p codex-app-server rate_limit` (18 passed) Part of #29618. |
||
|
|
7affe3e3e4 |
refactor(protocol): isolate legacy item fanout (#30956)
## Stack 1. [#30956](https://github.com/openai/codex/pull/30956) — isolate legacy item fanout ← **this PR** 2. [#30283](https://github.com/openai/codex/pull/30283) — emit canonical `TurnItem` lifecycle 3. [#30188](https://github.com/openai/codex/pull/30188) — persist canonical items for paginated threads ## Description Move legacy `EventMsg` projection code out of the canonical item and protocol schema modules into `protocol/src/legacy_events.rs`. This is a behavior-neutral extraction. It keeps the existing `HasLegacyEvent` API and the existing legacy projections unchanged, while giving compatibility fanout a single home. ## Why Canonical `TurnItem` types and wire event schemas should not own the implementation details for legacy compatibility projections. Isolating that code makes the boundary explicit and keeps follow-up canonical lifecycle work easier to review. |
||
|
|
2e20d2ef44 |
Revert "Conditional codex_home dotenv" (#31276)
## Summary - Revert the conditional `CODEX_HOME` dotenv behavior introduced in #29959. - Restore the previous startup and configuration behavior |
||
|
|
a86d525e4d |
core: trace executor skill discovery (#30318)
## Why Make it easier to measure the performance of different parts of skill loading. ## What - Add spans for step-context capture, world-state construction, executor catalog snapshot/root loading, and environment skill loading. - Record the discovered environment skill count. - Trace outbound exec-server requests with client kind and RPC method fields. - Update trace propagation tests to assert that requests keep the parent trace id while creating their own child span. |
||
|
|
84fe70c30e |
elicitations: Move to shared ElicitationService (#30627)
## Why Code-mode tool results could return to the model while an MCP elicitation was still waiting for user input. This differed from parallel tool calling and could let the model continue before the user resolved the request. We need one session-level view of outstanding elicitations so tool runtimes can consistently hold results until every pending elicitation is resolved. ## What changed - Added a counted, session-owned ElicitationService with RAII registrations. - Registered both core-originated and server-originated MCP elicitations with the service. - Migrated out-of-band elicitation tracking and unified exec timeout pausing to the shared service. - Made code-mode functions.exec and functions.wait capture their runtime result normally, then hold it before returning while an elicitation is outstanding. - Kept terminate: true immediate; only its result is held. - Preserved model-visible wall time across the elicitation hold. - Kept the behavior session-scoped, with concurrent elicitations holding the pause until all registrations are released. |
||
|
|
8268cbfb0e |
Conditional codex_home dotenv (#29959)
## Summary
Adds conditional dotenv overlays under `CODEX_HOME`. After loading the
current `.env`, Codex discovers `.env.*` files in lexicographic order
and applies each overlay when its TCP condition passes.
Evaluation and environment mutation occur during single-threaded
startup, before Codex creates its runtime, workers, sessions, or network
clients.
## Supported behavior
- TCP connectivity checks using either:
- Explicit `host` and `port`.
- A URL or authority stored in an overlay assignment referenced by
`from`.
- Direct negation of a TCP check using `not`.
- Setting dotenv assignments when a condition passes.
- Unsetting variables with `# codex-env-unset`.
- A default 500 ms connection timeout with a maximum of 5 seconds.
- Ignores filenames ending in `~` or a case-insensitive final suffix of
`bak`, `back`, `backup`, `bkp`, `old`, `orig`, `original`, `save`,
`saved`, `disable`, `disabled`, `inactive`, `off`, `tmp`, `temp`, `swp`,
`swo`, `example`, `sample`, `template`, or `dist`.
- Fail-closed handling of malformed overlays without exposing
environment values.
- Case-insensitive protection against setting or unsetting `CODEX_*`
variables.
Files without a `# codex-env-if:` directive as their first non-empty
line are ignored.
## Usage
Set variables when an endpoint is reachable:
```dotenv
# ~/.codex/.env.10-proxy-on
# codex-env-if: {"type":"tcp_connect","from":"HTTPS_PROXY","timeout_ms":500}
HTTPS_PROXY=http://proxy.example.com:8080
HTTP_PROXY=http://proxy.example.com:8080
ALL_PROXY=http://proxy.example.com:8080
NO_PROXY=localhost,127.0.0.1,.example.com
```
Unset variables when the endpoint is unreachable:
```dotenv
# ~/.codex/.env.20-proxy-off
# codex-env-if: {"not":{"type":"tcp_connect","host":"proxy.example.com","port":8080,"timeout_ms":500}}
# codex-env-unset: ["HTTPS_PROXY","HTTP_PROXY","ALL_PROXY","NO_PROXY"]
```
Each overlay is evaluated independently. A full Codex restart is
required after changing overlays or moving between networks.
The timeout bounds TCP connection attempts but does not bound
synchronous DNS resolution.
## Testing
```console
just test -p codex-arg0
```
For manual validation:
1. Configure an overlay with a reachable TCP endpoint and a test
assignment.
2. Start Codex and verify the assignment is present in a spawned
command.
3. Restart Codex with the endpoint unreachable and verify a negated
overlay removes inherited variables.
4. Verify malformed overlays are skipped and `CODEX_*` variables remain
unchanged.
## Future ideas:
- File-existence conditions.
- Environment-variable equality conditions.
- Operating-system conditions.
- General condition composition with `all`, `any`, and arbitrarily
nested `not`.
|
||
|
|
8f5bb6171e |
Remove TUI exec-policy core exports (#31179)
## Why The TUI still reached through `codex_app_server_client::legacy_core` to validate exec-policy rules during local startup. The app server already owns this validation and reports parse failures through `configWarning`, so the duplicate TUI preflight preserved an unnecessary core dependency and could inspect the wrong machine when connected to a remote app server. ## What changed - Remove the TUI's direct exec-policy startup check. - Remove the two exec-policy re-exports from `legacy_core`. - Rely on the app server's existing config-warning flow for malformed custom rules in both embedded and remote sessions. |
||
|
|
dbf67f34a0 |
Emit exec-policy warnings for freshly loaded thread config (#31253)
## Why App-server initialization captures exec-policy parse warnings only once. Each `thread/start` then reloads config for that thread's cwd and rereads its `.rules` files, so rules that become malformed after initialization—or belong to a different project—are dropped without a fresh warning to the requesting client. ## What changed - Validate exec-policy rules against the freshly loaded per-thread config during `thread/start`. - Send the existing structured `configWarning` only to the connection that requested the thread. - Preserve nonfatal startup and avoid repeating an identical warning already delivered during initialization. This is intentionally separate from the TUI `legacy_core` cleanup in #31179 and the managed-requirements fallback fix in #31188. |
||
|
|
7b4e70d567 |
Revert "[core] Support interleaved response items" (#31261)
Reverts openai/codex#30876 |
||
|
|
7094fa467e |
[codex] Read retry model from buffering events (#31262)
## Summary - deserialize `retry_model` from streamed `safety_buffering` payloads - preserve the existing downstream faster-model API and legacy header fallback - update SSE, WebSocket, and end-to-end safety-buffering coverage ## Root cause Follow-up to #31064. The Responses API emits the retry target as `retry_model`, but the client was looking for `faster_model`, so the payload value was ignored in favor of the compatibility fallback. ## Behavior A non-null `retry_model` from the buffering payload takes precedence. An explicit null leaves the retry target unset, while an omitted field continues to fall back to the existing response header. ## Validation - `just test -p codex-api` (135 tests) - `just test -p codex-core safety_buffering` (2 tests) - `just fix -p codex-api` - `just fmt` - `git diff --check` |
||
|
|
8917244f7d |
[core] Support interleaved response items (#30876)
## Summary - preserve reasoning item IDs on summary part and text delta events - track streamed response items by ID so reasoning summaries can continue after later items begin - keep TUI output complete and deduplicated when reasoning and final-answer events interleave ## Stack - **1/2: this PR — interleaved item support** - 2/2: #30752 — wire reasoning summary delivery configuration through the CLI and app-server ## Validation - just test -p codex-api preserves_reasoning_summary_item_ids - just test -p codex-core interleaved_reasoning_summary_events_keep_reasoning_item_metadata - just test -p codex-tui live_reasoning_summary_is_not_rendered_twice_when_item_completes - just fix -p codex-api -p codex-core -p codex-tui - just fmt |
||
|
|
bce481fdcb |
Fix cancelled review leaving MCP startup busy (#31189)
## Summary Cancelling an inline review could leave the TUI stuck in MCP startup state, so subsequent `/review` commands were rejected as though another task were still running. Specifically, the child’s “Starting MCP servers” event was incorrectly forwarded to the parent TUI, so the parent was marking itself as busy. This keeps delegate-session MCP startup events inside the delegate instead of exposing them as parent-session state. ## Reproduction Here's the before -- notice that after I cancel the first review, I'm prevented from running `/review` again: https://github.com/user-attachments/assets/571a0793-3253-4bcc-8f10-3782d176162f And the after -- notice that after I cancel, I can immediately start a new `/review`: https://github.com/user-attachments/assets/dd98b1d7-6a71-4a1f-a4b2-3295bc4848e5 |
||
|
|
9c5be7e1d5 |
Make plugin guidance react to environment readiness (#30223)
## Why Generic plugin guidance is currently emitted only with initial context from host plugin state. An executor-selected plugin can become available later in the same turn, making its skills and tools usable without ever telling the model how plugin capabilities should be used. ## What - project every ready selected plugin package, including skill-only plugins - carry plugin availability with the exact MCP runtime projection while preserving MCP manager reuse when servers and connectors are unchanged - move generic plugin guidance from the static initial-context path into persisted World State - recognize legacy and retained plugin fragments so resume and compaction do not duplicate guidance ## Testing - `just test -p codex-mcp-extension` - `just test -p codex-core plugins_instructions` - `just test -p codex-core plugin_availability_change_reuses_the_mcp_manager` - `just test -p codex-app-server --test all selected_capabilit` |
||
|
|
be33f80bc6 |
[codex] Read buffering metadata from response events (#31064)
## Summary - read optional faster-model metadata from streamed buffering payloads - use the buffering payload itself to determine whether buffering UI should be shown - retain the existing header value as a compatibility fallback when the payload omits the field ## Behavior An object-valued buffering signal now enables the buffering UI. The response event's faster-model field takes precedence when present, while omitted fields fall back to existing response metadata. An explicit null leaves the retry target unset. ## Validation - `just test -p codex-api` - `just fix -p codex-api` - `cargo fmt --all -- --check` - `git diff --check` |
||
|
|
d206a5d68f | [codex] expose remote plugin versions (#30981) | ||
|
|
1f17e7512f |
Fix MIME types for path-backed feedback attachments (#30796)
## Why Path-backed feedback attachments were always labeled `text/plain`, even when the attached file was a gzip archive. Sentry consumers could therefore UTF-8-decode a valid Codex Desktop log bundle and corrupt the transferred bytes before anyone inspected it. Desktop already creates a valid archive and sends its path through `feedback/upload`; the bad metadata was assigned later by app-server's feedback upload path. Slack investigation: https://openai.slack.com/archives/C09NZ54M4KY/p1782867266569699 ## What changed Path-backed feedback attachments now derive their MIME type from the final uploaded filename. Gzip files use `application/gzip`, known text formats remain text, and unrecognized files use the safe `application/octet-stream` fallback. Attachment filenames and bytes are unchanged. ## How it works - **Classify at the upload boundary:** The feedback crate selects MIME metadata after resolving the final filename, including filename overrides. - **Preserve text rollouts:** Codex `.jsonl` rollouts remain `text/plain`, while other known formats use the repository's existing `mime_guess` mapping. - **Protect unknown binaries:** Unrecognized extensions fall back to `application/octet-stream` instead of being treated as UTF-8 text. - **Keep the wire stable:** `feedback/upload` still accepts the same path list, so Desktop, generated protocol surfaces, and remote-host minimums do not change. ## Verification Added focused coverage for gzip MIME, unknown binary fallback, `.jsonl` text handling, and exact filename/byte preservation. Ran the complete `codex-feedback` test suite (9 tests), crate-scoped Clippy, Rust formatting, Bazel lock refresh, and diff checks successfully. |
||
|
|
da4c8ca57d |
[codex] Add configurable multi-agent mode hint text (#30493)
## Why
Multi-agent V2 normally derives its mode instructions from reasoning
effort: Ultra enables proactive delegation, while other efforts require
an explicit request. Some deployments need to provide one configured
delegation policy that replaces those built-ins and remains stable when
reasoning effort changes.
## What changed
- Add `features.multi_agent_v2.multi_agent_mode_hint_text` alongside the
existing root and subagent hint settings.
- Treat any configured value, including an empty string, as
`MultiAgentMode::Custom(hint_text)`, so the configured text replaces the
built-in explicit-only and proactive policies.
- Persist the full custom variant and hint text in the turn-context
snapshot, so the durable comparison baseline detects both
reasoning-effort changes and configured policy-text changes.
- Preserve the existing explicit-only/proactive behavior when the
setting is absent.
- Replace the ambiguous `MultiAgentMode::None` variant with
`MultiAgentMode::Custom(String)` in new rollouts and API schemas. A
compatibility wire type maps legacy serialized `none` values to
`Custom("")` when resuming existing rollouts.
- Regenerate the config and app-server schemas.
## Configuration examples
The distinction is whether `multi_agent_mode_hint_text` is present. An
empty string is still a configured value and intentionally suppresses
the built-in mode instructions.
### Unset: preserve existing effort-derived behavior
```toml
[features.multi_agent_v2]
enabled = true
# multi_agent_mode_hint_text is omitted
```
- Ultra reasoning uses the built-in proactive delegation instructions.
- Other reasoning efforts use the built-in explicit-request-only
instructions.
### Empty: suppress all mode hint text
```toml
[features.multi_agent_v2]
enabled = true
multi_agent_mode_hint_text = ""
```
This selects effective mode `custom` at every reasoning effort and
injects an empty mode body, suppressing both built-in policies.
### Set: always use the configured text
```toml
[features.multi_agent_v2]
enabled = true
multi_agent_mode_hint_text = "Delegate to subagents when it will materially improve the result."
```
This selects effective mode `custom` at every reasoning effort and
injects the configured text verbatim instead of either built-in policy.
## Verification
- `just test -p codex-core multi_agent_mode`
- Covers a configured hint across High and Ultra reasoning efforts and
verifies the full custom hint is recorded for both turns.
- Covers an empty-string override suppressing both built-in instruction
bodies.
- `just test -p codex-protocol -p codex-app-server-protocol`
- Covers legacy `none` turn-context deserialization as `Custom("")` and
verifies the regenerated schemas.
|
||
|
|
beca198b8a |
telemetry: log structured direct tool-call timing (#30334)
## Why App-server deployments can consume structured JSON logs for operational measurements without requiring an OTEL exporter. Existing tool-result telemetry reports the handler outcome, but it does not separate time spent waiting to dispatch from time spent executing the handler. A compact completion event for the outer, direct tool call lets consumers measure those phases and correlate them with a conversation and turn. Code-mode calls are intentionally excluded so nested runtime calls do not create overlapping events that are easy to double-count. ## What changed - Added a [`ToolCallTimingGuard`](https://github.com/openai/codex/blob/141110a73cff041c42fd51f47e363e83df1dde51/codex-rs/core/src/tools/parallel.rs#L32) around direct tool calls. Event-only strings and timing state are captured only when the `codex_core::tools::parallel` `INFO` target is enabled. - Added a [`codex.tool_call`](https://github.com/openai/codex/blob/141110a73cff041c42fd51f47e363e83df1dde51/codex-rs/core/src/tools/parallel.rs#L313) completion event with conversation, turn, tool, call, trace, dispatch, handler, and total timing fields. - Recorded the execution-start marker after the dispatch lock is acquired. Event emission snapshots that marker once so a concurrently starting dispatch cannot produce internally inconsistent fields. - Limited the event to `ToolCallSource::Direct`; [unit coverage](https://github.com/openai/codex/blob/141110a73cff041c42fd51f47e363e83df1dde51/codex-rs/core/src/tools/parallel.rs#L365) verifies code-mode calls are ignored. - Added [cancellation coverage](https://github.com/openai/codex/blob/141110a73cff041c42fd51f47e363e83df1dde51/codex-rs/core/src/tools/parallel.rs#L408) that holds the execution gate and verifies a call cancelled before admission emits exactly one dispatch-only timing event. - Added reusable [`JsonLogCapture`](https://github.com/openai/codex/blob/141110a73cff041c42fd51f47e363e83df1dde51/codex-rs/app-server/tests/common/json_logging.rs#L15) support, a [JSON-logging-specific `TestAppServer` constructor](https://github.com/openai/codex/blob/141110a73cff041c42fd51f47e363e83df1dde51/codex-rs/app-server/tests/common/test_app_server.rs#L172), and an [end-to-end app-server test](https://github.com/openai/codex/blob/141110a73cff041c42fd51f47e363e83df1dde51/codex-rs/app-server/tests/suite/logging.rs#L52) that drives a direct `exec_command` through the public v2 JSON-RPC API and validates the emitted JSON event. Exec-server-specific request and process timing remains in the stacked PR #30901. ## Suggested logging filter ```bash LOG_FORMAT=json \ RUST_LOG='warn,codex_core::tools::parallel=info' \ codex app-server ``` ## Event example Identifier and timing values are illustrative. ### `codex.tool_call` ```json { "timestamp": "2026-06-27T03:45:20.443Z", "level": "INFO", "fields": { "message": "tool call completed", "event.name": "codex.tool_call", "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "conversation.id": "67e55044-10b1-426f-9247-bb680e5fe0c8", "turn_id": "019f04f8-6ac2-78f1-8625-f04a6d35af18", "tool_name": "exec_command", "call_id": "call_7b8483", "tool_source": "direct", "execution_started": true, "dispatch_duration_ms": 12, "handler_duration_ms": 431, "total_duration_ms": 443 }, "target": "codex_core::tools::parallel" } ``` If execution never starts, `execution_started` is `false`, `handler_duration_ms` is `0`, and `dispatch_duration_ms` covers the full observed lifetime. If a duration cannot be represented as an unsigned 64-bit millisecond value, all three duration fields are omitted rather than populated with a sentinel that could corrupt downstream calculations. ## Test plan - `just test -p codex-core tool_call_timing_guard_ignores_code_mode_source` - `just test -p codex-core cancellation_before_dispatch_admission_logs_dispatch_only_timing` - `just test -p codex-app-server app_server_emits_structured_tool_call_timing_event` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/30334). * __->__ #30334 |
||
|
|
b35d4b6b9d |
fix(websockets) ignore metadata for incremental requests (#30770)
## Summary The Responses API may or may not send back metadata on response items. So when comparing request data to the last response, we should discard it and only consider the content. This change results in a higher success rate of incremental requests. Notably, there is one subtle change to the behavior here - we are now ignoring metadata when comparing the previous request items to the new request items as well. This should be fine, since the metadata is explicitly out of scope for the comparison, regardless of whether the item is an item from the request or response. ## Testing - [x] Added unit test coverage for both cases of metadata existence and absence. |
||
|
|
0ccb676dd0 |
fix: address quick-xml security advisories (#30941)
## Why The `cargo-deny` job on `main` began failing after [RUSTSEC-2026-0194](https://rustsec.org/advisories/RUSTSEC-2026-0194) and [RUSTSEC-2026-0195](https://rustsec.org/advisories/RUSTSEC-2026-0195) flagged the workspace `quick-xml 0.38.4`. Both denial-of-service issues are fixed in `quick-xml 0.41.0`. A `quick-xml 0.39.4` copy must temporarily remain because the latest `plist` and `wayland-scanner` releases have not adopted 0.41 yet. Neither retained path accepts attacker-controlled XML at runtime: `plist` does not exercise the affected APIs, and `wayland-scanner` parses trusted protocol definitions at build time. Compatible upstream bumps are already open in [rust-plist#191](https://github.com/ebarnard/rust-plist/pull/191) and [wayland-rs#938](https://github.com/Smithay/wayland-rs/pull/938). ## What changed - Upgrade the workspace `quick-xml` dependency used by `codex-protocol` to 0.41.0. - Refresh `Cargo.lock` and `MODULE.bazel.lock`; this also updates `plist` to 1.9.0 and `wayland-scanner` to 0.31.10. - Add synchronized, temporary `cargo-deny` and `cargo-audit` exceptions for the trusted `quick-xml 0.39.4` paths, with both upstream releases recorded as the removal condition. ## Testing - `cargo deny check` - `just test -p codex-protocol` (238 tests) - `just bazel-lock-check` |
||
|
|
cbdd7f0047 |
Fix inherited availability metadata for Bedrock models (#30897)
## Why Amazon Bedrock's static catalog derives its GPT model definitions from bundled OpenAI model metadata. The GPT-5.6 variants introduced in #30285 clone GPT-5.5, which carries an `availability_nux`; because app-server forwards that metadata through `model/list`, clients can show GPT-5.5 launch copy for a GPT-5.6 Bedrock model. `upgrade` is also model-catalog availability metadata and should not be inherited by provider-specific Bedrock models. ## What changed - Clear `availability_nux` and `upgrade` when constructing static Bedrock GPT models. - Add a regression test asserting that every static Bedrock model omits both fields. ## Testing - `just test -p codex-model-provider` |
||
|
|
6ff670bd03 |
[codex] emit per-request TTFT completion telemetry (#30883)
## Why Codex telemetry pipeline needs a per-request TTFT value. The existing `codex.turn_ttft` is recorded once per turn, so it cannot represent later inference requests in the same turn and can miss the beginning of hidden reasoning. This restores the low-volume per-request signal proposed in https://github.com/bk-nvidia/codex/pull/3 without bringing back per-WebSocket-event TRACE logging. ## What changed - start a timer when each mapped Responses stream begins - latch the timer on the first `response.output_item.added`, including an empty hidden-reasoning item - attach `ttft_ms` to the existing `codex.sse_event` / `response.completed` telemetry record - cover the new completion field with an integration test ## Semantics The value is per inference request, not per turn. It measures mapped-stream-to-first-output-item latency, matching the customer-proposed metric. For HTTP, the stream is already established before timing begins, so request setup and response-header latency are excluded. `response.output_item.added` is a client-visible proxy for the start of hidden reasoning; this does not claim access to the server's internal first raw-token timestamp. ## Validation - `just test -p codex-otel` (47 passed) - `just test -p codex-core process_sse_emits_completed_telemetry` (1 passed after the final timer-placement change) - attempted `just test -p codex-core`: 2,855 passed and 53 failed because of unrelated local-environment failures (missing `test_stdio_server` fixture binary, shell startup noise, and timing-sensitive tests); the focused telemetry test passed in that run as well |
||
|
|
129ea2aaf5 |
Log multi-agent communication lifecycle (#30872)
## Why [#30867](https://github.com/openai/codex/pull/30867) makes `submit_inter_agent_communication` the common outbound sink for multi-agent v2 communications. This follow-up uses that single point to log every communication lifecycle without requiring new hooks as spawn, messaging, follow-up, or result paths evolve. For each communication, the logs need to identify its type, sender and receiver threads, and content, while correlating the successful send with receipt by the destination mailbox. The logging path must not query externally supplied time providers because those calls can be expensive for app-server clients. ## What changed - Added structured `INFO` events on the OpenTelemetry-exported `codex_otel.agent_communication` target for `spawn`, `message`, `followup`, and `result` communications. - Logged successful sends from `submit_inter_agent_communication` with the communication kind, sender and receiver thread IDs, content, and submission ID. - Logged receives after the communication has been enqueued in the receiver mailbox, using the same submission ID. - Avoided time-provider calls and other asynchronous work in the logging path. - Narrowed ordinary spawn and send-input APIs to `Vec<UserInput>` so `Op::InterAgentCommunication` cannot bypass the context-bearing centralized path. The refactor does not change submission IDs, capacity checks, last-task bookkeeping, mailbox ordering, protocol types, rollout data, or model-visible context. ## Event shape Illustrative JSON representation of the two independently emitted records: ```json [ { "event.name": "codex.agent_communication", "communication_id": "019f20e1-40d1-7890-a123-456789abcdef", "kind": "spawn", "state": "send", "sender_thread_id": "019f20df-fbe1-7890-a123-456789abcdef", "receiver_thread_id": "019f20e1-3f79-7890-a123-456789abcdef", "content": "inspect the repository" }, { "event.name": "codex.agent_communication", "communication_id": "019f20e1-40d1-7890-a123-456789abcdef", "state": "receive" } ] ``` Consumers join the receive record to the send record by `communication_id` for the immutable communication metadata. ## Testing - Extended the existing end-to-end multi-agent v2 spawn test to verify content, both thread IDs, and a correlated send/receive submission ID. - Re-ran focused control and handler coverage for direct messages, follow-up tasks, and completion results. |
||
|
|
a98a21798c |
Consolidate multi-agent v2 communication sends (#30867)
## Why Multi-agent v2 communications currently use separate outbound paths: direct messages, follow-up tasks, and completion results go through `send_inter_agent_communication`, while a spawn's initial message goes through the generic input submission path. That split makes it difficult to add complete communication lifecycle logging in one place. This refactor makes `submit_inter_agent_communication` the common sink for those paths, preparing the follow-up observability work discussed in [#30516](https://github.com/openai/codex/pull/30516). ## What changed - Routed all current outbound `InterAgentCommunication` paths in `AgentControl`—direct messages, follow-up tasks, completion results, and multi-agent v2 spawn initial messages—through `submit_inter_agent_communication`. - Centralized the actual submission and last-task-message bookkeeping there, providing one place for the follow-up PR to instrument communication creation and successful enqueue. - Left non-communication input handling and the multi-agent v1 spawn flow unchanged. ## Testing - `just test -p codex-core 'agent::control::tests::'` (51 passed) - `just test -p codex-core 'suite::subagent_notifications::encrypted_multi_agent_v2_spawn_sends_agent_message_to_child'` (passed) --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/30867). * #30872 * __->__ #30867 |
||
|
|
042e61726d |
[codex] bound Rendezvous WebSocket liveness (#30643)
## Summary - require a Pong within 60 seconds for established Noise Rendezvous WebSockets on both the harness and executor - bound steady-state WebSocket writes and harness event delivery so backpressure cannot mask the deadline - classify executor disconnects with bounded reasons and feed them into the existing reconnect metric and structured log - cover silent peers, responsive peers, continuous non-Pong traffic, and local application backpressure ## Why The existing periodic Pings did not track Pongs, so a half-open or blackholed connection could remain stuck until the operating system's TCP timeout. This adds the smallest explicit liveness contract without new spans, RTT histograms, feature flags, or TCP diagnostics. ## Testing - `just test -p codex-exec-server` on devbox `richard-6` — 300 passed, 2 skipped - `just fix -p codex-exec-server` - `just fmt` - independent correctness, performance/security, and YAGNI reviews — no findings |
||
|
|
db887d03e1 |
fix(core) Remove full text websocket trace (#30757)
## Summary This is a follow-up to https://github.com/openai/codex/pull/29432 to remove one additional trace statement that is not being filtered by https://github.com/openai/codex/pull/29457. ## Testing - [x] Unit tests pass |
||
|
|
020828170f |
[codex] Update safety notice wording (#30645)
## Summary The TUI biosafety block still included obsolete copy telling approved researchers they may be able to apply for Trusted Access. Remove that sentence and update the UI snapshot to match the approved wording. |
||
|
|
cfead68e5d |
[codex] disable Nagle on Rendezvous WebSockets (#30269)
## Summary Disable Nagle unconditionally for both exec-server Rendezvous WebSocket connections. - pass `disable_nagle=true` at the executor and harness connection call sites - keep the existing signed URL, protocol, and connection flow unchanged - add no feature flag, rollout schema, path variant, or experiment-specific telemetry The companion internal PR enables `TCP_NODELAY` on accepted Rendezvous sockets: https://github.com/openai/openai/pull/1082463 ## Why Rendezvous carries small, latency-sensitive relay and JSON-RPC frames. Three staging runs of 30 steady-state `process/read` calls per configuration measured p50 improving from 139.1 ms to 81.5 ms and p95 from 162.0 ms to 95.8 ms with Nagle disabled. The expected packet overhead is small at the current connection scale. We will use existing latency, error, packet, and CPU monitoring and revert normally if production regresses. ## Rollout and rollback The client and accepted-socket changes can deploy independently. New connections receive the setting as each side deploys. Rollback is a normal code revert; there is no persisted assignment or gate state to unwind. ## Validation - `just test -p codex-exec-server --lib`: 164 passed - `just fix -p codex-exec-server`: passed - `just fmt`: passed - independent final review found no actionable issue |
||
|
|
9d13291955 |
Update safety check links (#30491)
## Summary Bio/Cyber safety surfaces in the TUI could send users to stale Trusted Access pages, and safety buffering did not always expose the Help Center. This follow-up to #30317 adds the missing Learn more action, refreshes the Bio access URL and block copy, and updates the affected snapshots while preserving the existing retry and wait behavior. |
||
|
|
80f54d1266 |
[codex] Treat max as a first-class reasoning effort (#30467)
## Why The Bedrock GPT-5.6 catalog advertises `max`, but Codex treated it as an opaque custom effort. That made the reasoning picker render it as lowercase `max` while known efforts use productized labels. Making `max` a known effort aligns catalog data, parsing, and UI presentation without changing the `max` wire value or persisted representation. ## What changed - Add first-class `ReasoningEffort::Max` parsing and serialization. - Use the typed effort in the Bedrock catalog and render it as `Max` in the TUI. - Preserve forward-compatible custom-effort coverage with a genuinely unknown `future` value. ### Before <img width="559" height="124" alt="Screenshot 2026-06-28 at 12 08 47 PM" src="https://github.com/user-attachments/assets/7c43cf4f-020b-4605-9239-0a9c97eb7364" /> ### After <img width="558" height="107" alt="Screenshot 2026-06-28 at 12 09 10 PM" src="https://github.com/user-attachments/assets/b9cc5ded-c940-43b4-b024-bba25abe0a17" /> |
||
|
|
ccdfb4f342 |
Revert "Make auto-review on-request prompt more proactive" (#30508)
Reverts openai/codex#26496 |