feat: batch consecutive tool calls in chat UI with shared utility#11245
Open
hannesrudolph wants to merge 8 commits intomainfrom
Open
feat: batch consecutive tool calls in chat UI with shared utility#11245hannesrudolph wants to merge 8 commits intomainfrom
hannesrudolph wants to merge 8 commits intomainfrom
Conversation
Consolidate consecutive listFilesTopLevel/listFilesRecursive ask messages into a single 'Roo wants to view multiple directories' block, matching the existing read_file batching pattern.
Contributor
The latest commit (
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
db94d81 to
0160847
Compare
…atRow Merge the separate listFilesTopLevel and listFilesRecursive case blocks into a single combined case with shared batch-detection logic, selecting the icon and translation key based on the tool type. This removes the duplicated isBatchDirRequest check and BatchListFilesPermission render.
Add edit-file batching in ChatView groupedMessages that consolidates consecutive editedExistingFile, appliedDiff, newFileCreated, insertContent, and searchAndReplace asks into a single BatchDiffApproval block. Move batchDiffs detection in ChatRow above the switch statement so it applies to any file-edit tool type.
- Extract generic batchConsecutive() utility from 3 identical while-loops - Fix React key collisions in BatchListFilesPermission, BatchFilePermission, BatchDiffApproval - Normalize language prop to "shellsession" (was "shell-session" for top-level) - Remove unused _batchedMessages property from synthetic messages - Remove dead didViewMultipleDirectories i18n key from all 18 locale files - Add batch button text for listFilesTopLevel/listFilesRecursive - Add batchConsecutive utility tests (6 cases)
- Make batchConsecutive() generic instead of ClineMessage-specific
- Add batch-aware button text for edit-file batches ("Save All"/"Deny All")
- Add dedicated list-batch/edit-batch i18n keys (stop reusing read-batch)
- Add JSON.parse defense-in-depth in all three synthesizers
- Fix mixed list_files batch icon to default to FolderTree
- Add 6 missing test cases (all-match, immutability, spy, single-dir)
- Trim unused recursive/isOutsideWorkspace from DirPermissionItem interface - Remove 4 pre-existing `as any` casts in ChatView.tsx: - window cast → precise inline type - checkpoint bracket access → removed unnecessary casts - condensing message → `as ClineMessage` - debounce cancel → `.clear()` (correct API) - Update BatchListFilesPermission test data to match trimmed interface
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #11246
After

Summary
Consolidates consecutive
list_files,read_file, and file-edit tool ask messages into single grouped UI blocks in the chat — reducing visual clutter when the agent performs multiple similar operations in sequence.Before: Multiple consecutive
list_filescalls each render their own "Roo wants to view the top level files in this directory" block with repeated headers. Same for consecutive file edits.After: They collapse into a single block with all paths listed together.
Changes
New files
webview-ui/src/utils/batchConsecutive.ts— Generic utility that walks a message array and batches consecutive matches into synthetic messages. Used for all three batching passes (read_file, list_files, file-edits).webview-ui/src/utils/__tests__/batchConsecutive.spec.ts— 11 test cases covering empty input, passthrough, batching, mixed sequences, generic typing, immutability, and edge cases.Modified files
packages/types/src/vscode-extension-host.ts— AddedbatchDirsproperty toClineSayToolinterfacewebview-ui/src/components/chat/ChatView.tsx— Replaced three near-identical batching while-loops (~170 lines) with threebatchConsecutive()calls (~70 lines). Added batch button text forlistFilesTopLevel/listFilesRecursiveand edit-file batches ("Save All"/"Deny All"). Added JSON.parse defense-in-depth in all three synthesizers.webview-ui/src/components/chat/ChatRow.tsx— MergedlistFilesTopLevel/listFilesRecursivecases; added batch detection forBatchListFilesPermission; normalized language prop to"shellsession"; movedbatchDiffscheck before switch for all file-edit tool types. Fixed mixedlist_filesbatch icon to default to FolderTree.webview-ui/src/components/chat/BatchListFilesPermission.tsx— New component for grouped directory listing UI. Fixed React key to include array index.webview-ui/src/components/chat/BatchFilePermission.tsx— Fixed React key to include array index.webview-ui/src/components/chat/BatchDiffApproval.tsx— Fixed React key to include array index.webview-ui/src/components/chat/__tests__/BatchListFilesPermission.spec.tsx— 5 tests covering rendering, empty state, re-render, container structure, and batch icon fallback.webview-ui/src/i18n/locales/en/chat.json— AddedwantsToViewMultipleDirectories, dedicatedlist-batch/edit-batchi18n keys (stop reusingread-batchkeys).chat.jsonfiles — AddedwantsToViewMultipleDirectories; removed unuseddidViewMultipleDirectoriesAudit improvements
The following quality fixes were applied during code review:
batchConsecutive()— Refactored fromClineMessage-specific to a fully generic<T>utility, improving reusability and type safety.list-batch.*andedit-batch.*i18n key namespaces instead of reusingread-batchkeys for different tool types.JSON.parsecalls to prevent runtime crashes on malformed message content.list_filesbatch icon — Fixed icon for batches mixinglistFilesTopLevelandlistFilesRecursiveto default toFolderTreeinstead of rendering incorrectly.Footnote — Minor out-of-scope cleanup:
These changes are unrelated to the batch tool-call feature but were discovered during code review and cleaned up while in the area:
recursive/isOutsideWorkspacefields fromDirPermissionIteminterface inBatchListFilesPermission.tsx(the upstream type invscode-extension-host.tsretains them)as anycasts inChatView.tsx— replaced with proper types (ClineMessage, inline window type, direct bracket access, correct debounce API)Design rationale — which tools are batched and why
This PR batches only homogeneous, low-context tool calls where the meaningful information is a file/directory path:
list_filesread_fileeditedExistingFile,appliedDiff,newFileCreated,insertContent,searchAndReplace)codebaseSearchsearchFilesexecute_commandGuiding principle: Batch when the per-call output is a simple path or diff. Don't batch when each result has rich, query-specific content that would be lost in a combined view.