Skip to content

feat(ui): dedicated chat components for tool search/select/query - #430

Open
Zerlight wants to merge 10 commits into
masterfrom
ruocheng/code-412
Open

feat(ui): dedicated chat components for tool search/select/query#430
Zerlight wants to merge 10 commits into
masterfrom
ruocheng/code-412

Conversation

@Zerlight

@Zerlight Zerlight commented Aug 8, 2026

Copy link
Copy Markdown
Member

Summary

Search-type tool calls get their own chat presentation (Closes CODE-412):

  • Search rows (Grep/Glob and agent-native search tools) render a humanized query + scope instead of raw JSON, with expressive per-kind icons.
  • ToolSearch renders its result rows inline; select-style calls keep neutral wording when no result rows exist.
  • Search context is preserved across pending/running/failed states.
  • Codex MCP tool titles — live app-server events and rollout replay (history-tools.ts) — normalize to the shared mcp__<server>__<tool> slug so server identity survives into these rows.
  • Engine git fixtures set commit.gpgsign=false so integration tests pass on signing machines.

Verification

  • pnpm check:ci (0 errors) and full pnpm exec vitest run (2741 passed) at this tip.
  • New unit coverage: tool-search.test.tsx, tool-call-metadata.test.tsx, tool-result-content.test.ts, codex-mcp-tools.test.ts, codex-history.test.ts.
  • Mock showcase extended with the new search/ToolSearch cases — renderable end-to-end via the webview dev:mock conversation showcase.

Checklist

  • pnpm check:ci and pnpm test both pass (plus cargo fmt / clippy / test for Rust changes)
  • I ran the affected surface and observed the change working
  • If a wire message changed: WIRE_PROTOCOL_VERSION is bumped (no wire change in this PR)
  • New code and assets are my own work, or their origin and license compatibility are noted above
  • Docs and comments are updated where behavior changed

Copilot AI lite review requested due to automatic review settings August 8, 2026 02:35
@linear-code

linear-code Bot commented Aug 8, 2026

Copy link
Copy Markdown

CODE-412

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the chat transcript UI for tool calls by introducing dedicated rendering for “search-like” tool calls (including Claude’s ToolSearch) and by normalizing Codex MCP tool titles to the shared mcp__<server>__<tool> slug so MCP server identity is consistently preserved in the UI and in history replays.

Changes:

  • Add ToolSearch-specific parsing + rendering (inline tool-name rows, humanized headers, preserved context across states).
  • Humanize generic search tool headers to summarize counts (matches/files) while keeping raw queries in the expandable body only.
  • Normalize Codex MCP tool-call titles (live adapter + history replay) to mcp__<server>__<tool>, including plugin-app namespace unwrapping; update mocks/tests and fix git fixture signing config for integration tests.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/presentation/ui/src/tool-utils.ts Adds toolCallSearchCounts, adjusts search header/body behavior, and integrates ToolSearch handling into body visibility logic.
