Use native Codex steering and transcript deletion
This commit is contained in:
1 parent
00538cc19b
commit
8c88a7e991
12 files changed
+1004
-390
No files matched your search
@@ -29,7 +29,7 @@ Android app (Compose)
|
||||
backend (Rust/Axum, desktop)
|
||||
├─ SessionManager ── Session ── Driver (trait)
|
||||
│ ├─ ClaudeDriver (claude stream-json over stdio)
|
||||
│ ├─ CodexDriver (codex exec --json, one process per turn)
|
||||
│ ├─ CodexDriver (persistent codex app-server JSONL)
|
||||
│ ├─ LlamaDriver (llama-server over HTTP)
|
||||
│ └─ EchoDriver (the test rig)
|
||||
│ each driver's process is spawned through a Transport,
|
||||
@@ -193,25 +193,24 @@ is the rule behind the import refusal, the single `ClaudeDriver::launch`
|
||||
entry point, and the `Exited` correction below; two CLIs on one session file
|
||||
duplicate the conversation into it and bill the second for re-reading it all.
|
||||
|
||||
### Codex driver specifics (2026-09-07)
|
||||
### Codex driver specifics (2026-09-09)
|
||||
|
||||
Codex uses `codex exec --json`, whose stdout is JSONL: `thread.started`, turn
|
||||
boundaries, item start/completion records, and the final token usage. The
|
||||
driver translates those records into the same events as every other session
|
||||
and persists the reported thread id. Later turns run `codex exec resume <id>
|
||||
--json`; model, effort and attachments remain launch arguments owned by the
|
||||
driver rather than branches in routes or screens.
|
||||
Codex uses one persistent `codex app-server --stdio` per session. The original
|
||||
2026-09-07 implementation used one `codex exec --json` process per turn, but
|
||||
that surface cannot steer: a message typed during work was held until the turn
|
||||
ended, and Pause killed the whole process before starting another resume. The
|
||||
app-server protocol provides the operations the interface actually promises:
|
||||
`turn/steer` injects a message into the active turn and `turn/interrupt` stops
|
||||
that turn while leaving the conversation process alive.
|
||||
|
||||
One `exec` process is one turn and exits normally at its end. The session
|
||||
therefore owns a sequence of child processes rather than one permanently idle
|
||||
child: a clean exit after `turn.completed` means `idle`, while an exit before a
|
||||
turn boundary is an error. A process in flight still uses `process.json` plus
|
||||
detached stdout/stderr logs, so it survives and is adopted across a backend
|
||||
restart exactly like the long-lived CLI. Messages received during a turn are
|
||||
persisted and start later turns in order. The JSON exec surface has no stdin
|
||||
steering or interactive approval protocol, so it cannot inject a message at a
|
||||
tool boundary or answer a question inside the same process; those limits are
|
||||
reported rather than guessed around.
|
||||
The process's stdin is a fifo and its output is a detached log, with protocol
|
||||
state persisted beside the thread id. It therefore survives and is adopted
|
||||
across a backend restart like the Claude CLI. A steer is sent immediately and
|
||||
is announced where Codex emits its user-message item; if Codex says the active
|
||||
turn is not steerable, the message remains queued and starts the next turn
|
||||
instead of being lost. An interrupt requested while a turn is still starting
|
||||
is applied once Codex supplies that turn's id, so it cannot leak forward and
|
||||
hide a later failure.
|
||||
|
||||
Codex subscription limits come from the CLI's `account/rateLimits/read`
|
||||
app-server request on the machine whose setup runs Codex. This keeps login and
|
||||
@@ -810,6 +809,13 @@ directory under `$XDG_DATA_HOME/ai-app/sessions/` (transcript, attachments,
|
||||
produced images, process record), owner-only. Deleting a session is the
|
||||
complete path out of everything spawning one created.
|
||||
|
||||
Claude Code and Codex also keep their own durable transcript. The delete
|
||||
dialog names that owner and can remove its copy too: Claude files are resolved
|
||||
under `~/.claude/projects`, while a Codex thread id resolves only the matching
|
||||
rollout under `~/.codex/sessions`. The provider-owned copy is deleted first, so
|
||||
a remote-machine failure leaves the app session intact rather than reporting a
|
||||
half-delete as success.
|
||||
|
||||
**Every request body refuses fields it does not know**
|
||||
(`serde(deny_unknown_fields)`). A caller that misspells `permissionMode` got
|
||||
a 200 and a session in the default mode, which is indistinguishable from
|
||||
|
||||
Reference in new issue
Block a user