Commit Graph
8051 Commits
Author SHA1 Message Date
Michael Bolin ff8ccedf53 Merge 3eb45b55db into sapling-pr-archive-bolinfest 2026-02-20 22:47:07 -08:00
Michael Bolin 3eb45b55db chore: move core/src/config_loader/diagnostics.rs to config/src/diagnostics.rs 2026-02-20 22:47:00 -08:00
Michael Bolin 8393f72d59 Merge 95060cf2b4 into sapling-pr-archive-bolinfest 2026-02-20 22:42:50 -08:00
Michael Bolin 95060cf2b4 chore: move core/src/config_loader/diagnostics.rs to config/src/diagnostics.rs 2026-02-20 22:42:42 -08:00
Michael Bolin c523dcadf7 Merge d022fb53fd into sapling-pr-archive-bolinfest 2026-02-20 22:30:42 -08:00
Michael Bolin d022fb53fd chore: move core/src/config_loader/diagnostics.rs to config/src/diagnostics.rs 2026-02-20 22:30:35 -08:00
Dylan Hurd a8b4b569fb fix(core) Filter non-matching prefix rules (#12314)
## Summary
`gpt-5.3-codex` really likes to write complicated shell scripts, and
suggest a partial prefix_rule that wouldn't actually approve the
command. We should only show the `prefix_rule` suggestion from the model
if it would actually fully approve the command the user is seeing.

This will technically cause more instances of overly-specific
suggestions when we fallback, but I think the UX is clearer,
particularly when the model doesn't necessarily understand the current
limitations of execpolicy parsing.

## Testing
 - [x] Add unit tests
 - [x] Add integration tests
2026-02-20 22:02:35 -08:00
Michael Bolin 1779feb6a7 ignore v1 in JSON schema codegen (#12408)
## Why

The generated unnamespaced JSON envelope schemas (`ClientRequest` and
`ServerNotification`) still contained both v1 and v2 variants, which
pulled legacy v1/core types and v2 types into the same `definitions`
graph. That caused `schemars` to produce numeric suffix names (for
example `AskForApproval2`, `ByteRange2`, `MessagePhase2`).

This PR moves JSON codegen toward v2-only output while preserving the
unnamespaced envelope artifacts, and avoids reintroducing numeric-suffix
tolerance by removing the v1/internal-only variants that caused the
collisions in those envelope schemas.

## What Changed

- In `codex-rs/app-server-protocol/src/export.rs`, JSON generation now
excludes v1 schema artifacts (`v1/*`) while continuing to emit
unnamespaced/root JSON schemas and the JSON bundle.
- Added a narrow JSON v1 allowlist (`JSON_V1_ALLOWLIST`) so
`InitializeParams` and `InitializeResponse` are still emitted.
- Added JSON-only post-processing for the mixed envelope schemas before
collision checks run:
- `ClientRequest`: strips v1 request variants from the generated `oneOf`
using the temporary `V1_CLIENT_REQUEST_METHODS` list
- `ServerNotification`: strips v1 notifications plus the internal-only
`rawResponseItem/completed` notification using the temporary
`EXCLUDED_SERVER_NOTIFICATION_METHODS_FOR_JSON` list
- Added a temporary local-definition pruning pass for those envelope
schemas so now-unreferenced v1/core definitions are removed from
`definitions` after method filtering.
- Updated the variant-title naming heuristic for single-property literal
object variants to use the literal value (when available), avoiding
collisions like multiple `state`-only variants all deriving the same
title.
- Collision handling remains fail-fast (no numeric suffix fallback map
in this PR path).

## Verification

- `just write-app-server-schema`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/12408).
* __->__ #12408
* #12406
2026-02-20 21:36:12 -08:00
Yaroslav Volovich dca9c40dd5 test(app-server): wait for turn/completed in turn_start tests (#12376)
## Summary
- switch a few app-server `turn_start` tests from
`codex/event/task_complete` waits to `turn/completed` waits
- avoid matching unrelated/background `task_complete` events
- keep this flaky test fix separate from the /title feature PR

## Why
On Windows ARM CI, these tests can return early after observing a
generic `codex/event/task_complete` notification from another task. That
can leave the mock Responses server with fewer calls than expected and
fail the test with a wiremock verification mismatch.

Using `turn/completed` matches the app-server turn lifecycle
notification the tests actually care about.

## Validation
- `cargo test -p codex-app-server
turn_start_updates_sandbox_and_cwd_between_turns_v2 -- --nocapture`
- `cargo test -p codex-app-server turn_start_exec_approval_ --
--nocapture`
- `just fmt`
2026-02-20 21:15:21 -08:00
Michael Bolin 2891d6505a merge commit for archive created by Sapling 2026-02-20 21:10:15 -08:00
Michael Bolin 5f3808c38a ignore v1 in JSON schema codegen 2026-02-20 21:10:10 -08:00
Michael Bolin 879b596270 merge commit for archive created by Sapling 2026-02-20 21:08:10 -08:00
Michael Bolin 2656d8a163 ignore v1 in JSON schema codegen 2026-02-20 21:08:05 -08:00
Michael Bolin 1a20c9914f merge commit for archive created by Sapling 2026-02-20 20:45:43 -08:00
Michael Bolin 97c63205d1 ignore v1 in JSON schema codegen 2026-02-20 20:45:37 -08:00
Michael Bolin 48af93399e feat: use OAI Responses API MessagePhase type directly in App Server v2 (#12422)
https://github.com/openai/codex/pull/10455 introduced the `phase` field,
and then https://github.com/openai/codex/pull/12072 introduced a
`MessagePhase` type in `v2.rs` that paralleled the `MessagePhase` type
in `codex-rs/protocol/src/models.rs`.

The app server protocol prefers `camelCase` while the Responses API uses
`snake_case`, so this meant we had two versions of `MessagePhase` with
different serialization rules. When the app server protocol refers to
types from the Responses API, we use the wire format of the the
Responses API even though it is inconsistent with the app server API.

This PR deletes `MessagePhase` from `v2.rs` and consolidates on the
Responses API version to eliminate confusion.
2026-02-20 20:43:36 -08:00
Michael Bolin a73efab8dd fix: address flakiness in thread_resume_rejoins_running_thread_even_with_override_mismatch (#12381)
## Why
`thread/resume` responses for already-running threads can be reported as
`Idle` even while a turn is still in progress. This is caused by a
timing window where the runtime watch state has not yet observed the
running-thread transition, so API clients can receive stale status
information at resume time.

Possibly related: https://github.com/openai/codex/pull/11786

## What
- Add a shared status normalization helper, `resolve_thread_status`, in
`codex-rs/app-server/src/thread_status.rs` that resolves
`Idle`/`NotLoaded` to `Active { active_flags: [] }` when an in-progress
turn is known.
- Reuse this helper across thread response paths in
`codex-rs/app-server/src/codex_message_processor.rs` (including
`thread/start`, `thread/unarchive`, `thread/read`, `thread/resume`,
`thread/fork`, and review/thread-started notification responses).
- In `handle_pending_thread_resume_request`, use both the in-memory
`active_turn_snapshot` and the resumed rollout turns to decide whether a
turn is in progress before resolving thread status for the response.
- Extend `thread_status` tests to validate the new status-resolution
behavior directly.

## Verification
- `cargo test -p codex-app-server
suite::v2::thread_resume::thread_resume_rejoins_running_thread_even_with_override_mismatch`
2026-02-20 20:36:04 -08:00
Michael Bolin 1bfc5b5708 merge commit for archive created by Sapling 2026-02-20 20:29:24 -08:00
Michael Bolin 8f937a4f25 feat: use OAI Responses API MessagePhase type directly in App Server v2 2026-02-20 20:29:16 -08:00
Ahmed Ibrahim b237f7cbb1 Add experimental realtime websocket backend prompt override (#12418)
- add top-level `experimental_realtime_ws_backend_prompt` config key
(experimental / do not use) and include it in config schema
- apply the override only to `Op::RealtimeConversation` websocket
`backend_prompt`, with config + realtime tests
2026-02-20 20:10:51 -08:00
Charley Cunningham 4c1744afb2 Improve Plan mode reasoning selection flow (#12303)
Addresses https://github.com/openai/codex/issues/11013

## Summary
- add a Plan implementation path in the TUI that lets users choose
reasoning before switching to Default mode and implementing
- add Plan-mode reasoning scope handling (Plan-only override vs
all-modes default), including config/schema/docs plumbing for
`plan_mode_reasoning_effort`
- remove the hardcoded Plan preset medium default and make the reasoning
popup reflect the active Plan override as `(current)`
- split the collaboration-mode switch notification UI hint into #12307
to keep this diff focused

If I have `plan_mode_reasoning_effort = "medium"` set in my
`config.toml`:
<img width="699" height="127" alt="Screenshot 2026-02-20 at 6 59 37 PM"
src="https://github.com/user-attachments/assets/b33abf04-6b7a-49ed-b2e9-d24b99795369"
/>

If I don't have `plan_mode_reasoning_effort` set in my `config.toml`:
<img width="704" height="129" alt="Screenshot 2026-02-20 at 7 01 51 PM"
src="https://github.com/user-attachments/assets/88a086d4-d2f1-49c7-8be4-f6f0c0fa1b8d"
/>

## Codex author
`codex resume 019c78a2-726b-7fe3-adac-3fa4523dcc2a`
2026-02-20 20:08:56 -08:00
Ahmed Ibrahim 7ae5d88016 Add experimental realtime websocket URL override (#12416)
- add top-level `experimental_realtime_ws_base_url` config key
(experimental / do not use) and include it in config schema
- apply the override only to `Op::RealtimeConversation` websocket
transport, with config + realtime tests
2026-02-20 19:51:20 -08:00
Michael Bolin 64c47faf42 Merge 81a7fd2a71 into sapling-pr-archive-bolinfest 2026-02-20 19:51:06 -08:00
Michael Bolin 81a7fd2a71 ignore v1 in JSON schema codegen 2026-02-20 19:40:36 -08:00
Michael Bolin 6861dd1c9c merge commit for archive created by Sapling 2026-02-20 19:38:20 -08:00
Michael Bolin 44731bc607 fix: address flakiness in thread_resume_rejoins_running_thread_even_with_override_mismatch 2026-02-20 19:37:51 -08:00
Rohan Godha 0644ba7b7e fix(nix): include libcap dependency on linux builds (#12415)
commit 923f931121 introduced a dependency
on `libcap`. This PR fixes the nix build by including `libcap` in nix's
build inputs

issue number: #12102. @etraut-openai gave me permission to open pr 

Testing:
running `nix run .#codex-rs` works on both macos (aarch64) and nixos
(x86-64)
2026-02-20 19:32:15 -08:00
Ahmed Ibrahim 6817f0be8a Wire realtime api to core (#12268)
- Introduce `RealtimeConversationManager` for realtime API management 
- Add `op::conversation` to start conversation, insert audio, insert
text, and close conversation.
- emit conversation lifecycle and realtime events.
- Move shared realtime payload types into codex-protocol and add core
e2e websocket tests for start/replace/transport-close paths.

Things to consider:
- Should we use the same `op::` and `Events` channel to carry audio? I
think we should try this simple approach and later we can create
separate one if the channels got congested.
- Sending text updates to the client: we can start simple and later
restrict that.
- Provider auth isn't wired for now intentionally
2026-02-20 19:06:35 -08:00
Michael Bolin 997f094587 merge commit for archive created by Sapling 2026-02-20 18:40:12 -08:00
Michael Bolin c17b80cb0e ignore v1 in JSON schema codegen 2026-02-20 18:40:06 -08:00
Michael Bolin 2c2fda3695 Merge 1ae001f0a2 into sapling-pr-archive-bolinfest 2026-02-20 18:27:39 -08:00
Michael Bolin 1ae001f0a2 fix: address flakiness in thread_resume_rejoins_running_thread_even_with_override_mismatch 2026-02-20 18:27:35 -08:00
natea-oai 936e744c93 Add field to Thread object for the latest rename set for a given thread (#12301)
Exposes through the app server updated names set for a thread. This
enables other surfaces to use the core as the source of truth for thread
naming. `threadName` is gathered using the helper functions used to
interact with `session_index.jsonl`, and is hydrated in:
- `thread/list`
- `thread/read`
- `thread/resume`
- `thread/unarchive`
- `thread/rollback`

We don't do this for `thread/start` and `thread/fork`.
2026-02-20 18:26:57 -08:00
Michael Bolin 1d87516326 merge commit for archive created by Sapling 2026-02-20 18:12:22 -08:00
Michael Bolin 16150e3045 ignore v1 in JSON schema codegen 2026-02-20 18:12:17 -08:00
Michael Bolin 53bcfaf42d fix: explicitly list name collisions in JSON schema generation (#12406)
## Why

JSON schema codegen was silently resolving naming collisions by
appending numeric suffixes (for example `...2`, `...3`). That makes the
generated schema names unstable: removing an earlier colliding type can
cause a later type to be renumbered, which is a breaking change for
consumers that referenced the old generated name.

This PR makes those collisions explicit and reviewable.

Though note that once we remove `v1` from the codegen, we will no longer
support naming collisions. Or rather, naming collisions will have to be
handled explicitly rather than the numeric suffix approach.

## What Changed

- In `codex-rs/app-server-protocol/src/export.rs`, replaced implicit
numeric suffix collision handling for generated variant titles with
explicit special-case maps.
- Added a panic when a collision occurs without an entry in the map, so
new collisions fail loudly instead of silently renaming generated schema
types.
- Added the currently required special cases so existing generated names
remain stable.
- Extended the same approach to numbered `definitions` / `$defs`
collisions (for example `MessagePhase2`-style names) so those are also
explicitly tracked.

## Verification

- Ran targeted generator-path test:
- `cargo test -p codex-app-server-protocol
generate_json_filters_experimental_fields_and_methods -- --nocapture`


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/12406).
* #12408
* __->__ #12406
2026-02-20 17:51:53 -08:00
Michael Bolin ab5f1a6cda merge commit for archive created by Sapling 2026-02-20 17:38:49 -08:00
Michael Bolin 77295de5eb ignore v1 in JSON schema codegen 2026-02-20 17:37:31 -08:00
Matthew Zeng 36a2a9fdbb [apps] Bump MCP tool call timeout. (#12405)
- [x] Bump MCP tool call timeout.
2026-02-20 17:35:07 -08:00
Michael Bolin 89eddb0f7a Merge ab6e2f4a46 into sapling-pr-archive-bolinfest 2026-02-20 17:14:49 -08:00
Michael Bolin ab6e2f4a46 ignore v1 in JSON schema codegen 2026-02-20 17:14:15 -08:00
Michael Bolin 630984da67 Merge 8ae9f99d41 into sapling-pr-archive-bolinfest 2026-02-20 17:13:44 -08:00
Michael Bolin 8ae9f99d41 feat: exclude v1 from the JSON schema 2026-02-20 17:13:36 -08:00
Michael Bolin e0dd63f416 merge commit for archive created by Sapling 2026-02-20 17:12:42 -08:00
Michael Bolin 4e38c6a73b fix: explicitly list name collisions in JSON schema generation 2026-02-20 17:11:27 -08:00
Michael Bolin b480a0eeae ignore v1 in JSON schema codegen 2026-02-20 17:11:27 -08:00
Michael Bolin 262dce480e Merge 8f6a59a37f into sapling-pr-archive-bolinfest 2026-02-20 16:58:47 -08:00
Michael Bolin 8f6a59a37f fix: explicitly list name collisions in JSON schema generation 2026-02-20 16:58:42 -08:00
Felipe Coury a5d0757ed1 fix(tui): queued-message edit shortcut unreachable in some terminals (#12240)
## Problem

The TUI's "edit queued message" shortcut (Alt+Up) is either silently
swallowed or recognized as another key combination by Apple Terminal,
Warp, and VSCode's integrated terminal on macOS. Users in those
environments see the hint but pressing the keys does nothing.

## Mental model

When a model turn is in progress the user can still type follow-up
messages. These are queued and displayed below the composer with a hint
line showing how to pop the most recent one back into the editor. The
hint text and the actual key handler must agree on which shortcut is
used, and that shortcut must actually reach the TUI—i.e. it must not be
intercepted by the host terminal.

Three terminals are known to intercept Alt+Up: Apple Terminal (remaps it
to cursor movement), Warp (consumes it for its own command palette), and
VSCode (maps it to "move line up"). For these we use Shift+Left instead.

<p align="center">
<img width="283" height="182" alt="image"
src="https://github.com/user-attachments/assets/4a9c5d13-6e47-4157-bb41-28b4ce96a914"
/>
</p>

| macOS Native Terminal | Warp | VSCode Terminal |
|---|---|---|
| <img width="1557" height="1010" alt="SCR-20260219-kigi"
src="https://github.com/user-attachments/assets/f4ff52f8-119e-407b-a3f3-52f564c36d70"
/> | <img width="1479" height="1261" alt="SCR-20260219-krrf"
src="https://github.com/user-attachments/assets/5807d7c4-17ae-4a2b-aa27-238fd49d90fd"
/> | <img width="1612" height="1312" alt="SCR-20260219-ksbz"
src="https://github.com/user-attachments/assets/1cedb895-6966-4d63-ac5f-0eea0f7057e8"
/> |

## Non-goals

- Making the binding user-configurable at runtime (deferred to a broader
keybinding-config effort).
- Remapping any other shortcuts that might be terminal-specific.

## Tradeoffs

- **Exhaustive match instead of a wildcard default.** The
`queued_message_edit_binding_for_terminal` function explicitly lists
every `TerminalName` variant. This is intentional: adding a new terminal
to the enum will produce a compile error, forcing the author to decide
which binding that terminal should use.

- **Binding lives on `ChatWidget`, hint lives on `QueuedUserMessages`.**
The key event handler that actually acts on the press is in
`ChatWidget`, but the rendered hint text is inside `QueuedUserMessages`.
These are kept in sync by `ChatWidget` calling
`bottom_pane.set_queued_message_edit_binding(self.queued_message_edit_binding)`
during construction. A mismatch would show the wrong hint but would not
lose data.

## Architecture

```mermaid
  graph TD
      TI["terminal_info().name"] --> FN["queued_message_edit_binding_for_terminal(name)"]
      FN --> KB["KeyBinding"]
      KB --> CW["ChatWidget.queued_message_edit_binding<br/><i>key event matching</i>"]
      KB --> BP["BottomPane.set_queued_message_edit_binding()"]
      BP --> QUM["QueuedUserMessages.edit_binding<br/><i>rendered in hint line</i>"]

      subgraph "Special terminals (Shift+Left)"
          AT["Apple Terminal"]
          WT["Warp"]
          VS["VSCode"]
      end

      subgraph "Default (Alt+Up)"
          GH["Ghostty"]
          IT["iTerm2"]
          OT["Others…"]
      end

      AT --> FN
      WT --> FN
      VS --> FN
      GH --> FN
      IT --> FN
      OT --> FN
```

No new crates or public API surface. The only cross-crate dependency
added is `codex_core::terminal::{TerminalName, terminal_info}`, which
already existed for telemetry.

## Observability

No new logging. Terminal detection already emits a `tracing::debug!` log
line at startup with the detected terminal name, which is sufficient to
diagnose binding mismatches.

## Tests

- Existing `alt_up_edits_most_recent_queued_message` test is preserved
and explicitly sets the Alt+Up binding to isolate from the host
terminal.
- New parameterized async tests verify Shift+Left works for Apple
Terminal, Warp, and VSCode.
- A sync unit test asserts the mapping table covers the three special
terminals (Shift+Left) and that iTerm2 still gets Alt+Up.
  
Fixes #4490
2026-02-20 16:56:41 -08:00
Matthew Zeng 4ebdddaa34 [apps] Fix gateway url. (#12403)
- [x] Fix connectors gateway url.
2026-02-21 00:47:15 +00:00