@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.
Files changed (110) hide show
  1. package/index.d.ts +2 -1
  2. package/index.js +64 -1
  3. package/package.json +32 -13
  4. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.d.ts +21 -0
  5. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.js +73 -60
  6. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.d.ts +3 -0
  7. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.js +73 -81
  8. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.d.ts +9 -0
  9. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.js +73 -112
  10. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.d.ts +12 -0
  11. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.js +253 -101
  12. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.d.ts +1 -0
  13. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.js +8 -8
  14. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatDeveloperActions.d.ts +1 -0
  15. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatDeveloperActions.js +2 -1
  16. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.d.ts +1 -0
  17. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.js +16 -14
  18. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.d.ts +23 -0
  19. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.js +30 -11
  20. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatImportExport.d.ts +1 -0
  21. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatImportExport.js +12 -12
  22. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatMoveActions.d.ts +1 -0
  23. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatMoveActions.js +22 -20
  24. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.d.ts +2 -0
  25. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.js +23 -20
  26. package/vscode/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.d.ts +52 -0
  27. package/vscode/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.js +50 -47
  28. package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.d.ts +1 -0
  29. package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js +124 -95
  30. package/vscode/src/vs/workbench/contrib/chat/browser/chatAccessibilityService.d.ts +17 -0
  31. package/vscode/src/vs/workbench/contrib/chat/browser/chatAccessibilityService.js +6 -3
  32. package/vscode/src/vs/workbench/contrib/chat/browser/chatEdinputInputContentProvider.d.ts +12 -0
  33. package/vscode/src/vs/workbench/contrib/chat/browser/chatEdinputInputContentProvider.js +30 -0
  34. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingService.d.ts +69 -0
  35. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingService.js +203 -182
  36. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.d.ts +103 -0
  37. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.js +458 -165
  38. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditor.d.ts +42 -0
  39. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditor.js +14 -10
  40. package/vscode/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.d.ts +26 -0
  41. package/vscode/src/vs/workbench/contrib/chat/browser/{chatParticipantContributions.js → chatParticipant.contribution.js} +101 -92
  42. package/vscode/src/vs/workbench/contrib/chat/browser/chatPasteProviders.d.ts +42 -0
  43. package/vscode/src/vs/workbench/contrib/chat/browser/chatPasteProviders.js +164 -25
  44. package/vscode/src/vs/workbench/contrib/chat/browser/chatQuick.d.ts +26 -0
  45. package/vscode/src/vs/workbench/contrib/chat/browser/chatQuick.js +6 -5
  46. package/vscode/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.d.ts +30 -0
  47. package/vscode/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.js +10 -7
  48. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup.d.ts +17 -0
  49. package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup.js +941 -0
  50. package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.d.ts +26 -0
  51. package/vscode/src/vs/workbench/contrib/chat/browser/chatVariables.js +9 -6
  52. package/vscode/src/vs/workbench/contrib/chat/browser/chatViewPane.d.ts +54 -0
  53. package/vscode/src/vs/workbench/contrib/chat/browser/chatViewPane.js +32 -15
  54. package/vscode/src/vs/workbench/contrib/chat/browser/codeBlockContextProviderService.d.ts +9 -0
  55. package/vscode/src/vs/workbench/contrib/chat/browser/codeBlockContextProviderService.js +1 -0
  56. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.d.ts +1 -0
  57. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.js +8 -6
  58. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorHover.d.ts +26 -0
  59. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorHover.js +16 -19
  60. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputRelatedFilesContrib.d.ts +15 -0
  61. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputRelatedFilesContrib.js +108 -0
  62. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/editorHoverWrapper.d.ts +7 -0
  63. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/editorHoverWrapper.js +3 -8
  64. package/vscode/src/vs/workbench/contrib/chat/browser/contrib/media/editorHoverWrapper.css.js +1 -1
  65. package/vscode/src/vs/workbench/contrib/chat/browser/languageModelToolsService.d.ts +31 -0
  66. package/vscode/src/vs/workbench/contrib/chat/browser/languageModelToolsService.js +70 -49
  67. package/vscode/src/vs/workbench/contrib/chat/browser/media/chatViewSetup.css.js +6 -0
  68. package/vscode/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcomeHandler.d.ts +7 -0
  69. package/vscode/src/vs/workbench/contrib/chat/browser/viewsWelcome/{chatViewsWelcomeContributions.js → chatViewsWelcomeHandler.js} +13 -13
  70. package/vscode/src/vs/workbench/contrib/chat/common/chatCodeMapperService.d.ts +44 -0
  71. package/vscode/src/vs/workbench/contrib/chat/common/chatCodeMapperService.js +3 -1
  72. package/vscode/src/vs/workbench/contrib/chat/common/chatProgressTypes/chatToolInvocation.d.ts +22 -0
  73. package/vscode/src/vs/workbench/contrib/chat/common/chatProgressTypes/chatToolInvocation.js +1 -0
  74. package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.d.ts +80 -0
  75. package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.js +152 -104
  76. package/vscode/src/vs/workbench/contrib/chat/common/chatServiceTelemetry.d.ts +8 -0
  77. package/vscode/src/vs/workbench/contrib/chat/common/chatServiceTelemetry.js +2 -1
  78. package/vscode/src/vs/workbench/contrib/chat/common/chatSlashCommands.d.ts +41 -0
  79. package/vscode/src/vs/workbench/contrib/chat/common/chatSlashCommands.js +2 -1
  80. package/vscode/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.d.ts +31 -0
  81. package/vscode/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.js +6 -4
  82. package/vscode/src/vs/workbench/contrib/chat/common/ignoredFiles.d.ts +13 -0
  83. package/vscode/src/vs/workbench/contrib/chat/common/ignoredFiles.js +1 -0
  84. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.d.ts +24 -0
  85. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.js +23 -21
  86. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsParametersSchema.d.ts +1 -0
  87. package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsParametersSchema.js +1 -0
  88. package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.d.ts +39 -0
  89. package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.js +20 -19
  90. package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.service.d.ts +7 -0
  91. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.d.ts +1 -0
  92. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +30 -33
  93. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.d.ts +10 -0
  94. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.js +6 -4
  95. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.d.ts +10 -0
  96. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.js +9 -7
  97. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatCurrentLine.d.ts +44 -0
  98. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatCurrentLine.js +247 -83
  99. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatNotebook.d.ts +8 -0
  100. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatNotebook.js +5 -4
  101. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSavingServiceImpl.d.ts +29 -0
  102. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSavingServiceImpl.js +35 -35
  103. package/chat.js +0 -59
  104. package/vscode/src/vs/editor/common/diff/documentDiffProvider.js +0 -8
  105. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedFileEntry.js +0 -326
  106. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelContentProviders.js +0 -76
  107. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditorActions.js +0 -110
  108. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditorController.js +0 -287
  109. package/vscode/src/vs/workbench/contrib/chat/common/languageModelStats.js +0 -130
  110. package/vscode/src/vs/workbench/contrib/chat/common/languageModels.js +0 -172