packages/presentation/ui/src/chat/tool-search.tsx New ToolSearch result renderer that displays loaded tool names inline with MCP server suffix.
packages/presentation/ui/src/chat/tool-result-preview.tsx Routes ToolSearch calls to the dedicated renderer; updates search preview card icon/behavior for empty-output searches.
packages/presentation/ui/src/chat/tool-result-content.ts Adds toolSearchPresentation parsing to classify ToolSearch output into rows vs. prose message.
packages/presentation/ui/src/chat/tool-kind-icons.ts Updates the search kind icon to TextSearchIcon.
packages/presentation/ui/src/chat/tool-call-item.tsx Humanizes search headers (ToolSearch verbs + generic search counts), suppresses search metadata badges in the body.
packages/presentation/ui/src/chat/activity-run.tsx Swaps activity “explore” icon to TelescopeIcon.
packages/presentation/ui/src/chat/tests/tool-search.test.tsx Adds unit tests covering ToolSearch header/body behavior across states and MCP name splitting.
packages/presentation/ui/src/chat/tests/tool-result-content.test.ts Adds unit tests for toolSearchPresentation parsing behavior.
packages/presentation/ui/src/chat/tests/tool-call-metadata.test.tsx Updates tests to validate search header summarization/count extraction and query placement.
packages/presentation/i18n/src/locales/en.ts Adds localized strings for ToolSearch header verbs and search count summaries.
packages/presentation/i18n/src/locales/zh-cn.ts Adds localized strings for ToolSearch header verbs and search count summaries (zh-CN).
packages/host/engine/tests/integration/git-mutations.test.ts Disables GPG signing in the git fixture to make commits reliable on signing-enabled machines.
packages/host/agent-adapter/src/native/codex/history-tools.ts Normalizes rollout/history MCP function calls into mcp__<server>__<tool> titles.
packages/host/agent-adapter/src/native/codex/adapter.ts Normalizes live Codex MCP tool-call titles to the shared MCP slug and unwraps plugin namespace.
packages/host/agent-adapter/src/tests/codex-mcp-tools.test.ts Adds tests for Codex MCP slug normalization and plugin namespace unwrapping.
packages/host/agent-adapter/src/tests/codex-history.test.ts Adds tests ensuring history replay uses the same MCP slug format as live events.
packages/client/workbench/src/mock/data/showcase.ts Updates mock showcase tool bursts to exercise new search/ToolSearch presentation paths.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/host/agent-adapter/src/native/codex/history-tools.ts Outdated
Comment thread packages/host/agent-adapter/src/native/codex/adapter.ts Outdated
Comment thread packages/presentation/ui/src/chat/tool-search.tsx Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[!IMPORTANT]

The new ToolSearch rendering is solid, but the toolCallHeaderSummary search-case deletion strips header context from search tools that don't emit match counts — WebSearch collapses to a bare WebSearch label. Verified by rendering through ToolCallItem.

Reviewed changes

This PR adds dedicated presentation for Claude Code's deferred-tool ToolSearch calls and normalizes Codex MCP tool titles.

  • New ToolSearchResult component (packages/presentation/ui/src/chat/tool-search.tsx) plus toolSearchPresentation() in tool-result-content.ts, splitting select: mode from keyword mode and rendering mcp__server__tool as tool (server).
  • tool-call-item.tsx grows a header branch computing toolSearch / searchCounts and swaps in ToolCaseIcon; search-kind rows now suppress generic metadata.
  • tool-utils.ts adds toolCallSearchCounts() and changes toolCallHeaderSummary's case 'search' from returning the query to break; SearchRows drops its result-count badge.
  • Codex adapter titles change from ${server}.${tool} to mcp__${server}__${tool}, with a new codexMcpToolName() handling the rollout-JSONL replay path.
  • i18n keys added to both zh-cn.ts and en.ts with matching key sets and valid ICU plurals.

ℹ️ The Codex title change is safe — confirming so it isn't re-litigated

I traced whether mcp__${server}__${tool} could break anything downstream that keys off toolCall.title. It can't: the engine reads title only for approval toolTitle (session-event-processor.ts:150), Codex MCP tools announce as kind: 'other' with no approval path, and deduplication is by toolCallId throughout conversation.ts. codexToolSettle spreads ...existing, so the announce title survives the settle. No action needed — noting it as verified negative evidence.

ℹ️ Nitpicks

The PR bundles three loosely-related concerns — the UI search presentation, the Codex MCP title normalization, and the commit.gpgsign=false git fixture. They're each small, so this isn't worth splitting retroactively, but the title only describes the first.

Separately, the description promises "humanized query + scope" in the header, while the implemented behavior shows counts and removes the query. Worth reconciling the description with what shipped, since the two read as contradictory to a future reader.

Finally, the "I ran the affected surface and observed the change working" checklist item is unchecked — and the search-header path above is exactly the surface where a manual pass would have caught the regression.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread packages/presentation/ui/src/tool-utils.ts Outdated

