refactor(codex): drive host-installed codex via the app-server protocol - #137
refactor(codex): drive host-installed codex via the app-server protocol#137Waishnav wants to merge 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThe PR replaces one-shot
Confidence Score: 4/5The terminal response-selection defect should be fixed before merging because it can persist and display an answer that differs from the authoritative completed turn. The parser replaces streamed items with the completed turn’s authoritative items but retains any previously streamed response, allowing the returned answer and item log to disagree. Files Needing Attention: src/local-agent-runtime.ts
|
| Filename | Overview |
|---|---|
| src/local-agent-runtime.ts | Implements the app-server transport and protocol lifecycle, but terminal response selection can preserve stale streamed text. |
| src/local-agent-runtime.test.ts | Adds broad scripted protocol coverage, though streamed and terminal agent messages are always identical. |
| src/local-agent-adapters.ts | Replaces the Codex one-shot runtime with the new app-server runtime without an independently identified adapter defect. |
Sequence Diagram
sequenceDiagram
participant D as DevSpace
participant C as codex app-server
D->>C: initialize
C-->>D: initialize result
D->>C: initialized
alt New session
D->>C: thread/start
else Existing providerSessionId
D->>C: thread/resume
end
C-->>D: thread id
D->>C: turn/start
C-->>D: item/completed notifications
C-->>D: turn/completed (authoritative items)
D->>D: Build finalResponse and result
D->>C: Close stdin
Reviews (1): Last reviewed commit: "refactor(codex): drive host-installed co..." | Re-trigger Greptile
| for (const item of items) { | ||
| if (finalResponse) break; | ||
| const record = asRecord(item); | ||
| if (record?.type === "agentMessage" && typeof record.text === "string") { | ||
| finalResponse = record.text; | ||
| } | ||
| } |
There was a problem hiding this comment.
Terminal response remains stale
When a streamed agentMessage differs from the authoritative message in turn/completed, this loop retains the streamed text while replacing the item list with the terminal items, causing DevSpace to store and display the wrong final answer.
| for (const item of items) { | |
| if (finalResponse) break; | |
| const record = asRecord(item); | |
| if (record?.type === "agentMessage" && typeof record.text === "string") { | |
| finalResponse = record.text; | |
| } | |
| } | |
| for (const item of items) { | |
| const record = asRecord(item); | |
| if (record?.type === "agentMessage" && typeof record.text === "string") { | |
| finalResponse = record.text; | |
| } | |
| } |
The first version of the host-CLI Codex runner spawned a one-shot
codex execper turn and parsed a single JSON blob. That loses the streamed item events, depends on the exec JSON shape, and can't preserve a thread across turns without separate bookkeeping.Codex subagent runs now drive the persistent
codex app-serverJSON-RPC protocol over the child's stdio, the same harness shape the t3code agent uses:initialize->initialized->thread/start(orthread/resume) ->turn/start, then streamed notifications untilturn/completedcarries the authoritative item list.providerSessionIdmaps to an app-server thread id, so follow-up turns resume the same~/.codex/sessionsthread across process spawns. Runs stay non-interactive: approvals and other server->client requests are declined.The protocol lives behind an injectable
CodexAppServerWiretransport seam, sorunCodexAppServerTurnis exercisable offline against a scripted in-memory peer (start, resume, failed turn, and JSON-wrapped provider-gate errors are covered). Failed turns surface the CLI version, raw stderr, and the human-readable inner error message for model gates like "The '' model is not supported".Stacked on #136.