@@ -176,6 +176,7 @@ export class NotebookChatController extends Disposable implements INotebookEdito
176176 private _strategy : EditStrategy | undefined ;
177177 private _sessionCtor : CancelablePromise < void > | undefined ;
178178 private _activeSession ?: Session ;
179+ private _warmupRequestCts ?: CancellationTokenSource ;
179180 private readonly _ctxHasActiveRequest : IContextKey < boolean > ;
180181 private readonly _ctxCellWidgetFocused : IContextKey < boolean > ;
181182 private readonly _ctxUserDidEdit : IContextKey < boolean > ;
@@ -275,6 +276,10 @@ export class NotebookChatController extends Disposable implements INotebookEdito
275276 inlineChatWidget . placeholder = localize ( 'default.placeholder' , "Ask a question" ) ;
276277 inlineChatWidget . updateInfo ( localize ( 'welcome.1' , "AI-generated code may be incorrect" ) ) ;
277278 widgetContainer . appendChild ( inlineChatWidget . domNode ) ;
279+ this . _widgetDisposableStore . add ( inlineChatWidget . onDidChangeInput ( ( ) => {
280+ this . _warmupRequestCts ?. dispose ( true ) ;
281+ this . _warmupRequestCts = undefined ;
282+ } ) ) ;
278283
279284 this . _notebookEditor . changeViewZones ( accessor => {
280285 const notebookViewZone = {
@@ -307,6 +312,8 @@ export class NotebookChatController extends Disposable implements INotebookEdito
307312
308313 if ( fakeParentEditor . hasModel ( ) ) {
309314 await this . _startSession ( fakeParentEditor , token ) ;
315+ this . _warmupRequestCts = new CancellationTokenSource ( ) ;
316+ this . _startInitialFolowups ( fakeParentEditor , this . _warmupRequestCts . token ) ;
310317
311318 if ( this . _widget ) {
312319 this . _widget . inlineChatWidget . placeholder = this . _activeSession ?. session . placeholder ?? localize ( 'default.placeholder' , "Ask a question" ) ;
@@ -368,6 +375,8 @@ export class NotebookChatController extends Disposable implements INotebookEdito
368375 async acceptInput ( ) {
369376 assertType ( this . _activeSession ) ;
370377 assertType ( this . _widget ) ;
378+ this . _warmupRequestCts ?. dispose ( true ) ;
379+ this . _warmupRequestCts = undefined ;
371380 this . _activeSession . addInput ( new SessionPrompt ( this . _widget . inlineChatWidget . value ) ) ;
372381
373382 assertType ( this . _activeSession . lastInput ) ;
@@ -559,6 +568,50 @@ export class NotebookChatController extends Disposable implements INotebookEdito
559568 this . _strategy = new EditStrategy ( session ) ;
560569 }
561570
571+ private async _startInitialFolowups ( editor : IActiveCodeEditor , token : CancellationToken ) {
572+ if ( ! this . _activeSession || ! this . _activeSession . provider . provideFollowups ) {
573+ return ;
574+ }
575+
576+ const request : IInlineChatRequest = {
577+ requestId : generateUuid ( ) ,
578+ prompt : '' ,
579+ attempt : 0 ,
580+ selection : { selectionStartLineNumber : 1 , selectionStartColumn : 1 , positionLineNumber : 1 , positionColumn : 1 } ,
581+ wholeRange : { startLineNumber : 1 , startColumn : 1 , endLineNumber : 1 , endColumn : 1 } ,
582+ live : true ,
583+ previewDocument : editor . getModel ( ) . uri ,
584+ withIntentDetection : true
585+ } ;
586+
587+ const progress = new AsyncProgress < IInlineChatProgressItem > ( async data => { } ) ;
588+ const task = this . _activeSession . provider . provideResponse ( this . _activeSession . session , request , progress , token ) ;
589+ const reply = await raceCancellationError ( Promise . resolve ( task ) , token ) ;
590+ if ( token . isCancellationRequested ) {
591+ return ;
592+ }
593+
594+ if ( ! reply ) {
595+ return ;
596+ }
597+
598+ const markdownContents = new MarkdownString ( '' , { supportThemeIcons : true , supportHtml : true , isTrusted : false } ) ;
599+ const response = this . _instantiationService . createInstance ( ReplyResponse , reply , markdownContents , this . _activeSession . textModelN . uri , this . _activeSession . textModelN . getAlternativeVersionId ( ) , [ ] , request . requestId ) ;
600+ const followups = await this . _activeSession . provider . provideFollowups ( this . _activeSession . session , response . raw , token ) ;
601+ if ( followups && this . _widget ) {
602+ const widget = this . _widget ;
603+ widget . inlineChatWidget . updateFollowUps ( followups , async followup => {
604+ if ( followup . kind === 'reply' ) {
605+ widget . inlineChatWidget . value = followup . message ;
606+ this . acceptInput ( ) ;
607+ } else {
608+ await this . acceptSession ( ) ;
609+ this . _commandService . executeCommand ( followup . commandId , ...( followup . args ?? [ ] ) ) ;
610+ }
611+ } ) ;
612+ }
613+ }
614+
562615 private async _makeChanges ( edits : TextEdit [ ] , opts : ProgressingEditsOptions | undefined ) {
563616 assertType ( this . _activeSession ) ;
564617 assertType ( this . _strategy ) ;
0 commit comments