@opensumi/ide-ai-native 3.2.5 → 3.2.6-next-1724809247.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 (178) hide show
  1. package/lib/browser/ai-core.contribution.d.ts +1 -0
  2. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contribution.js +12 -23
  4. package/lib/browser/ai-core.contribution.js.map +1 -1
  5. package/lib/browser/ai-editor.contribution.d.ts +1 -0
  6. package/lib/browser/ai-editor.contribution.d.ts.map +1 -1
  7. package/lib/browser/ai-editor.contribution.js +8 -0
  8. package/lib/browser/ai-editor.contribution.js.map +1 -1
  9. package/lib/browser/chat/chat-agent.service.d.ts +1 -0
  10. package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-agent.service.js +1 -3
  12. package/lib/browser/chat/chat-agent.service.js.map +1 -1
  13. package/lib/browser/chat/chat.module.less +1 -0
  14. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  15. package/lib/browser/chat/chat.view.js +21 -3
  16. package/lib/browser/chat/chat.view.js.map +1 -1
  17. package/lib/browser/components/ChatEditor.d.ts.map +1 -1
  18. package/lib/browser/components/ChatEditor.js +2 -2
  19. package/lib/browser/components/ChatEditor.js.map +1 -1
  20. package/lib/browser/components/ChatMarkdown.js +1 -1
  21. package/lib/browser/components/ChatMarkdown.js.map +1 -1
  22. package/lib/browser/components/ChatThinking.d.ts.map +1 -1
  23. package/lib/browser/components/ChatThinking.js +2 -2
  24. package/lib/browser/components/ChatThinking.js.map +1 -1
  25. package/lib/browser/contextkey/ai-native.contextkey.service.d.ts +1 -0
  26. package/lib/browser/contextkey/ai-native.contextkey.service.d.ts.map +1 -1
  27. package/lib/browser/contextkey/ai-native.contextkey.service.js +1 -0
  28. package/lib/browser/contextkey/ai-native.contextkey.service.js.map +1 -1
  29. package/lib/browser/contrib/inline-completions/completeProvider.d.ts +4 -31
  30. package/lib/browser/contrib/inline-completions/completeProvider.d.ts.map +1 -1
  31. package/lib/browser/contrib/inline-completions/completeProvider.js +3 -224
  32. package/lib/browser/contrib/inline-completions/completeProvider.js.map +1 -1
  33. package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts +1 -3
  34. package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts.map +1 -1
  35. package/lib/browser/contrib/inline-completions/inline-completions.handler.js +8 -20
  36. package/lib/browser/contrib/inline-completions/inline-completions.handler.js.map +1 -1
  37. package/lib/browser/contrib/inline-completions/model/competionModel.d.ts +2 -2
  38. package/lib/browser/contrib/inline-completions/model/competionModel.d.ts.map +1 -1
  39. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.d.ts +28 -0
  40. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.d.ts.map +1 -0
  41. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js +209 -0
  42. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js.map +1 -0
  43. package/lib/browser/contrib/inline-completions/promptCache.d.ts +3 -2
  44. package/lib/browser/contrib/inline-completions/promptCache.d.ts.map +1 -1
  45. package/lib/browser/contrib/inline-completions/promptCache.js.map +1 -1
  46. package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts +5 -6
  47. package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts.map +1 -1
  48. package/lib/browser/contrib/inline-completions/service/ai-completions.service.js +33 -23
  49. package/lib/browser/contrib/inline-completions/service/ai-completions.service.js.map +1 -1
  50. package/lib/browser/contrib/intelligent-completions/diff-computer.d.ts +18 -0
  51. package/lib/browser/contrib/intelligent-completions/diff-computer.d.ts.map +1 -0
  52. package/lib/browser/contrib/intelligent-completions/diff-computer.js +144 -0
  53. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -0
  54. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts +8 -0
  55. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts.map +1 -0
  56. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +47 -0
  57. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -0
  58. package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts +15 -0
  59. package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts.map +1 -0
  60. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts +8 -0
  61. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts.map +1 -0
  62. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js +19 -0
  63. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js.map +1 -0
  64. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.d.ts +20 -0
  65. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.d.ts.map +1 -0
  66. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.js +94 -0
  67. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.js.map +1 -0
  68. package/lib/browser/contrib/intelligent-completions/intelligent-completions.js +3 -0
  69. package/lib/browser/contrib/intelligent-completions/intelligent-completions.js.map +1 -0
  70. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts +33 -0
  71. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts.map +1 -0
  72. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js +258 -0
  73. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js.map +1 -0
  74. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.d.ts +0 -1
  75. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.d.ts.map +1 -1
  76. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.js +0 -3
  77. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.js.map +1 -1
  78. package/lib/browser/index.d.ts.map +1 -1
  79. package/lib/browser/index.js +7 -0
  80. package/lib/browser/index.js.map +1 -1
  81. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  82. package/lib/browser/layout/ai-layout.js +4 -4
  83. package/lib/browser/layout/ai-layout.js.map +1 -1
  84. package/lib/browser/layout/layout.module.less +0 -9
  85. package/lib/browser/model/enhanceDecorationsCollection.d.ts +38 -4
  86. package/lib/browser/model/enhanceDecorationsCollection.d.ts.map +1 -1
  87. package/lib/browser/model/enhanceDecorationsCollection.js +44 -23
  88. package/lib/browser/model/enhanceDecorationsCollection.js.map +1 -1
  89. package/lib/browser/types.d.ts +20 -13
  90. package/lib/browser/types.d.ts.map +1 -1
  91. package/lib/browser/types.js +0 -4
  92. package/lib/browser/types.js.map +1 -1
  93. package/lib/browser/widget/inline-chat/inline-chat.handler.d.ts.map +1 -1
  94. package/lib/browser/widget/inline-chat/inline-chat.handler.js +18 -10
  95. package/lib/browser/widget/inline-chat/inline-chat.handler.js.map +1 -1
  96. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +5 -2
  97. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
  98. package/lib/browser/widget/inline-chat/inline-content-widget.js +45 -53
  99. package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
  100. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +16 -14
  101. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
  102. package/lib/browser/widget/inline-diff/inline-diff-previewer.js +98 -46
  103. package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
  104. package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts +5 -2
  105. package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts.map +1 -1
  106. package/lib/browser/widget/inline-diff/inline-diff-widget.js +11 -2
  107. package/lib/browser/widget/inline-diff/inline-diff-widget.js.map +1 -1
  108. package/lib/browser/widget/inline-diff/inline-diff.handler.d.ts +12 -13
  109. package/lib/browser/widget/inline-diff/inline-diff.handler.d.ts.map +1 -1
  110. package/lib/browser/widget/inline-diff/inline-diff.handler.js +69 -77
  111. package/lib/browser/widget/inline-diff/inline-diff.handler.js.map +1 -1
  112. package/lib/browser/widget/inline-input/inline-input-widget.d.ts +1 -0
  113. package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
  114. package/lib/browser/widget/inline-input/inline-input-widget.js +1 -0
  115. package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
  116. package/lib/browser/widget/inline-input/inline-input.handler.js +2 -2
  117. package/lib/browser/widget/inline-input/inline-input.handler.js.map +1 -1
  118. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +28 -15
  119. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  120. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +56 -31
  121. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  122. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.module.less +9 -6
  123. package/lib/browser/widget/inline-stream-diff/live-preview-stack.d.ts +21 -0
  124. package/lib/browser/widget/inline-stream-diff/live-preview-stack.d.ts.map +1 -0
  125. package/lib/browser/widget/inline-stream-diff/live-preview-stack.js +41 -0
  126. package/lib/browser/widget/inline-stream-diff/live-preview-stack.js.map +1 -0
  127. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +105 -0
  128. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -0
  129. package/lib/browser/widget/inline-stream-diff/live-preview.component.js +237 -0
  130. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -0
  131. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +27 -103
  132. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  133. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +186 -370
  134. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  135. package/lib/common/index.d.ts +1 -0
  136. package/lib/common/index.d.ts.map +1 -1
  137. package/lib/common/index.js.map +1 -1
  138. package/package.json +19 -19
  139. package/src/browser/ai-core.contribution.ts +12 -26
  140. package/src/browser/ai-editor.contribution.ts +9 -0
  141. package/src/browser/chat/chat-agent.service.ts +1 -3
  142. package/src/browser/chat/chat.module.less +1 -0
  143. package/src/browser/chat/chat.view.tsx +48 -3
  144. package/src/browser/components/ChatEditor.tsx +14 -2
  145. package/src/browser/components/ChatMarkdown.tsx +1 -1
  146. package/src/browser/components/ChatThinking.tsx +3 -1
  147. package/src/browser/contextkey/ai-native.contextkey.service.ts +3 -0
  148. package/src/browser/contrib/inline-completions/completeProvider.ts +7 -289
  149. package/src/browser/contrib/inline-completions/inline-completions.handler.ts +15 -22
  150. package/src/browser/contrib/inline-completions/model/competionModel.ts +3 -2
  151. package/src/browser/contrib/inline-completions/model/inlineCompletionRequestTask.ts +270 -0
  152. package/src/browser/contrib/inline-completions/promptCache.ts +3 -2
  153. package/src/browser/contrib/inline-completions/service/ai-completions.service.ts +37 -36
  154. package/src/browser/contrib/intelligent-completions/diff-computer.ts +185 -0
  155. package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +54 -0
  156. package/src/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.ts +17 -0
  157. package/src/browser/contrib/intelligent-completions/intelligent-completions.handler.ts +130 -0
  158. package/src/browser/contrib/intelligent-completions/intelligent-completions.ts +15 -0
  159. package/src/browser/contrib/intelligent-completions/multi-line.decoration.ts +325 -0
  160. package/src/browser/contrib/merge-conflict/merge-conflict.feature.registry.ts +0 -4
  161. package/src/browser/index.ts +8 -1
  162. package/src/browser/layout/ai-layout.tsx +7 -1
  163. package/src/browser/layout/layout.module.less +0 -9
  164. package/src/browser/model/enhanceDecorationsCollection.ts +71 -34
  165. package/src/browser/types.ts +27 -14
  166. package/src/browser/widget/inline-chat/inline-chat.handler.ts +20 -16
  167. package/src/browser/widget/inline-chat/inline-content-widget.tsx +58 -61
  168. package/src/browser/widget/inline-diff/inline-diff-previewer.ts +102 -62
  169. package/src/browser/widget/inline-diff/inline-diff-widget.tsx +36 -5
  170. package/src/browser/widget/inline-diff/inline-diff.handler.ts +82 -94
  171. package/src/browser/widget/inline-input/inline-input-widget.tsx +1 -0
  172. package/src/browser/widget/inline-input/inline-input.handler.ts +2 -2
  173. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +108 -45
  174. package/src/browser/widget/inline-stream-diff/inline-stream-diff.module.less +9 -6
  175. package/src/browser/widget/inline-stream-diff/live-preview-stack.ts +52 -0
  176. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +388 -0
  177. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +244 -544
  178. package/src/common/index.ts +2 -0
