Skip to content

Conversation

@2witstudios
Copy link
Owner

@2witstudios 2witstudios commented Feb 2, 2026

Summary

Enhanced tool call renderers to support multiple output formats from AI tools, improving compatibility with different response structures while maintaining backward compatibility.

Key Changes

  • list_pages tool: Added support for converting paths array format to tree structure via new parsePathsToTree() helper function that parses path strings and builds a hierarchical tree
  • list_drives tool: Added data transformation to map tool output field title to renderer's expected name field, with fallback logic
  • get_activity tool: Added support for grouped drives format in addition to flat activities array, with automatic flattening and operation-to-action mapping

Implementation Details

  • Path parsing: Regex-based parser extracts folder/page type, ID, and path from formatted strings like "📁 [FOLDER](Task) ID: xxx Path: /drive/folder"
  • Tree building: Recursive depth-first algorithm constructs hierarchical tree from flat parsed pages
  • Activity mapping: Converts grouped drive activities to flat ActivityItem array with proper timestamp sorting and actor resolution
  • Backward compatibility: All changes preserve existing format support - renderers check for new formats only if old formats aren't present
  • Type safety: Maintains proper TypeScript typing throughout transformations with explicit type annotations

These changes allow the renderers to work with both current and future tool output formats without breaking existing functionality.

https://claude.ai/code/session_01AKG5EjddKT1CVdkLYfnvX9

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced support for displaying pages in alternative formats.
    • Improved activity data presentation with better organization and enriched metadata display.
  • Bug Fixes

    • Fixed compatibility issues with various drive and page listing formats to ensure consistent rendering.

- list_drives: map 'title' field to 'name' for DriveListRenderer
- list_pages: parse flat 'paths' strings into tree structure for PageTreeRenderer
- get_activity: flatten grouped 'drives[].activities' format into flat 'activities' array for ActivityRenderer

https://claude.ai/code/session_01AKG5EjddKT1CVdkLYfnvX9
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

Warning

Rate limit exceeded

@2witstudios has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 32 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Enhances the ToolCallRenderer component to support multiple format variations for AI tool outputs: adds a tree-conversion utility for page paths, normalizes drive object fields, and extends activity handling to process both direct activity arrays and grouped drive formats with standardized metadata enrichment.

Changes

Cohort / File(s) Summary
ToolCallRenderer Enhancement
apps/web/src/components/ai/shared/chat/tool-calls/ToolCallRenderer.tsx
Adds parsePathsToTree helper function for converting path-formatted strings to nested tree structures. Extends list_drives handler with field normalization (name fallback from title). Implements dual-format support in list_pages (existing tree format or new paths array converted to tree). Extends get_activity handler to process both direct activity arrays and grouped drives format with flattened activities, operation-to-action mapping, metadata enrichment, and timestamp sorting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #110: Modifies ToolCallRenderer.tsx with changes to list_pages rendering logic and display handling for page title/currentTitle attributes.
  • PR #320: Adds and wires specialized renderers (DriveListRenderer, ActivityRenderer) within ToolCallRenderer.tsx for centralized rich-content rendering.
  • PR #111: Updates ToolCallRenderer.tsx with modifications to list_pages/list_drives rendering and drive/title display logic.

Poem

🐰 With paths now trees, and drives made whole,
Activities grouped in a unified scroll,
New formats bloom where old ones grew,
The renderer dances in formats both new! 🌳✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Support multiple output formats in tool renderers' accurately and concisely summarizes the main change: enabling tool renderers to handle multiple output formats while maintaining backward compatibility.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/fix-tool-rendering-ZRwaG

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.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 539453fd61

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 88 to 92
const currentSegment = page.pathSegments[depth];
const isDirectChild = page.pathSegments.length === depth + 1;

