diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index e946885460b..dbd4e9a4d31 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -1272,7 +1272,7 @@ export class InlineChatController2 implements IEditorContribution { private readonly _editor: ICodeEditor, @IInstantiationService private readonly _instaService: IInstantiationService, @INotebookEditorService private readonly _notebookEditorService: INotebookEditorService, - @IInlineChatSessionService private readonly _inlineChatSessions: IInlineChatSessionService, + @IInlineChatSessionService private readonly _inlineChatSessionService: IInlineChatSessionService, @ICodeEditorService codeEditorService: ICodeEditorService, @IContextKeyService contextKeyService: IContextKeyService, @ISharedWebContentExtractorService private readonly _webContentExtractorService: ISharedWebContentExtractorService, @@ -1360,22 +1360,35 @@ export class InlineChatController2 implements IEditorContribution { const editorObs = observableCodeEditor(_editor); - const sessionsSignal = observableSignalFromEvent(this, _inlineChatSessions.onDidChangeSessions); + const sessionsSignal = observableSignalFromEvent(this, _inlineChatSessionService.onDidChangeSessions); this._currentSession = derived(r => { sessionsSignal.read(r); const model = editorObs.model.read(r); - const value = model && _inlineChatSessions.getSession2(model.uri); - return value ?? undefined; + const session = model && _inlineChatSessionService.getSession2(model.uri); + return session ?? undefined; }); + let lastSession: IInlineChatSession2 | undefined = undefined; + this._store.add(autorun(r => { const session = this._currentSession.read(r); if (!session) { this._isActiveController.set(false, undefined); + + if (lastSession && !lastSession.chatModel.hasRequests) { + const state = lastSession.chatModel.inputModel.state.read(undefined); + if (!state || (!state.inputText && state.attachments.length === 0)) { + lastSession.dispose(); + lastSession = undefined; + } + } return; } + + lastSession = session; + let foundOne = false; for (const editor of codeEditorService.listCodeEditors()) { if (Boolean(InlineChatController2.get(editor)?._isActiveController.read(undefined))) { @@ -1409,11 +1422,12 @@ export class InlineChatController2 implements IEditorContribution { const session = visibleSessionObs.read(r); if (!session) { this._zone.rawValue?.hide(); + this._zone.value.widget.chatWidget.setModel(undefined); _editor.focus(); ctxInlineChatVisible.reset(); } else { ctxInlineChatVisible.set(true); - this._zone.value.widget.setChatModel(session.chatModel); + this._zone.value.widget.chatWidget.setModel(session.chatModel); if (!this._zone.value.position) { this._zone.value.widget.chatWidget.input.renderAttachedContext(); // TODO - fights layout bug this._zone.value.show(session.initialPosition); @@ -1537,7 +1551,7 @@ export class InlineChatController2 implements IEditorContribution { const uri = this._editor.getModel().uri; - const existingSession = this._inlineChatSessions.getSession2(uri); + const existingSession = this._inlineChatSessionService.getSession2(uri); if (existingSession) { await existingSession.editingSession.accept(); existingSession.dispose(); @@ -1545,7 +1559,7 @@ export class InlineChatController2 implements IEditorContribution { this._isActiveController.set(true, undefined); - const session = await this._inlineChatSessions.createSession2(this._editor, uri, CancellationToken.None); + const session = await this._inlineChatSessionService.createSession2(this._editor, uri, CancellationToken.None); // ADD diagnostics const entries: IChatRequestVariableEntry[] = []; diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.ts index 6794218c60e..b79dbc97bec 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.ts @@ -67,7 +67,7 @@ export interface IInlineChatSessionService { createSession2(editor: ICodeEditor, uri: URI, token: CancellationToken): Promise; getSession2(uri: URI): IInlineChatSession2 | undefined; - getSession2(sessionId: string): IInlineChatSession2 | undefined; + getSessionBySessionUri(uri: URI): IInlineChatSession2 | undefined; readonly onDidChangeSessions: Event; } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts index 4de3a41ff22..6728e0ce3c1 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts @@ -408,26 +408,25 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService { return result; } - getSession2(uriOrSessionId: URI | string): IInlineChatSession2 | undefined { - if (URI.isUri(uriOrSessionId)) { - - let result = this._sessions2.get(uriOrSessionId); - if (!result) { - // no direct session, try to find an editing session which has a file entry for the uri - for (const [_, candidate] of this._sessions2) { - const entry = candidate.editingSession.getEntry(uriOrSessionId); - if (entry) { - result = candidate; - break; - } + getSession2(uri: URI): IInlineChatSession2 | undefined { + let result = this._sessions2.get(uri); + if (!result) { + // no direct session, try to find an editing session which has a file entry for the uri + for (const [_, candidate] of this._sessions2) { + const entry = candidate.editingSession.getEntry(uri); + if (entry) { + result = candidate; + break; } } - return result; - } else { - for (const session of this._sessions2.values()) { - if (session.chatModel.sessionId === uriOrSessionId) { - return session; - } + } + return result; + } + + getSessionBySessionUri(sessionResource: URI): IInlineChatSession2 | undefined { + for (const session of this._sessions2.values()) { + if (isEqual(session.chatModel.sessionResource, sessionResource)) { + return session; } } return undefined; @@ -523,17 +522,17 @@ export class InlineChatEscapeToolContribution extends Disposable { this._store.add(lmTools.registerTool(InlineChatEscapeToolContribution._data, { invoke: async (invocation, _tokenCountFn, _progress, _token) => { - const sessionId = invocation.context?.sessionId; + const sessionResource = invocation.context?.sessionResource; - if (!sessionId) { + if (!sessionResource) { logService.warn('InlineChatEscapeToolContribution: no sessionId in tool invocation context'); return { content: [{ kind: 'text', value: 'Cancel' }] }; } - const session = inlineChatSessionService.getSession2(sessionId); + const session = inlineChatSessionService.getSessionBySessionUri(sessionResource); if (!session) { - logService.warn(`InlineChatEscapeToolContribution: no session found for id ${sessionId}`); + logService.warn(`InlineChatEscapeToolContribution: no session found for id ${sessionResource}`); return { content: [{ kind: 'text', value: 'Cancel' }] }; } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts index 7a261fadb92..1b331466ef4 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts @@ -290,7 +290,6 @@ export class InlineChatZoneWidget extends ZoneWidget { const scrollState = StableEditorBottomScrollState.capture(this.editor); this._scrollUp.disable(); this._ctxCursorPosition.reset(); - this.widget.reset(); this.widget.chatWidget.setVisible(false); super.hide(); aria.status(localize('inlineChatClosed', 'Closed inline chat widget'));