@codingame/monaco-vscode-chat-service-override 11.1.2 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +2 -1
- package/index.js +64 -1
- package/package.json +32 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.d.ts +21 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.js +73 -60
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.d.ts +3 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.js +73 -81
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.d.ts +9 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.js +73 -112
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.d.ts +12 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.js +253 -101
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.js +8 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatDeveloperActions.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatDeveloperActions.js +2 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.js +16 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.d.ts +23 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.js +30 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatImportExport.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatImportExport.js +12 -12
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatMoveActions.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatMoveActions.js +22 -20
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.js +23 -20
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.d.ts +52 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.js +50 -47
- package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js +124 -95
- package/vscode/src/vs/workbench/contrib/chat/browser/chatAccessibilityService.d.ts +17 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatAccessibilityService.js +6 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEdinputInputContentProvider.d.ts +12 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEdinputInputContentProvider.js +30 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingService.d.ts +69 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingService.js +203 -182
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.d.ts +103 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.js +458 -165
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditor.d.ts +42 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditor.js +14 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.d.ts +26 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/{chatParticipantContributions.js → chatParticipant.contribution.js} +101 -92
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPasteProviders.d.ts +42 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPasteProviders.js +164 -25
- package/vscode/src/vs/workbench/contrib/chat/browser/chatQuick.d.ts +26 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatQuick.js +6 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.d.ts +30 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.js +10 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup.d.ts +17 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup.js +941 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.d.ts +26 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.js +9 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/chatViewPane.d.ts +54 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatViewPane.js +32 -15
- package/vscode/src/vs/workbench/contrib/chat/browser/codeBlockContextProviderService.d.ts +9 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/codeBlockContextProviderService.js +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.js +8 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorHover.d.ts +26 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorHover.js +16 -19
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputRelatedFilesContrib.d.ts +15 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputRelatedFilesContrib.js +108 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/editorHoverWrapper.d.ts +7 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/editorHoverWrapper.js +3 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/media/editorHoverWrapper.css.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/languageModelToolsService.d.ts +31 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/languageModelToolsService.js +70 -49
- package/vscode/src/vs/workbench/contrib/chat/browser/media/chatViewSetup.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcomeHandler.d.ts +7 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/viewsWelcome/{chatViewsWelcomeContributions.js → chatViewsWelcomeHandler.js} +13 -13
- package/vscode/src/vs/workbench/contrib/chat/common/chatCodeMapperService.d.ts +44 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatCodeMapperService.js +3 -1
- package/vscode/src/vs/workbench/contrib/chat/common/chatProgressTypes/chatToolInvocation.d.ts +22 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatProgressTypes/chatToolInvocation.js +1 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.d.ts +80 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.js +152 -104
- package/vscode/src/vs/workbench/contrib/chat/common/chatServiceTelemetry.d.ts +8 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatServiceTelemetry.js +2 -1
- package/vscode/src/vs/workbench/contrib/chat/common/chatSlashCommands.d.ts +41 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatSlashCommands.js +2 -1
- package/vscode/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.d.ts +31 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.js +6 -4
- package/vscode/src/vs/workbench/contrib/chat/common/ignoredFiles.d.ts +13 -0
- package/vscode/src/vs/workbench/contrib/chat/common/ignoredFiles.js +1 -0
- package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.d.ts +24 -0
- package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.js +23 -21
- package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsParametersSchema.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsParametersSchema.js +1 -0
- package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.d.ts +39 -0
- package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.js +20 -19
- package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.service.d.ts +7 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +30 -33
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.d.ts +10 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.js +6 -4
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.d.ts +10 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.js +9 -7
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatCurrentLine.d.ts +44 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatCurrentLine.js +247 -83
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatNotebook.d.ts +8 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatNotebook.js +5 -4
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSavingServiceImpl.d.ts +29 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSavingServiceImpl.js +35 -35
- package/chat.js +0 -59
- package/vscode/src/vs/editor/common/diff/documentDiffProvider.js +0 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedFileEntry.js +0 -326
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelContentProviders.js +0 -76
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditorActions.js +0 -110
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditorController.js +0 -287
- package/vscode/src/vs/workbench/contrib/chat/common/languageModelStats.js +0 -130
- package/vscode/src/vs/workbench/contrib/chat/common/languageModels.js +0 -172
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
|
|
2
|
+
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6';
|
|
3
|
+
import { Sequencer, timeout } from 'vscode/vscode/vs/base/common/async';
|
|
3
4
|
import { BugIndicatingError } from 'vscode/vscode/vs/base/common/errors';
|
|
4
5
|
import { Emitter } from 'vscode/vscode/vs/base/common/event';
|
|
5
6
|
import { Disposable } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
6
7
|
import { ResourceMap, ResourceSet } from 'vscode/vscode/vs/base/common/map';
|
|
7
8
|
import { observableValue, transaction } from 'vscode/vscode/vs/base/common/observableInternal/base';
|
|
8
9
|
import 'vscode/vscode/vs/base/common/arrays';
|
|
9
|
-
import 'vscode/vscode/vs/base/common/observableInternal/autorun';
|
|
10
|
+
import { autorun } from 'vscode/vscode/vs/base/common/observableInternal/autorun';
|
|
10
11
|
import { derived } from 'vscode/vscode/vs/base/common/observableInternal/derived';
|
|
11
12
|
import 'vscode/vscode/vs/base/common/cancellation';
|
|
12
13
|
import 'vscode/vscode/vs/base/common/observableInternal/utils';
|
|
14
|
+
import { URI } from 'vscode/vscode/vs/base/common/uri';
|
|
13
15
|
import { isDiffEditor, isCodeEditor } from 'vscode/vscode/vs/editor/browser/editorBrowser';
|
|
14
16
|
import { IBulkEditService } from 'vscode/vscode/vs/editor/browser/services/bulkEditService';
|
|
15
17
|
import { ILanguageService } from 'vscode/vscode/vs/editor/common/languages/language';
|
|
@@ -21,18 +23,55 @@ import { EditorActivation } from 'vscode/vscode/vs/platform/editor/common/editor
|
|
|
21
23
|
import { IFileService } from 'vscode/vscode/vs/platform/files/common/files.service';
|
|
22
24
|
import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
|
|
23
25
|
import { IWorkspaceContextService } from 'vscode/vscode/vs/platform/workspace/common/workspace.service';
|
|
24
|
-
import { DiffEditorInput } from 'vscode/vscode/vs/workbench/common/editor/diffEditorInput';
|
|
26
|
+
import { DiffEditorInput } from '@codingame/monaco-vscode-5108c2c9-4ada-52d8-8c4b-fe03b3160e71-common/vscode/vs/workbench/common/editor/diffEditorInput';
|
|
25
27
|
import { IEditorGroupsService } from 'vscode/vscode/vs/workbench/services/editor/common/editorGroupsService.service';
|
|
26
28
|
import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService.service';
|
|
27
|
-
import { MultiDiffEditorInput } from 'vscode/vscode/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput';
|
|
29
|
+
import { MultiDiffEditorInput } from '@codingame/monaco-vscode-1cc4ea0a-c5b6-54ed-bb60-078a99119b55-common/vscode/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput';
|
|
28
30
|
import { ChatAgentLocation } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents';
|
|
29
31
|
import { IChatAgentService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatAgents.service';
|
|
30
|
-
import {
|
|
32
|
+
import { ChatEditingSessionState, ChatEditingSessionChangeType, WorkingSetEntryState, WorkingSetEntryRemovalReason, ChatEditKind } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatEditingService';
|
|
31
33
|
import { ChatEditingMultiDiffSourceResolver } from './chatEditingService.js';
|
|
32
|
-
import { ChatEditingModifiedFileEntry } from '
|
|
33
|
-
import { ChatEditingTextModelContentProvider } from '
|
|
34
|
+
import { ChatEditingModifiedFileEntry } from '@codingame/monaco-vscode-fab30422-b487-5f4e-8d30-8b4d266e3fcd-common/vscode/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedFileEntry';
|
|
35
|
+
import { ChatEditingTextModelContentProvider } from '@codingame/monaco-vscode-fab30422-b487-5f4e-8d30-8b4d266e3fcd-common/vscode/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelContentProviders';
|
|
34
36
|
import { Schemas } from 'vscode/vscode/vs/base/common/network';
|
|
37
|
+
import { isEqual, joinPath } from 'vscode/vscode/vs/base/common/resources';
|
|
38
|
+
import { StringSHA1 } from 'vscode/vscode/vs/base/common/hash';
|
|
39
|
+
import { IEnvironmentService } from 'vscode/vscode/vs/platform/environment/common/environment.service';
|
|
40
|
+
import { VSBuffer } from 'vscode/vscode/vs/base/common/buffer';
|
|
41
|
+
import { OffsetEdit } from 'vscode/vscode/vs/editor/common/core/offsetEdit';
|
|
42
|
+
import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service';
|
|
43
|
+
import { IChatService } from 'vscode/vscode/vs/workbench/contrib/chat/common/chatService.service';
|
|
44
|
+
import { INotebookService } from 'vscode/vscode/vs/workbench/contrib/notebook/common/notebookService.service';
|
|
45
|
+
import { ChatEditingModifiedNotebookEntry } from '@codingame/monaco-vscode-e4d0fd26-1b26-5583-b3f7-582e08d7b389-common/vscode/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedNotebookEntry';
|
|
46
|
+
import { isNotebookEditorInput } from '@codingame/monaco-vscode-271a23cd-c7d7-5761-ae35-a923a42987b8-common/vscode/vs/workbench/contrib/notebook/common/notebookEditorInput';
|
|
35
47
|
|
|
48
|
+
const STORAGE_CONTENTS_FOLDER = 'contents';
|
|
49
|
+
const STORAGE_STATE_FILE = 'state.json';
|
|
50
|
+
class ThrottledSequencer extends Sequencer {
|
|
51
|
+
constructor(_minDuration, _maxOverallDelay) {
|
|
52
|
+
super();
|
|
53
|
+
this._minDuration = _minDuration;
|
|
54
|
+
this._maxOverallDelay = _maxOverallDelay;
|
|
55
|
+
this._size = 0;
|
|
56
|
+
}
|
|
57
|
+
queue(promiseTask) {
|
|
58
|
+
this._size += 1;
|
|
59
|
+
const noDelay = this._size * this._minDuration > this._maxOverallDelay;
|
|
60
|
+
return super.queue(async () => {
|
|
61
|
+
try {
|
|
62
|
+
const p1 = promiseTask();
|
|
63
|
+
const p2 = noDelay
|
|
64
|
+
? Promise.resolve(undefined)
|
|
65
|
+
: timeout(this._minDuration);
|
|
66
|
+
const [result] = await Promise.all([p1, p2]);
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
this._size -= 1;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
36
75
|
let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
37
76
|
get entries() {
|
|
38
77
|
this._assertNotDisposed();
|
|
@@ -40,9 +79,9 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
40
79
|
}
|
|
41
80
|
get workingSet() {
|
|
42
81
|
this._assertNotDisposed();
|
|
43
|
-
const result = (
|
|
82
|
+
const result = ( new ResourceMap(this._workingSet));
|
|
44
83
|
for (const entry of this._entriesObs.get()) {
|
|
45
|
-
result.set(entry.modifiedURI, entry.state.get());
|
|
84
|
+
result.set(entry.modifiedURI, { state: entry.state.get() });
|
|
46
85
|
}
|
|
47
86
|
return result;
|
|
48
87
|
}
|
|
@@ -59,12 +98,11 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
59
98
|
}
|
|
60
99
|
get isVisible() {
|
|
61
100
|
this._assertNotDisposed();
|
|
62
|
-
return Boolean(this.
|
|
101
|
+
return Boolean(this._editorPane && this._editorPane.isVisible());
|
|
63
102
|
}
|
|
64
|
-
constructor(chatSessionId,
|
|
103
|
+
constructor(chatSessionId, editingSessionFileLimitPromise, _instantiationService, _modelService, _languageService, _textModelService, _bulkEditService, _editorGroupsService, _editorService, _workspaceContextService, _fileService, _dialogService, _chatAgentService, _chatService, _notebookService) {
|
|
65
104
|
super();
|
|
66
105
|
this.chatSessionId = chatSessionId;
|
|
67
|
-
this.editorPane = editorPane;
|
|
68
106
|
this.editingSessionFileLimitPromise = editingSessionFileLimitPromise;
|
|
69
107
|
this._instantiationService = _instantiationService;
|
|
70
108
|
this._modelService = _modelService;
|
|
@@ -73,29 +111,30 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
73
111
|
this._bulkEditService = _bulkEditService;
|
|
74
112
|
this._editorGroupsService = _editorGroupsService;
|
|
75
113
|
this._editorService = _editorService;
|
|
76
|
-
this._chatWidgetService = _chatWidgetService;
|
|
77
114
|
this._workspaceContextService = _workspaceContextService;
|
|
78
115
|
this._fileService = _fileService;
|
|
79
116
|
this._dialogService = _dialogService;
|
|
80
117
|
this._chatAgentService = _chatAgentService;
|
|
81
|
-
this.
|
|
118
|
+
this._chatService = _chatService;
|
|
119
|
+
this._notebookService = _notebookService;
|
|
120
|
+
this._state = observableValue(this, ChatEditingSessionState.Initial);
|
|
82
121
|
this._linearHistory = observableValue(this, []);
|
|
83
122
|
this._linearHistoryIndex = observableValue(this, 0);
|
|
84
|
-
this._initialFileContents = (
|
|
85
|
-
this.
|
|
86
|
-
this._filesToSkipCreating = ( (new ResourceSet()));
|
|
123
|
+
this._initialFileContents = ( new ResourceMap());
|
|
124
|
+
this._filesToSkipCreating = ( new ResourceSet());
|
|
87
125
|
this._entriesObs = observableValue(this, []);
|
|
88
|
-
this._sequencer = (
|
|
89
|
-
this._workingSet = (
|
|
126
|
+
this._sequencer = ( new ThrottledSequencer(15, 1000));
|
|
127
|
+
this._workingSet = ( new ResourceMap());
|
|
128
|
+
this._removedTransientEntries = ( new ResourceSet());
|
|
90
129
|
this.canUndo = derived((r) => {
|
|
91
|
-
if (this.state.read(r) !==
|
|
130
|
+
if (this.state.read(r) !== ChatEditingSessionState.Idle) {
|
|
92
131
|
return false;
|
|
93
132
|
}
|
|
94
133
|
const linearHistoryIndex = this._linearHistoryIndex.read(r);
|
|
95
134
|
return linearHistoryIndex > 0;
|
|
96
135
|
});
|
|
97
136
|
this.canRedo = derived((r) => {
|
|
98
|
-
if (this.state.read(r) !==
|
|
137
|
+
if (this.state.read(r) !== ChatEditingSessionState.Idle) {
|
|
99
138
|
return false;
|
|
100
139
|
}
|
|
101
140
|
const linearHistory = this._linearHistory.read(r);
|
|
@@ -105,76 +144,113 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
105
144
|
this.hiddenRequestIds = derived((r) => {
|
|
106
145
|
const linearHistory = this._linearHistory.read(r);
|
|
107
146
|
const linearHistoryIndex = this._linearHistoryIndex.read(r);
|
|
108
|
-
return (
|
|
147
|
+
return ( linearHistory.slice(linearHistoryIndex).map(s => s.requestId)).filter((r) => !!r);
|
|
109
148
|
});
|
|
110
|
-
this._onDidChange = (
|
|
111
|
-
this._onDidDispose = (
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
149
|
+
this._onDidChange = ( new Emitter());
|
|
150
|
+
this._onDidDispose = ( new Emitter());
|
|
151
|
+
}
|
|
152
|
+
async init() {
|
|
153
|
+
const restoredSessionState = await this._instantiationService.createInstance(ChatEditingSessionStorage, this.chatSessionId).restoreState();
|
|
154
|
+
if (restoredSessionState) {
|
|
155
|
+
for (const uri of restoredSessionState.filesToSkipCreating) {
|
|
156
|
+
this._filesToSkipCreating.add(uri);
|
|
157
|
+
}
|
|
158
|
+
for (const [uri, content] of restoredSessionState.initialFileContents) {
|
|
159
|
+
this._initialFileContents.set(uri, content);
|
|
160
|
+
}
|
|
161
|
+
this._pendingSnapshot = restoredSessionState.pendingSnapshot;
|
|
162
|
+
await this._restoreSnapshot(restoredSessionState.recentSnapshot);
|
|
163
|
+
this._linearHistoryIndex.set(restoredSessionState.linearHistoryIndex, undefined);
|
|
164
|
+
this._linearHistory.set(restoredSessionState.linearHistory, undefined);
|
|
165
|
+
this._state.set(ChatEditingSessionState.Idle, undefined);
|
|
115
166
|
}
|
|
116
167
|
this._trackCurrentEditorsInWorkingSet();
|
|
117
|
-
this._register(this._editorService.
|
|
168
|
+
this._register(this._editorService.onDidVisibleEditorsChange(() => {
|
|
118
169
|
this._trackCurrentEditorsInWorkingSet();
|
|
119
170
|
}));
|
|
120
|
-
this._register(
|
|
121
|
-
this.
|
|
171
|
+
this._register(autorun(reader => {
|
|
172
|
+
const entries = this.entries.read(reader);
|
|
173
|
+
entries.forEach(entry => {
|
|
174
|
+
entry.state.read(reader);
|
|
175
|
+
});
|
|
176
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.WorkingSet);
|
|
122
177
|
}));
|
|
123
178
|
}
|
|
179
|
+
getEntry(uri) {
|
|
180
|
+
return this._entriesObs.get().find(e => isEqual(e.modifiedURI, uri));
|
|
181
|
+
}
|
|
182
|
+
readEntry(uri, reader) {
|
|
183
|
+
return this._entriesObs.read(reader).find(e => isEqual(e.modifiedURI, uri));
|
|
184
|
+
}
|
|
185
|
+
storeState() {
|
|
186
|
+
const storage = this._instantiationService.createInstance(ChatEditingSessionStorage, this.chatSessionId);
|
|
187
|
+
const state = {
|
|
188
|
+
filesToSkipCreating: [...this._filesToSkipCreating],
|
|
189
|
+
initialFileContents: this._initialFileContents,
|
|
190
|
+
pendingSnapshot: this._pendingSnapshot,
|
|
191
|
+
recentSnapshot: this._createSnapshot(undefined),
|
|
192
|
+
linearHistoryIndex: this._linearHistoryIndex.get(),
|
|
193
|
+
linearHistory: this._linearHistory.get(),
|
|
194
|
+
};
|
|
195
|
+
return storage.storeState(state);
|
|
196
|
+
}
|
|
124
197
|
_trackCurrentEditorsInWorkingSet(e) {
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
const closedEditor = e?.editor.resource?.toString();
|
|
131
|
-
const existingTransientEntries = ( (new ResourceSet()));
|
|
132
|
-
for (const file of ( (this._workingSet.keys()))) {
|
|
133
|
-
if (this._workingSet.get(file) === 3 ) {
|
|
198
|
+
const existingTransientEntries = ( new ResourceSet());
|
|
199
|
+
for (const file of ( this._workingSet.keys())) {
|
|
200
|
+
if (this._workingSet.get(file)?.state === WorkingSetEntryState.Transient) {
|
|
134
201
|
existingTransientEntries.add(file);
|
|
135
202
|
}
|
|
136
203
|
}
|
|
137
|
-
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
const activeEditors = ( (new ResourceSet()));
|
|
204
|
+
const activeEditors = ( new ResourceSet());
|
|
141
205
|
this._editorGroupsService.groups.forEach((group) => {
|
|
142
206
|
if (!group.activeEditorPane) {
|
|
143
207
|
return;
|
|
144
208
|
}
|
|
145
|
-
let
|
|
146
|
-
if (
|
|
147
|
-
|
|
209
|
+
let uri;
|
|
210
|
+
if (isNotebookEditorInput(group.activeEditorPane.input)) {
|
|
211
|
+
uri = group.activeEditorPane.input.resource;
|
|
148
212
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
existingTransientEntries.delete(uri);
|
|
213
|
+
else {
|
|
214
|
+
let activeEditorControl = group.activeEditorPane.getControl();
|
|
215
|
+
if (isDiffEditor(activeEditorControl)) {
|
|
216
|
+
activeEditorControl = activeEditorControl.getOriginalEditor().hasTextFocus() ? activeEditorControl.getOriginalEditor() : activeEditorControl.getModifiedEditor();
|
|
154
217
|
}
|
|
155
|
-
|
|
156
|
-
|
|
218
|
+
if ((isCodeEditor(activeEditorControl)) && activeEditorControl.hasModel()) {
|
|
219
|
+
uri = activeEditorControl.getModel().uri;
|
|
157
220
|
}
|
|
158
221
|
}
|
|
222
|
+
if (!uri) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (( existingTransientEntries.has(uri))) {
|
|
226
|
+
existingTransientEntries.delete(uri);
|
|
227
|
+
}
|
|
228
|
+
else if (!( this._workingSet.has(uri)) && !( this._removedTransientEntries.has(uri))) {
|
|
229
|
+
activeEditors.add(uri);
|
|
230
|
+
}
|
|
159
231
|
});
|
|
160
232
|
let didChange = false;
|
|
161
233
|
for (const entry of existingTransientEntries) {
|
|
162
234
|
didChange = this._workingSet.delete(entry) || didChange;
|
|
163
235
|
}
|
|
164
236
|
for (const entry of activeEditors) {
|
|
165
|
-
this._workingSet.set(entry,
|
|
237
|
+
this._workingSet.set(entry, { state: WorkingSetEntryState.Transient, description: ( localize(4386, "Open Editor")) });
|
|
166
238
|
didChange = true;
|
|
167
239
|
}
|
|
168
240
|
if (didChange) {
|
|
169
|
-
this._onDidChange.fire();
|
|
241
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.WorkingSet);
|
|
170
242
|
}
|
|
171
243
|
}
|
|
244
|
+
_findSnapshot(requestId) {
|
|
245
|
+
return this._linearHistory.get().find(s => s.requestId === requestId);
|
|
246
|
+
}
|
|
172
247
|
createSnapshot(requestId) {
|
|
173
248
|
const snapshot = this._createSnapshot(requestId);
|
|
174
249
|
if (requestId) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
250
|
+
for (const [uri, data] of this._workingSet) {
|
|
251
|
+
if (data.state !== WorkingSetEntryState.Suggested) {
|
|
252
|
+
this._workingSet.set(uri, { state: WorkingSetEntryState.Sent });
|
|
253
|
+
}
|
|
178
254
|
}
|
|
179
255
|
const linearHistory = this._linearHistory.get();
|
|
180
256
|
const linearHistoryIndex = this._linearHistoryIndex.get();
|
|
@@ -190,11 +266,11 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
190
266
|
}
|
|
191
267
|
}
|
|
192
268
|
_createSnapshot(requestId) {
|
|
193
|
-
const workingSet = (
|
|
269
|
+
const workingSet = ( new ResourceMap());
|
|
194
270
|
for (const [file, state] of this._workingSet) {
|
|
195
271
|
workingSet.set(file, state);
|
|
196
272
|
}
|
|
197
|
-
const entries = (
|
|
273
|
+
const entries = ( new ResourceMap());
|
|
198
274
|
for (const entry of this._entriesObs.get()) {
|
|
199
275
|
entries.set(entry.modifiedURI, entry.createSnapshot(requestId));
|
|
200
276
|
}
|
|
@@ -205,131 +281,153 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
205
281
|
};
|
|
206
282
|
}
|
|
207
283
|
async getSnapshotModel(requestId, snapshotUri) {
|
|
208
|
-
const entries = this.
|
|
284
|
+
const entries = this._findSnapshot(requestId)?.entries;
|
|
209
285
|
if (!entries) {
|
|
210
286
|
return null;
|
|
211
287
|
}
|
|
212
|
-
const snapshotEntry = [...(
|
|
288
|
+
const snapshotEntry = [...( entries.values())].find((e) => isEqual(e.snapshotUri, snapshotUri));
|
|
213
289
|
if (!snapshotEntry) {
|
|
214
290
|
return null;
|
|
215
291
|
}
|
|
216
292
|
return this._modelService.createModel(snapshotEntry.current, this._languageService.createById(snapshotEntry.languageId), snapshotUri, false);
|
|
217
293
|
}
|
|
218
294
|
getSnapshot(requestId, uri) {
|
|
219
|
-
const snapshot = this.
|
|
295
|
+
const snapshot = this._findSnapshot(requestId);
|
|
220
296
|
const snapshotEntries = snapshot?.entries;
|
|
221
297
|
return snapshotEntries?.get(uri);
|
|
222
298
|
}
|
|
299
|
+
getSnapshotUri(requestId, uri) {
|
|
300
|
+
return this.getSnapshot(requestId, uri)?.snapshotUri;
|
|
301
|
+
}
|
|
223
302
|
async restoreSnapshot(requestId) {
|
|
224
303
|
if (requestId !== undefined) {
|
|
225
|
-
const snapshot = this.
|
|
304
|
+
const snapshot = this._findSnapshot(requestId);
|
|
226
305
|
if (snapshot) {
|
|
306
|
+
if (!this._pendingSnapshot) {
|
|
307
|
+
this.createSnapshot(undefined);
|
|
308
|
+
}
|
|
227
309
|
await this._restoreSnapshot(snapshot);
|
|
228
310
|
}
|
|
229
311
|
}
|
|
230
312
|
else {
|
|
231
|
-
await this._restoreSnapshot(undefined);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
async _restoreSnapshot(snapshot) {
|
|
235
|
-
if (!snapshot) {
|
|
236
313
|
if (!this._pendingSnapshot) {
|
|
237
314
|
return;
|
|
238
315
|
}
|
|
239
|
-
snapshot = this._pendingSnapshot;
|
|
316
|
+
const snapshot = this._pendingSnapshot;
|
|
240
317
|
this._pendingSnapshot = undefined;
|
|
318
|
+
await this._restoreSnapshot(snapshot);
|
|
241
319
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this._workingSet = ( (new ResourceMap()));
|
|
320
|
+
}
|
|
321
|
+
async _restoreSnapshot(snapshot) {
|
|
322
|
+
this._workingSet = ( new ResourceMap());
|
|
246
323
|
snapshot.workingSet.forEach((state, uri) => this._workingSet.set(uri, state));
|
|
247
324
|
for (const entry of this._entriesObs.get()) {
|
|
248
325
|
const snapshotEntry = snapshot.entries.get(entry.modifiedURI);
|
|
249
326
|
if (!snapshotEntry) {
|
|
250
|
-
|
|
251
|
-
if (typeof initialContents === 'string') {
|
|
252
|
-
entry.resetToInitialValue(initialContents);
|
|
253
|
-
}
|
|
327
|
+
entry.resetToInitialValue();
|
|
254
328
|
entry.dispose();
|
|
255
329
|
}
|
|
256
330
|
}
|
|
257
331
|
const entriesArr = [];
|
|
258
|
-
for (const snapshotEntry of (
|
|
332
|
+
for (const snapshotEntry of ( snapshot.entries.values())) {
|
|
259
333
|
const entry = await this._getOrCreateModifiedFileEntry(snapshotEntry.resource, snapshotEntry.telemetryInfo);
|
|
260
334
|
entry.restoreFromSnapshot(snapshotEntry);
|
|
261
335
|
entriesArr.push(entry);
|
|
262
336
|
}
|
|
263
337
|
this._entriesObs.set(entriesArr, undefined);
|
|
264
338
|
}
|
|
265
|
-
remove(...uris) {
|
|
339
|
+
remove(reason, ...uris) {
|
|
266
340
|
this._assertNotDisposed();
|
|
267
341
|
let didRemoveUris = false;
|
|
268
342
|
for (const uri of uris) {
|
|
269
|
-
|
|
343
|
+
const entry = this._entriesObs.get().find(e => isEqual(e.modifiedURI, uri));
|
|
344
|
+
if (entry) {
|
|
345
|
+
entry.dispose();
|
|
346
|
+
const newEntries = this._entriesObs.get().filter(e => !isEqual(e.modifiedURI, uri));
|
|
347
|
+
this._entriesObs.set(newEntries, undefined);
|
|
348
|
+
didRemoveUris = true;
|
|
349
|
+
}
|
|
350
|
+
const state = this._workingSet.get(uri);
|
|
351
|
+
if (state !== undefined) {
|
|
352
|
+
didRemoveUris = this._workingSet.delete(uri) || didRemoveUris;
|
|
353
|
+
if (reason === WorkingSetEntryRemovalReason.User && (state.state === WorkingSetEntryState.Transient || state.state === WorkingSetEntryState.Suggested)) {
|
|
354
|
+
this._removedTransientEntries.add(uri);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
270
357
|
}
|
|
271
358
|
if (!didRemoveUris) {
|
|
272
359
|
return;
|
|
273
360
|
}
|
|
274
|
-
this._onDidChange.fire();
|
|
361
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.WorkingSet);
|
|
275
362
|
}
|
|
276
363
|
_assertNotDisposed() {
|
|
277
|
-
if (this._state.get() ===
|
|
278
|
-
throw (
|
|
364
|
+
if (this._state.get() === ChatEditingSessionState.Disposed) {
|
|
365
|
+
throw ( new BugIndicatingError(`Cannot access a disposed editing session`));
|
|
279
366
|
}
|
|
280
367
|
}
|
|
281
368
|
async accept(...uris) {
|
|
282
369
|
this._assertNotDisposed();
|
|
283
370
|
if (uris.length === 0) {
|
|
284
|
-
await Promise.all((
|
|
371
|
+
await Promise.all(( this._entriesObs.get().map(entry => entry.accept(undefined))));
|
|
285
372
|
}
|
|
286
373
|
for (const uri of uris) {
|
|
287
|
-
const entry = this._entriesObs.get().find(e => (
|
|
374
|
+
const entry = this._entriesObs.get().find(e => isEqual(e.modifiedURI, uri));
|
|
288
375
|
if (entry) {
|
|
289
376
|
await entry.accept(undefined);
|
|
290
377
|
}
|
|
291
378
|
}
|
|
292
|
-
this._onDidChange.fire();
|
|
379
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.Other);
|
|
293
380
|
}
|
|
294
381
|
async reject(...uris) {
|
|
295
382
|
this._assertNotDisposed();
|
|
296
383
|
if (uris.length === 0) {
|
|
297
|
-
await Promise.all((
|
|
384
|
+
await Promise.all(( this._entriesObs.get().map(entry => entry.reject(undefined))));
|
|
298
385
|
}
|
|
299
386
|
for (const uri of uris) {
|
|
300
|
-
const entry = this._entriesObs.get().find(e => (
|
|
387
|
+
const entry = this._entriesObs.get().find(e => isEqual(e.modifiedURI, uri));
|
|
301
388
|
if (entry) {
|
|
302
389
|
await entry.reject(undefined);
|
|
303
390
|
}
|
|
304
391
|
}
|
|
305
|
-
this._onDidChange.fire();
|
|
392
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.Other);
|
|
306
393
|
}
|
|
307
394
|
async show() {
|
|
308
395
|
this._assertNotDisposed();
|
|
309
|
-
if (this.
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
396
|
+
if (this._editorPane) {
|
|
397
|
+
if (this._editorPane.isVisible()) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
else if (this._editorPane.input) {
|
|
401
|
+
await this._editorGroupsService.activeGroup.openEditor(this._editorPane.input, { pinned: true, activation: EditorActivation.ACTIVATE });
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
315
404
|
}
|
|
316
405
|
const input = MultiDiffEditorInput.fromResourceMultiDiffEditorInput({
|
|
317
406
|
multiDiffSource: ChatEditingMultiDiffSourceResolver.getMultiDiffSourceUri(),
|
|
318
|
-
label: ( localize(
|
|
407
|
+
label: ( localize(4387, "Suggested Edits"))
|
|
319
408
|
}, this._instantiationService);
|
|
320
|
-
|
|
321
|
-
this.editorPane = editorPane;
|
|
409
|
+
this._editorPane = await this._editorGroupsService.activeGroup.openEditor(input, { pinned: true, activation: EditorActivation.ACTIVATE });
|
|
322
410
|
}
|
|
323
|
-
async stop() {
|
|
324
|
-
this.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
411
|
+
async stop(clearState = false) {
|
|
412
|
+
if (!this.stopPromise) {
|
|
413
|
+
this.stopPromise = this._performStop();
|
|
414
|
+
}
|
|
415
|
+
await this.stopPromise;
|
|
416
|
+
if (clearState) {
|
|
417
|
+
await this._instantiationService.createInstance(ChatEditingSessionStorage, this.chatSessionId).clearState();
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async _performStop() {
|
|
421
|
+
const schemes = [ChatEditingModifiedFileEntry.scheme, ChatEditingTextModelContentProvider.scheme];
|
|
422
|
+
await Promise.allSettled(this._editorGroupsService.groups.flatMap(async (g) => {
|
|
423
|
+
return ( g.editors.map(async (e) => {
|
|
424
|
+
if ((e instanceof MultiDiffEditorInput && e.initialResources?.some(r => r.originalUri && schemes.indexOf(r.originalUri.scheme) !== -1))
|
|
425
|
+
|| (e instanceof DiffEditorInput && e.original.resource && schemes.indexOf(e.original.resource.scheme) !== -1)) {
|
|
328
426
|
await g.closeEditor(e);
|
|
329
427
|
}
|
|
330
|
-
}))
|
|
331
|
-
}))
|
|
332
|
-
if (this._state.get() !==
|
|
428
|
+
}));
|
|
429
|
+
}));
|
|
430
|
+
if (this._state.get() !== ChatEditingSessionState.Disposed) {
|
|
333
431
|
this.dispose();
|
|
334
432
|
}
|
|
335
433
|
}
|
|
@@ -339,84 +437,93 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
339
437
|
entry.dispose();
|
|
340
438
|
}
|
|
341
439
|
super.dispose();
|
|
342
|
-
this._state.set(
|
|
440
|
+
this._state.set(ChatEditingSessionState.Disposed, undefined);
|
|
343
441
|
this._onDidDispose.fire();
|
|
344
442
|
}
|
|
345
443
|
getVirtualModel(documentId) {
|
|
346
444
|
this._assertNotDisposed();
|
|
347
445
|
const entry = this._entriesObs.get().find(e => e.entryId === documentId);
|
|
348
|
-
return entry?.
|
|
446
|
+
return entry?.originalModel ?? null;
|
|
349
447
|
}
|
|
350
448
|
acceptStreamingEditsStart() {
|
|
351
|
-
if (this._state.get() ===
|
|
449
|
+
if (this._state.get() === ChatEditingSessionState.Disposed) {
|
|
352
450
|
return;
|
|
353
451
|
}
|
|
354
452
|
this._sequencer.queue(() => this._acceptStreamingEditsStart());
|
|
355
453
|
}
|
|
356
|
-
acceptTextEdits(resource, textEdits, responseModel) {
|
|
357
|
-
if (this._state.get() ===
|
|
454
|
+
acceptTextEdits(resource, textEdits, isLastEdits, responseModel) {
|
|
455
|
+
if (this._state.get() === ChatEditingSessionState.Disposed) {
|
|
358
456
|
return;
|
|
359
457
|
}
|
|
360
|
-
this._sequencer.queue(() => this._acceptTextEdits(resource, textEdits, responseModel));
|
|
458
|
+
this._sequencer.queue(() => this._acceptTextEdits(resource, textEdits, isLastEdits, responseModel));
|
|
361
459
|
}
|
|
362
460
|
resolve() {
|
|
363
|
-
if (this._state.get() ===
|
|
461
|
+
if (this._state.get() === ChatEditingSessionState.Disposed) {
|
|
364
462
|
return;
|
|
365
463
|
}
|
|
366
464
|
this._sequencer.queue(() => this._resolve());
|
|
367
465
|
}
|
|
368
|
-
addFileToWorkingSet(resource) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
this._workingSet.set(file, 4 );
|
|
374
|
-
}
|
|
466
|
+
addFileToWorkingSet(resource, description, proposedState) {
|
|
467
|
+
const state = this._workingSet.get(resource);
|
|
468
|
+
if (proposedState === WorkingSetEntryState.Suggested) {
|
|
469
|
+
if (state !== undefined || ( this._removedTransientEntries.has(resource))) {
|
|
470
|
+
return;
|
|
375
471
|
}
|
|
376
|
-
this.
|
|
472
|
+
this._workingSet.set(resource, { description, state: WorkingSetEntryState.Suggested });
|
|
473
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.WorkingSet);
|
|
474
|
+
}
|
|
475
|
+
else if (state === undefined || state.state === WorkingSetEntryState.Transient || state.state === WorkingSetEntryState.Suggested) {
|
|
476
|
+
this._workingSet.set(resource, { description, state: WorkingSetEntryState.Attached });
|
|
477
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.WorkingSet);
|
|
377
478
|
}
|
|
378
479
|
}
|
|
379
480
|
async undoInteraction() {
|
|
380
481
|
const linearHistory = this._linearHistory.get();
|
|
381
|
-
const
|
|
382
|
-
if (
|
|
482
|
+
const newIndex = this._linearHistoryIndex.get() - 1;
|
|
483
|
+
if (newIndex < 0) {
|
|
383
484
|
return;
|
|
384
485
|
}
|
|
385
|
-
const previousSnapshot = linearHistory[
|
|
486
|
+
const previousSnapshot = linearHistory[newIndex];
|
|
386
487
|
await this.restoreSnapshot(previousSnapshot.requestId);
|
|
387
|
-
this._linearHistoryIndex.set(
|
|
488
|
+
this._linearHistoryIndex.set(newIndex, undefined);
|
|
489
|
+
this._updateRequestHiddenState();
|
|
388
490
|
}
|
|
389
491
|
async redoInteraction() {
|
|
390
492
|
const linearHistory = this._linearHistory.get();
|
|
391
|
-
const
|
|
392
|
-
if (
|
|
493
|
+
const newIndex = this._linearHistoryIndex.get() + 1;
|
|
494
|
+
if (newIndex > linearHistory.length) {
|
|
393
495
|
return;
|
|
394
496
|
}
|
|
395
|
-
const nextSnapshot =
|
|
497
|
+
const nextSnapshot = newIndex < linearHistory.length ? linearHistory[newIndex] : this._pendingSnapshot;
|
|
396
498
|
if (!nextSnapshot) {
|
|
397
499
|
return;
|
|
398
500
|
}
|
|
399
501
|
await this.restoreSnapshot(nextSnapshot.requestId);
|
|
400
|
-
this._linearHistoryIndex.set(
|
|
502
|
+
this._linearHistoryIndex.set(newIndex, undefined);
|
|
503
|
+
this._updateRequestHiddenState();
|
|
504
|
+
}
|
|
505
|
+
_updateRequestHiddenState() {
|
|
506
|
+
const hiddenRequestIds = ( this._linearHistory.get().slice(this._linearHistoryIndex.get()).map(s => s.requestId)).filter((r) => !!r);
|
|
507
|
+
this._chatService.getSession(this.chatSessionId)?.disableRequests(hiddenRequestIds);
|
|
401
508
|
}
|
|
402
509
|
async _acceptStreamingEditsStart() {
|
|
403
510
|
transaction((tx) => {
|
|
404
|
-
this._state.set(
|
|
511
|
+
this._state.set(ChatEditingSessionState.StreamingEdits, tx);
|
|
405
512
|
for (const entry of this._entriesObs.get()) {
|
|
406
513
|
entry.acceptStreamingEditsStart(tx);
|
|
407
514
|
}
|
|
408
515
|
});
|
|
409
516
|
}
|
|
410
|
-
async _acceptTextEdits(resource, textEdits, responseModel) {
|
|
411
|
-
if ((
|
|
517
|
+
async _acceptTextEdits(resource, textEdits, isLastEdits, responseModel) {
|
|
518
|
+
if (( this._filesToSkipCreating.has(resource))) {
|
|
412
519
|
return;
|
|
413
520
|
}
|
|
414
|
-
if (!this._entriesObs.get().find(e => (
|
|
521
|
+
if (!this._entriesObs.get().find(e => isEqual(e.modifiedURI, resource)) && this._entriesObs.get().length >= (await this.editingSessionFileLimitPromise)) {
|
|
415
522
|
return;
|
|
416
523
|
}
|
|
417
524
|
if (resource.scheme !== Schemas.untitled && !this._workspaceContextService.getWorkspaceFolder(resource) && !(await this._fileService.exists(resource))) {
|
|
418
525
|
const saveLocation = await this._dialogService.showSaveDialog({ title: ( localize(
|
|
419
|
-
|
|
526
|
+
4388,
|
|
420
527
|
'{0} wants to create a file. Choose where it should be saved.',
|
|
421
528
|
this._chatAgentService.getDefaultAgent(ChatAgentLocation.EditingSession)?.fullName ?? 'Chat'
|
|
422
529
|
)) });
|
|
@@ -434,44 +541,50 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
434
541
|
get result() { return responseModel.result; }
|
|
435
542
|
};
|
|
436
543
|
const entry = await this._getOrCreateModifiedFileEntry(resource, telemetryInfo);
|
|
437
|
-
entry.acceptAgentEdits(textEdits);
|
|
544
|
+
entry.acceptAgentEdits(textEdits, isLastEdits);
|
|
438
545
|
}
|
|
439
546
|
async _resolve() {
|
|
440
547
|
transaction((tx) => {
|
|
441
548
|
for (const entry of this._entriesObs.get()) {
|
|
442
549
|
entry.acceptStreamingEditsEnd(tx);
|
|
443
550
|
}
|
|
444
|
-
this._state.set(
|
|
551
|
+
this._state.set(ChatEditingSessionState.Idle, tx);
|
|
445
552
|
});
|
|
446
|
-
this._onDidChange.fire();
|
|
553
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.Other);
|
|
447
554
|
}
|
|
448
555
|
async _getOrCreateModifiedFileEntry(resource, responseModel) {
|
|
449
|
-
const existingEntry = this._entriesObs.get().find(e => (
|
|
556
|
+
const existingEntry = this._entriesObs.get().find(e => isEqual(e.modifiedURI, resource));
|
|
450
557
|
if (existingEntry) {
|
|
451
558
|
if (responseModel.requestId !== existingEntry.telemetryInfo.requestId) {
|
|
452
559
|
existingEntry.updateTelemetryInfo(responseModel);
|
|
453
560
|
}
|
|
454
561
|
return existingEntry;
|
|
455
562
|
}
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
563
|
+
const initialContent = this._initialFileContents.get(resource);
|
|
564
|
+
const entry = await this._createModifiedFileEntry(resource, responseModel, false, initialContent);
|
|
565
|
+
if (!initialContent) {
|
|
566
|
+
this._initialFileContents.set(resource, entry.initialContent);
|
|
459
567
|
}
|
|
460
568
|
this._register(entry.onDidDelete(() => {
|
|
461
|
-
const newEntries = this._entriesObs.get().filter(e => (
|
|
569
|
+
const newEntries = this._entriesObs.get().filter(e => !isEqual(e.modifiedURI, entry.modifiedURI));
|
|
462
570
|
this._entriesObs.set(newEntries, undefined);
|
|
463
571
|
this._workingSet.delete(entry.modifiedURI);
|
|
464
|
-
this.
|
|
572
|
+
this._editorService.closeEditors(this._editorService.findEditors(entry.modifiedURI));
|
|
573
|
+
entry.dispose();
|
|
574
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.WorkingSet);
|
|
465
575
|
}));
|
|
466
576
|
const entriesArr = [...this._entriesObs.get(), entry];
|
|
467
577
|
this._entriesObs.set(entriesArr, undefined);
|
|
468
|
-
this._onDidChange.fire();
|
|
578
|
+
this._onDidChange.fire(ChatEditingSessionChangeType.WorkingSet);
|
|
469
579
|
return entry;
|
|
470
580
|
}
|
|
471
|
-
async _createModifiedFileEntry(resource, responseModel, mustExist = false) {
|
|
581
|
+
async _createModifiedFileEntry(resource, responseModel, mustExist = false, initialContent) {
|
|
472
582
|
try {
|
|
473
583
|
const ref = await this._textModelService.createModelReference(resource);
|
|
474
|
-
|
|
584
|
+
if (this._notebookService.hasSupportedNotebooks(resource)) {
|
|
585
|
+
return this._instantiationService.createInstance(ChatEditingModifiedNotebookEntry, ref, { collapse: (transaction) => this._collapse(resource, transaction) }, responseModel, mustExist ? ChatEditKind.Created : ChatEditKind.Modified, initialContent);
|
|
586
|
+
}
|
|
587
|
+
return this._instantiationService.createInstance(ChatEditingModifiedFileEntry, ref, { collapse: (transaction) => this._collapse(resource, transaction) }, responseModel, mustExist ? ChatEditKind.Created : ChatEditKind.Modified, initialContent);
|
|
475
588
|
}
|
|
476
589
|
catch (err) {
|
|
477
590
|
if (mustExist) {
|
|
@@ -479,29 +592,209 @@ let ChatEditingSession = class ChatEditingSession extends Disposable {
|
|
|
479
592
|
}
|
|
480
593
|
await this._bulkEditService.apply({ edits: [{ newResource: resource }] });
|
|
481
594
|
this._editorService.openEditor({ resource, options: { inactive: true, preserveFocus: true, pinned: true } });
|
|
482
|
-
return this._createModifiedFileEntry(resource, responseModel, true);
|
|
595
|
+
return this._createModifiedFileEntry(resource, responseModel, true, initialContent);
|
|
483
596
|
}
|
|
484
597
|
}
|
|
485
598
|
_collapse(resource, transaction) {
|
|
486
|
-
const multiDiffItem = this.
|
|
599
|
+
const multiDiffItem = this._editorPane?.findDocumentDiffItem(resource);
|
|
487
600
|
if (multiDiffItem) {
|
|
488
|
-
this.
|
|
601
|
+
this._editorPane?.viewModel?.items.get().find((documentDiffItem) => isEqual(documentDiffItem.originalUri, multiDiffItem.originalUri) &&
|
|
602
|
+
isEqual(documentDiffItem.modifiedUri, multiDiffItem.modifiedUri))
|
|
603
|
+
?.collapsed.set(true, transaction);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
ChatEditingSession = ( __decorate([
|
|
608
|
+
( __param(2, IInstantiationService)),
|
|
609
|
+
( __param(3, IModelService)),
|
|
610
|
+
( __param(4, ILanguageService)),
|
|
611
|
+
( __param(5, ITextModelService)),
|
|
612
|
+
( __param(6, IBulkEditService)),
|
|
613
|
+
( __param(7, IEditorGroupsService)),
|
|
614
|
+
( __param(8, IEditorService)),
|
|
615
|
+
( __param(9, IWorkspaceContextService)),
|
|
616
|
+
( __param(10, IFileService)),
|
|
617
|
+
( __param(11, IFileDialogService)),
|
|
618
|
+
( __param(12, IChatAgentService)),
|
|
619
|
+
( __param(13, IChatService)),
|
|
620
|
+
( __param(14, INotebookService))
|
|
621
|
+
], ChatEditingSession));
|
|
622
|
+
let ChatEditingSessionStorage = class ChatEditingSessionStorage {
|
|
623
|
+
constructor(chatSessionId, _fileService, _environmentService, _logService, _workspaceContextService) {
|
|
624
|
+
this.chatSessionId = chatSessionId;
|
|
625
|
+
this._fileService = _fileService;
|
|
626
|
+
this._environmentService = _environmentService;
|
|
627
|
+
this._logService = _logService;
|
|
628
|
+
this._workspaceContextService = _workspaceContextService;
|
|
629
|
+
}
|
|
630
|
+
_getStorageLocation() {
|
|
631
|
+
const workspaceId = this._workspaceContextService.getWorkspace().id;
|
|
632
|
+
return joinPath(this._environmentService.workspaceStorageHome, workspaceId, 'chatEditingSessions', this.chatSessionId);
|
|
633
|
+
}
|
|
634
|
+
async restoreState() {
|
|
635
|
+
const storageLocation = this._getStorageLocation();
|
|
636
|
+
const getFileContent = (hash) => {
|
|
637
|
+
return this._fileService.readFile(joinPath(storageLocation, STORAGE_CONTENTS_FOLDER, hash)).then(content => ( content.value.toString()));
|
|
638
|
+
};
|
|
639
|
+
const deserializeResourceMap = (resourceMap, deserialize, result) => {
|
|
640
|
+
resourceMap.forEach(([resourceURI, value]) => {
|
|
641
|
+
result.set(( URI.parse(resourceURI)), deserialize(value));
|
|
642
|
+
});
|
|
643
|
+
return result;
|
|
644
|
+
};
|
|
645
|
+
const deserializeChatEditingSessionSnapshot = async (snapshot) => {
|
|
646
|
+
const entriesMap = ( new ResourceMap());
|
|
647
|
+
for (const entryDTO of snapshot.entries) {
|
|
648
|
+
const entry = await deserializeSnapshotEntry(entryDTO);
|
|
649
|
+
entriesMap.set(entry.resource, entry);
|
|
650
|
+
}
|
|
651
|
+
return ({
|
|
652
|
+
requestId: snapshot.requestId,
|
|
653
|
+
workingSet: deserializeResourceMap(snapshot.workingSet, (value) => value, ( new ResourceMap())),
|
|
654
|
+
entries: entriesMap
|
|
655
|
+
});
|
|
656
|
+
};
|
|
657
|
+
const deserializeSnapshotEntry = async (entry) => {
|
|
658
|
+
return {
|
|
659
|
+
resource: ( URI.parse(entry.resource)),
|
|
660
|
+
languageId: entry.languageId,
|
|
661
|
+
original: await getFileContent(entry.originalHash),
|
|
662
|
+
current: await getFileContent(entry.currentHash),
|
|
663
|
+
originalToCurrentEdit: OffsetEdit.fromJson(entry.originalToCurrentEdit),
|
|
664
|
+
state: entry.state,
|
|
665
|
+
snapshotUri: ( URI.parse(entry.snapshotUri)),
|
|
666
|
+
telemetryInfo: { requestId: entry.telemetryInfo.requestId, agentId: entry.telemetryInfo.agentId, command: entry.telemetryInfo.command, sessionId: this.chatSessionId, result: undefined }
|
|
667
|
+
};
|
|
668
|
+
};
|
|
669
|
+
try {
|
|
670
|
+
const stateFilePath = joinPath(storageLocation, STORAGE_STATE_FILE);
|
|
671
|
+
if (!(await this._fileService.exists(stateFilePath))) {
|
|
672
|
+
this._logService.debug(`chatEditingSession: No editing session state found at ${( stateFilePath.toString())}`);
|
|
673
|
+
return undefined;
|
|
674
|
+
}
|
|
675
|
+
this._logService.debug(`chatEditingSession: Restoring editing session at ${( stateFilePath.toString())}`);
|
|
676
|
+
const stateFileContent = await this._fileService.readFile(stateFilePath);
|
|
677
|
+
const data = JSON.parse(( stateFileContent.value.toString()));
|
|
678
|
+
if (data.version !== STORAGE_VERSION) {
|
|
679
|
+
return undefined;
|
|
680
|
+
}
|
|
681
|
+
const linearHistory = await Promise.all(( data.linearHistory.map(deserializeChatEditingSessionSnapshot)));
|
|
682
|
+
const filesToSkipCreating = ( data.filesToSkipCreating.map((uriStr) => ( URI.parse(uriStr))));
|
|
683
|
+
const initialFileContents = ( new ResourceMap());
|
|
684
|
+
for (const fileContentDTO of data.initialFileContents) {
|
|
685
|
+
initialFileContents.set(( URI.parse(fileContentDTO[0])), await getFileContent(fileContentDTO[1]));
|
|
686
|
+
}
|
|
687
|
+
const pendingSnapshot = data.pendingSnapshot ? await deserializeChatEditingSessionSnapshot(data.pendingSnapshot) : undefined;
|
|
688
|
+
const recentSnapshot = await deserializeChatEditingSessionSnapshot(data.recentSnapshot);
|
|
689
|
+
return {
|
|
690
|
+
filesToSkipCreating,
|
|
691
|
+
initialFileContents,
|
|
692
|
+
pendingSnapshot,
|
|
693
|
+
recentSnapshot,
|
|
694
|
+
linearHistoryIndex: data.linearHistoryIndex,
|
|
695
|
+
linearHistory
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
catch (e) {
|
|
699
|
+
this._logService.error(`Error restoring chat editing session from ${( storageLocation.toString())}`, e);
|
|
700
|
+
}
|
|
701
|
+
return undefined;
|
|
702
|
+
}
|
|
703
|
+
async storeState(state) {
|
|
704
|
+
const storageFolder = this._getStorageLocation();
|
|
705
|
+
const contentsFolder = URI.joinPath(storageFolder, STORAGE_CONTENTS_FOLDER);
|
|
706
|
+
const existingContents = ( new Set());
|
|
707
|
+
try {
|
|
708
|
+
const stat = await this._fileService.resolve(contentsFolder);
|
|
709
|
+
stat.children?.forEach(child => {
|
|
710
|
+
if (child.isDirectory) {
|
|
711
|
+
existingContents.add(child.name);
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
catch (e) {
|
|
716
|
+
try {
|
|
717
|
+
await this._fileService.createFolder(contentsFolder);
|
|
718
|
+
}
|
|
719
|
+
catch (e) {
|
|
720
|
+
this._logService.error(`Error creating chat editing session content folder ${( contentsFolder.toString())}`, e);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
const fileContents = ( new Map());
|
|
725
|
+
const addFileContent = (content) => {
|
|
726
|
+
const shaComputer = ( new StringSHA1());
|
|
727
|
+
shaComputer.update(content);
|
|
728
|
+
const sha = shaComputer.digest().substring(0, 7);
|
|
729
|
+
if (!( existingContents.has(sha))) {
|
|
730
|
+
fileContents.set(sha, content);
|
|
731
|
+
}
|
|
732
|
+
return sha;
|
|
733
|
+
};
|
|
734
|
+
const serializeResourceMap = (resourceMap, serialize) => {
|
|
735
|
+
return ( Array.from(resourceMap.entries()).map(([resourceURI, value]) => [( resourceURI.toString()), serialize(value)]));
|
|
736
|
+
};
|
|
737
|
+
const serializeChatEditingSessionSnapshot = (snapshot) => {
|
|
738
|
+
return ({
|
|
739
|
+
requestId: snapshot.requestId,
|
|
740
|
+
workingSet: serializeResourceMap(snapshot.workingSet, value => value),
|
|
741
|
+
entries: ( Array.from(( snapshot.entries.values())).map(serializeSnapshotEntry))
|
|
742
|
+
});
|
|
743
|
+
};
|
|
744
|
+
const serializeSnapshotEntry = (entry) => {
|
|
745
|
+
return {
|
|
746
|
+
resource: ( entry.resource.toString()),
|
|
747
|
+
languageId: entry.languageId,
|
|
748
|
+
originalHash: addFileContent(entry.original),
|
|
749
|
+
currentHash: addFileContent(entry.current),
|
|
750
|
+
originalToCurrentEdit: ( entry.originalToCurrentEdit.edits.map(
|
|
751
|
+
edit => ({ pos: edit.replaceRange.start, len: edit.replaceRange.length, txt: edit.newText })
|
|
752
|
+
)),
|
|
753
|
+
state: entry.state,
|
|
754
|
+
snapshotUri: ( entry.snapshotUri.toString()),
|
|
755
|
+
telemetryInfo: { requestId: entry.telemetryInfo.requestId, agentId: entry.telemetryInfo.agentId, command: entry.telemetryInfo.command }
|
|
756
|
+
};
|
|
757
|
+
};
|
|
758
|
+
try {
|
|
759
|
+
const data = {
|
|
760
|
+
version: STORAGE_VERSION,
|
|
761
|
+
sessionId: this.chatSessionId,
|
|
762
|
+
linearHistory: ( state.linearHistory.map(serializeChatEditingSessionSnapshot)),
|
|
763
|
+
linearHistoryIndex: state.linearHistoryIndex,
|
|
764
|
+
initialFileContents: serializeResourceMap(state.initialFileContents, value => addFileContent(value)),
|
|
765
|
+
pendingSnapshot: state.pendingSnapshot ? serializeChatEditingSessionSnapshot(state.pendingSnapshot) : undefined,
|
|
766
|
+
recentSnapshot: serializeChatEditingSessionSnapshot(state.recentSnapshot),
|
|
767
|
+
filesToSkipCreating: ( state.filesToSkipCreating.map(uri => ( uri.toString()))),
|
|
768
|
+
};
|
|
769
|
+
this._logService.debug(`chatEditingSession: Storing editing session at ${( storageFolder.toString())}: ${fileContents.size} files`);
|
|
770
|
+
for (const [hash, content] of fileContents) {
|
|
771
|
+
await this._fileService.writeFile(joinPath(contentsFolder, hash), VSBuffer.fromString(content));
|
|
772
|
+
}
|
|
773
|
+
await this._fileService.writeFile(joinPath(storageFolder, STORAGE_STATE_FILE), VSBuffer.fromString(JSON.stringify(data, undefined, 2)));
|
|
774
|
+
}
|
|
775
|
+
catch (e) {
|
|
776
|
+
this._logService.debug(`Error storing chat editing session to ${( storageFolder.toString())}`, e);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
async clearState() {
|
|
780
|
+
const storageFolder = this._getStorageLocation();
|
|
781
|
+
if (await this._fileService.exists(storageFolder)) {
|
|
782
|
+
this._logService.debug(`chatEditingSession: Clearing editing session at ${( storageFolder.toString())}`);
|
|
783
|
+
try {
|
|
784
|
+
await this._fileService.del(storageFolder, { recursive: true });
|
|
785
|
+
}
|
|
786
|
+
catch (e) {
|
|
787
|
+
this._logService.debug(`Error clearing chat editing session from ${( storageFolder.toString())}`, e);
|
|
788
|
+
}
|
|
489
789
|
}
|
|
490
790
|
}
|
|
491
791
|
};
|
|
492
|
-
|
|
493
|
-
(
|
|
494
|
-
(
|
|
495
|
-
(
|
|
496
|
-
(
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
( (__param(9, IEditorService))),
|
|
500
|
-
( (__param(10, IChatWidgetService))),
|
|
501
|
-
( (__param(11, IWorkspaceContextService))),
|
|
502
|
-
( (__param(12, IFileService))),
|
|
503
|
-
( (__param(13, IFileDialogService))),
|
|
504
|
-
( (__param(14, IChatAgentService)))
|
|
505
|
-
], ChatEditingSession)));
|
|
792
|
+
ChatEditingSessionStorage = ( __decorate([
|
|
793
|
+
( __param(1, IFileService)),
|
|
794
|
+
( __param(2, IEnvironmentService)),
|
|
795
|
+
( __param(3, ILogService)),
|
|
796
|
+
( __param(4, IWorkspaceContextService))
|
|
797
|
+
], ChatEditingSessionStorage));
|
|
798
|
+
const STORAGE_VERSION = 1;
|
|
506
799
|
|
|
507
800
|
export { ChatEditingSession };
|