openai/codex
A user prompt enters either as a TUI `Op::UserTurn`, an exec submit, or an app-server `turn/start` params object. Core enqueues it on the session submission channel. `submission_loop` turns it into model input: prior rollout items plus a bounded developer/user context built from `core/context` fragments. The model streams Responses events; tool calls are dispatched by the tool router, their outputs are appended as function-call items, and the loop continues until the turn completes. Side effects (shell stdout, patch files, MCP results) are approved, sandboxed, then written back into the event stream and the rollout JSONL. Clients render `Event` values; nothing rewrites history except explicit compact, which summarizes and replaces older items under a size cap.
- `ModelClient::stream` posts to `/responses` or the Chat Completions endpoint. SSE frames are parsed into internal response items (`ResponseItem`) that the session converts into protocol events and rollout records.
- Shell output crosses a sandbox boundary. The orchestrator builds a `SandboxCommand`, asks the approval policy (`AskForApproval` plus execpolicy), then `spawn`s via the platform sandbox. Stdout/stderr are captured, truncated, and emitted as `ExecCommandEnd`.
- The TUI does not own business state. `ChatWidget` subscribes to core `Event`s, maps them to ratatui lines, and submits `Op`s when the composer submits or an approval overlay resolves. Transcript rendering helpers live in `tui/src/history_cell.rs` and wrapping helpers in `tui/src/wrapping.rs`.
- Auth data flows from `auth.json` or `CODEX_API_KEY` into `AuthManager::auth()`, which attaches a bearer token on `ModelClient` requests. Tokens are refreshed by the login crate; the CLI never puts the API key on the command line of the model request.
- Config override precedence is CLI flags over profile over project `.codex/config.toml` over user `config.toml` over system config. The resolved `Config` is the only object the session reads after startup.