Skip to content

fix(ai): unwrap execute_tool in chat renderers - #1314

Merged
2witstudios merged 2 commits into
masterfrom
pu/execute-tool
May 12, 2026
Merged

2witstudios merged 2 commits into
masterfrom
pu/execute-tool

Conversation

@2witstudios

@2witstudios 2witstudios commented May 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • execute_tool dispatcher calls are now transparently unwrapped in both ToolCallRenderer and CompactToolCallRenderer — the UI shows the actual underlying tool (e.g. "Create Page", "Web Search") instead of "Execute Tool"
  • tool_search calls are hidden entirely — schema discovery is an implementation detail users don't need to see
  • Special-case routing (update_task → TaskRenderer, ask_agent → PageAgentConversationRenderer) still applies correctly after unwrap

Test plan

  • Trigger a non-core tool via global AI chat (e.g. "create a new workspace") — card should show "Create Workspace" not "Execute Tool"
  • Trigger a flow that requires tool_search — nothing should render in the UI for it
  • Trigger update_task via execute_tool — TaskRenderer should still fire
  • Trigger a core tool directly (e.g. list_pages) — existing rendering unchanged

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of nested tool calls in the AI chat so inner tool names and parameters are correctly detected and used.
    • Skips rendering unsupported search tool calls to avoid spurious UI output.
    • Ensures task updates and agent interactions are routed and displayed consistently after resolving the actual tool and payload.

Review Change Stack

- Unwrap execute_tool calls to show the underlying tool name and rich content instead of the dispatcher wrapper
- Hide tool_search entirely — schema discovery is an impl detail
- Works for both ToolCallRenderer and CompactToolCallRenderer
- Special-case routing (update_task, ask_agent) still applies after unwrap
@coderabbitai

coderabbitai Bot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 205ef6f2-57ba-4fef-b619-dfaae294b0c2

📥 Commits

Reviewing files that changed from the base of the PR and between c0a6cc0 and a772900.

📒 Files selected for processing (2)
  • apps/web/src/components/ai/shared/chat/tool-calls/CompactToolCallRenderer.tsx
  • apps/web/src/components/ai/shared/chat/tool-calls/ToolCallRenderer.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/src/components/ai/shared/chat/tool-calls/CompactToolCallRenderer.tsx
  • apps/web/src/components/ai/shared/chat/tool-calls/ToolCallRenderer.tsx

📝 Walkthrough

Walkthrough

Both ToolCallRenderer and CompactToolCallRenderer now resolve nested tool names by unwrapping execute_tool calls, skip rendering tool_search, and route using resolved parts and tool names instead of the original part.

Changes

Tool-call unwrapping and routing

Layer / File(s) Summary
ToolCallRenderer resolver and routing
apps/web/src/components/ai/shared/chat/tool-calls/ToolCallRenderer.tsx
Compute mutable toolName and resolvedPart, return null for tool_search, safely parse execute_tool's part.input to extract an inner tool_name and set resolvedPart.input to the extracted parameters, then route update_task/ask_agent to their dedicated renderers and other tools through ToolCallRendererInternal using the resolved values.
CompactToolCallRenderer resolver and routing
apps/web/src/components/ai/shared/chat/tool-calls/CompactToolCallRenderer.tsx
Same resolution flow as ToolCallRenderer: derive toolName/resolvedPart, skip tool_search, unwrap execute_tool to inner tool and parameters, route update_task to TaskRenderer, otherwise render CompactToolCallRendererInternal with resolved values.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • 2witstudios/PageSpace#1310: The execute_tool dispatcher and core/non-core tool wiring directly align with the nested tool-name unwrapping and execute_tool special handling introduced here.
  • 2witstudios/PageSpace#1183: Both PRs modify tool-name resolution and derivation logic in CompactToolCallRenderer by parsing and rewriting tool names and inputs.
  • 2witstudios/PageSpace#320: Both PRs refactor ToolCallRenderer rendering flow to resolve and route tool calls to specific renderers based on tool type.

Poem

🐰 A rabbit hops through nested tools with glee,
Unwrapping execute_tool layers carefully,
Skipping tool_search with a bound so swift,
Resolving names in style—what a nifty gift!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: unwrapping execute_tool calls in chat renderers to display underlying tools instead of the execute_tool wrapper itself.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pu/execute-tool

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/web/src/components/ai/shared/chat/tool-calls/CompactToolCallRenderer.tsx`:
- Around line 829-841: The top-level filter skips only a first-level
'tool_search' but misses when execute_tool unwraps into an inner 'tool_search';
update the execute_tool branch in CompactToolCallRenderer (where safeJsonParse
is used and innerName/resolvedPart are set) to check if innerName ===
'tool_search' and return null in that case before continuing, ensuring you still
handle the update_task case and ultimately call CompactToolCallRendererInternal
only when the unwrapped toolName is not 'tool_search'.

In `@apps/web/src/components/ai/shared/chat/tool-calls/ToolCallRenderer.tsx`:
- Around line 821-834: The current logic only hides direct "tool_search" calls
before unwrapping; after the execute_tool block (where toolName may be
reassigned by parsing part.input via safeJsonParse), add a second guard that
returns null when the unwrapped toolName equals 'tool_search'. Concretely: after
the execute_tool handling that sets toolName and resolvedPart, check if toolName
=== 'tool_search' and return null so nested schema-discovery calls are also
suppressed; keep the rest (update_task, ask_agent, ToolCallRendererInternal)
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6c8c2bb4-5a96-4bc0-b30e-0a273b3193af

📥 Commits

Reviewing files that changed from the base of the PR and between 028d750 and c0a6cc0.

📒 Files selected for processing (2)
  • apps/web/src/components/ai/shared/chat/tool-calls/CompactToolCallRenderer.tsx
  • apps/web/src/components/ai/shared/chat/tool-calls/ToolCallRenderer.tsx

Add a second tool_search guard after the execute_tool unwrap block so that execute_tool dispatching to tool_search is also hidden, not just top-level tool_search calls.
@2witstudios

Copy link
Copy Markdown
Owner Author

Addressed both CodeRabbit findings in commit a772900:

  • ToolCallRenderer.tsx: Added a second if (toolName === 'tool_search') return null guard after the execute_tool unwrap block, so nested schema-discovery calls are also suppressed.
  • CompactToolCallRenderer.tsx: Same fix applied identically.

Both renderers now suppress tool_search whether it arrives directly or as the unwrapped target of execute_tool.

@2witstudios
2witstudios merged commit 75c7e5d into master May 12, 2026
3 checks passed
@2witstudios
2witstudios deleted the pu/execute-tool branch May 12, 2026 20:04
2witstudios added a commit that referenced this pull request May 15, 2026
* fix(ai): unwrap execute_tool in chat renderers

- Unwrap execute_tool calls to show the underlying tool name and rich content instead of the dispatcher wrapper
- Hide tool_search entirely — schema discovery is an impl detail
- Works for both ToolCallRenderer and CompactToolCallRenderer
- Special-case routing (update_task, ask_agent) still applies after unwrap

* fix(ai): suppress tool_search after execute_tool unwrap

Add a second tool_search guard after the execute_tool unwrap block so that execute_tool dispatching to tool_search is also hidden, not just top-level tool_search calls.
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.

1 participant