Commit Graph
5234 Commits
Author SHA1 Message Date
Ahmed Ibrahim 4a3466efbf ## New Features
- Realtime voice sessions now default to the v2 WebRTC path, with configurable transport, voice selection, native TUI media support, and app-server coverage for the new flow (#16960, #17057, #17058, #17093, #17097, #17145, #17165, #17176, #17183, #17188).
- MCP Apps and custom MCP servers gained richer support, including resource reads, tool-call metadata, custom-server tool search, server-driven elicitations, file-parameter uploads, and more reliable plugin cache refreshes (#16082, #16465, #16944, #17043, #15197, #16191, #16947).
- Remote/app-server workflows now support egress websocket transport, remote `--cd` forwarding, runtime remote-control enablement, sandbox-aware filesystem APIs, and an experimental `codex exec-server` subcommand (#15951, #16700, #16973, #16751, #17059, #17142, #17162).
- The TUI can copy the latest agent response with `Ctrl+O`, including better clipboard behavior over SSH and across platforms (#16966).
- `/resume` can now jump directly to a session by ID or name from the TUI (#17222).
- TUI notifications are more configurable, including Warp OSC 9 support and an opt-in mode for notifications even while the terminal is focused (#17174, #17175).

## Bug Fixes

- The TUI starts faster by fetching rate limits asynchronously, and `/status` now refreshes stale limits instead of showing frozen or misleading quota information (#16201, #17039).
- Resume flows are more stable: the picker no longer flashes false empty states, uses fresher thread names, stabilizes timestamp labels, preserves resume hints on zero-token exits, and avoids crashing when resuming the current thread (#16591, #16601, #16822, #16987, #17086).
- Composer and chat behavior are smoother, including fixed paste teardown, CJK word navigation, stale `/copy` output, percent-decoded local file links, and clearer truncated exec-output hints (#16202, #16829, #16648, #16810, #17076).
- Fast Mode no longer stays stuck on after `/fast off` in app-server-backed TUI sessions (#16833).
- MCP status and startup are less noisy and faster: hyphenated server names list tools correctly, `/mcp` avoids slow full inventory probes, disabled servers skip auth probing, and residency headers are honored by `codex mcp-server` (#16674, #16831, #17098, #16952).
- Sandbox, network, and platform edge cases were tightened, including clearer read-only `apply_patch` errors, refreshed network proxy policy after sandbox changes, suppressed irrelevant bubblewrap warnings, a macOS HTTP-client sandbox panic fix, and Windows firewall address handling (#16885, #17040, #16667, #16670, #17053).

## Documentation

- The README now uses the current ChatGPT Business plan name (#16348).
- Developer guidance for `argument_comment_lint` was updated to favor getting CI started instead of blocking on slow local lint runs (#16375).
- Obsolete `codex-cli` README content was removed to avoid stale setup guidance (#17096).
- `codex exec --help` now shows clearer usage and approval-mode wording (#16881, #16888).

## Chores

- `codex-core` was slimmed down through major crate extractions for MCP, tools, config, model management, auth, feedback, protocol, and related ownership boundaries (#15919, #16379, #16508, #16523, #16962).
- Rust CI and workspace guardrails were simplified by blocking new crate features and dropping routine `--all-features` runs (#16455, #16473).
- Core compile times were reduced by removing expensive async-trait expansion from hot tool/task abstractions (#16630, #16631).
- Bazel diagnostics and dependency wiring improved with compact execution logs, repository-cache persistence, remote downloader support, and several platform-specific build fixes (#16577, #16926, #16928, #16634, #16744).

## Changelog

Full Changelog: https://github.com/openai/codex/compare/rust-v0.118.0...rust-v0.119.0

- #16308 fix: one shot end of turn @jif-oai
- #16238 fix: ma2 @jif-oai
- #16317 chore: clean wait v2 @jif-oai
- #16318 nit: update aborted line @jif-oai
- #15771 feat: fork pattern v2 @jif-oai
- #16322 fix: update fork boundaries computation @jif-oai
- #16325 feat: restrict spawn_agent v2 to messages @jif-oai
- #16324 chore: drop interrupt from send_message @jif-oai
- #16345 fix: fix clippy issue caught by cargo but not bazel @bolinfest
- #16184 Route TUI `/feedback` submission through the app server @etraut-openai
- #16330 feat: log db better maintenance @jif-oai
- #15690 [codex-analytics] thread events @rhan-oai
- #16363 Fix PR babysitter review comment monitoring @etraut-openai
- #16356 Refactor external auth to use a single trait @etraut-openai
- #16366 Fix Windows external bearer refresh test @bolinfest
- #16353 ci: verify codex-rs Cargo manifests inherit workspace settings @bolinfest
- #16361 Refactor chatwidget tests into topical modules @etraut-openai
- #16201 Fix stale /status rate limits in active TUI sessions @etraut-openai
- #16351 ci: sync Bazel clippy lints and fix uncovered violations @bolinfest
- #16378 fix: suppress status card expect_used warnings after #16351 @bolinfest
- #16406 Use message string in v2 spawn_agent @jif-oai
- #16409 Use message string in v2 send_message @jif-oai
- #16419 Use message string in v2 assign_task @jif-oai
- #16424 feat: tasks can't be assigned to root agent @jif-oai
- #16425 nit: update wait v2 desc @jif-oai
- #16426 chore: interrupted as state @jif-oai
- #16427 nit: deny field v2 @jif-oai
- #16433 chore: drop log DB @jif-oai
- #16434 feat: auto vaccum state DB @jif-oai
- #16422 fix(core) rm execute_exec_request sandbox_policy @dylan-hurd-oai
- #16375 docs: update argument_comment_lint instructions in AGENTS.md @bolinfest
- #16449 fix: remove unused import @bolinfest
- #15772 Make fuzzy file search case insensitive @meyers-oai
- #16455 ci: block new workspace crate features @bolinfest
- #16456 cloud-tasks: split the mock client out of cloud-tasks-client @bolinfest
- #16457 tui: remove debug/test-only crate features @bolinfest
- #16467 tui: remove the voice-input crate feature @bolinfest
- #16379 Extract tool config into codex-tools @bolinfest
- #16469 otel: remove the last workspace crate feature @bolinfest
- #16471 Extract tool spec helpers into codex-tools @bolinfest
- #16473 ci: stop running rust CI with --all-features @bolinfest
- #16477 Extract tool discovery helpers into codex-tools @bolinfest
- #16480 login: treat provider auth refresh_interval_ms=0 as no auto-refresh @bolinfest
- #16448 fix(guardian): make GuardianAssessmentEvent.action strongly typed @owenlin0
- #16481 Extract update_plan tool spec into codex-tools @bolinfest
- #15919 Extract MCP into codex-mcp crate @aibrahim-oai
- #16482 Remove client_common tool re-exports @bolinfest
- #16495 fix: remove unused import @bolinfest
- #16493 Extract built-in tool spec constructors into codex-tools @bolinfest
- #16273 Fix regression: "not available in TUI" error message @etraut-openai
- #16497 Extract tool-search output helpers into codex-tools @bolinfest
- #16498 fix: guard guardian_command_source_tool_name with cfg(unix) @bolinfest
- #16499 Extract tool-suggest wire helpers into codex-tools @bolinfest
- #16284 Fix TUI app-server permission profile conversions @etraut-openai
- #16202 Fix paste-driven bottom pane completion teardown @etraut-openai
- #16504 core: use codex-tools config types directly @bolinfest
- #16503 Extract request_user_input normalization into codex-tools @bolinfest
- #16510 core: use codex-mcp APIs directly @bolinfest
- #16509 Extract code-mode nested tool collection into codex-tools @bolinfest
- #16512 core: remove cross-crate re-exports from lib.rs @bolinfest
- #16516 fix: add update to Cargo.lock that was missed in #16512 @bolinfest
- #16513 Extract tool registry planning into codex-tools @bolinfest
- #16521 Move tool registry plan tests into codex-tools @bolinfest
- #16523 [codex] Move config types into codex-config @bolinfest
- #16524 fix: move some test utilities out of codex-rs/core/src/tools/spec.rs @bolinfest
- #16529 [codex] Remove codex-core config type shim @bolinfest
- #16559 chore: memories mini model @jif-oai
- #16561 fix: race pending @jif-oai
- #16564 nit: lint @jif-oai
- #16566 fix: races in end of turn @jif-oai
- #16567 chore: rework state machine further @jif-oai
- #16569 nit: state machine desc @jif-oai
- #16571 chore: rename assign_task for followup_task @jif-oai
- #16577 ci: upload compact Bazel execution logs for bazel.yml @bolinfest
- #16581 chore: move codex-exec unit tests into sibling files @bolinfest
- #16590 Fix non-determinism in rules_rs/crate_git_repository.bzl @tyler-french
- #16604 test: deflake external bearer auth token tests on Windows @bolinfest
- #16606 fix: add more detail to test assertion @bolinfest
- #16608 fix: increase timeout to account for slow PowerShell startup @bolinfest
- #16591 Fix resume picker initial loading state @etraut-openai
- #16613 fix: increase another startup timeout for PowerShell @bolinfest
- #16601 Fix resume picker stale thread names @etraut-openai
- #16616 Fixed some existing labels and added a few new ones @etraut-openai
- #16588 Fix stale turn steering during TUI review follow-ups @etraut-openai
- #16617 fix: add shell fallback paths for pwsh/powershell that work on GitHub Actions Windows runners @bolinfest
- #16596 Fix fork source display in /status (expose forked_from_id in app server) @etraut-openai
- #16578 fix(tui): handle zellij redraw and composer rendering @fcoury-oai
- #16630 core: cut codex-core compile time 63% with native async ToolHandler @bolinfest
- #16631 core: cut codex-core compile time 48% with native async SessionTask @bolinfest
- #16492 Auto-trust cwd on thread start @aibrahim-oai
- #16633 fix: address unused variable on windows @bolinfest
- #16635 app-server: make thread/shellCommand tests shell-aware @bolinfest
- #16629 test: use cmd.exe for ProviderAuthScript on Windows @bolinfest
- #16634 build: fix Bazel lzma-sys wiring @starr-openai
- #16658 Fix deprecated login --api-key parsing @etraut-openai
- #16508 extract models manager and related ownership from core @aibrahim-oai
- #16662 fix: changes to test that should help them pass on Windows under Bazel @bolinfest
- #16665 fix: use COMSPEC in Windows unicode shell test @bolinfest
- #16668 fix: use cmd.exe in Windows unicode shell test @bolinfest
- #16626 remove temporary ownership re-exports @aibrahim-oai
- #16648 Fix stale /copy output after commentary-only turns @etraut-openai
- #16674 Fix MCP tool listing for hyphenated server names @etraut-openai
- #16667 Suppress bwrap warning when sandboxing is bypassed @etraut-openai
- #16670 Fix macOS sandbox panic in Codex HTTP client @etraut-openai
- #16699 Fix macOS malloc diagnostics leaking into TUI composer @etraut-openai
- #16700 Add remote --cd forwarding for app-server sessions @etraut-openai
- #16707 fix: preserve platform-specific core shell env vars @bolinfest
- #16715 fix: address clippy violations that sneaked in @bolinfest
- #16722 fix windows-only clippy lint violation @bolinfest
- #16710 fix(tui): sort skill mentions by display name first @fcoury-oai
- #16709 Sanitize forked child history @aibrahim-oai
- #16711 Fix Windows Bazel app-server trust tests @bolinfest
- #16720 Remove OPENAI_BASE_URL config fallback @etraut-openai
- #16528 Codex/windows bazel rust test coverage no rs @bolinfest
- #16450 bazel: lint rust_test targets in clippy workflow @bolinfest
- #16735 [codex] allow disabling prompt instruction blocks @tibo-openai
- #16745 [codex] allow disabling environment context injection @tibo-openai
- #16725 Preempt mailbox mail after reasoning/commentary items @aibrahim-oai
- #16755 Use Node 24 for npm publish @aibrahim-oai
- #16753 [codex] add responses proxy JSON dumps @tibo-openai
- #16746 Add spawn context for MultiAgentV2 children @aibrahim-oai
- #16757 Back out "bazel: lint rust_test targets in clippy workflow (#16450)" @bolinfest
- #16737 test: avoid PowerShell startup in Windows auth fixture @bolinfest
- #16740 ci: align Bazel repo cache and Windows clippy target handling @bolinfest
- #16758 [codex] add context-window lineage headers @tibo-openai
- #16763 Add CODEX_SKIP_VENDORED_BWRAP @andmis
- #15915 [codex-analytics] subagent analytics @rhan-oai
- #16823 Fix flaky test relating to metadata remote URL @etraut-openai
- #16825 Fix flaky permissions escalation test on Windows @etraut-openai
- #16881 Fix misleading codex exec help usage @etraut-openai
- #16888 Clarify `codex exec` approval help @etraut-openai
- #16876 [codex] add response proxy subagent header test @tibo-openai
- #16829 Fix CJK word navigation in the TUI composer @etraut-openai
- #16833 Fix TUI fast mode toggle regression @etraut-openai
- #16795 [regression] Fix ephemeral turn backfill in exec @etraut-openai
- #16822 Fix resume picker timestamp labels and stability @etraut-openai
- #16813 Annotate skill doc reads with skill names @etraut-openai
- #16810 (tui): Decode percent-escaped bare local file links @etraut-openai
- #16877 [codex-backend] Make thread metadata updates tolerate pending backfill @joeytrasatti-openai
- #16701 feat(requirements): support allowed_approval_reviewers @owenlin0
- #16925 fix(bazel): fix simdutf @owenlin0
- #16926 bazel: Always save bazel repository cache @euroelessar
- #16928 bazel: Enable `--experimental_remote_downloader` @euroelessar
- #16462 fix(guardian): fix ordering of guardian events @owenlin0
- #16924 fix(sqlite): don't hard fail migrator if DB is newer @owenlin0
- #16744 build: restore lzma-sys Bazel wiring for devbox codex run @starr-openai
- #16764 app-server: centralize AuthManager initialization @euroelessar
- #16939 Fix clippy warning @mzeng-openai
- #16923 Revert "[codex-backend] Make thread metadata updates tolerate pending backfill" @joeytrasatti-openai
- #15951 app-server: Add egress websocket transport @euroelessar
- #16945 [codex] Allow PyTorch libomp shm in Seatbelt @viyatb-oai
- #16947 feat: fallback curated plugin download from backend endpint. @xl-openai
- #16191 feat: refresh non-curated cache from plugin list. @xl-openai
- #16952 Respect residency requirements in mcp-server @etraut-openai
- #16827 tui: route device-code auth through app server @etraut-openai
- #16638 [codex-analytics] add protocol-native turn timestamps @rhan-oai
- #16831 Speed up /mcp inventory listing @etraut-openai
- #16349 Disable env-bound tools when exec server is none @starr-openai
- #16957 Promote image_detail_original to experimental @fjord-oai
- #16962 Refactor config types into a separate crate @pakrym-oai
- #16153 Add setTimeout support to code mode @pakrym-oai
- #16961 app-server: Unify config changes handling a bit @euroelessar
- #16890 Validate exec input before starting app-server @etraut-openai
- #16082 [mcp] Support MCP Apps part 1. @mzeng-openai
- #15893 fix: warn when bwrap cannot create user namespaces @viyatb-oai
- #16946 [codex] Add danger-full-access denylist-only network mode @viyatb-oai
- #16972 app-server: Fix compilation of a test in mcp_resource @euroelessar
- #15826 Make AGENTS.md discovery FS-aware @pakrym-oai
- #16964 Honor null thread instructions @aibrahim-oai
- #16988 collapse dev message into one @won-openai
- #16724 [codex] ez - rename env=>request in codex-rs/core/src/unified_exec/process_manager.rs @starr-openai
- #16999 feat: empty role ok @jif-oai
- #17002 chore: debug flag to hide some parameters @jif-oai
- #17005 feat: drop agent ID from v2 @jif-oai
- #17008 chore: send_message and followup_task do not return anything @jif-oai
- #17007 chore: hide nickname for debug flag @jif-oai
- #16442 feat: /feedback cascade @jif-oai
- #16978 [codex] reduce module visibility @pakrym-oai
- #17009 chore: keep request_user_input tool to persist cache on multi-agents @jif-oai
- #16739 Stabilize flaky multi-agent followup interrupt test @etraut-openai
- #16885 Fix read-only apply_patch rejection message @etraut-openai
- #16882 Fix nested exec thread ID restore @etraut-openai
- #16976 Preserve null developer instructions @aibrahim-oai
- #16987 Fix missing resume hint on zero-token exits @etraut-openai
- #16912 feat(analytics): generate an installation_id and pass it in responsesapi client_metadata @owenlin0
- #16956 fix(guardian): don't throw away transcript when over budget @owenlin0
- #16981 [codex] Make AbsolutePathBuf joins infallible @pakrym-oai
- #16348 Update README @romainhuet
- #16977 [codex] Make unified exec tests remote aware @pakrym-oai
- #16465 [mcp] Support MCP Apps part 2 - Add meta to mcp tool call result. @mzeng-openai
- #17026 app-server: Move watch_id to request of fs/watch @euroelessar
- #16980 Add full-ci branch trigger @pakrym-oai
- #16973 app-server: Allow enabling remote control in runtime @euroelessar
- #17032 [codex] Fix unified exec test build @pakrym-oai
- #17031 fix(core) revert Command line in unified exec output @dylan-hurd-oai
- #17027 [codex] Migrate apply_patch to executor filesystem @pakrym-oai
- #17044 [app-server-protocol] introduce generic ServerResponse for app-server-protocol @rhan-oai
- #17047 fix(app-server) revert null instructions changes @dylan-hurd-oai
- #16960 Add WebRTC transport to realtime start @aibrahim-oai
- #17053 Fix remote address format to work with Windows Firewall rules. @iceweasel-oai
- #17048 [codex] Apply patches through executor filesystem @pakrym-oai
- #16949 Use model metadata for Fast Mode status @pash-openai
- #17039 fix(tui): reduce startup and new-session latency @fcoury-oai
- #17052 Add regression tests for JsonSchema @vivi
- #17059 Add remote exec start script @pakrym-oai
- #17064 Add project-local codex bug triage skill @etraut-openai
- #17040 fix: refresh network proxy settings when sandbox mode changes @viyatb-oai
- #16698 Remove expired April 2nd tooltip copy @etraut-openai
- #17096 Remove obsolete codex-cli README @etraut-openai
- #16875 Support anyOf and enum in JsonSchema @vivi
- #16880 Render function attribute descriptions @vivi
- #16879 Render namespace description for tools @vivi
- #16582 feat: single app-server bootstrap in TUI @jif-oai
- #17117 codex debug 1 (guardian approved) @jif-oai
- #17119 codex debug 3 (guardian approved) @jif-oai
- #17121 codex debug 5 (guardian approved) @jif-oai
- #17123 codex debug 7 (guardian approved) @jif-oai
- #17125 codex debug 9 (guardian approved) @jif-oai
- #17127 codex debug 11 (guardian approved) @jif-oai
- #17129 codex debug 13 (guardian approved) @jif-oai
- #17131 codex debug 15 (guardian approved) @jif-oai
- #17118 codex debug 2 (guardian approved) @jif-oai
- #17120 codex debug 4 (guardian approved) @jif-oai
- #17122 codex debug 6 (guardian approved) @jif-oai
- #17124 codex debug 8 (guardian approved) @jif-oai
- #17126 codex debug 10 (guardian approved) @jif-oai
- #17128 codex debug 12 (guardian approved) @jif-oai
- #17130 codex debug 14 (guardian approved) @jif-oai
- #17071 Configure multi_agent_v2 spawn agent hints @pakrym-oai
- #17091 Show global AGENTS.md in /status @etraut-openai
- #17086 Fix TUI crash when resuming the current thread @etraut-openai
- #17098 Skip MCP auth probing for disabled servers @etraut-openai
- #17097 Add realtime transport config @aibrahim-oai
- #17043 [mcp] Support server-driven elicitations @mzeng-openai
- #17058 Add WebRTC media transport to realtime TUI @aibrahim-oai
- #17063 Use AbsolutePathBuf for exec cwd plumbing @pakrym-oai
- #17138 fix(debug-config, guardian): fix /debug-config rendering and guardian… @owenlin0
- #17046 release ready, enabling only for siwc users @won-openai
- #16751 Add sandbox support to filesystem APIs @starr-openai
- #17142 [codex] Support remote exec cwd in TUI startup @pakrym-oai
- #17149 Fix missing fields @canvrno-oai
- #17154 Fix ToolsConfigParams initializer in tool registry test @won-openai
- #17145 Wire realtime WebRTC native media into Bazel @aibrahim-oai
- #17057 Attach WebRTC realtime starts to sideband websocket @aibrahim-oai
- #17162 Add top-level exec-server subcommand @starr-openai
- #17061 Update guardian output schema @maja-openai
- #17164 Auto-approve MCP server elicitations in Full Access mode @leoshimo-oai
- #17093 Add WebRTC realtime app-server e2e tests @aibrahim-oai
- #17174 Support Warp for OSC 9 notifications @etraut-openai
- #16646 Fix stale thread-name resume lookups @etraut-openai
- #17165 Move default realtime prompt into core @aibrahim-oai
- #17176 Add realtime voice selection @aibrahim-oai
- #17175 Add TUI notification condition config @etraut-openai
- #17183 Default realtime startup to v2 model @aibrahim-oai
- #17186 Skip update prompts for source builds @etraut-openai
- #17188 make webrtc the default experience @aibrahim-oai
- #17163 [codex] Defer steering until after sampling the model post-compaction @jgershen-oai
- #17222 feat: /resume per ID/name @jif-oai
- #17226 feat: advanced announcements per OS and plans @jif-oai
- #17170 Render statusline context as a meter @etraut-openai
- #17217 Skip local shell snapshots for remote unified exec @jif-oai
- #17116 chore: merge name and title @jif-oai
- #16276 [codex] add memory extensions @kliu128
- #17168 refactor(proxy): clarify sandbox block messages @viyatb-oai
- #17076 [codex] Show ctrl + t hint on truncated exec output in TUI @mom-oai
- #15197 Add Codex Apps sediment file remapping @caseychow-oai
- #16009 Forward app-server turn clientMetadata to Responses @neil-oai
- #17256 app-server: Use shared receivers for app-server message processors @euroelessar
- #16944 [mcp] Expand tool search to custom MCPs. @mzeng-openai
- #16966 feat(tui): Ctrl+O copy hotkey and harden copy-as-markdown behavior @fcoury-oai
- #17262 app-server: Fix clippy by removing extra `mut` @euroelessar
- #17258 Omit empty app-server instruction overrides @aibrahim-oai
rust-v0.119.0
2026-04-10 13:45:23 -07:00
Ahmed Ibrahim ecca34209d Omit empty app-server instruction overrides (#17258)
## Summary
- omit serialized Responses instructions when an app-server base
instruction override is empty
- skip empty developer instruction messages and add v2 coverage for the
empty-override request shape

## Validation
- just fmt
- git diff --check
2026-04-09 15:29:35 -07:00
Ruslan Nigmatullin ff1ab61e4f app-server: Fix clippy by removing extra mut (#17262) 2026-04-09 14:30:18 -07:00
ef330eff6d feat(tui): Ctrl+O copy hotkey and harden copy-as-markdown behavior (#16966)
## TL;DR

- New `Ctrl+O` shortcut on top of the existing `/copy` command, allowing
users to copy the latest agent response without having to cancel a plan
or type `/copy`
- Copy server clipboard to the client over SSH (OSC 52)
- Fixes linux copy behavior: a clipboard handle has to be kept alive
while the paste happens for the contents to be preserved
- Uses arboard as primary mechanism on Windows, falling back to
PowerShell copy clipboard function
- Works with resumes, rolling back during a session, etc.

Tested on macOS, Linux/X11, Windows WSL2, Windows cmd.exe, Windows
PowerShell, Windows VSCode PowerShell, Windows VSCode WSL2, SSH (macOS
-> macOS).

## Problem

The TUI's `/copy` command was fragile. It relied on a single
`last_copyable_output` field that was bluntly cleared on every rollback
and thread reconfiguration, making copied content unavailable after
common operations like backtracking. It also had no keyboard shortcut,
requiring users to type `/copy` each time. The previous clipboard
backend mixed platform selection policy with low-level I/O in a way that
was hard to test, and it did not keep the Linux clipboard owner alive —
meaning pasted content could vanish once the process that wrote it
dropped its `arboard::Clipboard`.

This addresses the text-copy failure modes reported in #12836, #15452,
and #15663: native Linux clipboard access failing in remote or
unreachable-display environments, copy state going blank even after
visible assistant output, and local Linux X11 reporting success while
leaving the clipboard empty.

## Shortcut rationale

The copy hotkey is `Ctrl+O` rather than `Alt+C` because Alt/Option
combinations are not delivered consistently by macOS terminal emulators.
Terminal.app and iTerm2 can treat Option as text input or as a
configurable Meta/Esc prefix, and Option+C may be consumed or
transformed before the TUI sees an `Alt+C` key event. `Ctrl+O` is a
stable control-key chord in Terminal.app, iTerm2, SSH, and the existing
cross-platform terminal stack.

## Mental model

Agent responses are now tracked as a bounded, ordinal-indexed history
(`agent_turn_markdowns: Vec<AgentTurnMarkdown>`) rather than a single
nullable string. Each completed agent turn appends an entry keyed by its
ordinal (the number of user turns seen so far). Rollbacks pop entries
whose ordinal exceeds the remaining turn count, then use the visible
transcript cells as a best-effort fallback if the ordinal history no
longer has a surviving entry. This means `/copy` and `Ctrl+O` reflect
the most recent surviving agent response after a backtrack, instead of
going blank.

The clipboard backend was rewritten as `clipboard_copy.rs` with a
strategy-injection design: `copy_to_clipboard_with` accepts closures for
the OSC 52, arboard, and WSL PowerShell paths, making the selection
logic fully unit-testable without touching real clipboards. On Linux,
the `Clipboard` handle is returned as a `ClipboardLease` stored on
`ChatWidget`, keeping X11/Wayland clipboard ownership alive for the
lifetime of the TUI. When native copy fails under WSL, the backend now
tries the Windows clipboard through PowerShell before falling back to
OSC 52.

## Non-goals

- This change does not introduce rich-text (HTML) clipboard support; the
copied content is raw markdown.
- It does not add a paste-from-history picker or multi-entry clipboard
ring.
- WSL support remains a best-effort fallback, not a new configuration
surface or guarantee for every terminal/host combination.

## Tradeoffs

- **Bounded history (256 entries)**: `MAX_AGENT_COPY_HISTORY` caps
memory. For sessions with thousands of turns this silently drops the
oldest entries. The cap is generous enough for realistic sessions.
- **`saw_copy_source_this_turn` flag**: Prevents double-recording when
both `AgentMessage` and `TurnComplete.last_agent_message` fire for the
same turn. The flag is reset on turn start and on turn complete,
creating a narrow window where a race between the two events could
theoretically skip recording. In practice the protocol delivers them
sequentially.
- **Transcript fallback on rollback**:
`last_agent_markdown_from_transcript` walks the visible transcript cells
to reconstruct plain text when the ordinal history has been fully
truncated. This path uses `AgentMessageCell::plain_text()` which joins
rendered spans, so it reconstructs display text rather than the original
raw markdown. It keeps visible text copyable after rollback, but
responses with markdown-specific syntax can diverge from the original
source.
- **Clipboard fallback ordering**: SSH still uses OSC 52 exclusively
because native/PowerShell clipboard access would target the wrong
machine. Local sessions try native clipboard first, then WSL PowerShell
when running under WSL, then OSC 52. This adds one process-spawn
fallback for WSL users but keeps the normal desktop and SSH paths
simple.

## Architecture

```
chatwidget.rs
├── agent_turn_markdowns: Vec<AgentTurnMarkdown>  // ordinal-indexed history
├── last_agent_markdown: Option<String>            // always == last entry's markdown
├── completed_turn_count: usize                    // incremented when user turns enter history
├── saw_copy_source_this_turn: bool                // dedup guard
├── clipboard_lease: Option<ClipboardLease>        // keeps Linux clipboard owner alive
│
├── record_agent_markdown(&str)                    // append/update history entry
├── truncate_agent_turn_markdowns_to_turn_count()  // rollback support
├── copy_last_agent_markdown()                     // public entry point (slash + hotkey)
└── copy_last_agent_markdown_with(fn)              // testable core

clipboard_copy.rs
├── copy_to_clipboard(text) -> Result<Option<ClipboardLease>>
├── copy_to_clipboard_with(text, ssh, wsl, osc52_fn, arboard_fn, wsl_fn)
├── ClipboardLease { _clipboard on linux }
├── arboard_copy(text)          // platform-conditional native clipboard path
├── wsl_clipboard_copy(text)    // WSL PowerShell fallback
├── osc52_copy(text)            // /dev/tty -> stdout fallback
├── SuppressStderr              // macOS stderr redirect guard
├── is_ssh_session()
└── is_wsl_session()

app_backtrack.rs
├── last_agent_markdown_from_transcript()  // reconstruct from visible cells
└── truncate call sites in trim/apply_confirmed_rollback
```

## Observability

- `tracing::warn!` on native clipboard failure before OSC 52 fallback.
- `tracing::debug!` on `/dev/tty` open/write failure before stdout
fallback.
- History cell messages: "Copied last message to clipboard", "Copy
failed: {error}", "No agent response to copy" appear in the TUI
transcript.

## Tests

- `clipboard_copy.rs`: Unit tests cover OSC 52 encoding roundtrip,
payload size rejection, writer output, SSH-only OSC52 routing, non-WSL
native-to-OSC52 fallback, WSL native-to-PowerShell fallback, WSL
PowerShell-to-OSC52 fallback, and all-error reporting via strategy
injection.
- `chatwidget/tests/slash_commands.rs`: Updated existing `/copy` tests
to use `last_agent_markdown_text()` accessor. Added coverage for the
Linux clipboard lease lifecycle, missing
`TurnComplete.last_agent_message` fallback through completed assistant
items, replayed legacy agent messages, stale-output prevention after
rollback, and the `Ctrl+O` no-output hotkey path.
- `app_backtrack.rs`: Added
`agent_group_count_ignores_context_compacted_marker` verifying that
info-event cells don't inflate the agent group count.

---------

Co-authored-by: Felipe Coury <felipe.coury@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 18:10:38 -03:00
Matthew Zeng d7f99b0fa6 [mcp] Expand tool search to custom MCPs. (#16944)
- [x] Expand tool search to custom MCPs.
- [x] Rename several variables/fields to be more generic.

Updated tool & server name lifecycles:

**Raw Identity**

ToolInfo.server_name is raw MCP server name.
ToolInfo.tool.name is raw MCP tool name.
MCP calls route back to raw via parse_tool_name() returning
(tool.server_name, tool.tool.name).
mcpServerStatus/list now groups by raw server and keys tools by
Tool.name: mod.rs:599
App-server just forwards that grouped raw snapshot:
codex_message_processor.rs:5245

**Callable Names**

On list-tools, we create provisional callable_namespace / callable_name:
mcp_connection_manager.rs:1556
For non-app MCP, provisional callable name starts as raw tool name.
For codex-apps, provisional callable name is sanitized and strips
connector name/id prefix; namespace includes connector name.
Then qualify_tools() sanitizes callable namespace + name to ASCII alnum
/ _ only: mcp_tool_names.rs:128
Note: this is stricter than Responses API. Hyphen is currently replaced
with _ for code-mode compatibility.

**Collision Handling**

We do initially collapse example-server and example_server to the same
base.
Then qualify_tools() detects distinct raw namespace identities behind
the same sanitized namespace and appends a hash to the callable
namespace: mcp_tool_names.rs:137
Same idea for tool-name collisions: hash suffix goes on callable tool
name.
Final list_all_tools() map key is callable_namespace + callable_name:
mcp_connection_manager.rs:769

**Direct Model Tools**

Direct MCP tool declarations use the full qualified sanitized key as the
Responses function name.
The raw rmcp Tool is converted but renamed for model exposure.

**Tool Search / Deferred**

Tool search result namespace = final ToolInfo.callable_namespace:
tool_search.rs:85
Tool search result nested name = final ToolInfo.callable_name:
tool_search.rs:86
Deferred tool handler is registered as "{namespace}:{name}":
tool_registry_plan.rs:248
When a function call comes back, core recombines namespace + name, looks
up the full qualified key, and gets the raw server/tool for MCP
execution: codex.rs:4353

**Separate Legacy Snapshot**

collect_mcp_snapshot_from_manager_with_detail() still returns a map
keyed by qualified callable name.
mcpServerStatus/list no longer uses that; it uses
McpServerStatusSnapshot, which is raw-inventory shaped.
2026-04-09 13:34:52 -07:00
Ruslan Nigmatullin 545f3daba0 app-server: Use shared receivers for app-server message processors (#17256)
We do not rely on the mutability here, so express it in the type system.
2026-04-09 19:53:50 +00:00
neil-oai a92a5085bd Forward app-server turn clientMetadata to Responses (#16009)
## Summary
App-server v2 already receives turn-scoped `clientMetadata`, but the
Rust app-server was dropping it before the outbound Responses request.
This change keeps the fix lightweight by threading that metadata through
the existing turn-metadata path rather than inventing a new transport.

## What we're trying to do and why
We want turn-scoped metadata from the app-server protocol layer,
especially fields like Hermes/GAAS run IDs, to survive all the way to
the actual Responses API request so it is visible in downstream
websocket request logging and analytics.

The specific bug was:
- app-server protocol uses camelCase `clientMetadata`
- Responses transport already has an existing turn metadata carrier:
`x-codex-turn-metadata`
- websocket transport already rewrites that header into
`request.request_body.client_metadata["x-codex-turn-metadata"]`
- but the Rust app-server never parsed or stored `clientMetadata`, so
nothing from the app-server request was making it into that existing
path

This PR fixes that without adding a new header or a second metadata
channel.

## How we did it
### Protocol surface
- Add optional `clientMetadata` to v2 `TurnStartParams` and
`TurnSteerParams`
- Regenerate the JSON schema / TypeScript fixtures
- Update app-server docs to describe the field and its behavior

### Runtime plumbing
- Add a dedicated core op for app-server user input carrying turn-scoped
metadata: `Op::UserInputWithClientMetadata`
- Wire `turn/start` and `turn/steer` through that op / signature path
instead of dropping the metadata at the message-processor boundary
- Store the metadata in `TurnMetadataState`

### Transport behavior
- Reuse the existing serialized `x-codex-turn-metadata` payload
- Merge the new app-server `clientMetadata` into that JSON additively
- Do **not** replace built-in reserved fields already present in the
turn metadata payload
- Keep websocket behavior unchanged at the outer shape level: it still
sends only `client_metadata["x-codex-turn-metadata"]`, but that JSON
string now contains the merged fields
- Keep HTTP fallback behavior unchanged except that the existing
`x-codex-turn-metadata` header now includes the merged fields too

### Request shape before / after
Before, a websocket `response.create` looked like:
```json
{
  "type": "response.create",
  "client_metadata": {
    "x-codex-turn-metadata": "{\"session_id\":\"...\",\"turn_id\":\"...\"}"
  }
}
```
Even if the app-server caller supplied `clientMetadata`, it was not
represented there.

After, the same request shape is preserved, but the serialized payload
now includes the new turn-scoped fields:
```json
{
  "type": "response.create",
  "client_metadata": {
    "x-codex-turn-metadata": "{\"session_id\":\"...\",\"turn_id\":\"...\",\"fiber_run_id\":\"fiber-start-123\",\"origin\":\"gaas\"}"
  }
}
```

## Validation
### Targeted tests added / updated
- protocol round-trip coverage for `clientMetadata` on `turn/start` and
`turn/steer`
- protocol round-trip coverage for `Op::UserInputWithClientMetadata`
- `TurnMetadataState` merge test proving client metadata is added
without overwriting reserved built-in fields
- websocket request-shape test proving outbound `response.create`
contains merged metadata inside
`client_metadata["x-codex-turn-metadata"]`
- app-server integration tests proving:
- `turn/start` forwards `clientMetadata` into the outbound Responses
request path
  - websocket warmup + real turn request both behave correctly
  - `turn/steer` updates the follow-up request metadata

### Commands run
- `just write-app-server-schema`
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-protocol`
- `cargo test -p codex-core
turn_metadata_state_merges_client_metadata_without_replacing_reserved_fields
--lib`
- `cargo test -p codex-core --test all
responses_websocket_preserves_custom_turn_metadata_fields`
- `cargo test -p codex-app-server --test all client_metadata`
- `cargo test -p codex-app-server --test all
turn_start_forwards_client_metadata_to_responses_websocket_request_body_v2
-- --nocapture`
- `just fmt`
- `just fix -p codex-core -p codex-protocol -p codex-app-server-protocol
-p codex-app-server`
- `just fix -p codex-exec -p codex-tui-app-server`
- `just argument-comment-lint`

### Full suite note
`cargo test` in `codex-rs` still fails in:
-
`suite::v2::turn_interrupt::turn_interrupt_resolves_pending_command_approval_request`

I verified that same failure on a clean detached `HEAD` worktree with an
isolated `CARGO_TARGET_DIR`, so it is not caused by this patch.
2026-04-09 11:52:37 -07:00
Casey ChowandCodex 244b15c95d feat: add Codex Apps sediment file remapping (#15197)
## Summary
- bridge Codex Apps tools that declare `_meta["openai/fileParams"]`
through the OpenAI file upload flow
- mask those file params in model-visible tool schemas so the model
provides absolute local file paths instead of raw file payload objects
- rewrite those local file path arguments client-side into
`ProvidedFilePayload`-shaped objects before the normal MCP tool call

## Details
- applies to scalar and array file params declared in
`openai/fileParams`
- Codex uploads local files directly to the backend and uses the
uploaded file metadata to build the MCP tool arguments locally
- this PR is input-only

## Verification
- `just fmt`
- `cargo test -p codex-core mcp_tool_call -- --nocapture`

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-09 14:10:44 -04:00
mom-oai 25a0f6784d [codex] Show ctrl + t hint on truncated exec output in TUI (#17076)
## What

Show an inline `ctrl + t to view transcript` hint when exec output is
truncated in the main TUI chat view.

## Why

Today, truncated exec output shows `… +N lines`, but it does not tell
users that the full content is already available through the existing
transcript overlay. That makes hidden output feel lost instead of
discoverable.

This change closes that discoverability gap without introducing a new
interaction model.

Fixes: CLI-5740

## How

- added an output-specific truncation hint in `ExecCell` rendering
- applied that hint in both exec-output truncation paths:
  - logical head/tail truncation before wrapping
  - row-budget truncation after wrapping
- preserved the existing row-budget behavior on narrow terminals by
reserving space for the longer hint line
- updated the relevant snapshot and added targeted regression coverage

## Intentional design decisions

- **Aligned shortcut styling with the visible footer UI**  
The inline hint uses `ctrl + t`, not `Ctrl+T`, to match the TUI’s
rendered key-hint style.

- **Kept the noun `transcript`**  
The product already exposes this flow as the transcript overlay, so the
hint points at the existing concept instead of inventing a new label.

- **Preserved narrow-terminal behavior**  
The longer hint text is accounted for in the row-budget truncation path
so the visible output still respects the existing viewport cap.

- **Did not add the hint to long command truncation**  
This PR only changes hidden **output** truncation. Long command
truncation still uses the plain ellipsis form because `ctrl + t` is not
the same kind of “show hidden output” escape hatch there.

- **Did not widen scope to other truncation surfaces**  
This does not change MCP/tool-call truncation in `history_cell.rs`, and
it does not change transcript-overlay behavior itself.

## Validation

### Automated
- `just fmt`
- `cargo test -p codex-tui`

### Manual
- ran `just tui-with-exec-server`
- executed `!seq 1 200`
- confirmed the main view showed the new `ctrl + t to view transcript`
truncation hint
- pressed `ctrl + t` and confirmed the transcript overlay still exposed
the full output
- closed the overlay and returned to the main view

## Visual proof

Screenshot/video attached in the PR UI showing:
- the truncated exec output row with the new hint
- the transcript overlay after `ctrl + t`
2026-04-09 11:01:30 -07:00
viyatb-oai 7ab825e047 refactor(proxy): clarify sandbox block messages (#17168)
## Summary
- Replace Codex-branded network-proxy block responses with concise
reason text
- Mention sandbox policy for local/private network and deny-policy
wording
- Remove “managed” from the proxy-disabled denial detail
2026-04-09 10:53:06 -07:00
Kevin Liu 76de99ff25 [codex] add memory extensions (#16276)
# External (non-OpenAI) Pull Request Requirements

Before opening this Pull Request, please read the dedicated
"Contributing" markdown file or your PR may be closed:
https://github.com/openai/codex/blob/main/docs/contributing.md

If your PR conforms to our contribution guidelines, replace this text
with a detailed and high quality description of your changes.

Include a link to a bug report or enhancement request.
2026-04-09 10:45:02 -07:00
jif-oaiandCodex 12f0e0b0eb chore: merge name and title (#17116)
Merge title and name concept to leverage the sqlite title column and
have more efficient queries

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-09 18:44:26 +01:00
jif-oaiandCodex c0b5d8d24a Skip local shell snapshots for remote unified exec (#17217)
## Summary
- detect remote exec-server sessions in the unified-exec runtime
- bypass the local shell-snapshot bootstrap only for those remote
sessions
- preserve existing local snapshot wrapping, PowerShell UTF-8 prefixing,
sandbox orchestration, and zsh-fork handling

## Why
The shell snapshot file is currently captured and stored next to Core.
If Core wraps a remote command with `. /path/to/local/snapshot`, the
process starts on the executor and tries to source a path from the
orchestrator filesystem. This keeps remote commands from receiving that
known-local path until shell snapshots are captured/restored on the
executor side.

## Validation
- `just fmt`
- `git diff --check`
- `cargo test -p codex-core --lib tools::runtimes::tests`

Co-authored-by: Codex <noreply@openai.com>
2026-04-09 17:30:18 +01:00
Eric Traut 598d6ff056 Render statusline context as a meter (#17170)
Problem: The statusline reported context as an “X% left” value, which
could be mistaken for quota, and context usage was included in the
default footer.

Solution: Render configured context status items as a filling context
meter, preserve `context-used` as a legacy alias while hiding it from
the setup menu, and remove context from the default statusline. It will
still be available as an opt-in option for users who want to see it.

<img width="317" height="39" alt="image"
src="https://github.com/user-attachments/assets/3aeb39bb-f80d-471f-88fe-d55e25b31491"
/>
2026-04-09 07:52:07 -07:00
jif-oai 9f6f2c84c1 feat: advanced announcements per OS and plans (#17226)
Support things like
```
  [[announcements]]
  content = "custom message"
  from_date = "2026-04-09"
  to_date = "2026-06-01"
  target_app = "cli"
  target_plan_types = ["pro"]
  target_oses = ["macos"]
  version_regex = "..." # add version of the patch
  ```
2026-04-09 15:17:06 +01:00
jif-oai 6c5471feb2 feat: /resume per ID/name (#17222)
Support `/resume 00000-0000-0000-00000000` from the TUI (equivalent for
the name)
2026-04-09 14:21:27 +01:00
jgershen-oai 8f705b0702 [codex] Defer steering until after sampling the model post-compaction (#17163)
## Summary
- keep pending steered input buffered until the active user prompt has
received a model response
- keep steering pending across auto-compact when there is real
model/tool continuation to resume
- allow queued steering to follow compaction immediately when the prior
model response was already final
- keep pending-input follow-up owned by `run_turn` instead of folding it
into `SamplingRequestResult`
- add regression coverage for mid-turn compaction, final-response
compaction, and compaction triggered before the next request after tool
output

## Root Cause
Steered input was drained at the top of every `run_turn` loop. After
auto-compaction, the loop continued and immediately appended any pending
steer after the compact summary, making a queued prompt look like the
newest task instead of letting the model first resume interrupted
model/tool work.

## Implementation Notes
This patch keeps the follow-up signals separated:

- `SamplingRequestResult.needs_follow_up` means model/tool continuation
is needed
- `sess.has_pending_input().await` means queued user steering exists
- `run_turn` computes the combined loop condition from those two signals

In `run_turn`:

```rust
let has_pending_input = sess.has_pending_input().await;
let needs_follow_up = model_needs_follow_up || has_pending_input;
```

After auto-compact we choose whether the next request may drain
steering:

```rust
can_drain_pending_input = !model_needs_follow_up;
```

That means:

- model/tool continuation + pending steer: compact -> resume once
without draining steer
- completed model answer + pending steer: compact -> drain/send the
steer immediately
- fresh user prompt: do not drain steering before the model has answered
the prompt once

The drain is still only `sess.get_pending_input().await`; when
`can_drain_pending_input` is false, core uses an empty local vec and
leaves the steer pending in session state.

## Validation
- PASS `cargo test -p codex-core --test all steered_user_input --
--nocapture`
- PASS `just fmt`
- PASS `git diff --check`
- NOT PASSING HERE `just fix -p codex-core` currently stops before
linting this change on an unrelated mainline test-build error:
`core/src/tools/spec_tests.rs` initializes `ToolsConfigParams` without
`image_generation_tool_auth_allowed`; this PR does not touch that file.
2026-04-09 02:08:41 -07:00
Ahmed IbrahimandCodex 84a24fe333 make webrtc the default experience (#17188)
## Summary
- make realtime default to the v2 WebRTC path
- keep partial realtime config tables inheriting
`RealtimeConfig::default()`

## Validation
- CI found a stale config-test expectation; fixed in 974ba51bb3
- just fmt
- git diff --check

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 23:52:32 -07:00
Eric Traut 23f4cd8459 Skip update prompts for source builds (#17186)
Addresses #17166

Problem: Source builds report version 0.0.0, so the TUI update path can
treat any released Codex version as upgradeable and show startup or
popup prompts.

Solution: Skip both TUI update prompt entry points when the running CLI
version is the source-build sentinel 0.0.0.
2026-04-08 22:26:05 -07:00
Ahmed IbrahimandCodex 1fdb695e42 Default realtime startup to v2 model (#17183)
- Default realtime sessions to v2 and gpt-realtime-1.5 when no override
is configured.
- Add Op::RealtimeConversationStart integration coverage and keep
v1-specific tests explicit.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 22:11:30 -07:00
Eric Traut 6dc5391c7c Add TUI notification condition config (#17175)
Problem: TUI desktop notifications are hard-gated on terminal focus, so
terminal/IDE hosts that want in-focus notifications cannot opt in.

Solution: Add a flat `[tui] notification_condition` setting (`unfocused`
by default, `always` opt-in), carry grouped TUI notification settings
through runtime config, apply method + condition together in the TUI,
and regenerate the config schema.
2026-04-08 21:50:02 -07:00
Ahmed Ibrahim 2f9090be62 Add realtime voice selection (#17176)
- Add realtime voice selection for realtime/start.
- Expose the supported v1/v2 voice lists and cover explicit, configured,
default, and invalid voice paths.
2026-04-08 20:19:15 -07:00
Ahmed IbrahimandCodex 4c2a1ae31b Move default realtime prompt into core (#17165)
- Adds a core-owned realtime backend prompt template and preparation
path.
- Makes omitted realtime start prompts use the core default, while null
or empty prompts intentionally send empty instructions.
- Covers the core realtime path and app-server v2 path with integration
coverage.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 19:34:40 -07:00
Eric Traut 36586eafed Fix stale thread-name resume lookups (#16646)
Addresses #15943

Problem: Name-based resume could stop on a newer session_index entry
whose rollout was never persisted, shadowing an older saved thread with
the same name.

Solution: Materialize rollouts before indexing thread names and make
name lookup skip unresolved entries until it finds a persisted rollout.
2026-04-08 18:51:29 -07:00
Eric Traut 4dca906e19 Support Warp for OSC 9 notifications (#17174)
Problem: Warp supports OSC 9 notifications, but the TUI's automatic
notification backend selection did not recognize its
`TERM_PROGRAM=WarpTerminal` environment value.

Solution: Treat `TERM_PROGRAM=WarpTerminal` as OSC 9-capable when
choosing the TUI desktop notification backend.
2026-04-08 18:49:31 -07:00
Ahmed Ibrahim 22d07e7f8f Add WebRTC realtime app-server e2e tests (#17093)
Summary:
- add app-server WebRTC realtime e2e harness
- cover v1 handoff and v2 codex tool delegation over sideband

Validation:
- just fmt
- git diff --check
- local tests not run; relying on PR CI
2026-04-08 18:38:21 -07:00
Leo ShimonakaandCodex 01537f0bd2 Auto-approve MCP server elicitations in Full Access mode (#17164)
Currently, when a MCP server sends an elicitation to Codex running in
Full Access (`sandbox_policy: DangerFullAccess` + `approval_policy:
Never`), the elicitations are auto-cancelled.

This PR updates the automatic handling of MCP elicitations to be
consistent with other approvals in full-access, where they are
auto-approved. Because MCP elicitations may actually require user input,
this mechanism is limited to empty form elicitations.

## Changeset
- Add policy helper shared with existing MCP tool call approval
auto-approve
- Update `ElicitationRequestManager` to auto-approve elicitations in
full access when `can_auto_accept_elicitation` is true.
- Add tests

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 16:41:02 -07:00
maja-openaiandOwen Lin dcbc91fd39 Update guardian output schema (#17061)
## Summary
- Update guardian output schema to separate risk, authorization,
outcome, and rationale.
- Feed guardian rationale into rejection messages.
- Split the guardian policy into template and tenant-config sections.

## Validation
- `cargo test -p codex-core mcp_tool_call`
- `env -u CODEX_SANDBOX_NETWORK_DISABLED INSTA_UPDATE=always cargo test
-p codex-core guardian::`

---------

Co-authored-by: Owen Lin <owen@openai.com>
2026-04-08 15:47:29 -07:00
starr-openaiandCodex 49677ec71f Add top-level exec-server subcommand (#17162)
## Summary
- add a top-level `codex exec-server` subcommand, marked experimental in
CLI help
- launch an adjacent or PATH-provided `codex-exec-server`, with a
source-tree `cargo run -p codex-exec-server --` fallback
- cover the new subcommand parser path

## Validation
- `just fmt`
- `git diff --check`
- not run: Rust test suite

Co-authored-by: Codex <noreply@openai.com>

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 15:38:07 -07:00
Ahmed Ibrahim 794a0240f9 Attach WebRTC realtime starts to sideband websocket (#17057)
Summary:
- parse the realtime call Location header and join that call over the
direct realtime WebSocket
- keep WebRTC starts alive on the existing realtime conversation path

Validation:
- just fmt
- git diff --check
- cargo check -p codex-api
- cargo check -p codex-core --tests
- local cargo tests not run; relying on PR CI
2026-04-08 15:25:42 -07:00
Ahmed IbrahimandCodex 19bd018300 Wire realtime WebRTC native media into Bazel (#17145)
- Builds codex-realtime-webrtc through the normal Bazel Rust macro so
native macOS WebRTC sources are included.\n- Shares the macOS -ObjC link
flag with Bazel targets that can link libwebrtc.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 15:15:55 -07:00
Won Park 56dfe41605 Fix ToolsConfigParams initializer in tool registry test (#17154)
## Summary
- add the missing `image_generation_tool_auth_allowed` field to the new
tool registry plan test initializer

## Validation
- `just fmt`
- `cargo test -p codex-tools image_generation`
- `cargo test -p codex-tools --no-run`
2026-04-08 14:05:24 -07:00
canvrno-oai 58ad79b60e Fix missing fields (#17149)
Fix missing `image_generation_tool_auth_allowed` in two locations.
2026-04-08 13:53:53 -07:00
pakrym-oai e4d6702b87 [codex] Support remote exec cwd in TUI startup (#17142)
When running with remote executor the cwd is the remote path. Today we
check for existence of a local directory on startup and attempt to load
config from it.

For remote executors don't do that.
2026-04-08 13:09:28 -07:00
starr-openaiandCodex f383cc980d Add sandbox support to filesystem APIs (#16751)
## Summary
- add optional `sandboxPolicy` support to the app-server filesystem
request surface
- thread sandbox-aware filesystem options through app-server and
exec-server adapters
- enforce sandboxed read/write access in the filesystem abstraction with
focused local and remote coverage

## Validation
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-exec-server file_system`
- `cargo test -p codex-app-server suite::v2::fs`

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 12:10:48 -07:00
Won Park e003f84e1e release ready, enabling only for siwc users (#17046)
**Disabling Image-Gen for Non-SIWC Codex Users**

We are only enabling image-gen feature for SIWC Codex users until there
comes a fix in ResponsesAPI to omit output from responses.completed, to
prevent the following issues:

1. websocket blows up due to heavier load (images) than before (text) 
2. http parser streams through n^2 of n-base64 bytes (sum of base64s of
all images generated in turn) that causes long delays in
turn_completion.
2026-04-08 11:22:39 -07:00
Owen Lin e794457a59 fix(debug-config, guardian): fix /debug-config rendering and guardian… (#17138)
## Description

This PR fixes `/debug-config` so it shows more of the active
requirements state, including reviewer requirements and managed feature
pins. This made it clear that legacy MDM config was setting
`approvals_reviewer = "guardian_subagent"` and that we were translating
that into a requirements constraint.

Also, translate `approvals_reviewer = "guardian_subagent"` (from legacy
managed_config.toml) to `allowed_approvals_reviewers: guardian_subagent,
user` instead of `allowed_approvals_reviewers: guardian_subagent`.

Example `/debug-config`:
```
Config layer stack (lowest precedence first):
  1. system (/etc/codex/config.toml) (enabled)
  2. user (/Users/owen/.codex/config.toml) (enabled)
  3. project (/Users/owen/repos/codex/.codex/config.toml) (enabled)
  4. legacy managed_config.toml (MDM) (enabled)
     MDM value:
       ...

       # Enable Guardian Mode
       features.guardian_approval = true
       approvals_reviewer = "guardian_subagent"

Requirements:
  - allowed_approvals_reviewers: guardian_subagent, user (source: MDM managed_config.toml (legacy))
  - features: apps=true, plugins=true (source: cloud requirements)
```

Before this PR, the `Requirements` section showed None.
2026-04-08 11:08:09 -07:00
pakrym-oai 35b5720e8d Use AbsolutePathBuf for exec cwd plumbing (#17063)
## Summary
- Carry `AbsolutePathBuf` through tool cwd parsing/resolution instead of
resolving workdirs to raw `PathBuf`s.
- Type exec/sandbox request cwd fields as `AbsolutePathBuf` through
`ExecParams`, `ExecRequest`, `SandboxCommand`, and unified exec runtime
requests.
- Keep `PathBuf` conversions at external/event boundaries and update
existing tests/fixtures for the typed cwd.

## Validation
- `cargo check -p codex-core --tests`
- `cargo check -p codex-sandboxing --tests`
- `cargo test -p codex-sandboxing`
- `cargo test -p codex-core --lib tools::handlers::`
- `just fix -p codex-sandboxing`
- `just fix -p codex-core`
- `just fmt`

Full `codex-core` test suite was not run locally; per repo guidance I
kept local validation targeted.
2026-04-08 10:54:12 -07:00
Ahmed IbrahimandCodex d90a348870 Add WebRTC media transport to realtime TUI (#17058)
Adds the `[realtime].transport = "webrtc"` TUI media path using a new
`codex-realtime-webrtc` crate, while leaving app-server as the
signaling/event source.\n\nLocal checks: fmt, diff-check, dependency
tree only; test signal should come from CI.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 10:26:55 -07:00
Matthew Zeng 7b6486a145 [mcp] Support server-driven elicitations (#17043)
- [x] Enables MCP elicitation for custom servers, not just Codex Apps
- [x] Adds an RMCP service wrapper to preserve elicitation _meta
- [x] Round-trips response _meta for persist/approval choices
- [x] Updates TUI empty-schema elicitations into message-only approval
prompts
2026-04-08 10:18:58 -07:00
Ahmed IbrahimandCodex 06d88b7e81 Add realtime transport config (#17097)
Adds realtime.transport config with websocket as the default and webrtc
wired through the effective config.

Co-authored-by: Codex <noreply@openai.com>
2026-04-08 09:53:53 -07:00
Eric Traut 18171b1931 Skip MCP auth probing for disabled servers (#17098)
Addresses #16971

Problem: Disabled MCP servers were still queried for streamable HTTP
auth status during MCP inventory, so unreachable disabled entries could
add startup latency.

Solution: Return `Unsupported` immediately for disabled MCP server
configs before bearer token/OAuth status discovery.
2026-04-08 09:36:07 -07:00
Eric Traut 5c95e4588e Fix TUI crash when resuming the current thread (#17086)
Problem: Resuming the live TUI thread through `/resume` could
unsubscribe and reconnect the same app-server thread, leaving the UI
crashed or disconnected.

Solution: No-op `/resume` only when the selected thread is the currently
attached active thread; keep the normal resume path for
stale/displayed-only threads so recovery and reattach still work.
2026-04-08 09:35:54 -07:00
Eric Traut dc5feb916d Show global AGENTS.md in /status (#17091)
Addresses #3793

Problem: /status only reported project-level AGENTS files, so sessions
with a loaded global $CODEX_HOME/AGENTS.md still showed Agents.md as
<none>.

Solution: Track the global instructions file loaded during config
initialization and prepend that path to the /status Agents.md summary,
with coverage for AGENTS.md, AGENTS.override.md, and global-plus-project
ordering.
2026-04-08 09:04:32 -07:00
pakrym-oai 4c07dd4d25 Configure multi_agent_v2 spawn agent hints (#17071)
Allow multi_agent_v2 features to have its own temporary configuration
under `[features.multi_agent_v2]`

```
[features.multi_agent_v2]
enabled = true
usage_hint_enabled = false
usage_hint_text = "Custom delegation guidance."
hide_spawn_agent_metadata = true
```

Absent `usage_hint_text` means use the default hint.

```
[features]
multi_agent_v2 = true
```

still works as the boolean shorthand.
2026-04-08 08:42:18 -07:00
jif-oai 2250fdd54a codex debug 14 (guardian approved) (#17130)
Removes lines 92-98 from core/templates/agents/orchestrator.md.
2026-04-08 14:14:32 +01:00
jif-oai 34fd336e7b codex debug 12 (guardian approved) (#17128)
Removes lines 78-84 from core/templates/agents/orchestrator.md.
2026-04-08 14:14:28 +01:00
jif-oai 6ee4680a81 codex debug 10 (guardian approved) (#17126)
Removes lines 64-70 from core/templates/agents/orchestrator.md.
2026-04-08 14:14:24 +01:00
jif-oai 34422855bb codex debug 8 (guardian approved) (#17124)
Removes lines 50-56 from core/templates/agents/orchestrator.md.
2026-04-08 14:14:19 +01:00
jif-oai 9601f2af4b codex debug 6 (guardian approved) (#17122)
Removes lines 36-42 from core/templates/agents/orchestrator.md.
2026-04-08 14:14:15 +01:00