diff --git a/src/vs/workbench/contrib/chat/browser/chat.ts b/src/vs/workbench/contrib/chat/browser/chat.ts index f97e377c7dd..357ca063a54 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.ts @@ -99,6 +99,7 @@ export interface IChatListItemRendererOptions { export interface IChatWidgetViewOptions { renderInputOnTop?: boolean; + renderFollowups?: boolean; renderStyle?: 'default' | 'compact'; supportsFileReferences?: boolean; filter?: (item: ChatTreeItem) => boolean; diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 7e243af391a..b8a793deebf 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -259,15 +259,16 @@ export class ChatWidget extends Disposable implements IChatWidget { const viewId = 'viewId' in this.viewContext ? this.viewContext.viewId : undefined; this.editorOptions = this._register(this.instantiationService.createInstance(ChatEditorOptions, viewId, this.styles.listForeground, this.styles.inputEditorBackground, this.styles.resultEditorBackground)); const renderInputOnTop = this.viewOptions.renderInputOnTop ?? false; + const renderFollowups = this.viewOptions.renderFollowups ?? !renderInputOnTop; const renderStyle = this.viewOptions.renderStyle; this.container = dom.append(parent, $('.interactive-session')); if (renderInputOnTop) { - this.createInput(this.container, { renderFollowups: false, renderStyle }); + this.createInput(this.container, { renderFollowups, renderStyle }); this.listContainer = dom.append(this.container, $(`.interactive-list`)); } else { this.listContainer = dom.append(this.container, $(`.interactive-list`)); - this.createInput(this.container, { renderFollowups: true, renderStyle }); + this.createInput(this.container, { renderFollowups, renderStyle }); } this.createList(this.listContainer, { ...this.viewOptions.rendererOptions, renderStyle }); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget.ts index 90870d48786..dfd3b06a278 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget.ts @@ -68,6 +68,7 @@ export class InlineChatContentWidget implements IContentWidget { editorOverflowWidgetsDomNode: _editor.getOverflowWidgetsDomNode(), renderStyle: 'compact', renderInputOnTop: true, + renderFollowups: true, supportsFileReferences: false, menus: { telemetrySource: 'inlineChat-content' diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 78827e18545..ffec0fdfd21 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -343,9 +343,6 @@ export class InlineChatController implements IEditorContribution { break; } - if (session.session.input) { - options.message = session.session.input; - } this._session = session; return State.INIT_UI; } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts index ef4c23b3527..35a3b2f9f0b 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts @@ -186,6 +186,29 @@ class BridgeAgent implements IChatAgentImplementation { coalesceInPlace(chatFollowups); return chatFollowups; } + + provideWelcomeMessage(token: CancellationToken): string[] { + // without this provideSampleQuestions is not called + return []; + } + + async provideSampleQuestions(location: ChatAgentLocation, token: CancellationToken): Promise { + // TODO@jrieken DEBT + // (hack) this function is called while creating the session. We need the timeout to make sure this._sessions is populated. + // (hack) we have no context/session id and therefore use the first session with an active editor + await new Promise(resolve => setTimeout(resolve, 10)); + + for (const [, data] of this._sessions) { + if (data.session.session.input && data.editor.hasWidgetFocus()) { + return [{ + kind: 'reply', + agentId: _bridgeAgentId, + message: data.session.session.input, + }]; + } + } + return []; + } } type SessionData = { @@ -342,19 +365,6 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService { return undefined; } - const chatModel = this._chatService.startSession(ChatAgentLocation.Editor, token); - if (!chatModel) { - this._logService.trace('[IE] NO chatModel found'); - return undefined; - } - - const store = new DisposableStore(); - - store.add(toDisposable(() => { - this._chatService.clearSession(chatModel.sessionId); - chatModel.dispose(); - })); - this._onWillStartSession.fire(editor); const textModel = editor.getModel(); @@ -375,8 +385,19 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService { return undefined; } + const store = new DisposableStore(); this._logService.trace(`[IE] creating NEW session for ${editor.getId()}, ${provider.extensionId}`); + const chatModel = this._chatService.startSession(ChatAgentLocation.Editor, token); + if (!chatModel) { + this._logService.trace('[IE] NO chatModel found'); + return undefined; + } + + store.add(toDisposable(() => { + this._chatService.clearSession(chatModel.sessionId); + chatModel.dispose(); + })); const lastResponseListener = store.add(new MutableDisposable()); store.add(chatModel.onDidChange(e => { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index 20f5331bd70..989405de2a5 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -173,6 +173,7 @@ export class InlineChatWidget { defaultElementHeight: 32, renderStyle: 'compact', renderInputOnTop: true, + renderFollowups: true, supportsFileReferences: true, editorOverflowWidgetsDomNode: options.editorOverflowWidgetsDomNode, rendererOptions: options.rendererOptions,