Skip to content

Commit 1965431

Browse files
committed
refine: compact tool result rendering — one line + ellipsis in gray
Tool results now show only the first line (truncated to 120 chars) with an ellipsis when there's more content. Rendered in gray instead of green to de-emphasize intermediate tool output and keep the terminal scannable during multi-tool chains.
1 parent 6747cb0 commit 1965431

2 files changed

Lines changed: 51 additions & 12 deletions

File tree

internal/render/render.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,20 @@ func (r *Renderer) ToolCall(name, args string) {
161161
fmt.Fprintf(r.w, "%s %s\n", label, r.style(gray, r.truncate(args, 120)))
162162
}
163163

164-
// ToolResult prints the output from a tool call.
165-
// Long output is truncated to MaxToolOutput characters.
164+
// ToolResult prints a one-line summary of the tool output in gray.
165+
// Long output is collapsed to the first line + ellipsis to keep the
166+
// terminal readable during multi-step tool chains.
166167
func (r *Renderer) ToolResult(output string) {
167168
if r.disable() || output == "" {
168169
return
169170
}
170-
r.label("result", green, output)
171+
// Take first line only, truncate, add ellipsis if there's more.
172+
line, _, _ := strings.Cut(output, "\n")
173+
summary := r.truncate(line, 120)
174+
if len(output) > len(line) || len(line) > 120 {
175+
summary += " …"
176+
}
177+
fmt.Fprintf(r.w, "%s\n", r.style(gray, " "+summary))
171178
}
172179

173180
// FinalAnswer prints the model's concluding response.

internal/render/render_test.go

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,24 +101,56 @@ func TestRenderer_ToolResult(t *testing.T) {
101101
if !strings.Contains(out, "file1.txt") {
102102
t.Errorf("ToolResult() missing output: %q", out)
103103
}
104-
if !strings.Contains(out, "result") {
105-
t.Errorf("ToolResult() missing label: %q", out)
104+
// Multi-line output should include ellipsis
105+
if !strings.Contains(out, "…") {
106+
t.Errorf("ToolResult() missing ellipsis for multi-line output: %q", out)
107+
}
108+
// Should NOT contain lines beyond the first
109+
if strings.Contains(out, "file2.txt") {
110+
t.Errorf("ToolResult() should only show first line, got: %q", out)
111+
}
112+
}
113+
114+
func TestRenderer_ToolResult_SingleLine(t *testing.T) {
115+
var buf bytes.Buffer
116+
r := New(&buf, true)
117+
118+
r.ToolResult("short output")
119+
120+
out := buf.String()
121+
if !strings.Contains(out, "short output") {
122+
t.Errorf("ToolResult() missing output: %q", out)
123+
}
124+
// Single short line — no ellipsis
125+
if strings.Contains(out, "…") {
126+
t.Errorf("ToolResult() should not have ellipsis for short single line: %q", out)
127+
}
128+
}
129+
130+
func TestRenderer_ToolResult_GrayColor(t *testing.T) {
131+
var buf bytes.Buffer
132+
r := New(&buf, true)
133+
134+
r.ToolResult("result text")
135+
136+
out := buf.String()
137+
// Should use gray (dim), not green
138+
if strings.Contains(out, green) {
139+
t.Errorf("ToolResult() should use gray, not green: %q", out)
106140
}
107141
}
108142

109143
func TestRenderer_ToolResult_Truncation(t *testing.T) {
110144
var buf bytes.Buffer
111145
r := New(&buf, true)
112146

113-
// A single line longer than MaxToolOutput should be truncated.
114-
longLine := strings.Repeat("x", MaxToolOutput+100)
147+
// A single line longer than 120 chars should be truncated.
148+
longLine := strings.Repeat("x", 200)
115149
r.ToolResult(longLine)
116150

117151
out := buf.String()
118-
// The output should be shorter than the original (truncated) and
119-
// end with the ellipsis character.
120-
if strings.Count(out, "x") >= len(longLine) {
121-
t.Errorf("ToolResult() should truncate long line, got %d x chars (input was %d)", strings.Count(out, "x"), len(longLine))
152+
if strings.Count(out, "x") >= 200 {
153+
t.Errorf("ToolResult() should truncate long line, got %d x chars (input was %d)", strings.Count(out, "x"), 200)
122154
}
123155
if !strings.Contains(out, "…") {
124156
t.Errorf("ToolResult() missing truncation ellipsis: %q", out)
@@ -239,7 +271,7 @@ func TestRenderer_FullCycle(t *testing.T) {
239271
out := buf.String()
240272

241273
// Verify each phase is present
242-
phases := []string{"iter 1/90", "thinking", "shell", "result", "iter 2/90", "answer"}
274+
phases := []string{"iter 1/90", "thinking", "shell", "package main", "iter 2/90", "answer"}
243275
for _, phase := range phases {
244276
if !strings.Contains(strings.ToLower(out), phase) {
245277
t.Errorf("FullCycle missing phase %q in output:\n%s", phase, out)

0 commit comments

Comments
 (0)