Skip to content

feat(tool-display): add intent-first details and exec summaries#18592

Merged
steipete merged 3 commits intoopenclaw:mainfrom
xdLawless2:feat/tool-display-intent-first-summaries
Feb 16, 2026
Merged

feat(tool-display): add intent-first details and exec summaries#18592
steipete merged 3 commits intoopenclaw:mainfrom
xdLawless2:feat/tool-display-intent-first-summaries

Conversation

@xdLawless2
Copy link

@xdLawless2 xdLawless2 commented Feb 16, 2026

Summary

Improve verbose tool-call readability by switching to intent-first detail text in both runtime/TUI and Control UI tool cards.

What changed

  • File tools (read/write/edit/attach) now render human-readable phrases:
    • lines X-Y from ..., first N lines of ..., to ... (N chars), in ..., from ...
    • supports path, file_path, and filePath aliases
  • Web tools now render explicit phrasing:
    • web_search: for "<query>" (top N)
    • web_fetch: from <url> (mode <extractMode>, max <maxChars> chars)
  • Card detail formatter is now title-first: returns detail text directly instead of duplicating verb + detail.
  • Added deterministic exec summarization heuristics:
    • unwrap shell wrappers (bash/sh/zsh/fish -c/-lc/-ic)
    • strip setup preamble (set/export/unset)
    • summarize pipelines (A -> B (+N steps))
    • detect common command intents (git, grep/rg, find, head/tail, sed, cp/mv, node/python, etc.)
    • recognize heredocs (python3 <<PY, node <<NODE) and node --check
    • include cwd context when present

Files

  • src/agents/tool-display-common.ts
  • src/agents/tool-display.ts
  • ui/src/ui/tool-display.ts
  • src/agents/tool-display.e2e.test.ts

Validation

Ran:

corepack pnpm vitest run --config vitest.e2e.config.ts src/agents/tool-display.e2e.test.ts

Result: all tests in tool-display.e2e.test.ts passed.

Greptile Summary

This PR improves tool-call display readability by adding intent-first detail text for file tools (read/write/edit/attach), web tools (web_search/web_fetch), and a comprehensive exec command summarization engine. The exec summarizer handles shell wrapper unwrapping, preamble stripping, pipeline detection, and recognizes ~20 common CLI tools (git, grep, find, node, python, etc.).

  • Bug: node -c file.js (short flag for --check) is misidentified because -c is listed as a value-consuming option in firstPositional. The file argument gets swallowed, producing "run node" instead of "check js syntax for file.js". The test only covers --check (long flag), masking this issue.
  • Dead code: The subcommands Set in the git handler (line 553) is declared but never used — the map Record duplicates the same list and is the one actually referenced.
  • Code duplication: web_search and web_fetch detail resolution is copy-pasted identically into both src/agents/tool-display.ts and ui/src/ui/tool-display.ts rather than being extracted into tool-display-common.ts alongside the other resolvers (resolveReadDetail, resolveWriteDetail, resolveExecDetail).

Confidence Score: 3/5

  • This PR is safe to merge for most cases, but contains a confirmed logic bug in node -c handling that should be fixed first.
  • Score of 3 reflects a confirmed logic bug (node -c produces wrong output), dead code, and non-trivial code duplication. The bug is in display-only code so it won't cause runtime errors or data loss, but it contradicts the PR's stated goal of accurate exec summarization. The bulk of the changes are well-structured and tested.
  • src/agents/tool-display-common.ts needs attention for the node -c bug at line 794 and dead code at line 553.

Last reviewed commit: 973c7e7

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

- add human-readable read/write/edit/attach details with path alias support\n- add explicit web_search/web_fetch phrasing (quoted query, mode/limit)\n- make detail text title-first by returning detail-only in formatters\n- add deterministic exec summarizer (wrappers, pipelines, heredoc, git/node/python heuristics, preamble stripping)\n- extend e2e coverage for file/web/exec cases
@openclaw-barnacle openclaw-barnacle bot added app: web-ui App: web-ui agents Agent runtime and tooling size: L labels Feb 16, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

return `run ${bin} inline script`;
}