@lucas77778 lucas77778 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Blocking findings:

  1. packages/presentation/ui/src/tool-utils.ts:203-206 removes the query from every generic search header, while ToolCallItem only substitutes counts when rawOutput has a supported count envelope. WebSearch is classified as kind: search by toolKindFromName, and Pi/OpenCode-style searches also commonly have no numMatches/numFiles, so their collapsed rows become a bare tool name (and all in-progress searches are indistinguishable). I reproduced the resulting shape as {kind:"search", headerSummary:undefined, counts:undefined} for a WebSearch call with query linkcode release notes. Keep toolCallSearchQuery as the fallback summary (or append counts to it), while retaining the dedicated ToolSearch branch that hides select: queries; add coverage for an output-less generic search and a counted search.

  2. packages/host/agent-adapter/src/native/codex/adapter.ts:1287-1299 embeds the raw Codex MCP server name in mcp__<server>__<tool>, but mcpToolName splits on the first __. LinkCode accepts arbitrary non-empty custom MCP names, and the pinned Codex CLI accepts repo__prod (verified with an isolated CODEX_HOME: codex mcp add repo__prod -- /bin/true and codex mcp list --json both succeeded). A call from server repo__prod, tool search_files is emitted as mcp__repo__prod__search_files and rendered as server repo, tool prod__search_files, defeating the stated identity-preservation goal. Preserve a non-slug fallback for delimiter-containing Codex names (live and history), or introduce an unambiguous representation; add live/history parser cases for such a valid name.

Copilot AI review requested due to automatic review settings August 9, 2026 11:37
@Zerlight
Zerlight force-pushed the ruocheng/code-412 branch from e072cb6 to c4fa4a1 Compare August 9, 2026 11:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.

@Zerlight

Zerlight commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

Both addressed:

  1. 9a3fcb9 keeps toolCallSearchQuery as the header fallback whenever toolCallSearchCounts resolves nothing, so WebSearch-style settles and in-progress searches keep their query while counted settles still humanize. The dedicated ToolSearch branch still overrides the summary, so select: strings never surface. Coverage added for an uncounted settle and the in-progress case, alongside the existing counted-search test.

  2. c4fa4a1 routes the live adapter and the rollout replay through one codexMcpSlug() (tool-view.ts): a server name containing __ keeps codex's raw dotted server.tool title instead of emitting a slug that would mis-split in mcpToolName. Live + history parser cases added for repo__prod.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ No new issues — one unused-export nit inline.

Reviewed changes

Three commits since the last pullfrog review at e072cb6, all of them fixes to round-one feedback. Both the header-summary regression and the codex slug mis-split are addressed, and each fix ships a test that fails without it.

  • Restored the search query as the header fallbacktoolCallHeaderSummary's case 'search' now assigns toolCallSearchQuery(toolCall) whenever toolCallSearchCounts comes back empty, so counted settles still humanize to counts while WebSearch, Pi/opencode-shaped outputs, and in-progress searches keep their query.
  • Extracted codexMcpSlug() into tool-view.ts — the live mcpToolCall case and the rollout-replay path now share one slug builder instead of two copies of the template literal, and CODEX_PLUGIN_APPS_SERVER moved along with it.
  • Kept codex's raw dotted title for __-bearing server namescodexMcpSlug returns ${server}.${tool} when the server would mis-split, matching mcpToolName's first-__ split rule exactly.
  • Added parser coverage for both pathsrepo__prod cases in codex-mcp-tools.test.ts (live) and codex-history.test.ts (replay), plus a WebSearch header test and an updated toolCallHeaderSummary expectation.

I traced live-vs-replay title convergence input by input rather than trusting the tests: ordinary servers, the codex_apps dotted unwrap, the stray-trailing-__ namespace form, __-bearing server names, and codex_apps combined with a __-bearing app name all produce identical titles from both paths. The five touched test files pass locally, 73/73.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread packages/host/agent-adapter/src/native/codex/tool-view.ts Outdated
Copilot AI review requested due to automatic review settings August 9, 2026 11:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/presentation/ui/src/chat/tool-search.tsx:15

  • When ToolSearch settles with prose (e.g., multi-line error details), rendering it in a plain

    collapses newlines/whitespace, so the message can become hard to read or misleading. Preserve line breaks (similar to how other tool text is rendered) by using whitespace-pre-wrap (and optionally break-words).

  if (names.length === 0) {
    return message ? <p className="text-muted-foreground text-sm">{message}</p> : null;
  }

@Zerlight
Zerlight requested a review from lucas77778 August 9, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants