@@ -181,6 +181,8 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
181181 private readonly _diffEditorPool : DiffEditorPool ;
182182 private readonly _treePool : TreePool ;
183183 private readonly _contentReferencesListPool : CollapsibleListPool ;
184+ private _thinkingRenderStartTime : number = 0 ;
185+ private _activeThinkingPart : ChatThinkingContentPart | undefined ;
184186
185187 private _currentLayoutWidth : number = 0 ;
186188 private _isVisible = true ;
@@ -276,6 +278,8 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
276278
277279 updateViewModel ( viewModel : IChatViewModel | undefined ) : void {
278280 this . viewModel = viewModel ;
281+ this . _thinkingRenderStartTime = 0 ;
282+ this . _activeThinkingPart = undefined ;
279283 }
280284
281285 getCodeBlockInfoForEditor ( uri : URI ) : IChatCodeBlockInfo | undefined {
@@ -702,6 +706,10 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
702706 private renderChatResponseBasic ( element : IChatResponseViewModel , index : number , templateData : IChatListItemTemplate ) {
703707 templateData . rowContainer . classList . toggle ( 'chat-response-loading' , ( isResponseVM ( element ) && ! element . isComplete ) ) ;
704708
709+ if ( element . isComplete ) {
710+ this . finalizeActiveThinking ( ) ;
711+ }
712+
705713 const content : IChatRendererContent [ ] = [ ] ;
706714 const isFiltered = ! ! element . errorDetails ?. responseIsFiltered ;
707715 if ( ! isFiltered ) {
@@ -774,6 +782,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
774782 }
775783
776784 private renderChatRequest ( element : IChatRequestViewModel , index : number , templateData : IChatListItemTemplate ) {
785+ this . finalizeActiveThinking ( ) ;
777786 templateData . rowContainer . classList . toggle ( 'chat-response-loading' , false ) ;
778787 if ( element . id === this . viewModel ?. editing ?. id ) {
779788 this . _onDidRerender . fire ( templateData ) ;
@@ -897,6 +906,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
897906
898907 if ( element . isCanceled ) {
899908 this . traceLayout ( 'doNextProgressiveRender' , `canceled, index=${ index } ` ) ;
909+ this . finalizeActiveThinking ( ) ;
900910 element . renderData = undefined ;
901911 this . renderChatResponseBasic ( element , index , templateData ) ;
902912 return true ;
@@ -916,6 +926,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
916926 } else if ( element . isComplete ) {
917927 // All content is rendered, and response is done, so do a normal render
918928 this . traceLayout ( 'doNextProgressiveRender' , `END progressive render, index=${ index } and clearing renderData, response is complete` ) ;
929+ this . finalizeActiveThinking ( ) ;
919930 element . renderData = undefined ;
920931 this . renderChatResponseBasic ( element , index , templateData ) ;
921932 return true ;
@@ -1359,13 +1370,20 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
13591370 }
13601371
13611372 private renderThinking ( context : IChatContentPartRenderContext , thinking : IChatThinkingPart , templateData : IChatListItemTemplate ) : IChatContentPart {
1373+ this . finalizeActiveThinking ( ) ;
1374+ this . _thinkingRenderStartTime = Date . now ( ) ;
1375+
13621376 const thinkingPart = templateData . instantiationService . createInstance (
13631377 ChatThinkingContentPart ,
13641378 thinking ,
13651379 context
13661380 ) ;
13671381
1368- thinkingPart . domNode . classList . add ( 'chat-thinking-part' ) ;
1382+ thinkingPart . addDisposable ( thinkingPart . onDidChangeHeight ( ( ) => {
1383+ this . updateItemHeight ( templateData ) ;
1384+ } ) ) ;
1385+
1386+ this . _activeThinkingPart = thinkingPart ;
13691387
13701388 return thinkingPart ;
13711389 }
@@ -1391,6 +1409,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
13911409 }
13921410
13931411 private renderMarkdown ( markdown : IChatMarkdownContent , templateData : IChatListItemTemplate , context : IChatContentPartRenderContext ) : IChatContentPart {
1412+ this . finalizeActiveThinking ( ) ;
13941413 const element = context . element ;
13951414 const fillInIncompleteTokens = isResponseVM ( element ) && ( ! element . isComplete || element . isCanceled || element . errorDetails ?. responseIsFiltered || element . errorDetails ?. responseIsIncomplete || ! ! element . renderData ) ;
13961415 const codeBlockStartIndex = this . getCodeBlockStartIndex ( context ) ;
@@ -1481,6 +1500,15 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
14811500 private hoverHidden ( requestHover : HTMLElement ) {
14821501 requestHover . style . opacity = '0' ;
14831502 }
1503+
1504+ private finalizeActiveThinking ( ) {
1505+ if ( this . _activeThinkingPart && this . _thinkingRenderStartTime ) {
1506+ const duration = Date . now ( ) - this . _thinkingRenderStartTime ;
1507+ this . _activeThinkingPart . updateInProgressHeader ( duration ) ;
1508+ }
1509+ this . _activeThinkingPart = undefined ;
1510+ this . _thinkingRenderStartTime = 0 ;
1511+ }
14841512}
14851513
14861514export class ChatListDelegate implements IListVirtualDelegate < ChatTreeItem > {
0 commit comments