if (!seen.has(currentSegment)) {
seen.set(currentSegment, {

Choose a reason for hiding this comment

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

P2 Badge Preserve pages with duplicate titles in paths tree

The new parsePathsToTree groups nodes by currentSegment (the title segment) rather than by a stable identifier. If a drive has two sibling pages with the same title (which is allowed—titles aren’t unique), they will be merged into a single entry and one page will be dropped from the rendered tree. This only shows up for list_pages outputs that use the paths format. Consider keying the grouping by a unique identifier (e.g., include pageId alongside the segment in the map key) so distinct pages with identical titles don’t collapse.

Useful? React with 👍 / 👎.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Fixed in c7d3c31.

Changed the grouping logic to use a composite key ${segment}:${pageId} for direct children, so pages with identical titles are now preserved as separate entries in the tree. Intermediate folders still use just the segment name since they're synthetic nodes without their own pageId.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@apps/web/src/components/ai/shared/chat/tool-calls/ToolCallRenderer.tsx`:
- Around line 49-123: buildTreeFromParsed currently seeds a non-null page for
every segment which lets synthetic/intermediate folder nodes inherit descendant
pageId/type; change the seen map entry so page is optional (e.g., { page?:
ParsedPage; children: ParsedPage[] }), only assign entry.page when isDirectChild
is true, and when constructing the TreeItem use page?.type ?? 'folder' (or a
folder-like type) and page?.pageId ?? undefined so synthetic nodes have no
pageId and use a folder type; make these changes inside parsePathsToTree /
buildTreeFromParsed (refer to ParsedPage, buildTreeFromParsed, and the TreeItem
construction).
- Around line 543-624: The renderer is synthesizing IDs instead of using
upstream CUID2 ids—add an id:string to the CompactActivity type in
activity-tools.ts, ensure the function that maps DB rows to CompactActivity
includes the source id field, and update the ToolCallRenderer.tsx mapping (the
code that builds flatActivities inside the get_activity branch) to use
activity.id for ActivityItem.id (and update the ActivityItem/props types if
needed) rather than constructing
`${group.drive.id}-${activity.ts}-${activity.pageId}`; keep the rest of
opToAction and sorting logic unchanged.
🧹 Nitpick comments (1)
apps/web/src/components/ai/shared/chat/tool-calls/ToolCallRenderer.tsx (1)

279-303: Prefer driveName fallback to avoid slug-only labels

Using only driveSlug can show a technical slug (or nothing) even when a friendly name exists. Prefer driveName ?? driveSlug.

🔧 Suggested tweak
-          <PageTreeRenderer
-            tree={tree}
-            driveName={parsedOutput.driveSlug as string | undefined}
-            driveId={parsedOutput.driveId as string | undefined}
-          />
+          <PageTreeRenderer
+            tree={tree}
+            driveName={(parsedOutput.driveName ?? parsedOutput.driveSlug) as string | undefined}
+            driveId={parsedOutput.driveId as string | undefined}
+          />

- Fix synthetic folder nodes inheriting descendant IDs/types by making
  page optional in buildTreeFromParsed and defaulting to 'FOLDER' type
- Fix duplicate titles collapsing by using composite key (pageId+segment)
- Pass CUID2 activity IDs from tool output instead of synthesizing them
- Prefer driveName over driveSlug for friendly display names
- Remove unused DriveInfo import to fix lint error

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@2witstudios
Copy link
Owner Author

Response to Code Review Feedback

Thank you for the thorough review! I've addressed all the feedback in commit c7d3c31:

1. Synthetic folder nodes inheriting descendant IDs/types (CodeRabbit)

Fixed: Made page optional in buildTreeFromParsed seen map entries. Now synthetic/intermediate folder nodes default to type: 'FOLDER' with pageId: undefined instead of incorrectly inheriting descendant page properties.

2. Duplicate titles collapsing (Codex)

Fixed: Changed grouping key from just the segment title to a composite key ${segment}:${pageId} for direct children. This prevents pages with identical titles from being merged into a single entry.

3. Synthesized activity IDs (CodeRabbit)

Fixed: Added id: string field to CompactActivity interface and included the CUID2 activity.id from database. Updated the renderer to use activity.id directly instead of synthesizing ${driveId}-${ts}-${pageId} which could collide.

4. DriveSlug-only labels (CodeRabbit nitpick)

Fixed: Changed to prefer driveName ?? driveSlug for friendlier display labels.

Also fixed lint errors (unused DriveInfo import and unused driveId param → _driveId).

@2witstudios 2witstudios merged commit f5d2501 into master Feb 2, 2026
3 checks passed
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