@opensumi/ide-ai-native 3.2.4 → 3.2.5-next-1724062137.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 (181) 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 +14 -25
  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.view.d.ts.map +1 -1
  14. package/lib/browser/chat/chat.view.js +22 -4
  15. package/lib/browser/chat/chat.view.js.map +1 -1
  16. package/lib/browser/components/ChatEditor.d.ts +2 -1
  17. package/lib/browser/components/ChatEditor.d.ts.map +1 -1
  18. package/lib/browser/components/ChatEditor.js +8 -8
  19. package/lib/browser/components/ChatEditor.js.map +1 -1
  20. package/lib/browser/components/ChatMarkdown.d.ts +1 -0
  21. package/lib/browser/components/ChatMarkdown.d.ts.map +1 -1
  22. package/lib/browser/components/ChatMarkdown.js +2 -2
  23. package/lib/browser/components/ChatMarkdown.js.map +1 -1
  24. package/lib/browser/components/ChatThinking.d.ts.map +1 -1
  25. package/lib/browser/components/ChatThinking.js +2 -2
  26. package/lib/browser/components/ChatThinking.js.map +1 -1
  27. package/lib/browser/contextkey/ai-native.contextkey.service.d.ts +1 -0
  28. package/lib/browser/contextkey/ai-native.contextkey.service.d.ts.map +1 -1
  29. package/lib/browser/contextkey/ai-native.contextkey.service.js +1 -0
  30. package/lib/browser/contextkey/ai-native.contextkey.service.js.map +1 -1
  31. package/lib/browser/contrib/inline-completions/completeProvider.d.ts +4 -31
  32. package/lib/browser/contrib/inline-completions/completeProvider.d.ts.map +1 -1
  33. package/lib/browser/contrib/inline-completions/completeProvider.js +3 -224
  34. package/lib/browser/contrib/inline-completions/completeProvider.js.map +1 -1
  35. package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts +1 -3
  36. package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts.map +1 -1
  37. package/lib/browser/contrib/inline-completions/inline-completions.handler.js +8 -20
  38. package/lib/browser/contrib/inline-completions/inline-completions.handler.js.map +1 -1
  39. package/lib/browser/contrib/inline-completions/model/competionModel.d.ts +2 -2
  40. package/lib/browser/contrib/inline-completions/model/competionModel.d.ts.map +1 -1
  41. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.d.ts +28 -0
  42. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.d.ts.map +1 -0
  43. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js +210 -0
  44. package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js.map +1 -0
  45. package/lib/browser/contrib/inline-completions/promptCache.d.ts +3 -2
  46. package/lib/browser/contrib/inline-completions/promptCache.d.ts.map +1 -1
  47. package/lib/browser/contrib/inline-completions/promptCache.js.map +1 -1
  48. package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts +7 -6
  49. package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts.map +1 -1
  50. package/lib/browser/contrib/inline-completions/service/ai-completions.service.js +48 -25
  51. package/lib/browser/contrib/inline-completions/service/ai-completions.service.js.map +1 -1
  52. package/lib/browser/contrib/intelligent-completions/diff-computer.d.ts +18 -0
  53. package/lib/browser/contrib/intelligent-completions/diff-computer.d.ts.map +1 -0
  54. package/lib/browser/contrib/intelligent-completions/diff-computer.js +144 -0
  55. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -0
  56. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts +8 -0
  57. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts.map +1 -0
  58. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +47 -0
  59. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -0
  60. package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts +15 -0
  61. package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts.map +1 -0
  62. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts +8 -0
  63. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts.map +1 -0
  64. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js +19 -0
  65. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js.map +1 -0
  66. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.d.ts +20 -0
  67. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.d.ts.map +1 -0
  68. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.js +94 -0
  69. package/lib/browser/contrib/intelligent-completions/intelligent-completions.handler.js.map +1 -0
  70. package/lib/browser/contrib/intelligent-completions/intelligent-completions.js +3 -0
  71. package/lib/browser/contrib/intelligent-completions/intelligent-completions.js.map +1 -0
  72. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts +33 -0
  73. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts.map +1 -0
  74. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js +258 -0
  75. package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js.map +1 -0
  76. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.d.ts +0 -1
  77. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.d.ts.map +1 -1
  78. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.js +0 -3
  79. package/lib/browser/contrib/merge-conflict/merge-conflict.feature.registry.js.map +1 -1
  80. package/lib/browser/contrib/rename/rename.handler.d.ts.map +1 -1
  81. package/lib/browser/contrib/rename/rename.handler.js +1 -0
  82. package/lib/browser/contrib/rename/rename.handler.js.map +1 -1
  83. package/lib/browser/index.d.ts.map +1 -1
  84. package/lib/browser/index.js +7 -0
  85. package/lib/browser/index.js.map +1 -1
  86. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  87. package/lib/browser/layout/ai-layout.js +4 -4
  88. package/lib/browser/layout/ai-layout.js.map +1 -1
  89. package/lib/browser/model/enhanceDecorationsCollection.d.ts +38 -4
  90. package/lib/browser/model/enhanceDecorationsCollection.d.ts.map +1 -1
  91. package/lib/browser/model/enhanceDecorationsCollection.js +44 -23
  92. package/lib/browser/model/enhanceDecorationsCollection.js.map +1 -1
  93. package/lib/browser/types.d.ts +20 -13
  94. package/lib/browser/types.d.ts.map +1 -1
  95. package/lib/browser/types.js +0 -4
  96. package/lib/browser/types.js.map +1 -1
  97. package/lib/browser/widget/inline-chat/inline-chat.handler.d.ts.map +1 -1
  98. package/lib/browser/widget/inline-chat/inline-chat.handler.js +31 -12
  99. package/lib/browser/widget/inline-chat/inline-chat.handler.js.map +1 -1
  100. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +5 -2
  101. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
  102. package/lib/browser/widget/inline-chat/inline-content-widget.js +45 -53
  103. package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
  104. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +20 -14
  105. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
  106. package/lib/browser/widget/inline-diff/inline-diff-previewer.js +114 -46
  107. package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
  108. package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts +5 -2
  109. package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts.map +1 -1
  110. package/lib/browser/widget/inline-diff/inline-diff-widget.js +3 -0
  111. package/lib/browser/widget/inline-diff/inline-diff-widget.js.map +1 -1
  112. package/lib/browser/widget/inline-diff/inline-diff.handler.d.ts +13 -13
  113. package/lib/browser/widget/inline-diff/inline-diff.handler.d.ts.map +1 -1
  114. package/lib/browser/widget/inline-diff/inline-diff.handler.js +71 -76
  115. package/lib/browser/widget/inline-diff/inline-diff.handler.js.map +1 -1
  116. package/lib/browser/widget/inline-input/inline-input-widget.d.ts +1 -0
  117. package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
  118. package/lib/browser/widget/inline-input/inline-input-widget.js +1 -0
  119. package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
  120. package/lib/browser/widget/inline-input/inline-input.handler.js +2 -2
  121. package/lib/browser/widget/inline-input/inline-input.handler.js.map +1 -1
  122. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +28 -15
  123. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  124. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +52 -31
  125. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  126. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.module.less +9 -6
  127. package/lib/browser/widget/inline-stream-diff/live-preview-stack.d.ts +21 -0
  128. package/lib/browser/widget/inline-stream-diff/live-preview-stack.d.ts.map +1 -0
  129. package/lib/browser/widget/inline-stream-diff/live-preview-stack.js +41 -0
  130. package/lib/browser/widget/inline-stream-diff/live-preview-stack.js.map +1 -0
  131. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +105 -0
  132. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -0
  133. package/lib/browser/widget/inline-stream-diff/live-preview.component.js +237 -0
  134. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -0
  135. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +27 -103
  136. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  137. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +185 -369
  138. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  139. package/lib/common/index.d.ts +1 -0
  140. package/lib/common/index.d.ts.map +1 -1
  141. package/lib/common/index.js.map +1 -1
  142. package/package.json +19 -19
  143. package/src/browser/ai-core.contribution.ts +14 -28
  144. package/src/browser/ai-editor.contribution.ts +9 -0
  145. package/src/browser/chat/chat-agent.service.ts +1 -3
  146. package/src/browser/chat/chat.view.tsx +49 -4
  147. package/src/browser/components/ChatEditor.tsx +21 -7
  148. package/src/browser/components/ChatMarkdown.tsx +8 -2
  149. package/src/browser/components/ChatThinking.tsx +3 -1
  150. package/src/browser/contextkey/ai-native.contextkey.service.ts +3 -0
  151. package/src/browser/contrib/inline-completions/completeProvider.ts +7 -289
  152. package/src/browser/contrib/inline-completions/inline-completions.handler.ts +15 -22
  153. package/src/browser/contrib/inline-completions/model/competionModel.ts +3 -2
  154. package/src/browser/contrib/inline-completions/model/inlineCompletionRequestTask.ts +272 -0
  155. package/src/browser/contrib/inline-completions/promptCache.ts +3 -2
  156. package/src/browser/contrib/inline-completions/service/ai-completions.service.ts +55 -38
  157. package/src/browser/contrib/intelligent-completions/diff-computer.ts +185 -0
  158. package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +54 -0
  159. package/src/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.ts +17 -0
  160. package/src/browser/contrib/intelligent-completions/intelligent-completions.handler.ts +130 -0
  161. package/src/browser/contrib/intelligent-completions/intelligent-completions.ts +15 -0
  162. package/src/browser/contrib/intelligent-completions/multi-line.decoration.ts +325 -0
  163. package/src/browser/contrib/merge-conflict/merge-conflict.feature.registry.ts +0 -4
  164. package/src/browser/contrib/rename/rename.handler.ts +1 -0
  165. package/src/browser/index.ts +8 -1
  166. package/src/browser/layout/ai-layout.tsx +7 -1
  167. package/src/browser/model/enhanceDecorationsCollection.ts +71 -34
  168. package/src/browser/types.ts +27 -14
  169. package/src/browser/widget/inline-chat/inline-chat.handler.ts +34 -19
  170. package/src/browser/widget/inline-chat/inline-content-widget.tsx +58 -61
  171. package/src/browser/widget/inline-diff/inline-diff-previewer.ts +118 -61
  172. package/src/browser/widget/inline-diff/inline-diff-widget.tsx +8 -2
  173. package/src/browser/widget/inline-diff/inline-diff.handler.ts +83 -92
  174. package/src/browser/widget/inline-input/inline-input-widget.tsx +1 -0
  175. package/src/browser/widget/inline-input/inline-input.handler.ts +2 -2
  176. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +98 -44
  177. package/src/browser/widget/inline-stream-diff/inline-stream-diff.module.less +9 -6
  178. package/src/browser/widget/inline-stream-diff/live-preview-stack.ts +52 -0
  179. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +388 -0
  180. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +243 -543
  181. package/src/common/index.ts +2 -0
