Emit completed Codex plan artifacts via negotiated plan_update - #333
Open
s-cork wants to merge 3 commits into
Open
Emit completed Codex plan artifacts via negotiated plan_update#333s-cork wants to merge 3 commits into
s-cork wants to merge 3 commits into
Conversation
s-cork
marked this pull request as draft
July 24, 2026 08:44
s-cork
marked this pull request as ready for review
July 27, 2026 01:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
plan_updateevents when the client advertises the unstableclientCapabilities.plancapabilityagent_message_chunkfallback for clients without that capabilitysessionUpdate: "plan"execution-plan updates unchangedRationale
#326 fixed plan visibility by emitting completed Codex plan items as ordinary final-answer messages. That preserves broad client compatibility, but loses the plan semantic: a client cannot reliably distinguish a proposed plan from an ordinary final answer.
ACP currently exposes two related representations:
sessionUpdate: "plan", a complete execution-plan snapshot containing entries, priorities, and progress statusesplan_update, a richer plan artifact that can preserve Markdown content and a stableplanIdA completed Codex
ThreadItemof typeplancontains authoritative Markdown and a stable item ID. It therefore maps losslessly to a Markdownplan_update. Mapping it to the standard entry-based notification would require parsing the Markdown or inventing entry boundaries, priorities, and statuses, and would not preserve equivalent artifact identity.This PR does not replace or change the standard execution-plan notifications Codex already emits. It only changes the representation of the completed plan artifact when the client explicitly advertises support for the unstable richer update.
Compatibility
Clients without the unstable Plan capability retain the #326 representation:
agent_message_chunkmessageId_meta.codex.phase: "final_answer"The same choice is applied to live events and replayed session history.
Open design question
Should a completed Codex plan item be represented by the negotiated richer
plan_update, as implemented here, or should it be mapped into the standard entry-basedplannotification? The current implementation chooses the lossless richer representation when negotiated and preserves #326 as the fallback. Feedback on the intended protocol model is welcome.Testing
npm run typechecknpx vitest run src/__tests__/CodexACPAgent/load-session.test.ts— includes legacy replay without Plan capabilitynpm test— 329 passed, 28 skippednpm run bundle:allwith Bun 1.3.11git diff --check main...HEADRelated work
AI assisted with implementation, test verification, and PR text.