Skip to content

Commit 9f05c21

Browse files
justschenCopilot
andauthored
no thinking dropdown for single tool calls (#285630)
* no thinking dropdown for single tool calls * Update src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts Co-authored-by: Copilot <[email protected]> * for some reason copilot deleted this line --------- Co-authored-by: Copilot <[email protected]>
1 parent 912018c commit 9f05c21

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { $, clearNode } from '../../../../../../base/browser/dom.js';
6+
import { $, clearNode, hide } from '../../../../../../base/browser/dom.js';
77
import { IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized } from '../../../common/chatService/chatService.js';
88
import { IChatContentPartRenderContext, IChatContentPart } from './chatContentParts.js';
99
import { IChatRendererContent } from '../../../common/model/chatViewModel.js';
@@ -94,8 +94,8 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
9494
private toolInvocationCount: number = 0;
9595
private streamingCompleted: boolean = false;
9696
private isActive: boolean = true;
97-
private currentToolCallLabel: string | undefined;
9897
private toolInvocations: (IChatToolInvocation | IChatToolInvocationSerialized)[] = [];
98+
private singleToolItemInfo: { element: HTMLElement; originalParent: HTMLElement; originalNextSibling: Node | null } | undefined;
9999

100100
constructor(
101101
content: IChatThinkingPart,
@@ -356,11 +356,9 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
356356
return;
357357
}
358358

359-
// case where we only have one dropdown in the thinking container and no thinking parts
360-
if (this.toolInvocationCount === 1 && this.extractedTitles.length === 1 && this.currentToolCallLabel && this.currentThinkingValue.trim() === '') {
361-
const title = this.currentToolCallLabel;
362-
this.currentTitle = title;
363-
this.setTitleWithWidgets(new MarkdownString(title), this.instantiationService, this.chatMarkdownAnchorService, this.chatContentMarkdownRenderer);
359+
// case where we only have one tool in the thinking container and no thinking parts, we want to move it back to its original position
360+
if (this.toolInvocationCount === 1 && this.currentThinkingValue.trim() === '' && this.singleToolItemInfo) {
361+
this.restoreSingleToolToOriginalPosition();
364362
return;
365363
}
366364

@@ -455,6 +453,23 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
455453
this.setFallbackTitle();
456454
}
457455

456+
private restoreSingleToolToOriginalPosition(): void {
457+
if (!this.singleToolItemInfo) {
458+
return;
459+
}
460+
461+
const { element, originalParent, originalNextSibling } = this.singleToolItemInfo;
462+
463+
if (originalNextSibling && originalNextSibling.parentNode === originalParent) {
464+
originalParent.insertBefore(element, originalNextSibling);
465+
} else {
466+
originalParent.appendChild(element);
467+
}
468+
469+
hide(this.domNode);
470+
this.singleToolItemInfo = undefined;
471+
}
472+
458473
private setFallbackTitle(): void {
459474
const finalLabel = this.toolInvocationCount > 0
460475
? localize('chat.thinking.finished.withTools', 'Finished thinking and invoked {0} tool{1}', this.toolInvocationCount, this.toolInvocationCount === 1 ? '' : 's')
@@ -472,7 +487,18 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
472487
this.updateDropdownClickability();
473488
}
474489

475-
public appendItem(content: HTMLElement, toolInvocationId?: string, toolInvocation?: IChatToolInvocation | IChatToolInvocationSerialized): void {
490+
public appendItem(content: HTMLElement, toolInvocationId?: string, toolInvocation?: IChatToolInvocation | IChatToolInvocationSerialized, originalParent?: HTMLElement): void {
491+
// save the first tool item info for potential restoration later
492+
if (this.toolInvocationCount === 0 && originalParent) {
493+
this.singleToolItemInfo = {
494+
element: content,
495+
originalParent,
496+
originalNextSibling: this.domNode
497+
};
498+
} else {
499+
this.singleToolItemInfo = undefined;
500+
}
501+
476502
const itemWrapper = $('.chat-thinking-tool-wrapper');
477503
const icon = toolInvocationId ? getToolInvocationIcon(toolInvocationId) : Codicon.tools;
478504
const iconElement = createThinkingIcon(icon);
@@ -490,11 +516,6 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
490516
} else {
491517
toolCallLabel = `Invoked \`${toolInvocationId}\``;
492518
}
493-
494-
if (toolInvocation?.pastTenseMessage) {
495-
this.currentToolCallLabel = typeof toolInvocation.pastTenseMessage === 'string' ? toolInvocation.pastTenseMessage : toolInvocation.pastTenseMessage.value;
496-
}
497-
498519
if (toolInvocation) {
499520
this.toolInvocations.push(toolInvocation);
500521
}

src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,7 +1555,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
15551555
}, context, templateData);
15561556

15571557
if (thinkingPart instanceof ChatThinkingContentPart) {
1558-
thinkingPart.appendItem(part?.domNode, toolInvocation.toolId, toolInvocation);
1558+
thinkingPart.appendItem(part?.domNode, toolInvocation.toolId, toolInvocation, templateData.value);
15591559
thinkingPart.addDisposable(part);
15601560
thinkingPart.addDisposable(thinkingPart.onDidChangeHeight(() => {
15611561
this.updateItemHeight(templateData);
@@ -1567,7 +1567,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
15671567

15681568
if (this.shouldPinPart(toolInvocation, context.element)) {
15691569
if (lastThinking && part?.domNode && toolInvocation.presentation !== 'hidden') {
1570-
lastThinking.appendItem(part?.domNode, toolInvocation.toolId, toolInvocation);
1570+
lastThinking.appendItem(part?.domNode, toolInvocation.toolId, toolInvocation, templateData.value);
15711571
lastThinking.addDisposable(part);
15721572
}
15731573
} else {

0 commit comments

Comments
 (0)