Fix single tool calls getting stuck inside thinking parts#323059
Merged
Conversation
A thinking/"Working" section with exactly one tool call should promote that tool to the top level instead of leaving it nested inside the collapsed part. It stayed stuck in three cases: - Multi-child tools: promotion bailed when the tool's DOM had more than one child element, so terminal/search/edit tools never got promoted. - Late completion: finalizeTitleIfDefault() is one-shot, so if the tool was not yet Completed/Cancelled at that instant, promotion was skipped forever. - Lost original position: singleItemInfo gets wiped whenever the item count isn't 1, so a transient sibling or eager rendering left undefined behind. Fix: - Remove the childElementCount > 1 guard so a lone tool is promoted regardless of tool type. - Observe the tool's state and promote once it completes instead of giving up. - Persist each tool's original position so a lone tool can always be reconstructed and promoted. Adds regression tests covering all three cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request fixes a UX issue in the chat “thinking/Working” container where a single tool invocation could remain incorrectly nested inside the collapsed thinking section instead of being promoted back to the top-level response content. The change improves reliability across different tool DOM shapes, completion timing, and transient item-count changes during streaming.
Changes:
- Record each tool call’s original DOM position by
toolCallIdand use it to reconstruct promotion state whensingleItemInfois missing. - Retry single-item promotion when the lone tool finishes after
finalizeTitleIfDefault()runs by observing tool completion. - Add regression tests covering multi-child tool DOM, late completion, and transient sibling wipeout scenarios.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts | Makes lone-tool promotion resilient by persisting original placement, removing multi-child guard, and retrying promotion upon tool completion. |
| src/vs/workbench/contrib/chat/test/browser/widget/chatContentParts/chatThinkingContentPart.test.ts | Adds regression tests for the three previously failing promotion cases. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 2
- Review effort level: Low
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
roblourens
approved these changes
Jun 26, 2026
justschen
added a commit
that referenced
this pull request
Jun 26, 2026
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.
Problem
When a thinking/"Working" section contains exactly one tool call (and no reasoning text), that tool should be promoted to the top level instead of staying nested inside the collapsed thinking part. In several cases it stayed stuck:
finalizeTitleIfDefault()is one-shot, so if the tool hadn't reportedCompleted/Cancelledat that exact instant, promotion was skipped and never retried.singleItemInfo(which records where to move the tool back to) gets wiped whenever the item count isn't 1, so a transient sibling item or eager rendering left us withundefinedand nothing to promote.Fix
childElementCount > 1guard so a lone tool is promoted regardless of tool type.toolOriginalPositionByCallId) so a lone tool can always be reconstructed and promoted, even after a sibling came and went.Net result: a single tool call is reliably promoted to the top level regardless of its type, DOM shape, or completion timing.
Adds regression tests covering all three cases.