const script = firstPositional(words, 1, ["-c", "-e", "--eval", "-m"]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node -c misclassified as value-taking option

For Node.js, -c means --check (syntax check) and does not consume the next argument as its value — the filename is a positional argument. However, -c is listed in optionsWithValue here, which causes firstPositional to skip the filename (treating it as -c's value).

Result: node -c /tmp/test.js produces "run node" instead of "check js syntax for /tmp/test.js".

The existing test passes only because it uses --check rather than -c, avoiding the buggy code path. Consider handling node separately before calling firstPositional, or using different optionsWithValue lists per language:

Suggested change
const script = firstPositional(words, 1, ["-c", "-e", "--eval", "-m"]);
const nodeOptsWithValue = ["-e", "--eval", "-m"];
const otherOptsWithValue = ["-c", "-e", "--eval", "-m"];
const script = firstPositional(words, 1, bin === "node" ? nodeOptsWithValue : otherOptsWithValue);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tool-display-common.ts
Line: 794:794

Comment:
**`node -c` misclassified as value-taking option**

For Node.js, `-c` means `--check` (syntax check) and does *not* consume the next argument as its value — the filename is a positional argument. However, `-c` is listed in `optionsWithValue` here, which causes `firstPositional` to skip the filename (treating it as `-c`'s value).

Result: `node -c /tmp/test.js` produces `"run node"` instead of `"check js syntax for /tmp/test.js"`.

The existing test passes only because it uses `--check` rather than `-c`, avoiding the buggy code path. Consider handling node separately before calling `firstPositional`, or using different `optionsWithValue` lists per language:

```suggestion
    const nodeOptsWithValue = ["-e", "--eval", "-m"];
    const otherOptsWithValue = ["-c", "-e", "--eval", "-m"];
    const script = firstPositional(words, 1, bin === "node" ? nodeOptsWithValue : otherOptsWithValue);
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 553 to 572
const subcommands = new Set([
"status",
"diff",
"log",
"show",
"branch",
"checkout",
"switch",
"commit",
"pull",
"push",
"fetch",
"merge",
"rebase",
"add",
"restore",
"reset",
"stash",
]);
const globalWithValue = new Set([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused subcommands set is dead code

The subcommands Set is declared but never referenced. The map Record on line 612 duplicates the same subcommand list for the human-readable mapping and is the one actually used. Consider removing subcommands to avoid confusion.

Suggested change
const subcommands = new Set([
"status",
"diff",
"log",
"show",
"branch",
"checkout",
"switch",
"commit",
"pull",
"push",
"fetch",
"merge",
"rebase",
"add",
"restore",
"reset",
"stash",
]);
const globalWithValue = new Set([
const globalWithValue = new Set([
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tool-display-common.ts
Line: 553:572

Comment:
**Unused `subcommands` set is dead code**

The `subcommands` Set is declared but never referenced. The `map` Record on line 612 duplicates the same subcommand list for the human-readable mapping and is the one actually used. Consider removing `subcommands` to avoid confusion.

```suggestion
    const globalWithValue = new Set([
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 95 to 125
if (!detail && key === "web_search" && params.args && typeof params.args === "object") {
const record = params.args as Record<string, unknown>;
const query = typeof record.query === "string" ? record.query.trim() : undefined;
const count =
typeof record.count === "number" && Number.isFinite(record.count) && record.count > 0
? Math.floor(record.count)
: undefined;
if (query) {
detail = count !== undefined ? `for "${query}" (top ${count})` : `for "${query}"`;
}
}

if (!detail && key === "web_fetch" && params.args && typeof params.args === "object") {
const record = params.args as Record<string, unknown>;
const url = typeof record.url === "string" ? record.url.trim() : undefined;
const mode =
typeof record.extractMode === "string" ? record.extractMode.trim() : undefined;
const maxChars =
typeof record.maxChars === "number" && Number.isFinite(record.maxChars) && record.maxChars > 0
? Math.floor(record.maxChars)
: undefined;
if (url) {
const suffix = [
mode ? `mode ${mode}` : undefined,
maxChars !== undefined ? `max ${maxChars} chars` : undefined,
]
.filter((value): value is string => Boolean(value))
.join(", ");
detail = suffix ? `from ${url} (${suffix})` : `from ${url}`;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

web_search/web_fetch detail logic duplicated across files

These blocks (lines 95–125) are character-for-character identical to the same blocks in ui/src/ui/tool-display.ts (lines 95–125). The other tool-specific detail resolvers (resolveReadDetail, resolveWriteDetail, resolveExecDetail) were correctly extracted into tool-display-common.ts. Consider extracting resolveWebSearchDetail and resolveWebFetchDetail into the common module to follow the same pattern and prevent future drift between the two copies.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tool-display.ts
Line: 95:125

Comment:
**`web_search`/`web_fetch` detail logic duplicated across files**

These blocks (lines 95–125) are character-for-character identical to the same blocks in `ui/src/ui/tool-display.ts` (lines 95–125). The other tool-specific detail resolvers (`resolveReadDetail`, `resolveWriteDetail`, `resolveExecDetail`) were correctly extracted into `tool-display-common.ts`. Consider extracting `resolveWebSearchDetail` and `resolveWebFetchDetail` into the common module to follow the same pattern and prevent future drift between the two copies.

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

- extract web_search/web_fetch detail resolvers into common module\n- fix node -c classification so file path remains positional\n- remove dead git subcommands set\n- keep exec summary refinements (heredoc/node check/git -C/preamble strip)\n- make tests cover node -c syntax-check path\n- run format:check, tsgo, lint, and focused e2e tests
@xdLawless2
Copy link
Author

Follow-up pushed in efa76d4 to address CI + review feedback:\n\n- fixed node -c handling in exec summarization (syntax-check path now remains positional)\n- removed dead git subcommands set\n- extracted duplicated web_search/web_fetch detail logic into tool-display-common\n- verified locally: format:check, tsgo, lint, and tool-display e2e test all pass\n\nThanks for the review.

@steipete steipete merged commit facfa41 into openclaw:main Feb 16, 2026
23 checks passed
@xdLawless2 xdLawless2 deleted the feat/tool-display-intent-first-summaries branch February 17, 2026 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments