@@ -9,6 +9,7 @@ import { Codicon } from '../../../../../base/common/codicons.js';
99import { Emitter } from '../../../../../base/common/event.js' ;
1010import { IMarkdownString , MarkdownString } from '../../../../../base/common/htmlContent.js' ;
1111import { Disposable , DisposableStore , IDisposable , thenIfNotDisposed , toDisposable } from '../../../../../base/common/lifecycle.js' ;
12+ import { autorunWithStore } from '../../../../../base/common/observable.js' ;
1213import { ThemeIcon } from '../../../../../base/common/themables.js' ;
1314import { URI } from '../../../../../base/common/uri.js' ;
1415import { generateUuid } from '../../../../../base/common/uuid.js' ;
@@ -22,6 +23,8 @@ import { IContextKeyService } from '../../../../../platform/contextkey/common/co
2223import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js' ;
2324import { IKeybindingService } from '../../../../../platform/keybinding/common/keybinding.js' ;
2425import { IMarkerData , IMarkerService , MarkerSeverity } from '../../../../../platform/markers/common/markers.js' ;
26+ import { IProgressService } from '../../../../../platform/progress/common/progress.js' ;
27+ import { ILanguageModelToolProgressService } from '../../../../services/progress/browser/languageModelToolProgressService.js' ;
2528import { ChatContextKeys } from '../../common/chatContextKeys.js' ;
2629import { IChatMarkdownContent , IChatProgressMessage , IChatTerminalToolInvocationData , IChatToolInvocation , IChatToolInvocationSerialized } from '../../common/chatService.js' ;
2730import { IChatRendererContent } from '../../common/chatViewModel.js' ;
@@ -64,6 +67,7 @@ export class ChatToolInvocationPart extends Disposable implements IChatContentPa
6467 codeBlockModelCollection : CodeBlockModelCollection ,
6568 codeBlockStartIndex : number ,
6669 @IInstantiationService instantiationService : IInstantiationService ,
70+ @IProgressService progressService : IProgressService ,
6771 ) {
6872 super ( ) ;
6973
@@ -140,6 +144,7 @@ class ChatToolInvocationSubPart extends Disposable {
140144 @ILanguageModelToolsService private readonly languageModelToolsService : ILanguageModelToolsService ,
141145 @ICommandService private readonly commandService : ICommandService ,
142146 @IMarkerService private readonly markerService : IMarkerService ,
147+ @ILanguageModelToolProgressService private readonly languageModelToolProgressService : ILanguageModelToolProgressService ,
143148 ) {
144149 super ( ) ;
145150
@@ -454,27 +459,37 @@ class ChatToolInvocationSubPart extends Disposable {
454459 }
455460
456461 private createProgressPart ( ) : HTMLElement {
457- let content : IMarkdownString ;
458462 if ( this . toolInvocation . isComplete && this . toolInvocation . isConfirmed !== false && this . toolInvocation . pastTenseMessage ) {
459- content = typeof this . toolInvocation . pastTenseMessage === 'string' ?
460- new MarkdownString ( ) . appendText ( this . toolInvocation . pastTenseMessage ) :
461- this . toolInvocation . pastTenseMessage ;
463+ const part = this . renderProgressContent ( this . toolInvocation . pastTenseMessage ) ;
464+ this . _register ( part ) ;
465+ return part . domNode ;
462466 } else {
463- content = typeof this . toolInvocation . invocationMessage === 'string' ?
464- new MarkdownString ( ) . appendText ( this . toolInvocation . invocationMessage + '…' ) :
465- MarkdownString . lift ( this . toolInvocation . invocationMessage ) . appendText ( '…' ) ;
467+ const container = document . createElement ( 'div' ) ;
468+ const progressObservable = this . _register ( this . languageModelToolProgressService . listenForProgress ( this . toolInvocation . toolCallId ) ) ;
469+ this . _register ( autorunWithStore ( ( reader , store ) => {
470+ const progress = progressObservable . object . read ( reader ) ;
471+ const part = store . add ( this . renderProgressContent ( progress ?. message || this . toolInvocation . invocationMessage ) ) ;
472+ dom . reset ( container , part . domNode ) ;
473+ } ) ) ;
474+ return container ;
475+ }
476+ }
477+
478+ private renderProgressContent ( content : IMarkdownString | string ) {
479+ if ( typeof content === 'string' ) {
480+ content = new MarkdownString ( ) . appendText ( content ) ;
466481 }
467482
468483 const progressMessage : IChatProgressMessage = {
469484 kind : 'progressMessage' ,
470485 content
471486 } ;
487+
472488 const iconOverride = ! this . toolInvocation . isConfirmed ?
473489 Codicon . error :
474490 this . toolInvocation . isComplete ?
475491 Codicon . check : undefined ;
476- const progressPart = this . _register ( this . instantiationService . createInstance ( ChatProgressContentPart , progressMessage , this . renderer , this . context , undefined , true , iconOverride ) ) ;
477- return progressPart . domNode ;
492+ return this . instantiationService . createInstance ( ChatProgressContentPart , progressMessage , this . renderer , this . context , undefined , true , iconOverride ) ;
478493 }
479494
480495 private createTerminalMarkdownProgressPart ( toolInvocation : IChatToolInvocation | IChatToolInvocationSerialized , terminalData : IChatTerminalToolInvocationData ) : HTMLElement {
0 commit comments