feat(web): render transcript text as markdown and payloads as JSON - #631
Merged
Conversation
User, assistant, prompt and (expanded) system bodies go through the existing MessageResponse markdown pipeline; tool arguments/results, subagent task prompts/returns and failed-call status messages are pretty-printed and highlighted where they parse as JSON (same tryParseJson test as the log body), each with a copy button that copies what is displayed. Every rendered body keeps a raw switch back to the captured text, held in openRows so the choice survives virtualization. Tool payloads now start collapsed, and the lab fixture gained markdown replies and a markdown system prompt so the harness exercises the new paths.
A lone pressed icon named either the current view or the one a click would bring, depending on who read it. The switch is now two labelled segments — md|raw or json|raw — where the selected segment is the view the reader is in.
…own-json-rendering # Conflicts: # apps/web/src/components/agent-sessions/session-detail/session-transcript.tsx
JeremyFunk
had a problem deploying
to
pr-preview
August 25, 2026 15:15 — with
GitHub Actions
Failure
🍁 Maple PR previewWarning Preview cleanup could not be confirmed. The Alchemy teardown outcome was Final commit |
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.
Follow-up to #624: the Transcript view rendered every captured body as plain pre-wrapped text. This gives each kind of body the reading it deserves, while keeping the captured bytes one click away.
What changed
Markdown for message text. User, assistant, prompt and (expanded) system bodies render through the existing
MessageResponsepipeline (Streamdown + Shiki/KaTeX/Mermaid), so replies with code fences, lists and inline code read the way the chat surfaces already do. The collapsed system preview stays the plain first line — a one-line elision of markdown source reads better raw.JSON detection for payloads. Tool arguments/results, subagent task prompts/returns and failed-call status messages go through a shared
useJsonPayloadhook: the sametryParseJsonobject/array test the log body uses, then pretty-print + sugar-high highlighting on a hit. Everything else stays verbatim — including an emitter-truncated prefix, which fails the parse on purpose rather than being dressed up as a whole document. Each payload gets a copy button that copies what is displayed.A rendered ↔ raw selector on every rendered body. Rendering is a reading of the capture, and a reading can hide things — whitespace, key order, a literal
**. Each rendered body carries a small segment pair (md | rawon message text,json | rawon payloads) where the selected segment is the view you are in; switching to raw shows the captured text verbatim and points the copy button at it. The pair only appears where the two views actually differ, and the choice lives in the existingopenRowsset so it survives the row scrolling out of the virtualizer.Tool payloads start collapsed. The "Tool payloads" chip now defaults off; every card opens on its one-line size summary.
ClampedTextgainedhtml(highlighted markup) andbody(rendered node) modes so all of the above still clamps and "Show full"s identically;textremains the measurement source. The lab fixture's closing replies and investigation system prompt are now markdown so/lab/agent-sessionexercises the new paths.Verification
tscpass.Known trade-off
JSON pretty-printing goes through
JSON.parse/stringify— the same accepted pattern as the log body viewer — so an integer above 2^53 inside a payload displays and copies with precision loss. The raw view is the escape hatch; a lexeme-preserving re-indenter is the fix if this bites in practice.🤖 Generated with Claude Code