@@ -0,0 +1,325 @@
1
+ import { isUndefined } from '@opensumi/ide-core-common';
2
+ import { ICodeEditor, IModelDeltaDecoration, IPosition, Position, Range } from '@opensumi/ide-monaco';
3
+ import { empty } from '@opensumi/ide-utils/lib/strings';
4
+
5
+ import { EnhanceDecorationsCollection } from '../../model/enhanceDecorationsCollection';
6
+
7
+ import { IDiffChangeResult } from './diff-computer';
8
+
9
+ export interface IModificationsInline {
10
+ newValue: string;
11
+ oldValue: string;
12
+ lineNumber?: number;
13
+ column?: number;
14
+ isEolLine?: boolean;
15
+ }
16
+
17
+ enum EProcessStatus {
18
+ beginning = 'beginning',
19
+ end = 'end',
20
+ }
21
+
22
+ interface IProcessModificationsInline extends IModificationsInline {
23
+ status: EProcessStatus;
24
+ }
25
+
26
+ // https://github.com/microsoft/vscode/blob/main/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts#L156
27
+ export const GHOST_TEXT_DESCRIPTION = 'ghost-text-decoration';
28
+ export const GHOST_TEXT = 'ghost-text';
29
+
30
+ export class MultiLineDecorationModel {
31
+ private ghostTextDecorations: EnhanceDecorationsCollection;
32
+
33
+ constructor(private readonly editor: ICodeEditor) {
34
+ this.ghostTextDecorations = new EnhanceDecorationsCollection(this.editor);
35
+ }
36
+
37
+ /**
38
+ * 切割 diff 计算结果的换行符
39
+ */
40
+ private splitDiffChanges(lines: IDiffChangeResult[], eol: string): IDiffChangeResult[] {
41
+ const modifiedLines = lines.flatMap((line) => {
42
+ const segments = line.value.split(eol);
43
+ const wrap = (value: string): IDiffChangeResult => ({ value, added: line.added, removed: line.removed });
44
+
45
+ return segments
46
+ .flatMap((segment, index) => {
47
+ if (index < segments.length - 1) {
48
+ return [wrap(segment), wrap(eol)];
49
+ }
50
+
51
+ return wrap(segment);
52
+ })
53
+ .filter((line) => line.value !== empty);
54
+ });
55
+
56
+ // 对处理后的结果进行调整,确保相邻的添加和删除操作合并
57
+ for (let i = 0; i < modifiedLines.length - 1; i++) {
58
+ const currentLine = modifiedLines[i];
59
+ const nextLine = modifiedLines[i + 1];
60
+ // 如果当前行是删除操作,下一行是添加操作,并且下一行的值以当前行的值开头,则合并这两个操作
61
+ if (currentLine.removed && nextLine.added && nextLine.value.startsWith(currentLine.value)) {
62
+ currentLine.added = true;
63
+ currentLine.removed = true;
64
+ }
65
+ }
66
+
67
+ return modifiedLines;
68
+ }
69
+
70
+ /**
71
+ * 合并连续的修改操作
72
+ */
73
+ private combineContinuousMods(changes: IModificationsInline[]) {
74
+ const lines: string[] = [];
75
+ let currentLineContent = empty;
76
+ for (const change of changes) {
77
+ if (change.isEolLine) {
78
+ lines.push(currentLineContent);
79
+ currentLineContent = empty;
80
+ } else {
81
+ currentLineContent += change.newValue;
82
+ }
83
+ }
84
+ if (currentLineContent !== empty) {
85
+ lines.push(currentLineContent);
86
+ }
87
+ return lines;
88
+ }
89
+
90
+ private processLineModifications(
91
+ waitAddModificationsLines: IModificationsInline[],
92
+ eol: string,
93
+ previous: IDiffChangeResult,
94
+ next?: IDiffChangeResult,
95
+ ) {
96
+ const lines = this.combineContinuousMods(waitAddModificationsLines);
97
+ const len = lines.length;
98
+
99
+ const fullLineMods: string[] = [];
100
+ const inlineMods: IProcessModificationsInline[] = [];
101
+
102
+ if (len === 0) {
103
+ return {
104
+ fullLineMods,
105
+ inlineMods,
106
+ };
107
+ }
108
+
109
+ const firstLine = lines[0];
110
+ const lastLine = lines[len - 1];
111
+
112
+ if (len === 1) {
113
+ if (!isUndefined(previous) && previous.value !== eol) {
114
+ inlineMods.push({
115
+ status: EProcessStatus.beginning,
116
+ newValue: previous.value + firstLine,
117
+ oldValue: previous.value,
118
+ });
119
+ } else if (!isUndefined(next) && next.value !== eol) {
120
+ inlineMods.push({
121
+ status: EProcessStatus.end,
122
+ newValue: lastLine + next.value,
123
+ oldValue: next.value,
124
+ });
125
+ } else {
126
+ fullLineMods.push(firstLine);
127
+ }
128
+
129
+ return {
130
+ fullLineMods,
131
+ inlineMods,
132
+ };
133
+ }
134
+
135
+ if (isUndefined(previous) || previous.value === eol) {
136
+ fullLineMods.push(firstLine);
137
+ } else {
138
+ inlineMods.push({
139
+ status: EProcessStatus.beginning,
140
+ newValue: previous.value + firstLine,
141
+ oldValue: previous.value,
142
+ });
143
+ }
144
+
145
+ if (len > 2) {
146
+ const middleLines = lines.slice(1, -1);
147
+ for (const line of middleLines) {
148
+ fullLineMods.push(line);
149
+ }
150
+ }
151
+
152
+ if (isUndefined(next) || next.value === eol) {
153
+ fullLineMods.push(lastLine);
154
+ } else {
155
+ inlineMods.push({
156
+ status: EProcessStatus.end,
157
+ newValue: lastLine + next.value,
158
+ oldValue: next.value,
159
+ });
160
+ }
161
+
162
+ return {
163
+ fullLineMods,
164
+ inlineMods,
165
+ };
166
+ }
167
+
168
+ public clearDecorations(): void {
169
+ this.ghostTextDecorations.clear();
170
+ }
171
+
172
+ public getEdits() {
173
+ const decorations = this.ghostTextDecorations.getDecorations();
174
+ const edits = decorations.map(({ editorDecoration, range }) => {
175
+ const options = editorDecoration.options;
176
+ const text = options.after?.content || '';
177
+
178
+ return { range, text };
179
+ });
180
+
181
+ return edits;
182
+ }
183
+
184
+ public updateLineModificationDecorations(modifications: IModificationsInline[]) {
185
+ if (modifications.length === 0) {
186
+ this.clearDecorations();
187
+ return;
188
+ }
189
+
190
+ const decorations: IModelDeltaDecoration[] = modifications.map((modification) => {
191
+ let content: string;
192
+
193
+ if (modification.newValue.startsWith(modification.oldValue)) {
194
+ content = modification.newValue.slice(modification.oldValue.length);
195
+ } else {
196
+ const oldValueIndex = modification.newValue.indexOf(modification.oldValue);
197
+ content = oldValueIndex !== -1 ? modification.newValue.slice(0, oldValueIndex) : modification.newValue;
198
+ }
199
+
200
+ return {
201
+ range: Range.fromPositions(new Position(modification.lineNumber!, modification.column!)),
202
+ options: {
203
+ description: GHOST_TEXT,
204
+ showIfCollapsed: true,
205
+ after: {
206
+ content,
207
+ inlineClassName: GHOST_TEXT_DESCRIPTION,
208
+ },
209
+ },
210
+ };
211
+ });
212
+
213
+ this.ghostTextDecorations.set(decorations);
214
+ }
215
+
216
+ public applyInlineDecorations(
217
+ editor: ICodeEditor,
218
+ changes: IDiffChangeResult[],
219
+ startLine: number,
220
+ cursorPosition: IPosition,
221
+ ): IModificationsInline[] | undefined {
222
+ startLine = Math.max(startLine - 1, 0);
223
+
224
+ const model = editor.getModel();
225
+ if (!model) {
226
+ return;
227
+ }
228
+
229
+ const eol = model.getEOL();
230
+
231
+ changes = this.splitDiffChanges(changes, eol);
232
+ changes.unshift({
233
+ value: eol,
234
+ added: undefined,
235
+ removed: undefined,
236
+ });
237
+
238
+ const currentLineText = model.getLineContent(cursorPosition.lineNumber);
239
+ const resultModifications: IModificationsInline[] = [];
240
+
241
+ let lastChange: IDiffChangeResult;
242
+ let waitAddModificationsLines: IModificationsInline[] = [];
243
+ let columnNumber = 1;
244
+
245
+ const processChange = (change: IDiffChangeResult | undefined) => {
246
+ const { fullLineMods, inlineMods } = this.processLineModifications(
247
+ waitAddModificationsLines,
248
+ eol,
249
+ lastChange,
250
+ change,
251
+ );
252
+
253
+ inlineMods.forEach((mod) =>
254
+ resultModifications.push({
255
+ lineNumber: mod.status === EProcessStatus.beginning ? startLine : startLine + 1,
256
+ column: mod.status === EProcessStatus.beginning ? columnNumber : 1,
257
+ newValue: mod.newValue,
258
+ oldValue: mod.oldValue,
259
+ }),
260
+ );
261
+
262
+ return {
263
+ fullLineMods,
264
+ inlineMods,
265
+ };
266
+ };
267
+
268
+ let currentLineIndex = startLine;
269
+ let previousValue = empty;
270
+ let isEmptyLine = currentLineText.trim() === empty;
271
+
272
+ for (const change of changes) {
273
+ if (change.added) {
274
+ const isEolLine = change.value === eol;
275
+
276
+ if (isEolLine) {
277
+ previousValue = empty;
278
+ }
279
+
280
+ waitAddModificationsLines.push({
281
+ isEolLine,
282
+ lineNumber: startLine,
283
+ newValue: isEolLine ? empty : change.value,
284
+ oldValue: isEolLine ? empty : previousValue,
285
+ });
286
+ } else {
287
+ const { inlineMods } = processChange(change);
288
+
289
+ if (startLine === cursorPosition.lineNumber && inlineMods.length > 0) {
290
+ isEmptyLine = false;
291
+
292
+ if (startLine <= cursorPosition.lineNumber && columnNumber < cursorPosition.column) {
293
+ return;
294
+ }
295
+ }
296
+
297
+ lastChange = change;
298
+ waitAddModificationsLines = [];
299
+
300
+ // 如果 change 的值是 eol,则开启新的一行进行计算
301
+ if (change.value === eol) {
302
+ currentLineIndex++;
303
+ columnNumber = 1;
304
+ previousValue = empty;
305
+ } else {
306
+ startLine = Math.max(startLine, currentLineIndex);
307
+ columnNumber += change.value.length;
308
+ previousValue += change.value;
309
+ }
310
+ }
311
+ }
312
+
313
+ const { fullLineMods } = processChange(undefined);
314
+
315
+ if (startLine <= cursorPosition.lineNumber && columnNumber < cursorPosition.column) {
316
+ return;
317
+ }
318
+
319
+ if (!isEmptyLine && fullLineMods.length > 0) {
320
+ return;
321
+ }
322
+
323
+ return resultModifications;
324
+ }
325
+ }
@@ -15,10 +15,6 @@ export class ResolveConflictRegistry
15
15
  {
16
16
  private readonly providerMap = new Map<MergeConflictEditorMode, IResolveConflictHandler>();
17
17
 
18
- override dispose() {
19
- super.dispose();
20
- }
21
-
22
18
  registerResolveConflictProvider(editorMode: MergeConflictEditorMode, handler: IResolveConflictHandler): void {
23
19
  if (this.providerMap.has(editorMode)) {
24
20
  throw new Error(`Conflict provider for ${editorMode} already exists`);
@@ -13,7 +13,7 @@ import {
13
13
  RenameCandidatesProviderRegistryToken,
14
14
  ResolveConflictRegistryToken,
15
15
  } from '@opensumi/ide-core-browser';
16
- import { TerminalRegistryToken } from '@opensumi/ide-core-common';
16
+ import { IntelligentCompletionsRegistryToken, TerminalRegistryToken } from '@opensumi/ide-core-common';
17
17
 
18
18
  import { ChatProxyServiceToken, IChatAgentService, IChatInternalService, IChatManagerService } from '../common';
19
19
 
@@ -27,6 +27,8 @@ import { ChatFeatureRegistry } from './chat/chat.feature.registry';
27
27
  import { ChatInternalService } from './chat/chat.internal.service';
28
28
  import { ChatRenderRegistry } from './chat/chat.render.registry';
29
29
  import { AICodeActionContribution } from './contrib/code-action/code-action.contribution';
30
+ import { IntelligentCompletionsContribution } from './contrib/intelligent-completions/intelligent-completions.contribution';
31
+ import { IntelligentCompletionsRegistry } from './contrib/intelligent-completions/intelligent-completions.feature.registry';
30
32
  import { InterfaceNavigationContribution } from './contrib/interface-navigation/interface-navigation.contribution';
31
33
  import { MergeConflictContribution } from './contrib/merge-conflict';
32
34
  import { ResolveConflictRegistry } from './contrib/merge-conflict/merge-conflict.feature.registry';
@@ -57,6 +59,7 @@ export class AINativeModule extends BrowserModule {
57
59
  MergeConflictContribution,
58
60
  AICodeActionContribution,
59
61
  AINativePreferencesContribution,
62
+ IntelligentCompletionsContribution,
60
63
  {
61
64
  token: InlineChatFeatureRegistryToken,
62
65
  useClass: InlineChatFeatureRegistry,
@@ -73,6 +76,10 @@ export class AINativeModule extends BrowserModule {
73
76
  token: ResolveConflictRegistryToken,
74
77
  useClass: ResolveConflictRegistry,
75
78
  },
79
+ {
80
+ token: IntelligentCompletionsRegistryToken,
81
+ useClass: IntelligentCompletionsRegistry,
82
+ },
76
83
  {
77
84
  token: IAIInlineChatService,
78
85
  useClass: AIInlineChatService,
@@ -33,7 +33,13 @@ export const AILayout = () => {
33
33
  />
34
34
  <SplitPanel id='main-vertical' minResize={300} flexGrow={1} direction='top-to-bottom'>
35
35
  <SlotRenderer flex={2} flexGrow={1} minResize={200} slot='main' />
36
- <SlotRenderer flex={1} defaultSize={layout.bottom?.size} minResize={160} slot='bottom' isTabbar={true} />
36
+ <SlotRenderer
37
+ flex={1}
38
+ defaultSize={layout.bottom?.currentId ? layout.bottom?.size : 24}
39
+ minResize={160}
40
+ slot='bottom'
41
+ isTabbar={true}
42
+ />
37
43
  </SplitPanel>
38
44
  <SlotRenderer
39
45
  slot='right'
@@ -1,15 +1,6 @@
1
- /**
2
- * -------------------------------------------- 右侧 chat 面板样式 --------------------------------------------
3
- */
4
1
  #ai_chat_panel {
5
2
  height: 100%;
6
3
 
7
- div[class*='tab_panel'] {
8
- &::before {
9
- content: none;
10
- }
11
- }
12
-
13
4
  :global {
14
5
  .rce-mbox-left-notch,
15
6
  .rce-mbox-right-notch {
@@ -1,6 +1,4 @@
1
- import throttle from 'lodash/throttle';
2
-
3
- import { Disposable, Emitter, Event, isUndefined } from '@opensumi/ide-core-common';
1
+ import { Disposable, Emitter, Event, isDefined, isUndefined } from '@opensumi/ide-core-common';
4
2
  import {
5
3
  ICodeEditor,
6
4
  IContentSizeChangedEvent,
@@ -13,6 +11,7 @@ import {
13
11
  Range,
14
12
  } from '@opensumi/ide-monaco';
15
13
  import { space } from '@opensumi/ide-utils/lib/strings';
14
+ import { UndoRedoGroup } from '@opensumi/monaco-editor-core/esm/vs/platform/undoRedo/common/undoRedo';
16
15
 
17
16
  import styles from './styles.module.less';
18
17
 
@@ -35,8 +34,17 @@ export interface IEnhanceModelDeltaDecoration extends IDeltaData {
35
34
  resume(): void;
36
35
  getRange(): IRange;
37
36
  setRange(newRange: IRange): void;
37
+ group?: UndoRedoGroup;
38
+ setGroup(group: UndoRedoGroup): void;
39
+ }
38
40
 
39
- serializeState(): IDecorationSerializableState;
41
+ export interface IDeltaDecorationsOptions {
42
+ id: string;
43
+ editorDecoration: IModelDeltaDecoration;
44
+ codeEditor: ICodeEditor;
45
+ deltaData: Partial<IDeltaData>;
46
+ isHidden?: boolean;
47
+ group?: UndoRedoGroup;
40
48
  }
41
49
 
42
50
  class DeltaDecorations implements IEnhanceModelDeltaDecoration {
@@ -45,18 +53,36 @@ class DeltaDecorations implements IEnhanceModelDeltaDecoration {
45
53
  options: IModelDecorationOptions;
46
54
 
47
55
  private resumeRange: IRange;
56
+ private _group: UndoRedoGroup;
48
57
 
49
58
  private _hidden = false;
50
59
  get isHidden(): boolean {
51
60
  return this._hidden;
52
61
  }
53
62
 
54
- constructor(
55
- public readonly id: string,
56
- public readonly editorDecoration: IModelDeltaDecoration,
57
- private readonly codeEditor: ICodeEditor,
58
- private readonly deltaData: Partial<IDeltaData>,
59
- ) {
63
+ get codeEditor(): ICodeEditor {
64
+ return this.metadata.codeEditor;
65
+ }
66
+
67
+ get deltaData(): Partial<IDeltaData> {
68
+ return this.metadata.deltaData;
69
+ }
70
+
71
+ get id(): string {
72
+ return this.metadata.id;
73
+ }
74
+
75
+ get editorDecoration(): IModelDeltaDecoration {
76
+ return this.metadata.editorDecoration;
77
+ }
78
+
79
+ public get group(): UndoRedoGroup {
80
+ return this._group;
81
+ }
82
+
83
+ constructor(protected readonly metadata: IDeltaDecorationsOptions) {
84
+ const { editorDecoration, deltaData, isHidden, group } = metadata;
85
+
60
86
  if (isUndefined(deltaData.length)) {
61
87
  this.length = editorDecoration.range.endLineNumber - editorDecoration.range.startLineNumber;
62
88
  } else {
@@ -67,6 +93,19 @@ class DeltaDecorations implements IEnhanceModelDeltaDecoration {
67
93
  this.options = editorDecoration.options;
68
94
 
69
95
  this.resumeRange = this.range;
96
+
97
+ this._hidden = !!isHidden;
98
+ if (this._hidden) {
99
+ this.hide();
100
+ }
101
+
102
+ if (isDefined(group)) {
103
+ this.setGroup(group);
104
+ }
105
+ }
106
+
107
+ setGroup(group): void {
108
+ this._group = group;
70
109
  }
71
110
 
72
111
  private changeVisibility(newClassName: string, newRange: Range): void {
@@ -112,16 +151,6 @@ class DeltaDecorations implements IEnhanceModelDeltaDecoration {
112
151
  this._hidden = false;
113
152
  this.changeVisibility(styles.visible, Range.lift(this.resumeRange));
114
153
  }
115
-
116
- serializeState(): IDecorationSerializableState {
117
- const { range } = this;
118
- const startPosition = { lineNumber: range.startLineNumber, column: range.startColumn };
119
- const endPosition = {
120
- lineNumber: range.endLineNumber,
121
- column: range.endColumn,
122
- };
123
- return { startPosition, endPosition, len: this.length };
124
- }
125
154
  }
126
155
 
127
156
  export class EnhanceDecorationsCollection extends Disposable {
@@ -137,12 +166,6 @@ export class EnhanceDecorationsCollection extends Disposable {
137
166
  constructor(private readonly codeEditor: ICodeEditor) {
138
167
  super();
139
168
 
140
- this.addDispose(
141
- Disposable.create(() => {
142
- this.clear();
143
- }),
144
- );
145
-
146
169
  this.addDispose(
147
170
  this.codeEditor.onDidContentSizeChange((event: IContentSizeChangedEvent) => {
148
171
  const { contentHeightChanged } = event;
@@ -180,7 +203,14 @@ export class EnhanceDecorationsCollection extends Disposable {
180
203
  });
181
204
  }
182
205
 
183
- set(decorations: (IModelDeltaDecoration & Partial<Pick<IEnhanceModelDeltaDecoration, 'length'>>)[]): void {
206
+ protected createDecorations(metaData: IDeltaDecorationsOptions) {
207
+ return new DeltaDecorations(metaData);
208
+ }
209
+
210
+ set(
211
+ decorations: (IModelDeltaDecoration &
212
+ Partial<Pick<IEnhanceModelDeltaDecoration, 'length' | 'isHidden' | 'group'>>)[],
213
+ ): void {
184
214
  this.clear();
185
215
 
186
216
  this.codeEditor.changeDecorations((accessor: IModelDecorationsChangeAccessor) => {
@@ -189,9 +219,16 @@ export class EnhanceDecorationsCollection extends Disposable {
189
219
  for (const decoration of decorations) {
190
220
  const id = accessor.addDecoration(decoration.range, decoration.options);
191
221
  newDecorations.push(
192
- new DeltaDecorations(id, decoration, this.codeEditor, {
193
- length: decoration.length,
194
- dispose: () => this.delete(id),
222
+ this.createDecorations({
223
+ id,
224
+ editorDecoration: decoration,
225
+ codeEditor: this.codeEditor,
226
+ isHidden: decoration.isHidden,
227
+ group: decoration.group,
228
+ deltaData: {
229
+ dispose: () => this.delete(id),
230
+ length: decoration.length,
231
+ },
195
232
  }),
196
233
  );
197
234
  }
@@ -204,12 +241,12 @@ export class EnhanceDecorationsCollection extends Disposable {
204
241
  return this.deltaDecorations;
205
242
  }
206
243
 
207
- getDecorationByLineNumber(lineNumber: number): IEnhanceModelDeltaDecoration | undefined {
208
- return this.deltaDecorations.find((d) => d.getRange().startLineNumber === lineNumber);
244
+ getDecorationByGroup(group: UndoRedoGroup): IEnhanceModelDeltaDecoration | undefined {
245
+ return this.deltaDecorations.find((d) => d.group === group);
209
246
  }
210
247
 
211
- serializeState(): IDecorationSerializableState[] {
212
- return this.deltaDecorations.filter((d) => !d.isHidden).map((d) => d.serializeState());
248
+ getDecorationByLineNumber(lineNumber: number): IEnhanceModelDeltaDecoration | undefined {
249
+ return this.deltaDecorations.find((d) => d.getRange().startLineNumber === lineNumber);
213
250
  }
214
251
 
215
252
  clear(): void {
@@ -8,15 +8,17 @@ import {
8
8
  IAICompletionOption,
9
9
  IAICompletionResultModel,
10
10
  IDisposable,
11
+ IPosition,
11
12
  IResolveConflictHandler,
12
13
  MaybePromise,
13
14
  MergeConflictEditorMode,
14
15
  } from '@opensumi/ide-core-common';
15
- import { ICodeEditor, ITextModel, NewSymbolNamesProvider, Position } from '@opensumi/ide-monaco';
16
+ import { ICodeEditor, IRange, ITextModel, NewSymbolNamesProvider, Position } from '@opensumi/ide-monaco';
16
17
  import { SumiReadableStream } from '@opensumi/ide-utils/lib/stream';
17
18
 
18
19
  import { IChatWelcomeMessageContent, ISampleQuestions, ITerminalCommandSuggestionDesc } from '../common';
19
20
 
21
+ import { IIntelligentCompletionsResult } from './contrib/intelligent-completions/intelligent-completions';
20
22
  import { BaseTerminalDetectionLineMatcher } from './contrib/terminal/matcher';
21
23
  import { InlineChatController } from './widget/inline-chat/inline-chat-controller';
22
24
 
@@ -26,13 +28,13 @@ interface IBaseInlineChatHandler<T extends any[]> {
26
28
  */
27
29
  execute?: (...args: T) => MaybePromise<void>;
28
30
  /**
29
- * 提供 diff editor 的预览策略
31
+ * editor 里预览输出的结果
30
32
  */
31
- providerDiffPreviewStrategy?: (...args: T) => MaybePromise<ChatResponse | InlineChatController>;
33
+ providePreviewStrategy?: (...args: T) => MaybePromise<ChatResponse | InlineChatController>;
32
34
  /**
33
- * editor 里直接预览输出的结果
35
+ * @deprecated use providePreviewStrategy api
34
36
  */
35
- providerPreviewStrategy?: (...args: T) => MaybePromise<ChatResponse | InlineChatController>;
37
+ providerDiffPreviewStrategy?: (...args: T) => MaybePromise<ChatResponse | InlineChatController>;
36
38
  }
37
39
 
38
40
  export type IEditorInlineChatHandler = IBaseInlineChatHandler<[editor: ICodeEditor, token: CancellationToken]>;
@@ -45,10 +47,6 @@ export enum ERunStrategy {
45
47
  * 正常执行,执行后 input 直接消失
46
48
  */
47
49
  EXECUTE = 'EXECUTE',
48
- /**
49
- * 预览 diff,执行后 input 保留,显示 inline diff editor
50
- */
51
- DIFF_PREVIEW = 'DIFF_PREVIEW',
52
50
  /**
53
51
  * 预览输出结果,执行后 input 保留,并在 editor 里直接展示输出结果
54
52
  */
@@ -198,14 +196,19 @@ export interface ITerminalProviderRegistry {
198
196
  registerCommandSuggestionsProvider(provider: TTerminalCommandSuggestionsProviderFn): void;
199
197
  }
200
198
 
199
+ export type IIntelligentCompletionProvider = (
200
+ editor: ICodeEditor,
201
+ position: IPosition,
202
+ contextBean: IAICompletionOption,
203
+ token: CancellationToken,
204
+ ) => MaybePromise<IIntelligentCompletionsResult>;
205
+ export interface IIntelligentCompletionsRegistry {
206
+ registerIntelligentCompletionProvider(provider: IIntelligentCompletionProvider): void;
207
+ }
208
+
201
209
  export const AINativeCoreContribution = Symbol('AINativeCoreContribution');
202
210
 
203
211
  export interface AINativeCoreContribution {
204
- /**
205
- * 通过中间件扩展部分 ai 能力
206
- */
207
- middleware?: IAIMiddleware;
208
-
209
212
  /**
210
213
  * 注册 inline chat 相关功能
211
214
  * @param registry: IInlineChatFeatureRegistry
@@ -231,6 +234,10 @@ export interface AINativeCoreContribution {
231
234
  * 注册智能终端相关功能
232
235
  */
233
236
  registerTerminalProvider?(registry: ITerminalProviderRegistry): void;
237
+ /**
238
+ * 注册智能代码补全相关功能
239
+ */
240
+ registerIntelligentCompletionFeature?(registry: IIntelligentCompletionsRegistry): void;
234
241
  }
235
242
 
236
243
  export interface IChatComponentConfig {
@@ -245,6 +252,9 @@ export interface IChatAgentViewService {
245
252
  getChatComponentDeferred(componentId: string): Deferred<IChatComponentConfig> | null;
246
253
  }
247
254
 
255
+ /**
256
+ * @deprecated use registerIntelligentCompletionProvider API
257
+ */
248
258
  export type IProvideInlineCompletionsSignature = (
249
259
  this: void,
250
260
  model: ITextModel,
@@ -254,6 +264,9 @@ export type IProvideInlineCompletionsSignature = (
254
264
  requestOption: IAICompletionOption,
255
265
  ) => MaybePromise<IAICompletionResultModel | null>;
256
266
 
267
+ /**
268
+ * @deprecated use registerIntelligentCompletionProvider API
269
+ */
257
270
  export interface IAIMiddleware {
258
271
  language?: {
259
272
  provideInlineCompletions?: IProvideInlineCompletionsSignature;