[Feature] mcp-tool-output-collapse #2199
piromagnus
started this conversation in
Feature requests
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Area
Agent core, TUI
Problem
I remarked that the mcp tool called are not collapsed like the refinements tool call.
Could you add this. I have a local update if you want it, i can provide it.
Proposed direction
1. What the fix does (user-visible)
Ctrl+Ois bound toapp.tools.expand("Toggle tool output").interactive-mode.jstoggles
setExpanded(bool)on everyToolExecutionComponent— that part always worked.The bug: for tools without custom
renderCall/renderResultrenderers — which isthe case for all MCP tools (
ctx_execute,ctx_search, ...) — the component falls backto generic renderers that ignored
this.expandedand always printed the FULL tooloutput:
createResultFallback()→new Text(theme.fg("toolOutput", output))with full outputformatToolExecution()(used when the tool has no definition at all) → full pretty-JSONargs + full output
Built-in
bashalready collapsed properly (seerebuildBashResultRenderComponentindist/core/tools/bash.js): last 5 visual lines,... N earlier linesplus a(Ctrl+O to expand)hint, cached per render width.After the patch, MCP tool output behaves the same way:
Expanded (Ctrl+O again) shows the full output, as before. Built-in tool renderers
(bash, edit, ipython, ...) and the panel header logic are untouched.
2. How it works (internals)
Both copies of
ToolExecutionComponent(ESM + bundle) receive the same three changes:a)
createResultFallback()— the result fallback used by MCP tools. Whenthis.expandedis false it now returns a duck-typed "component" object instead of aText:render(width)lazily truncates the styled output withtruncateToVisualLines(styled, 5, width)and caches{lines, skipped, width}in a closure — recomputed only when therender width changes.
skippedCount > 0, it prepends the hint line:... N earlier lines+expandCollapseHint("app.tools.expand", false)whenthis.showExpandHint, else... (N earlier lines). The hint line is itself clampedwith
truncateToWidth(hint, width, "...").invalidate()clears the width cache.b)
createCollapsedArgsSummary()(new helper) —JSON.stringify(args)on a singleline, clamped to 120 columns via
truncateToWidth(..., "..."). Used byformatToolExecution()when collapsed, replacing the multi-line pretty JSON.c)
formatToolExecution()(no-definition path) — collapsed: emits only the compactargs summary (the output preview component is mounted separately by
updateDisplay());expanded: pretty JSON + full output exactly as before.
Module constants added in both files:
RESULT_PREVIEW_LINES = 5,ARGS_SUMMARY_MAX_WIDTH = 120.ESM file additionally imports
truncateToWidth(from@earendil-works/pi-tui),expandCollapseHint(./keybinding-hints.js) andtruncateToVisualLines(
./visual-truncate.js). The bundle chunk already had all three in scope at its top(lines ~165/344/345).
Files involved
dist/modes/interactive/components/tool-execution.jsdist/bundle/chunk-<HASH>.js(chunk name changes every release;ctrlo-reapply.pyauto-detects it by scanning forvar ToolExecutionComponent = class extends Container {)The bundle does NOT export
ToolExecutionComponent, so it cannot be unit-testeddirectly; it is kept behaviourally identical to the ESM file (verified by token-level
comparison of the class bodies — only bundler artifacts differ:
void 0vsundefined,var-class style, minified local param names, escaped unicode, import aliasing).
Alternatives considered
No response
Additional context
No response
All reactions