@@ -1,26 +1,12 @@
1
1
  import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
2
- import { AppConfig, PreferenceService } from '@opensumi/ide-core-browser';
3
- import { AI_INLINE_COMPLETION_REPORTER } from '@opensumi/ide-core-browser/lib/ai-native/command';
4
- import {
5
- AINativeSettingSectionsId,
6
- DisposableStore,
7
- URI,
8
- WithEventBus,
9
- raceCancellation,
10
- sleep,
11
- uuid,
12
- } from '@opensumi/ide-core-common';
13
- import { IAICompletionOption, IAICompletionResultModel } from '@opensumi/ide-core-common/lib/types/ai-native';
14
- import { AISerivceType, IAIReporter } from '@opensumi/ide-core-common/lib/types/ai-native/reporter';
2
+ import { PreferenceService } from '@opensumi/ide-core-browser';
3
+ import { AINativeSettingSectionsId, WithEventBus, raceCancellation, sleep } from '@opensumi/ide-core-common';
15
4
  import { IEditor } from '@opensumi/ide-editor';
16
5
  import * as monaco from '@opensumi/ide-monaco';
17
6
 
18
- import { DEFAULT_COMPLECTION_MODEL } from './constants';
19
- import { IInlineCompletionCache, InlineCompletionItem } from './model/competionModel';
20
- import { PromptCache } from './promptCache';
21
- import { getPrefixPrompt, getSuffixPrompt, lineBasedPromptProcessor } from './provider';
7
+ import { IInlineCompletionCache } from './model/competionModel';
8
+ import { InlineCompletionRequestTask } from './model/inlineCompletionRequestTask';
22
9
  import { AICompletionsService } from './service/ai-completions.service';
