feat(kap-server): add v3 message streaming and transcript APIs - #3532
feat(kap-server): add v3 message streaming and transcript APIs#3532sailist wants to merge 4 commits into
Conversation
|
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e28327a85d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| for (const item of materializer.materialize(op)) { | ||
| target.send(this.buildV3Envelope(state, v3ItemFrame(item, seq))); |
There was a problem hiding this comment.
Preserve op-batch atomicity in v3 catch-up
When one transcript op batch materializes into multiple items, this sends each as a separate frame carrying the same seq. If the connection drops after the client receives and persists that sequence from an early frame, reconnecting with transcript_since skips the entire batch, permanently losing the remaining messages; the client also has no marker indicating which frame is last. Send the materialized batch atomically or add an item index/count or completion marker so the watermark can be committed safely.
AGENTS.md reference: AGENTS.md:L28-L28
Useful? React with 👍 / 👎.
| id: `remove.${this.removeCounter}`, | ||
| session_id: env.sessionId, | ||
| agent_id: env.agentId, | ||
| ids: [...op.ids], |
There was a problem hiding this comment.
Remove child messages when undoing a turn
When context.undone removes a turn that has already streamed steps and frames, onContextUndone puts only top-level item IDs and anchored interaction IDs in op.ids, and this forwards that list unchanged. Because v3 exposes each step and frame as an independent message, applying this removal deletes the turn message but leaves its step_*, text, thinking, and tool messages orphaned, diverging from the REST snapshot where the whole turn subtree is gone. Include every flattened descendant ID in the removal.
Useful? React with 👍 / 👎.
Related Issue
Internal task (feat-148); no linked issue.
Problem
Session consumers that want a message-level view of a session must either run the transcript op-application engine themselves (subscribe_v2 pushes
TranscriptOperationbatches with upsert/append/offset semantics) or fall back to the legacy messages API, which covers only the main agent and carries no agent/turn/step identifiers. There is no message-granular streaming surface that is structurally identical to a REST read.What changed
@moonshot-ai/transcript— v3 wire contract + materializer: a 20-type snake_caseMessageunion (turn/step lifecycle incl. step retry, text/thinking/tool frames, marker/taskref, task/interaction/attachment/todo/prompt, four flat meta singletons, remove) plusMessageDelta(append);MessageV3Materializerconverts transcript ops into complete messages and snapshots into time-ordered message lists.subscribe_v3/unsubscribe_v3on the existing/api/v1/wsendpoint: pushesmessage.reset/message/message.deltaframes and reuses the v2 grade machinery (off/turn/block/delta). Deliberately no watermark/resume semantics: a (re)subscribe always starts with a full-snapshotmessage.reset, then only live frames; reconnect = resubscribe for a fresh snapshot. Reset is a subscribe invariant — every subscribed agent gets one (empty when stateless) — and any undo/clear re-sends a full reset instead of incremental removals.GET /api/v3/sessions/{session_id}/transcript?agent_id=: returns the same fullMessage[](unpaginated), wrapped in the standard response envelope; isomorphic tomessage.reset.items.removecarries cascaded interaction ids;prompt.queued/context.undoneare suppressed for graded connections (they were double-delivered before).packages/agent-core-v2is untouched; v1/v2 surfaces (incl. subscribe_v2 watermarks/replay) are unchanged.Reference docs for the v3 surface will follow in a separate change.
Checklist
/approve).gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.