@@ -1,15 +1,17 @@
1
- import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
- import { Sequencer } from 'vscode/vscode/vs/base/common/async';
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 { IChatWidgetService } from 'vscode/vscode/vs/workbench/contrib/chat/browser/chat.service';
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 './chatEditingModifiedFileEntry.js';
33
- import { ChatEditingTextModelContentProvider } from './chatEditingTextModelContentProviders.js';
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 = ( (new ResourceMap(this._workingSet)));
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.editorPane && this.editorPane.isVisible());
101
+ return Boolean(this._editorPane && this._editorPane.isVisible());
63
102
  }
64
- constructor(chatSessionId, editorPane, editingSessionFileLimitPromise, _instantiationService, _modelService, _languageService, _textModelService, _bulkEditService, _editorGroupsService, _editorService, _chatWidgetService, _workspaceContextService, _fileService, _dialogService, _chatAgentService) {
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._state = observableValue(this, 0 );
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 = ( (new ResourceMap()));
85
- this._snapshots = ( (new Map()));
86
- this._filesToSkipCreating = ( (new ResourceSet()));
123
+ this._initialFileContents = ( new ResourceMap());
124
+ this._filesToSkipCreating = ( new ResourceSet());
87
125
  this._entriesObs = observableValue(this, []);
88
- this._sequencer = ( (new Sequencer()));
89
- this._workingSet = ( (new ResourceMap()));
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) !== 2 ) {
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) !== 2 ) {
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 ( (linearHistory.slice(linearHistoryIndex).map(s => s.requestId))).filter((r) => !!r);
147
+ return ( linearHistory.slice(linearHistoryIndex).map(s => s.requestId)).filter((r) => !!r);
109
148
  });