23
- import { ICompletionContext } from './types';
24
10
 
25
11
  // 用来缓存最近一次的补全结果
26
12
  const inlineCompletionCache: IInlineCompletionCache = {
@@ -29,280 +15,12 @@ const inlineCompletionCache: IInlineCompletionCache = {
29
15
  last: null,
30
16
  };
31
17
 
32
- const makeHashSet = (str: string) => {
33
- const set = new Set<string>();
34
- for (const char of str) {
35
- set.add(char);
36
- }
37
- return set;
38
- };
39
-
40
- const removeChars = (insertText: string, textAfterCursor: string) => {
41
- let result = '';
42
- const aSet = makeHashSet(insertText);
43
- for (const char of textAfterCursor) {
44
- // 如果是空格或者 insertText 中不存在的字符,就加入到结果中
45
- if (char === ' ' || !aSet.has(char)) {
46
- result += char;
47
- }
48
- }
49
- return result;
50
- };
51
-
52
- @Injectable({ multiple: true })
53
- export class CompletionRequestTask {
54
- private _disposables = new DisposableStore();
55
-
56
- @Autowired(IAIReporter)
57
- private aiReporter: IAIReporter;
58
-
59
- @Autowired(INJECTOR_TOKEN)
60
- private readonly injector: Injector;
61
-
62
- @Autowired(PromptCache)
63
- private promptCache: PromptCache;
64
-
65
- @Autowired(AICompletionsService)
66
- private aiCompletionsService: AICompletionsService;
67
-
68
- @Autowired(PreferenceService)
69
- private readonly preferenceService: PreferenceService;
70
-
71
- @Autowired(AppConfig)
72
- private appConfig: AppConfig;
73
-
74
- isCancelFlag: boolean;
75
-
76
- private isEnablePromptEngineering = true;
77
-
78
- constructor(
79
- public model: monaco.editor.ITextModel,
80
- public position: monaco.Position,
81
- public token: monaco.CancellationToken,
82
- public _isManual: boolean,
83
- ) {
84
- this.isCancelFlag = false;
85
-
86
- this.isEnablePromptEngineering = this.preferenceService.getValid(
87
- AINativeSettingSectionsId.InlineCompletionsPromptEngineeringEnabled,
88
- this.isEnablePromptEngineering,
89
- );
90
-
91
- this._disposables.add(
92
- this.preferenceService.onSpecificPreferenceChange(
93
- AINativeSettingSectionsId.InlineCompletionsPromptEngineeringEnabled,
94
- ({ newValue }) => {
95
- this.isEnablePromptEngineering = newValue;
96
- },
97
- ),
98
- );
99
- }
100
-
101
- async constructRequestBean(
102
- context: ICompletionContext,
103
- token: monaco.CancellationToken,
104
- ): Promise<IAICompletionOption> {
105
- if (this.isEnablePromptEngineering) {
106
- const prompt = await getPrefixPrompt(context, DEFAULT_COMPLECTION_MODEL, this.injector, token);
107
- const suffix = await getSuffixPrompt(context, DEFAULT_COMPLECTION_MODEL, this.injector, token);
108
-
109
- return {
110
- prompt,
111
- suffix,
112
- sessionId: uuid(),
113
- language: context.language,
114
- fileUrl: context.fileUrl,
115
- workspaceDir: context.workspaceDir,
116
- };
117
- }
118
-
119
- const prompt = lineBasedPromptProcessor.processPrefix(context.prefix);
120
- const suffix = lineBasedPromptProcessor.processSuffix(context.suffix);
121
- return {
122
- prompt,
123
- suffix,
124
- sessionId: uuid(),
125
- language: context.language,
126
- fileUrl: context.fileUrl,
127
- workspaceDir: context.workspaceDir,
128
- };
129
- }
130
-
131
- // 发送请求
132
- async run() {
133
- const { model, position, token } = this;
134
- if (!model) {
135
- return [];
136
- }
137
- if (token.isCancellationRequested) {
138
- return [];
139
- }
140
-
141
- if (this.isCancelFlag) {
142
- return [];
143
- }
144
-
145
- const startRange = new monaco.Range(0, 0, position.lineNumber, position.column);
146
- let prefix = model.getValueInRange(startRange);
147
- if (prefix === '') {
148
- prefix += '\n';
149
- }
150
-
151
- const endRange = new monaco.Range(
152
- position.lineNumber,
153
- position.column,
154
- model.getLineCount(),
155
- Number.MAX_SAFE_INTEGER,
156
- );
157
-
158
- const suffix = model.getValueInRange(endRange);
159
-
160
- const languageId = model.getLanguageId();
161
- const context: ICompletionContext = {
162
- fileUrl: model.uri.fsPath,
163
- filename: model.uri.toString().split('/').pop()!,
164
- language: languageId,
165
- prefix,
166
- suffix,
167
- uri: URI.from(model.uri),
168
- workspaceDir: this.appConfig.workspaceDir,
169
- };
170
-
171
- // 组装请求参数,向远程发起请求
172
- const requestBean = await this.constructRequestBean(context, token);
173
- if (this.isCancelFlag) {
174
- return [];
175
- }
176
-
177
- this.aiCompletionsService.updateStatusBarItem('running', true);
178
- const requestStartTime = Date.now();
179
-
180
- let rs: IAICompletionResultModel | null;
181
- const cacheData = this.promptCache.getCache(requestBean);
182
- const relationId =
183
- cacheData?.relationId || this.aiReporter.start(AISerivceType.Completion, { message: AISerivceType.Completion });
184
-
185
- this.aiCompletionsService.setLastRelationId(relationId);
186
- // 如果存在缓存
187
- if (cacheData) {
188
- rs = cacheData;
189
- } else {
190
- try {
191
- rs = await this.aiCompletionsService.complete(requestBean, model, position, token);
192
- } catch (error) {
193
- this.aiCompletionsService.reporterEnd(relationId, {
194
- success: false,
195
- replytime: Date.now() - requestStartTime,
196
- message: error.toString(),
197
- });
198
- this.aiCompletionsService.hideStatusBarItem();
199
- return [];
200
- }
201
- }
202
-
203
- if (!(rs && rs.sessionId)) {
204
- this.aiCompletionsService.reporterEnd(relationId, { success: false, replytime: Date.now() - requestStartTime });
205
- this.aiCompletionsService.hideStatusBarItem();
206
- return [];
207
- }
208
-
209
- this.aiCompletionsService.setLastSessionId(rs.sessionId);
210
-
211
- // 如果是取消直接返回
212
- if ((rs && rs.isCancel) || token.isCancellationRequested || this.isCancelFlag) {
213
- this.aiCompletionsService.reporterEnd(relationId, {
214
- success: true,
215
- replytime: Date.now() - requestStartTime,
216
- isStop: true,
217
- completionNum: 0,
218
- });
219
- this.aiCompletionsService.updateStatusBarItem('canceled', false);
220
- return [];
221
- }
222
-
223
- // 返回补全结果为空直接返回
224
- if (!rs || !rs.codeModelList || rs.codeModelList.length === 0) {
225
- this.aiCompletionsService.reporterEnd(relationId, {
226
- success: true,
227
- replytime: Date.now() - requestStartTime,
228
- completionNum: 0,
229
- });
230
- this.aiCompletionsService.updateStatusBarItem('no result', false);
231
- return [];
232
- }
233
-
234
- if (rs.codeModelList.length > 0) {
235
- this.promptCache.setCache(requestBean, { ...rs, relationId });
236
- }
237
-
238
- this.aiCompletionsService.updateStatusBarItem('completion result: ' + rs.codeModelList.length, false);
239
-
240
- this.dispose();
241
- return this.pushResultAndRegist(rs, position, relationId);
242
- }
243
- /**
244
- * 将补全结果推给用户并注册{@link COMMAND_ACCEPT} 事件
245
- * @param codeModelList
246
- */
247
- pushResultAndRegist(
248
- rs: IAICompletionResultModel,
249
- position: monaco.Position,
250
- relationId: string,
251
- ): Array<InlineCompletionItem> {
252
- const result = new Array<InlineCompletionItem>();
253
- for (const codeModel of rs.codeModelList) {
254
- const contentText = codeModel.content;
255
-
256
- const insertText = contentText.trimEnd();
257
-
258
- const model = this.model;
259
-
260
- const textAfterCursor = model.getValueInRange({
261
- startLineNumber: position.lineNumber,
262
- startColumn: position.column,
263
- endLineNumber: position.lineNumber,
264
- endColumn: model.getLineMaxColumn(position.lineNumber),
265
- });
266
-
267
- // 临时修复方案,用于解决补全后面多了几个括号的问题
268
- const filteredString = removeChars(insertText, textAfterCursor);
269
-
270
- result.push({
271
- insertText: insertText + filteredString,
272
- range: new monaco.Range(
273
- position.lineNumber,
274
- position.column,
275
- position.lineNumber,
276
- position.column + insertText.length + textAfterCursor.length,
277
- ),
278
- sessionId: rs.sessionId,
279
- relationId,
280
- command: {
281
- id: AI_INLINE_COMPLETION_REPORTER.id,
282
- title: '',
283
- arguments: [relationId, rs.sessionId, true],
284
- },
285
- });
286
- }
287
- return result;
288
- }
289
-
290
- dispose() {
291
- this._disposables.dispose();
292
- }
293
-
294
- cancelRequest() {
295
- this.isCancelFlag = true;
296
- this.dispose();
297
- }
298
- }
299
-
300
18
  class ReqStack {
301
- queue: CompletionRequestTask[];
19
+ queue: InlineCompletionRequestTask[];
302
20
  constructor() {
303
21
  this.queue = [];
304
22
  }
305
- addReq(reqRequest: CompletionRequestTask) {
23
+ addReq(reqRequest: InlineCompletionRequestTask) {
306
24
  this.queue.push(reqRequest);
307
25
  }
308
26
  runReq() {
@@ -414,7 +132,7 @@ export class AIInlineCompletionsProvider extends WithEventBus {
414
132
  this.updateIsManual(false);
415
133
 
416
134
  // 放入队列
417
- const requestImp = this.injector.get(CompletionRequestTask, [model, position, token, _isManual]);
135
+ const requestImp = this.injector.get(InlineCompletionRequestTask, [model, position, token]);
418
136
 
419
137
  this.reqStack.addReq(requestImp);
420
138
 
@@ -3,15 +3,22 @@ import debounce from 'lodash/debounce';
3
3
  import { Autowired, Injectable } from '@opensumi/di';
4
4
  import { IDisposable } from '@opensumi/ide-core-browser';
5
5
  import { AI_INLINE_COMPLETION_VISIBLE } from '@opensumi/ide-core-browser/lib/ai-native/command';
6
- import { CommandServiceImpl, Disposable, IEventBus, Sequencer, runWhenIdle } from '@opensumi/ide-core-common';
7
- import { CommandRegistry, CommandRegistryImpl, CommandService } from '@opensumi/ide-core-common';
6
+ import {
7
+ CommandService,
8
+ CommandServiceImpl,
9
+ Disposable,
10
+ IEventBus,
11
+ Sequencer,
12
+ runWhenIdle,
13
+ } from '@opensumi/ide-core-common';
8
14
  import { EditorSelectionChangeEvent, IEditor } from '@opensumi/ide-editor/lib/browser';
9
15
  import { InlineCompletions, Position, Range } from '@opensumi/ide-monaco';
10
16
  import { monacoApi } from '@opensumi/ide-monaco/lib/browser/monaco-api';
11
17
  import { InlineCompletionContextKeys } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys';
12
18
 
13
- import { IAIMiddleware } from '../../types';
14
19
  import { IAIMonacoContribHandler } from '../base';
20
+ import { IIntelligentCompletionsResult } from '../intelligent-completions/intelligent-completions';
21
+ import { IntelligentCompletionsHandler } from '../intelligent-completions/intelligent-completions.handler';
15
22
 
16
23
  import { AIInlineCompletionsProvider } from './completeProvider';
17
24
  import { AICompletionsService } from './service/ai-completions.service';
@@ -24,12 +31,12 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
24
31
  @Autowired(CommandService)
25
32
  private commandService: CommandServiceImpl;
26
33
 
27
- @Autowired(CommandRegistry)
28
- private commandRegistry: CommandRegistryImpl;
29
-
30
34
  @Autowired(AIInlineCompletionsProvider)
31
35
  private readonly aiInlineCompletionsProvider: AIInlineCompletionsProvider;
32
36
 
37
+ @Autowired(IntelligentCompletionsHandler)
38
+ private readonly intelligentCompletionsHandler: IntelligentCompletionsHandler;
39
+
33
40
  @Autowired(AICompletionsService)
34
41
  private aiCompletionsService: AICompletionsService;
35
42
 
@@ -86,18 +93,6 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
86
93
  return this;
87
94
  }
88
95
 
89
- updateConfig(middlewares: IAIMiddleware[]) {
90
- const middleware = middlewares[middlewares.length - 1];
91
- if (!middleware) {
92
- return;
93
- }
94
-
95
- // currently only support one middleware
96
- if (middleware?.language?.provideInlineCompletions) {
97
- this.aiCompletionsService.setMiddlewareComplete(middleware?.language?.provideInlineCompletions);
98
- }
99
- }
100
-
101
96
  mountEditor(editor: IEditor) {
102
97
  const toDispose = new Disposable();
103
98
  this.aiInlineCompletionsProvider.mountEditor(editor);
@@ -135,8 +130,6 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
135
130
  return;
136
131
  }
137
132
 
138
- let resultList: InlineCompletions;
139
-
140
133
  /**
141
134
  * 如果新字符在 inline completion 的 ghost text 内,则走缓存,不重新请求
142
135
  */
@@ -153,11 +146,11 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
153
146
  }
154
147
  }
155
148
 
156
- resultList = await this.sequencer.queue(() =>
149
+ const completionsResult: IIntelligentCompletionsResult = await this.sequencer.queue(() =>
157
150
  this.aiInlineCompletionsProvider.provideInlineCompletionItems(model, position, context, token),
158
151
  );
159
152
 
160
- return resultList;
153
+ return completionsResult;
161
154
  },
162
155
  freeInlineCompletions() {},
163
156
  handleItemDidShow: (completions) => {
@@ -1,6 +1,7 @@
1
- import { IAICompletionResultModel } from '@opensumi/ide-core-common';
2
1
  import * as monaco from '@opensumi/ide-monaco';
3
2
 
3
+ import { IIntelligentCompletionsResult } from '../../intelligent-completions/intelligent-completions';
4
+
4
5
  /**
5
6
  * 缓存的结果
6
7
  */
@@ -48,7 +49,7 @@ export interface CompletionResultModelCache {
48
49
  /**
49
50
  * 缓存结果
50
51
  */
51
- completionResultModel: IAICompletionResultModel | null;
52
+ completionResultModel: IIntelligentCompletionsResult | null;
52
53
  }
53
54
 
54
55
  /**
@@ -0,0 +1,272 @@
1
+ import { Autowired, Injectable } from '@opensumi/di';
2
+ import { AppConfig, PreferenceService } from '@opensumi/ide-core-browser';
3
+ import { AI_INLINE_COMPLETION_REPORTER } from '@opensumi/ide-core-browser/lib/ai-native/command';
4
+ import { AINativeSettingSectionsId, Disposable, DisposableStore, URI } from '@opensumi/ide-core-common';
5
+ import { IAICompletionOption, uuid } from '@opensumi/ide-core-common';
6
+ import { IAICompletionResultModel } from '@opensumi/ide-core-common';
7
+ import { AISerivceType, IAIReporter } from '@opensumi/ide-core-common/lib/types/ai-native/reporter';
8
+ import * as monaco from '@opensumi/ide-monaco';
9
+
10
+ import { IIntelligentCompletionsResult } from '../../intelligent-completions/intelligent-completions';
11
+ import { InlineCompletionItem } from '../model/competionModel';
12
+ import { PromptCache } from '../promptCache';
13
+ import { lineBasedPromptProcessor } from '../provider';
14
+ import { AICompletionsService } from '../service/ai-completions.service';
15
+ import { ICompletionContext } from '../types';
16
+
17
+ const makeHashSet = (str: string) => {
18
+ const set = new Set<string>();
19
+ for (const char of str) {
20
+ set.add(char);
21
+ }
22
+ return set;
23
+ };
24
+
25
+ const removeChars = (insertText: string, textAfterCursor: string) => {
26
+ let result = '';
27
+ const aSet = makeHashSet(insertText);
28
+ for (const char of textAfterCursor) {
29
+ // 如果是空格或者 insertText 中不存在的字符,就加入到结果中
30
+ if (char === ' ' || !aSet.has(char)) {
31
+ result += char;
32
+ }
33
+ }
34
+ return result;
35
+ };
36
+
37
+ @Injectable({ multiple: true })
38
+ export class InlineCompletionRequestTask extends Disposable {
39
+ private _disposables = new DisposableStore();
40
+
41
+ @Autowired(IAIReporter)
42
+ private aiReporter: IAIReporter;
43
+
44
+ @Autowired(PromptCache)
45
+ private promptCache: PromptCache;
46
+
47
+ @Autowired(AICompletionsService)
48
+ private aiCompletionsService: AICompletionsService;
49
+
50
+ @Autowired(PreferenceService)
51
+ private readonly preferenceService: PreferenceService;
52
+
53
+ @Autowired(AppConfig)
54
+ private appConfig: AppConfig;
55
+
56
+ isCancelFlag: boolean;
57
+
58
+ private isEnablePromptEngineering = true;
59
+
60
+ constructor(
61
+ public model: monaco.editor.ITextModel,
62
+ public position: monaco.Position,
63
+ public token: monaco.CancellationToken,
64
+ ) {
65
+ super();
66
+
67
+ this.isCancelFlag = false;
68
+
69
+ this.isEnablePromptEngineering = this.preferenceService.getValid(
70
+ AINativeSettingSectionsId.InlineCompletionsPromptEngineeringEnabled,
71
+ this.isEnablePromptEngineering,
72
+ );
73
+
74
+ this._disposables.add(
75
+ this.preferenceService.onSpecificPreferenceChange(
76
+ AINativeSettingSectionsId.InlineCompletionsPromptEngineeringEnabled,
77
+ ({ newValue }) => {
78
+ this.isEnablePromptEngineering = newValue;
79
+ },
80
+ ),
81
+ );
82
+ }
83
+
84
+ protected async constructRequestBean(
85
+ context: ICompletionContext,
86
+ token: monaco.CancellationToken,
87
+ ): Promise<IAICompletionOption> {
88
+ const prompt = lineBasedPromptProcessor.processPrefix(context.prefix);
89
+ const suffix = lineBasedPromptProcessor.processSuffix(context.suffix);
90
+ return {
91
+ prompt,
92
+ suffix,
93
+ sessionId: uuid(),
94
+ language: context.language,
95
+ fileUrl: context.fileUrl,
96
+ workspaceDir: context.workspaceDir,
97
+ };
98
+ }
99
+
100
+ // 发送请求
101
+ async run() {
102
+ const { model, position, token } = this;
103
+ if (!model) {
104
+ return [];
105
+ }
106
+ if (token.isCancellationRequested) {
107
+ return [];
108
+ }
109
+
110
+ if (this.isCancelFlag) {
111
+ return [];
112
+ }
113
+
114
+ const startRange = new monaco.Range(0, 0, position.lineNumber, position.column);
115
+ let prefix = model.getValueInRange(startRange);
116
+ if (prefix === '') {
117
+ prefix += '\n';
118
+ }
119
+
120
+ const endRange = new monaco.Range(
121
+ position.lineNumber,
122
+ position.column,
123
+ model.getLineCount(),
124
+ Number.MAX_SAFE_INTEGER,
125
+ );
126
+
127
+ const suffix = model.getValueInRange(endRange);
128
+
129
+ const languageId = model.getLanguageId();
130
+ const context: ICompletionContext = {
131
+ fileUrl: model.uri.fsPath,
132
+ filename: model.uri.toString().split('/').pop()!,
133
+ language: languageId,
134
+ prefix,
135
+ suffix,
136
+ uri: URI.from(model.uri),
137
+ workspaceDir: this.appConfig.workspaceDir,
138
+ };
139
+
140
+ // 组装请求参数,向远程发起请求
141
+ const requestBean = await this.constructRequestBean(context, token);
142
+ if (this.isCancelFlag) {
143
+ return [];
144
+ }
145
+
146
+ this.aiCompletionsService.updateStatusBarItem('running', true);
147
+ const requestStartTime = Date.now();
148
+
149
+ let completeResult: IIntelligentCompletionsResult | undefined;
150
+ const cacheData = this.promptCache.getCache(requestBean);
151
+ const relationId =
152
+ cacheData?.relationId || this.aiReporter.start(AISerivceType.Completion, { message: AISerivceType.Completion });
153
+
154
+ this.aiCompletionsService.setLastRelationId(relationId);
155
+ // 如果存在缓存
156
+ if (cacheData) {
157
+ completeResult = cacheData;
158
+ } else {
159
+ try {
160
+ completeResult = await this.aiCompletionsService.complete(requestBean);
161
+ } catch (error) {
162
+ this.aiCompletionsService.reporterEnd(relationId, {
163
+ success: false,
164
+ replytime: Date.now() - requestStartTime,
165
+ message: error.toString(),
166
+ });
167
+ this.aiCompletionsService.hideStatusBarItem();
168
+ return [];
169
+ }
170
+ }
171
+
172
+ if (!completeResult) {
173
+ return [];
174
+ }
175
+
176
+ return this.pushLineCompletions(completeResult, requestBean, requestStartTime, relationId);
177
+ }
178
+
179
+ /**
180
+ * 将补全结果推给用户并注册{@link COMMAND_ACCEPT} 事件
181
+ */
182
+ private pushLineCompletions(
183
+ completeResult: IIntelligentCompletionsResult<IAICompletionResultModel> | undefined,
184
+ requestBean: IAICompletionOption,
185
+ requestStartTime: number,
186
+ relationId: string,
187
+ ): Array<InlineCompletionItem> {
188
+ const { position } = this;
189
+
190
+ this.aiCompletionsService.setLastSessionId(requestBean.sessionId);
191
+
192
+ // 如果是取消直接返回
193
+ if (completeResult?.extra?.isCancel || this.token.isCancellationRequested || this.isCancelFlag) {
194
+ this.aiCompletionsService.reporterEnd(relationId, {
195
+ success: true,
196
+ replytime: Date.now() - requestStartTime,
197
+ isStop: true,
198
+ completionNum: 0,
199
+ });
200
+ this.aiCompletionsService.updateStatusBarItem('canceled', false);
201
+ return [];
202
+ }
203
+
204
+ // 返回补全结果为空直接返回
205
+ if (!completeResult || !completeResult.items || completeResult.items.length === 0) {
206
+ this.aiCompletionsService.reporterEnd(relationId, {
207
+ success: true,
208
+ replytime: Date.now() - requestStartTime,
209
+ completionNum: 0,
210
+ });
211
+ this.aiCompletionsService.updateStatusBarItem('no result', false);
212
+ return [];
213
+ }
214
+
215
+ if (completeResult.items.length > 0) {
216
+ this.promptCache.setCache(requestBean, { ...completeResult, relationId });
217
+ }
218
+
219
+ this.aiCompletionsService.updateStatusBarItem('completion result: ' + completeResult.items.length, false);
220
+
221
+ this.dispose();
222
+
223
+ const result = new Array<InlineCompletionItem>();
224
+ for (const codeModel of completeResult.items) {
225
+ const contentText = codeModel.insertText.toString();
226
+
227
+ const insertText = contentText.trimEnd();
228
+
229
+ const model = this.model;
230
+
231
+ const textAfterCursor = model.getValueInRange({
232
+ startLineNumber: position.lineNumber,
233
+ startColumn: position.column,
234
+ endLineNumber: position.lineNumber,
235
+ endColumn: model.getLineMaxColumn(position.lineNumber),
236
+ });
237
+
238
+ // 临时修复方案,用于解决补全后面多了几个括号的问题
239
+ const filteredString = removeChars(insertText, textAfterCursor);
240
+
241
+ this.aiCompletionsService.setLastCompletionContent(filteredString);
242
+
243
+ result.push({
244
+ ...codeModel,
245
+ insertText: insertText + filteredString,
246
+ range: new monaco.Range(
247
+ position.lineNumber,
248
+ position.column,
249
+ position.lineNumber,
250
+ position.column + insertText.length + textAfterCursor.length,
251
+ ),
252
+ sessionId: requestBean.sessionId,
253
+ relationId,
254
+ command: {
255
+ id: AI_INLINE_COMPLETION_REPORTER.id,
256
+ title: '',
257
+ arguments: [relationId, requestBean.sessionId, true, filteredString],
258
+ },
259
+ });
260
+ }
261
+ return result;
262
+ }
263
+
264
+ dispose() {
265
+ this._disposables.dispose();
266
+ }
267
+
268
+ cancelRequest() {
269
+ this.isCancelFlag = true;
270
+ this.dispose();
271
+ }
272
+ }