Commit Graph

6 Commits

  • fix(tui): restore remote resume and fork history (#14930)
    ## Problem
    
    When the TUI connects to a **remote** app-server (via WebSocket), resume
    and fork operations lost all conversation history.
    `AppServerStartedThread` carried only the `SessionConfigured` event, not
    the full `Thread` snapshot. After resume or fork, the chat transcript
    was empty — prior turns were silently discarded.
    
    A secondary issue: `primary_session_configured` was not cleared on
    reset, causing stale session state after reconnection.
    
    ## Approach: TUI-side only, zero app-server changes
    
    The app-server **already returns** the full `Thread` object (with
    populated `turns: Vec<Turn>`) in its `ThreadStartResponse`,
    `ThreadResumeResponse`, and `ThreadForkResponse`. The data was always
    there — the TUI was simply throwing it away. The old
    `AppServerStartedThread` struct only kept the `SessionConfiguredEvent`,
    discarding the rich turn history that the server had already provided.
    
    This PR fixes the problem entirely within `tui_app_server` (3 files
    changed, 0 changes to `app-server`, `app-server-protocol`, or any other
    crate). Rather than modifying the server to send history in a different
    format or adding a new endpoint, the fix preserves the existing `Thread`
    snapshot and replays it through the TUI's standard event pipeline —
    making restored sessions indistinguishable from live ones.
    
    ## Solution
    
    Add a **thread snapshot replay** path. When the server hands back a
    `Thread` object (on start, resume, or fork),
    `restore_started_app_server_thread` converts its historical turns into
    the same core `Event` sequence the TUI already processes for live
    interactions, then replays them into the event store so the chat widget
    renders them.
    
    Key changes:
    - **`AppServerStartedThread` now carries the full `Thread`** —
    `started_thread_from_{start,resume,fork}_response` clone the thread into
    the struct alongside the existing `SessionConfiguredEvent`.
    - **`thread_snapshot_events()`** walks the thread's turns and items,
    producing `TurnStarted` → `ItemCompleted`* →
    `TurnComplete`/`TurnAborted` event sequences that the TUI already knows
    how to render.
    - **`restore_started_app_server_thread()`** pushes the session event +
    history events into the thread channel's store, activates the channel,
    and replays the snapshot — used for initial startup, resume, and fork.
    - **`primary_session_configured` cleared on reset** to prevent stale
    session state after reconnection.
    
    ## Tradeoffs
    
    - **`Thread` is cloned into `AppServerStartedThread`**: The full thread
    snapshot (including all historical turns) is cloned at startup. For
    long-lived threads this could be large, but it's a one-time cost and
    avoids lifetime gymnastics with the response.
    
    ## Tests
    
    - `restore_started_app_server_thread_replays_remote_history` —
    end-to-end: constructs a `Thread` with one completed turn, restores it,
    and asserts user/agent messages appear in the transcript.
    - `bridges_thread_snapshot_turns_for_resume_restore` — unit: verifies
    `thread_snapshot_events` produces the correct event sequence for
    completed and interrupted turns.
    
    ## Test plan
    
    - [ ] Verify `cargo check -p codex-tui-app-server` passes
    - [ ] Verify `cargo test -p codex-tui-app-server` passes
    - [ ] Manual: connect to a remote app-server, resume an existing thread,
    confirm history renders in the chat widget
    - [ ] Manual: fork a thread via remote, confirm prior turns appear
  • Fix tui_app_server: ignore duplicate legacy stream events (#14892)
    The in-process app-server currently emits both typed
    `ServerNotification`s and legacy `codex/event/*` notifications for the
    same live turn updates. `tui_app_server` was consuming both paths, so
    message deltas and completed items could be enqueued twice and rendered
    as duplicated output in the transcript.
    
    Ignore legacy notifications for event types that already have typed (app
    server) notification handling, while keeping legacy fallback behavior
    for events that still only arrive on the old path. This preserves
    compatibility without duplicating streamed commentary or final agent
    output.
    
    We will remove all of the legacy event handlers over time; they're here
    only during the short window where we're moving the tui to use the app
    server.
  • [stack 2/4] Align main realtime v2 wire and runtime flow (#14830)
    ## Stack Position
    2/4. Built on top of #14828.
    
    ## Base
    - #14828
    
    ## Unblocks
    - #14829
    - #14827
    
    ## Scope
    - Port the realtime v2 wire parsing, session, app-server, and
    conversation runtime behavior onto the split websocket-method base.
    - Branch runtime behavior directly on the current realtime session kind
    instead of parser-derived flow flags.
    - Keep regression coverage in the existing e2e suites.
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Apply argument comment lint across codex-rs (#14652)
    ## Why
    
    Once the repo-local lint exists, `codex-rs` needs to follow the
    checked-in convention and CI needs to keep it from drifting. This commit
    applies the fallback `/*param*/` style consistently across existing
    positional literal call sites without changing those APIs.
    
    The longer-term preference is still to avoid APIs that require comments
    by choosing clearer parameter types and call shapes. This PR is
    intentionally the mechanical follow-through for the places where the
    existing signatures stay in place.
    
    After rebasing onto newer `main`, the rollout also had to cover newly
    introduced `tui_app_server` call sites. That made it clear the first cut
    of the CI job was too expensive for the common path: it was spending
    almost as much time installing `cargo-dylint` and re-testing the lint
    crate as a representative test job spends running product tests. The CI
    update keeps the full workspace enforcement but trims that extra
    overhead from ordinary `codex-rs` PRs.
    
    ## What changed
    
    - keep a dedicated `argument_comment_lint` job in `rust-ci`
    - mechanically annotate remaining opaque positional literals across
    `codex-rs` with exact `/*param*/` comments, including the rebased
    `tui_app_server` call sites that now fall under the lint
    - keep the checked-in style aligned with the lint policy by using
    `/*param*/` and leaving string and char literals uncommented
    - cache `cargo-dylint`, `dylint-link`, and the relevant Cargo
    registry/git metadata in the lint job
    - split changed-path detection so the lint crate's own `cargo test` step
    runs only when `tools/argument-comment-lint/*` or `rust-ci.yml` changes
    - continue to run the repo wrapper over the `codex-rs` workspace, so
    product-code enforcement is unchanged
    
    Most of the code changes in this commit are intentionally mechanical
    comment rewrites or insertions driven by the lint itself.
    
    ## Verification
    
    - `./tools/argument-comment-lint/run.sh --workspace`
    - `cargo test -p codex-tui-app-server -p codex-tui`
    - parsed `.github/workflows/rust-ci.yml` locally with PyYAML
    
    ---
    
    * -> #14652
    * #14651
  • Move TUI on top of app server (parallel code) (#14717)
    This PR replicates the `tui` code directory and creates a temporary
    parallel `tui_app_server` directory. It also implements a new feature
    flag `tui_app_server` to select between the two tui implementations.
    
    Once the new app-server-based TUI is stabilized, we'll delete the old
    `tui` directory and feature flag.