mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-19 16:18:58 +01:00
Enhance inline chat functionality and affordances (#296291)
* Enhance inline chat functionality with new actions which allow to continue/enrich an existing chat session * Refactor inline chat affordances and adjust z-index for overlay widgets * Add support for queued chat requests in SubmitToChatAction
This commit is contained in:
@@ -39,7 +39,7 @@ import { ISharedWebContentExtractorService } from '../../../../platform/webConte
|
||||
import { IEditorService, SIDE_GROUP } from '../../../services/editor/common/editorService.js';
|
||||
import { IChatAttachmentResolveService } from '../../chat/browser/attachments/chatAttachmentResolveService.js';
|
||||
import { IChatWidgetLocationOptions } from '../../chat/browser/widget/chatWidget.js';
|
||||
import { ModifiedFileEntryState } from '../../chat/common/editing/chatEditingService.js';
|
||||
import { IChatEditingService, ModifiedFileEntryState } from '../../chat/common/editing/chatEditingService.js';
|
||||
import { ChatModel } from '../../chat/common/model/chatModel.js';
|
||||
import { ChatMode } from '../../chat/common/chatModes.js';
|
||||
import { IChatService } from '../../chat/common/chatService/chatService.js';
|
||||
@@ -51,14 +51,13 @@ import { isNotebookContainingCellEditor as isNotebookWithCellEditor } from '../.
|
||||
import { INotebookEditorService } from '../../notebook/browser/services/notebookEditorService.js';
|
||||
import { CellUri, ICellEditOperation } from '../../notebook/common/notebookCommon.js';
|
||||
import { INotebookService } from '../../notebook/common/notebookService.js';
|
||||
import { CTX_INLINE_CHAT_VISIBLE, InlineChatConfigKeys } from '../common/inlineChat.js';
|
||||
import { CTX_INLINE_CHAT_FILE_BELONGS_TO_CHAT, CTX_INLINE_CHAT_VISIBLE, InlineChatConfigKeys } from '../common/inlineChat.js';
|
||||
import { InlineChatAffordance } from './inlineChatAffordance.js';
|
||||
import { InlineChatInputWidget, InlineChatSessionOverlayWidget } from './inlineChatOverlayWidget.js';
|
||||
import { IInlineChatSession2, IInlineChatSessionService } from './inlineChatSessionService.js';
|
||||
import { EditorBasedInlineChatWidget } from './inlineChatWidget.js';
|
||||
import { InlineChatZoneWidget } from './inlineChatZoneWidget.js';
|
||||
|
||||
|
||||
export abstract class InlineChatRunOptions {
|
||||
|
||||
initialSelection?: ISelection;
|
||||
@@ -117,7 +116,7 @@ export class InlineChatController implements IEditorContribution {
|
||||
private readonly _isActiveController = observableValue(this, false);
|
||||
private readonly _renderMode: IObservable<'zone' | 'hover'>;
|
||||
private readonly _zone: Lazy<InlineChatZoneWidget>;
|
||||
private readonly _gutterIndicator: InlineChatAffordance;
|
||||
readonly inputOverlayWidget: InlineChatAffordance;
|
||||
private readonly _inputWidget: InlineChatInputWidget;
|
||||
|
||||
private readonly _currentSession: IObservable<IInlineChatSession2 | undefined>;
|
||||
@@ -149,17 +148,42 @@ export class InlineChatController implements IEditorContribution {
|
||||
@IMarkerDecorationsService private readonly _markerDecorationsService: IMarkerDecorationsService,
|
||||
@ILanguageModelsService private readonly _languageModelService: ILanguageModelsService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
@IChatEditingService private readonly _chatEditingService: IChatEditingService,
|
||||
) {
|
||||
const editorObs = observableCodeEditor(_editor);
|
||||
|
||||
|
||||
const ctxInlineChatVisible = CTX_INLINE_CHAT_VISIBLE.bindTo(contextKeyService);
|
||||
const ctxFileBelongsToChat = CTX_INLINE_CHAT_FILE_BELONGS_TO_CHAT.bindTo(contextKeyService);
|
||||
const notebookAgentConfig = observableConfigValue(InlineChatConfigKeys.notebookAgent, false, this._configurationService);
|
||||
this._renderMode = observableConfigValue(InlineChatConfigKeys.RenderMode, 'zone', this._configurationService);
|
||||
|
||||
// Track whether the current editor's file is being edited by any chat editing session
|
||||
this._store.add(autorun(r => {
|
||||
const model = editorObs.model.read(r);
|
||||
if (!model) {
|
||||
ctxFileBelongsToChat.set(false);
|
||||
return;
|
||||
}
|
||||
const sessions = this._chatEditingService.editingSessionsObs.read(r);
|
||||
let hasEdits = false;
|
||||
for (const session of sessions) {
|
||||
const entries = session.entries.read(r);
|
||||
for (const entry of entries) {
|
||||
if (isEqual(entry.modifiedURI, model.uri)) {
|
||||
hasEdits = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasEdits) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ctxFileBelongsToChat.set(hasEdits);
|
||||
}));
|
||||
|
||||
const overlayWidget = this._inputWidget = this._store.add(this._instaService.createInstance(InlineChatInputWidget, editorObs));
|
||||
const sessionOverlayWidget = this._store.add(this._instaService.createInstance(InlineChatSessionOverlayWidget, editorObs));
|
||||
this._gutterIndicator = this._store.add(this._instaService.createInstance(InlineChatAffordance, this._editor, overlayWidget));
|
||||
this.inputOverlayWidget = this._store.add(this._instaService.createInstance(InlineChatAffordance, this._editor, overlayWidget));
|
||||
|
||||
this._zone = new Lazy<InlineChatZoneWidget>(() => {
|
||||
|
||||
@@ -231,8 +255,6 @@ export class InlineChatController implements IEditorContribution {
|
||||
return result;
|
||||
});
|
||||
|
||||
|
||||
|
||||
const sessionsSignal = observableSignalFromEvent(this, _inlineChatSessionService.onDidChangeSessions);
|
||||
|
||||
this._currentSession = derived(r => {
|
||||
@@ -474,18 +496,10 @@ export class InlineChatController implements IEditorContribution {
|
||||
existingSession.dispose();
|
||||
}
|
||||
|
||||
// use hover overlay to ask for input
|
||||
if (!arg?.message && this._configurationService.getValue<string>(InlineChatConfigKeys.RenderMode) === 'hover') {
|
||||
// show menu and RETURN because the menu is re-entrant
|
||||
await this._gutterIndicator.showMenuAtSelection();
|
||||
return true;
|
||||
}
|
||||
|
||||
this._isActiveController.set(true, undefined);
|
||||
|
||||
const session = this._inlineChatSessionService.createSession(this._editor);
|
||||
|
||||
|
||||
// Store for tracking model changes during this session
|
||||
const sessionStore = new DisposableStore();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user