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' ;
77import { IChatThinkingPart , IChatToolInvocation , IChatToolInvocationSerialized } from '../../../common/chatService/chatService.js' ;
88import { IChatContentPartRenderContext , IChatContentPart } from './chatContentParts.js' ;
99import { 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 }
0 commit comments