Merge branch 'main' of https://github.com/openai/codex into dev/mzeng/connectors_codex_cli_1

This commit is contained in:
Matthew Zeng
2026-01-21 21:12:54 -08:00
950 changed files with 10629 additions and 82249 deletions
+4 -4
View File
@@ -1,8 +1,8 @@
# Exit and shutdown flow (tui + tui2)
# Exit and shutdown flow (tui)
This document describes how exit, shutdown, and interruption work in the Rust TUIs (`codex-rs/tui`
and `codex-rs/tui2`). It is intended for Codex developers and Codex itself when reasoning about
future exit/shutdown changes.
This document describes how exit, shutdown, and interruption work in the Rust TUI (`codex-rs/tui`).
It is intended for Codex developers and Codex itself when reasoning about future exit/shutdown
changes.
This doc replaces earlier separate history and design notes. High-level history is summarized
below; full details are captured in PR #8936.
+28 -8
View File
@@ -6,12 +6,10 @@ for Windows terminals.
Primary implementations:
- `codex-rs/tui/src/bottom_pane/chat_composer.rs`
- `codex-rs/tui2/src/bottom_pane/chat_composer.rs`
Paste-burst detector:
- `codex-rs/tui/src/bottom_pane/paste_burst.rs`
- `codex-rs/tui2/src/bottom_pane/paste_burst.rs`
## What problem is being solved?
@@ -51,6 +49,34 @@ The solution is to detect paste-like _bursts_ and buffer them into a single expl
- After handling the key, `sync_popups()` runs so popup visibility/filters stay consistent with the
latest text + cursor.
## Submission flow (Enter/Tab)
There are multiple submission paths, but they share the same core rules:
### Normal submit/queue path
`handle_submission` calls `prepare_submission_text` for both submit and queue. That method:
1. Expands any pending paste placeholders so element ranges align with the final text.
2. Trims whitespace and rebases element ranges to the trimmed buffer.
3. Expands `/prompts:` custom prompts:
- Named args use key=value parsing.
- Numeric args use positional parsing for `$1..$9` and `$ARGUMENTS`.
The expansion preserves text elements and yields the final submission payload.
4. Prunes attachments so only placeholders that survive expansion are sent.
5. Clears pending pastes on success and suppresses submission if the final text is empty and there
are no attachments.
### Numeric auto-submit path
When the slash popup is open and the first line matches a numeric-only custom prompt with
positional args, Enter auto-submits without calling `prepare_submission_text`. That path still:
- Expands pending pastes before parsing positional args.
- Uses expanded text elements for prompt expansion.
- Prunes attachments based on expanded placeholders.
- Clears pending pastes after a successful auto-submit.
## Paste burst: concepts and assumptions
The burst detector is intentionally conservative: it only processes “plain” character input
@@ -194,12 +220,6 @@ The `PasteBurst` logic is currently exercised through `ChatComposer` integration
- `question_mark_does_not_toggle_during_paste_burst`
- `burst_paste_fast_small_buffers_and_flushes_on_stop`
- `burst_paste_fast_large_inserts_placeholder_on_flush`
- `codex-rs/tui2/src/bottom_pane/chat_composer.rs`
- `non_ascii_burst_handles_newline`
- `ascii_burst_treats_enter_as_newline`
- `question_mark_does_not_toggle_during_paste_burst`
- `burst_paste_fast_small_buffers_and_flushes_on_stop`
- `burst_paste_fast_large_inserts_placeholder_on_flush`
This document calls out some additional contracts (like “flush before clearing”) that are not yet
fully pinned by dedicated `PasteBurst` unit tests.
+39
View File
@@ -0,0 +1,39 @@
# Request user input overlay (TUI)
This note documents the TUI overlay used to gather answers for
`RequestUserInputEvent`.
## Overview
The overlay renders one question at a time and collects:
- A single selected option (when options exist).
- Freeform notes (always available).
When options are present, notes are stored per selected option and the first
option is selected by default, so every option question has an answer. If a
question has no options and no notes are provided, the answer is submitted as
`skipped`.
## Focus and input routing
The overlay tracks a small focus state:
- **Options**: Up/Down move the selection and Space selects.
- **Notes**: Text input edits notes for the currently selected option.
Typing while focused on options switches into notes automatically to reduce
friction for freeform input.
## Navigation
- Enter advances to the next question.
- Enter on the last question submits all answers.
- PageUp/PageDown navigate across questions (when multiple are present).
- Esc interrupts the run.
## Layout priorities
The layout prefers to keep the question and all options visible. Notes and
footer hints collapse as space shrinks, with notes falling back to a single-line
"Notes: ..." input in tight terminals.
-97
View File
@@ -1,97 +0,0 @@
# Performance testing (`codex-tui2`)
This doc captures a repeatable workflow for investigating `codex-tui2` performance issues
(especially high idle CPU and high CPU while streaming) and validating optimizations to the draw
hot path.
## Scope (this round)
The current focus is the transcript draw hot path, specifically the cost of repeatedly rendering
the same visible transcript lines via Ratatui’s `Line::render_ref` (notably grapheme segmentation
and span layout).
The intended mitigation is a **rasterization cache**: render a wrapped transcript `Line` into a
row of `Cell`s once, cache it, and on subsequent redraws copy cached cells into the frame buffer.
Key invariants:
- The cache is width-scoped (invalidate on terminal width changes).
- The cache stores **base content** only; selection highlight and copy affordances are applied
after rendering, so they don’t pollute cached rows.
## Roles
- Human: runs `codex-tui2` in an interactive terminal (e.g. Ghostty), triggers “idle” and
“streaming” scenarios, and captures profiles.
- Assistant (or a script): reads profile output and extracts hotspots and deltas.
## Baseline setup
Build from a clean checkout:
```sh
cd codex-rs
cargo build -p codex-tui2
```
Run `codex-tui2` in a terminal and get a PID (macOS):
```sh
pgrep -n codex-tui2
```
Track CPU quickly while reproducing:
```sh
top -pid "$(pgrep -n codex-tui2)"
```
## Capture profiles (macOS)
Capture both an “idle” and a “streaming” profile so hotspots are not conflated:
```sh
sample "$(pgrep -n codex-tui2)" 1 -file /tmp/tui2.idle.sample.txt
sample "$(pgrep -n codex-tui2)" 1 -file /tmp/tui2.streaming.sample.txt
```
For the streaming sample, trigger a response that emits many deltas (e.g. “Tell me a story”) so
the stream runs long enough to sample.
## Quick hotspot extraction
These `rg` patterns keep the investigation grounded in the data:
```sh
# Buffer diff hot path (idle)
rg -n "custom_terminal::diff_buffers|diff_buffers" /tmp/tui2.*.sample.txt | head -n 80
# Transcript rendering hot path (streaming)
rg -n "App::render_transcript_cells|Line::render|render_spans|styled_graphemes|GraphemeCursor::next_boundary" /tmp/tui2.*.sample.txt | head -n 120
```
## Rasterization-cache validation checklist
After implementing a transcript rasterization cache, re-run the same scenarios and confirm:
- Streaming sample shifts away from `unicode_segmentation::grapheme::GraphemeCursor::next_boundary`
stacks dominating the main thread.
- CPU during streaming drops materially vs baseline for the same streaming load.
- Idle CPU does not regress (redraw gating changes can mask rendering improvements; always measure
both idle and streaming).
## Notes to record per run
- Terminal size: width × height
- Scenario: idle vs streaming (prompt + approximate response length)
- CPU snapshot: `top` (directional)
- Profile excerpt: 20–50 relevant lines for the dominant stacks
## Code pointers
- `codex-rs/tui2/src/transcript_view_cache.rs`: wrapped transcript memoization + per-line
rasterization cache (cached `Cell` rows).
- `codex-rs/tui2/src/transcript_render.rs`: incremental helper used by the wrapped-line cache
(`append_wrapped_transcript_cell`).
- `codex-rs/tui2/src/app.rs`: wiring in `App::render_transcript_cells` (uses cached rows instead of
calling `Line::render_ref` every frame).