110
- this._onDidChange = ( (new Emitter()));
111
- this._onDidDispose = ( (new Emitter()));
112
- const widget = _chatWidgetService.getWidgetBySessionId(chatSessionId);
113
- if (!widget) {
114
- return;
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.onDidActiveEditorChange(() => {
168
+ this._register(this._editorService.onDidVisibleEditorsChange(() => {
118
169
  this._trackCurrentEditorsInWorkingSet();
119
170
  }));
120
- this._register(this._editorService.onDidCloseEditor((e) => {
121
- this._trackCurrentEditorsInWorkingSet(e);
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 widget = this._chatWidgetService.getWidgetBySessionId(this.chatSessionId);
126
- const requests = widget?.viewModel?.getItems();
127
- if (requests && requests.length > 0) {
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
- if (existingTransientEntries.size === 0 && this._workingSet.size > 0) {
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 activeEditorControl = group.activeEditorPane.getControl();
146
- if (isDiffEditor(activeEditorControl)) {
147
- activeEditorControl = activeEditorControl.getOriginalEditor().hasTextFocus() ? activeEditorControl.getOriginalEditor() : activeEditorControl.getModifiedEditor();
209
+ let uri;
210
+ if (isNotebookEditorInput(group.activeEditorPane.input)) {
211
+ uri = group.activeEditorPane.input.resource;
148
212
  }
149
- if (isCodeEditor(activeEditorControl) && activeEditorControl.hasModel()) {
150
- const uri = activeEditorControl.getModel().uri;
151
- if (closedEditor === ( (uri.toString()))) ;
152
- else if (( (existingTransientEntries.has(uri)))) {
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
- else {
156
- activeEditors.add(uri);
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, 3 );
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
- this._snapshots.set(requestId, snapshot);
176
- for (const workingSetItem of ( (this._workingSet.keys()))) {
177
- this._workingSet.set(workingSetItem, 5 );
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 = ( (new ResourceMap()));
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 = ( (new ResourceMap()));
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._snapshots.get(requestId)?.entries;
284
+ const entries = this._findSnapshot(requestId)?.entries;
209
285
  if (!entries) {
210
286
  return null;
211
287
  }
212
- const snapshotEntry = [...( (entries.values()))].find((e) => ( (e.snapshotUri.toString())) === ( (snapshotUri.toString())));
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._snapshots.get(requestId);
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._snapshots.get(requestId);
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
- else if (!this._pendingSnapshot) {
243
- this.createSnapshot(undefined);
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
- const initialContents = this._initialFileContents.get(entry.modifiedURI);
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 ( (snapshot.entries.values()))) {
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
- didRemoveUris = this._workingSet.delete(uri) || didRemoveUris;
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() === 3 ) {
278
- throw ( (new BugIndicatingError(`Cannot access a disposed editing session`)));
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(( (this._entriesObs.get().map(entry => entry.accept(undefined)))));
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 => ( (e.modifiedURI.toString())) === ( (uri.toString())));
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(( (this._entriesObs.get().map(entry => entry.reject(undefined)))));
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 => ( (e.modifiedURI.toString())) === ( (uri.toString())));
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.editorPane?.isVisible()) {
310
- return;
311
- }
312
- else if (this.editorPane?.input) {
313
- await this._editorGroupsService.activeGroup.openEditor(this.editorPane.input, { pinned: true, activation: EditorActivation.ACTIVATE });
314
- return;
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(7701, "Suggested Edits"))
407
+ label: ( localize(4387, "Suggested Edits"))
319
408
  }, this._instantiationService);
320
- const editorPane = await this._editorGroupsService.activeGroup.openEditor(input, { pinned: true, activation: EditorActivation.ACTIVATE });
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._assertNotDisposed();
325
- await Promise.allSettled(( (this._editorGroupsService.groups.map(async (g) => {
326
- return Promise.allSettled(( (g.editors.map(async (e) => {
327
- if (e instanceof MultiDiffEditorInput || e instanceof DiffEditorInput && (e.original.resource?.scheme === ChatEditingModifiedFileEntry.scheme || e.original.resource?.scheme === ChatEditingTextModelContentProvider.scheme)) {
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() !== 3 ) {
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(3 , undefined);
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?.docSnapshot ?? null;
446
+ return entry?.originalModel ?? null;
349
447
  }
350
448
  acceptStreamingEditsStart() {
351
- if (this._state.get() === 3 ) {
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() === 3 ) {
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() === 3 ) {
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
- if (!( (this._workingSet.has(resource)))) {
370
- this._workingSet.set(resource, 4 );
371
- for (const file of ( (this._workingSet.keys()))) {
372
- if (this._workingSet.get(file) === 3 ) {
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._onDidChange.fire();
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 linearHistoryIndex = this._linearHistoryIndex.get();
382
- if (linearHistoryIndex <= 0) {
482
+ const newIndex = this._linearHistoryIndex.get() - 1;
483
+ if (newIndex < 0) {
383
484
  return;
384
485
  }
385
- const previousSnapshot = linearHistory[linearHistoryIndex - 1];
486
+ const previousSnapshot = linearHistory[newIndex];
386
487
  await this.restoreSnapshot(previousSnapshot.requestId);
387
- this._linearHistoryIndex.set(linearHistoryIndex - 1, undefined);
488
+ this._linearHistoryIndex.set(newIndex, undefined);
489
+ this._updateRequestHiddenState();
388
490
  }
389
491
  async redoInteraction() {
390
492
  const linearHistory = this._linearHistory.get();
391
- const linearHistoryIndex = this._linearHistoryIndex.get();
392
- if (linearHistoryIndex >= linearHistory.length) {
493
+ const newIndex = this._linearHistoryIndex.get() + 1;
494
+ if (newIndex > linearHistory.length) {
393
495
  return;
394
496
  }
395
- const nextSnapshot = (linearHistoryIndex + 1 < linearHistory.length ? linearHistory[linearHistoryIndex + 1] : this._pendingSnapshot);
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(linearHistoryIndex + 1, undefined);
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(1 , tx);
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 (( (this._filesToSkipCreating.has(resource)))) {
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 => ( (e.resource.toString())) === ( (resource.toString()))) && this._entriesObs.get().length >= (await this.editingSessionFileLimitPromise)) {
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
- 7702,
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(2 , tx);
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 => ( (e.resource.toString())) === ( (resource.toString())));
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 entry = await this._createModifiedFileEntry(resource, responseModel);
457
- if (!( (this._initialFileContents.has(resource)))) {
458
- this._initialFileContents.set(resource, entry.modifiedModel.getValue());
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 => ( (e.modifiedURI.toString())) !== ( (entry.modifiedURI.toString())));
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._onDidChange.fire();
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
- return this._instantiationService.createInstance(ChatEditingModifiedFileEntry, resource, ref, { collapse: (transaction) => this._collapse(resource, transaction) }, responseModel, mustExist ? 0 : 1 );
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.editorPane?.findDocumentDiffItem(resource);
599
+ const multiDiffItem = this._editorPane?.findDocumentDiffItem(resource);
487
600
  if (multiDiffItem) {
488
- this.editorPane?.viewModel?.items.get().find((documentDiffItem) => String(documentDiffItem.originalUri) === String(multiDiffItem.originalUri) && String(documentDiffItem.modifiedUri) === String(multiDiffItem.modifiedUri))?.collapsed.set(true, transaction);
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
- ChatEditingSession = ( (__decorate([
493
- ( (__param(3, IInstantiationService))),
494
- ( (__param(4, IModelService))),
495
- ( (__param(5, ILanguageService))),
496
- ( (__param(6, ITextModelService))),
497
- ( (__param(7, IBulkEditService))),
498
- ( (__param(8, IEditorGroupsService))),
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 };