Tool renderers collapsed/expanded#3291
Conversation
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
The collapsed renderer implementations are clean and well-structured. The refactoring correctly extracts shared logic (e.g. filteredToolArgs, readMultipleFilesMeta, extractCommand) and the collapsed/expanded split follows a consistent pattern across all tool components. Two minor observations noted as inline comments.
| return header + "\n" + styles.ToolCallResult.Render(details) | ||
| } | ||
|
|
||
| func renderDetails(msg *types.Message, width int) string { |
There was a problem hiding this comment.
[LOW] renderDetails may show stale "pending" status after the tool has already completed
When msg.Content is non-empty (the tool finished) but renderOutputDetails fails to parse the JSON output (e.g. the output is not valid JSON, or is unexpectedly shaped), it returns "" and the function falls through to the arg-based rendering path. That path constructs a todo with Status: "pending" directly from the tool-call arguments, so a completed todo is briefly displayed as pending.
The realistic trigger is a malformed or empty-object JSON result from the todo tool backend; impact is a cosmetic display glitch — the status shown in the TUI won't match the actual outcome until the view is refreshed or re-rendered.
A targeted fix would be to check the tool completion status before falling through:
if msg.Content != "" {
if details := renderOutputDetails(msg, width); details != "" {
return details
}
// Output parsing failed but tool completed — show nothing rather than stale args
return ""
}| func render(msg *types.Message, s spinner.Spinner, sessionState service.SessionStateReader, width, _ int) string { | ||
| path := toolcommon.ExtractField(func(a filesystem.ReadFileArgs) string { return pathx.ShortenHome(a.Path) })(msg.ToolCall.Function.Arguments) | ||
| header := toolcommon.RenderTool(msg, s, path, extractResult(msg), width, sessionState.HideToolResults()) | ||
| if sessionState.HideToolResults() || msg.ToolStatus == types.ToolStatusError { |
There was a problem hiding this comment.
[LOW] Read-file preview shown for in-progress / pending status — inconsistent with writefile
The new render function skips the preview only when HideToolResults() is true or the status is ToolStatusError:
if sessionState.HideToolResults() || msg.ToolStatus == types.ToolStatusError {
return header
}
preview := formatLastLines(msg.Content, width)If msg.Content is ever non-empty while the tool is still running (e.g. during streaming), a partial preview would be surfaced. The sibling writefile renderer guards against this explicitly:
if msg.ToolStatus == types.ToolStatusCompleted || msg.ToolStatus == types.ToolStatusError {
result = msg.Content
}If read_file is guaranteed to only produce content after completion this is fine as-is, but adding a ToolStatusCompleted guard would make the intent explicit and guard against future streaming changes:
if sessionState.HideToolResults() || msg.ToolStatus != types.ToolStatusCompleted {
return header
}
Still WIP, our tool call rendering is not really great for an expanded view
Tool renderer previews
Generated with
go run /tmp/docker-agent-tool-renderer-preview.go. ANSI styling is stripped so the layout is readable in Markdown.API / fetch
Expanded
Collapsed
Default fallback
Expanded
Collapsed
Directory tree
Expanded
Collapsed
Edit file
Expanded
Collapsed
List directory
Expanded
Collapsed
Read file
Expanded
Collapsed
Read multiple files
Expanded
Collapsed
Search files content
Expanded
Collapsed
Shell
Expanded
Collapsed
Todo
Expanded
Collapsed
Write file
Expanded
Collapsed