feat(workbench): Agent Document stage over server-decoded render events (#105 stage 2) - #231
Conversation
…ts (#105 stage 2) Decode a succeeded run's stored Flight on the dev server through the optional runtime peer, serve the bounded render-event sequence read-only, and render it in a shared Workbench stage with markdown projection, all node kinds, live progress, render diagnostics, and an inspectable event timeline.
🦋 Changeset detectedLatest commit: 6e28fc8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6e28fc83df
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Heads-up: hosted main CI went red with this merge and stayed red through #234 — deterministic failures in |
Second and final #105 stage-2 slice (per #107 rev 2: "Agent Document stage + Markdown projection"). The Workbench now renders the #140 Agent Document / render-event stream for route runs instead of raw JSON.
Flight stays internal (#107 constraint)
GET /api/runtime/runs/:id/documenton the foreground dev server (same-session guard, query strings rejected, GET-only): reads the succeeded run's stored Flight bytes (same source as the existing flight download) and decodes them throughdecodeAgentFlightStreamwith the defaultAgentRenderLimits, responding with the orderedshell/progress/replace/error/completeevent sequence as JSON. The browser never sees Flight bytes.@agent-bundle/runtimeis an optional peer, so the route uses the repo's documented cached lazy-import pattern: a missing peer yields AB8207 (503), an undecodable payload AB8208 (409) — honest diagnostics, never a fabricated document. A unit test renders REAL Flight in a react-server-condition child worker and proves the foreground process decodes it (plus absent-peer, guard, and query-rejection cases).Browser wire discipline
AgentDocumentClient(workbench) fetches via the same foreground-request authority as the manifest client and strictly decodes the full event union and every node kind withz.strictObjectschemas (recursiveresult,markdown,text,context,json,progress,image,audio,resource,error; document{version:1,status,root,value?}). Unknown fields fail loudly. Endpoint + decoder land together; no existing DTO widened. The Workbench does not import the runtime package.Stage + fold + integration
foldAgentDocumentEvents: latest snapshot-carrying event wins (replaceIS the Suspense replacement, resolved server-side), progress drives a live status line, error events accumulate into a diagnostics strip,completepins final status.AgentDocumentStage: markdown through the SAME audited projector the Skills page uses (extracted asMarkdownProjectorfromskill-markdown.tsx— no new markdown dependency), context labeled as the host context channel, json pretty-printed, image/audio as real data-URI elements, resource rows, error nodes marked with code+message, document status/version, and an event timeline where selecting an event renders the document as of that event.MCP wire shape (investigated, reported honestly)
documentToCallToolResultlowers the final document into plain MCP content blocks (text/image/audio/resource_link) withstructuredContentfromdocument.value— the AgentDocument itself is deliberately NOT on the MCP protocol wire (that lowering is the target-projection story). So the MCP page keeps showing the projection the server actually returned, and compiled MCP tools reach the document stage through their runtime runs (mcp-toolsurfaces produce Flight-bearing envelopes the playground now decodes). Nothing is fabricated client-side.Verification
pnpm typecheck+ all example typechecks: clean.pnpm lint: clean.runtime-playground.e2e.test.ts(real Chrome, 1440×900) 3/3 — the hook run's stored Flight decodes into a rendered Agent Document (Version 1 · success, text content as elements, Complete timeline entry) and an MCP-element run shows the honest decode diagnostic; rstest-browser Document-tab coverage renders real markdown headings.