fix(desktop): render tool calls in the transcript instead of blank "Tool" rows - #820
Merged
Merged
Conversation
…ool" rows Tool activity reached the desktop transcript as contentless rows labelled "Tool", and raw content-block JSON leaked into assistant bubbles. Three mismatches against what the renderer actually reads (lib/chat-messages.ts): - `tool.complete` sent no `name`, so `upsertToolPart` fell back to the literal "tool". A tool_result names only its tool_use_id, so the session now carries an id -> name map across the assistant/user frame pair. - It sent `output`/`is_error`; `toolResult()` reads `result`/`error`, so every finished tool rendered empty. The agent's trimmed display envelope (`tool_use_result`: structuredPatch, filePath, duration_s, inline_diff, summary, preview) is forwarded too, which is what lets an Edit row show a diff rather than raw text. - Prose payloads passed content blocks through untouched, and the renderer's coerceGatewayText JSON-stringifies an object it can't read. `as_text()` flattens blocks and keeps only the text ones, so a tool_use block can no longer print itself into the transcript. Verified live against a real agent turn: labelled Read/Glob/Write rows with output and duration, and no tool_use JSON anywhere in the transcript. Co-Authored-By: Claude <noreply@anthropic.com>
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.
Tool activity reached the desktop transcript as contentless rows labelled "Tool", and raw content-block JSON leaked into assistant bubbles. The transcript looked nothing like the TUI's tool output.
Three mismatches against what the renderer actually reads (
ui-desktop/src/lib/chat-messages.ts):name)payload?.name || "tool"outputpayload.resultis_errorpayload.errorChanges
tool_resultnames only itstool_use_id, soDesktopSessionnow keeps an id → name map populated from the assistant frame'stool_useblocks and consumed when the result arrives.tool.completesendsresult/error. The agent's trimmed display envelope (tool_use_result:structuredPatch,filePath,duration_s,inline_diff,summary,preview) is forwarded as well — that is what lets an Edit row show a diff instead of raw text, and what puts the elapsed time on a long-running row.coerceGatewayText, which JSON-stringifies an object it cannot read — that is how a bare{"type":"tool_use",…}block ended up printed inside an assistant bubble. Newas_text()flattens content blocks and keeps only the text ones, so a tool block can never reach the transcript as prose.Testing
tests/server/test_desktop_translate.pypins the payload contract: name carried across thetool_use→tool_resultpair,result/errorfield names, display envelope forwarded, andas_textflattening a tool block to the empty string.Read/Glob/Writerows with their output and duration, a rendered approval bar, and notool_useJSON anywhere in the transcript.🤖 Generated with Claude Code