Centralize slash command draft serialization on top of shlex so popup flows and queued replay use the same quoting and tokenization rules.
Co-authored-by: Codex <noreply@openai.com>
Pause queued replay on local slash actions that need app-side updates or popup dismissal, then resume once the app event queue and bottom pane are idle. Add regression coverage for queued theme replay and popup-gated resume.
Co-authored-by: Codex <noreply@openai.com>
Track whether /model effort and scope modifiers were provided so repeated sentinel values like default and global are rejected consistently.
Validation: cargo test -p codex-tui; just fix -p codex-tui; just fmt
Co-authored-by: Codex <noreply@openai.com>
Route interactive slash-command pickers through canonical serialized drafts so live dispatch and queued replay share one parser/executor path.
Validation: cargo test -p codex-tui; just fix -p codex-tui; just fmt
Co-authored-by: Codex <noreply@openai.com>
Switch supports_inline_args() and requires_interaction() to exhaustive matches so newly added SlashCommand variants must be classified explicitly.
Co-authored-by: Codex <noreply@openai.com>
Explain that the busy-path Stop return in dispatch_command() only matters for live dispatch because queued replay never reaches that branch.
Co-authored-by: Codex <noreply@openai.com>
Mark popup-opening slash commands as requiring interaction, open them immediately instead of queueing bare drafts while a task is running, and make queued replay restore any legacy bare interactive command draft instead of opening UI mid-drain.
Co-authored-by: Codex <noreply@openai.com>
Explain above dispatch_command that live callers usually ignore its return value while queued replay uses QueueReplayControl to decide whether draining can continue.
Co-authored-by: Codex <noreply@openai.com>
Document that the busy-path queueing in dispatch_command is only reached during live slash dispatch, not queued replay, so the returned drain-control value is effectively a throwaway for that branch.
Co-authored-by: Codex <noreply@openai.com>
Serialize custom /review instructions with an explicit custom marker so queued replay cannot reinterpret branch-like text as a structured review target, and rename queued replay to better reflect that it drains inputs until blocked.
Co-authored-by: Codex <noreply@openai.com>
Send interrupt ops directly from the bottom pane instead of routing them through the status indicator widget, and remove the now-unused event wiring from the widget and its tests.
Co-authored-by: Codex <noreply@openai.com>
Keep bare /model and /review interactive while preserving serialized queue replay, restore queued slash drafts into the composer on interrupt, and align queued slash parsing with the same feature-gated lookup used by the composer.
Co-authored-by: Codex <noreply@openai.com>
Unify queued slash commands as serialized drafts, route popup actions through the same replay path, and stop replay after commands that submit a turn.
Co-authored-by: Codex <noreply@openai.com>
Limit Esc interrupts to an empty composer when no popup is active, while preserving the pending-steer interrupt path.
This keeps dialog dismissal on Esc working normally without interrupting the running conversation.
Co-authored-by: Codex <noreply@openai.com>
Keep interactive slash flows usable while a turn is running, and queue the resulting action instead of the bare slash token.
Also let Esc interrupt through popup-active states so queued drafts restore without dropping queued slash actions.
Co-authored-by: Codex <noreply@openai.com>
Restore only queued user-message drafts into the composer when a turn is interrupted, keep queued slash-command actions replayable, and cover the interrupt replay behavior in codex-tui tests.
Co-authored-by: Codex <noreply@openai.com>
Drop the unused bottom-pane mention-binding drain helpers introduced by the queueing refactor and switch the affected tests to the existing non-destructive composer mention accessor.
Co-authored-by: Codex <noreply@openai.com>
Allow slash commands entered during a running turn to be queued and replayed after the turn completes, including /review and inline slash-command variants tested in codex-tui.
Co-authored-by: Codex <noreply@openai.com>
## Summary
- reuse a guardian subagent session across approvals so reviews keep a
stable prompt cache key and avoid one-shot startup overhead
- clear the guardian child history before each review so prior guardian
decisions do not leak into later approvals
- include the `smart_approvals` -> `guardian_approval` feature flag
rename in the same PR to minimize release latency on a very tight
timeline
- add regression coverage for prompt-cache-key reuse without
prior-review prompt bleed
## Request
- Bug/enhancement request: internal guardian prompt-cache and latency
improvement request
---------
Co-authored-by: Codex <noreply@openai.com>
### Motivation
- Interrupting a running turn (Ctrl+C / Esc) currently also terminates
long‑running background shells, which is surprising for workflows like
local dev servers or file watchers.
- The existing cleanup command name was confusing; callers expect an
explicit command to stop background terminals rather than a UI clear
action.
- Make background‑shell termination explicit and surface a clearer
command name while preserving backward compatibility.
### Description
- Renamed the background‑terminal cleanup slash command from `Clean`
(`/clean`) to `Stop` (`/stop`) and kept `clean` as an alias in the
command parsing/visibility layer, updated the user descriptions and
command popup wiring accordingly.
- Updated the unified‑exec footer text and snapshots to point to `/stop`
(and trimmed corresponding snapshot output to match the new label).
- Changed interrupt behavior so `Op::Interrupt` (Ctrl+C / Esc interrupt)
no longer closes or clears tracked unified exec / background terminal
processes in the TUI or core cleanup path; background shells are now
preserved after an interrupt.
- Updated protocol/docs to clarify that `turn/interrupt` (or
`Op::Interrupt`) interrupts the active turn but does not terminate
background terminals, and that `thread/backgroundTerminals/clean` is the
explicit API to stop those shells.
- Updated unit/integration tests and insta snapshots in the TUI and core
unified‑exec suites to reflect the new semantics and command name.
### Testing
- Ran formatting with `just fmt` in `codex-rs` (succeeded).
- Ran `cargo test -p codex-protocol` (succeeded).
- Attempted `cargo test -p codex-tui` but the build could not complete
in this environment due to a native build dependency that requires
`libcap` development headers (the `codex-linux-sandbox` vendored build
step); install `libcap-dev` / make `libcap.pc` available in
`PKG_CONFIG_PATH` to run the TUI test suite locally.
- Updated and accepted the affected `insta` snapshots for the TUI
changes so visual diffs reflect the new `/stop` wording and preserved
interrupt behavior.
------
[Codex
Task](https://chatgpt.com/codex/tasks/task_i_69b39c44b6dc8323bd133ae206310fae)
- [x] Bypass tool search and stuff tool specs directly into model
context when either a. Tool search is not available for the model or b.
There are not that many tools to search for.
CXC-392
[With
401](https://openai.sentry.io/issues/7333870443/?project=4510195390611458&query=019ce8f8-560c-7f10-a00a-c59553740674&referrer=issue-stream)
<img width="1909" height="555" alt="401 auth tags in Sentry"
src="https://github.com/user-attachments/assets/412ea950-61c4-4780-9697-15c270971ee3"
/>
- auth_401_*: preserved facts from the latest unauthorized response snapshot
- auth_*: latest auth-related facts from the latest request attempt
- auth_recovery_*: unauthorized recovery state and follow-up result
Without 401
<img width="1917" height="522" alt="happy-path auth tags in Sentry"
src="https://github.com/user-attachments/assets/3381ed28-8022-43b0-b6c0-623a630e679f"
/>
###### Summary
- Add client-visible 401 diagnostics for auth attachment, upstream auth classification, and 401 request id / cf-ray correlation.
- Record unauthorized recovery mode, phase, outcome, and retry/follow-up status without changing auth behavior.
- Surface the highest-signal auth and recovery fields on uploaded client bug reports so they are usable in Sentry.
- Preserve original unauthorized evidence under `auth_401_*` while keeping follow-up result tags separate.
###### Rationale (from spec findings)
- The dominant bucket needed proof of whether the client attached auth before send or upstream still classified the request as missing auth.
- Client uploads needed to show whether unauthorized recovery ran and what the client tried next.
- Request id and cf-ray needed to be preserved on the unauthorized response so server-side correlation is immediate.
- The bug-report path needed the same auth evidence as the request telemetry path, otherwise the observability would not be operationally useful.
###### Scope
- Add auth 401 and unauthorized-recovery observability in `codex-rs/core`, `codex-rs/codex-api`, and `codex-rs/otel`, including feedback-tag surfacing.
- Keep auth semantics, refresh behavior, retry behavior, endpoint classification, and geo-denial follow-up work out of this PR.
###### Trade-offs
- This exports only safe auth evidence: header presence/name, upstream auth classification, request ids, and recovery state. It does not export token values or raw upstream bodies.
- This keeps websocket connection reuse as a transport clue because it can help distinguish stale reused sessions from fresh reconnects.
- Misroute/base-url classification and geo-denial are intentionally deferred to a separate follow-up PR so this review stays focused on the dominant auth 401 bucket.
###### Client follow-up
- PR 2 will add misroute/provider and geo-denial observability plus the matching feedback-tag surfacing.
- A separate host/app-server PR should log auth-decision inputs so pre-send host auth state can be correlated with client request evidence.
- `device_id` remains intentionally separate until there is a safe existing source on the feedback upload path.
###### Testing
- `cargo test -p codex-core refresh_available_models_sorts_by_priority`
- `cargo test -p codex-core emit_feedback_request_tags_`
- `cargo test -p codex-core emit_feedback_auth_recovery_tags_`
- `cargo test -p codex-core auth_request_telemetry_context_tracks_attached_auth_and_retry_phase`
- `cargo test -p codex-core extract_response_debug_context_decodes_identity_headers`
- `cargo test -p codex-core identity_auth_details`
- `cargo test -p codex-core telemetry_error_messages_preserve_non_http_details`
- `cargo test -p codex-core --all-features --no-run`
- `cargo test -p codex-otel otel_export_routing_policy_routes_api_request_auth_observability`
- `cargo test -p codex-otel otel_export_routing_policy_routes_websocket_connect_auth_observability`
- `cargo test -p codex-otel otel_export_routing_policy_routes_websocket_request_transport_observability`
## Summary
- normalize effective readable, writable, and unreadable sandbox roots
after resolving special paths so symlinked roots use canonical runtime
paths
- add a protocol regression test for a symlinked writable root with a
denied child and update protocol expectations to canonicalized effective
paths
- update macOS seatbelt tests to assert against effective normalized
roots produced by the shared policy helpers
## Testing
- just fmt
- cargo test -p codex-protocol
- cargo test -p codex-core explicit_unreadable_paths_are_excluded_
- cargo clippy -p codex-protocol -p codex-core --tests -- -D warnings
## Notes
- This is intended to fix the symlinked TMPDIR bind failure in
bubblewrap described in #14672.
Fixes#14672
This extends dynamic_tool_calls to allow us to hide a tool from the
model context but still use it as part of the general tool calling
runtime (for ex from js_repl/code_mode)
make plugins' `defaultPrompt` an array, but keep backcompat for strings.
the array is limited by app-server to 3 entries of up to 128 chars
(drops extra entries, `None`s-out ones that are too long) without
erroring if those invariants are violating.
added tests, tested locally.
We receive bug reports from users who attempt to override one of the
three built-in model providers (openai, ollama, or lmstuio). Currently,
these overrides are silently ignored. This PR makes it an error to
override them.
## Summary
- add validation for `model_providers` so `openai`, `ollama`, and
`lmstudio` keys now produce clear configuration errors instead of being
silently ignored
Move the general `Apps`, `Skills` and `Plugins` instructions blocks out
of `user_instructions` and into the developer message, with new `Apps ->
Skills -> Plugins` order for better clarity.
Also wrap those sections in stable XML-style instruction tags (like
other sections) and update prompt-layout tests/snapshots. This makes the
tests less brittle in snapshot output (we can parse the sections), and
it consolidates the capability instructions in one place.
#### Tests
Updated snapshots, added tests.
`<AGENTS_MD>` disappearing in snapshots is expected: before this change,
the wrapped user-instructions message was kept alive by `Skills`
content. Now that `Skills` and `Plugins` are in the developer message,
that wrapper only appears when there is real
project-doc/user-instructions content.
---------
Co-authored-by: Charley Cunningham <ccunningham@openai.com>