@opensumi/ide-ai-native 3.1.2-next-1718960862.0 → 3.1.2

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 (126) hide show
  1. package/lib/browser/ai-core.contribution.d.ts +0 -1
  2. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contribution.js +11 -26
  4. package/lib/browser/ai-core.contribution.js.map +1 -1
  5. package/lib/browser/ai-editor.contribution.d.ts +1 -10
  6. package/lib/browser/ai-editor.contribution.d.ts.map +1 -1
  7. package/lib/browser/ai-editor.contribution.js +16 -81
  8. package/lib/browser/ai-editor.contribution.js.map +1 -1
  9. package/lib/browser/contextkey/ai-native.contextkey.service.d.ts +0 -2
  10. package/lib/browser/contextkey/ai-native.contextkey.service.d.ts.map +1 -1
  11. package/lib/browser/contextkey/ai-native.contextkey.service.js +0 -2
  12. package/lib/browser/contextkey/ai-native.contextkey.service.js.map +1 -1
  13. package/lib/browser/contrib/code-action/code-action.handler.d.ts.map +1 -1
  14. package/lib/browser/contrib/code-action/code-action.handler.js +0 -5
  15. package/lib/browser/contrib/code-action/code-action.handler.js.map +1 -1
  16. package/lib/browser/contrib/inline-completions/completeProvider.d.ts +0 -2
  17. package/lib/browser/contrib/inline-completions/completeProvider.d.ts.map +1 -1
  18. package/lib/browser/contrib/inline-completions/completeProvider.js +9 -18
  19. package/lib/browser/contrib/inline-completions/completeProvider.js.map +1 -1
  20. package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts +4 -0
  21. package/lib/browser/contrib/inline-completions/inline-completions.handler.d.ts.map +1 -1
  22. package/lib/browser/contrib/inline-completions/inline-completions.handler.js +51 -11
  23. package/lib/browser/contrib/inline-completions/inline-completions.handler.js.map +1 -1
  24. package/lib/browser/contrib/inline-completions/model/competionModel.d.ts +1 -0
  25. package/lib/browser/contrib/inline-completions/model/competionModel.d.ts.map +1 -1
  26. package/lib/browser/contrib/inline-completions/promptCache.d.ts +3 -1
  27. package/lib/browser/contrib/inline-completions/promptCache.d.ts.map +1 -1
  28. package/lib/browser/contrib/inline-completions/promptCache.js.map +1 -1
  29. package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts +2 -5
  30. package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts.map +1 -1
  31. package/lib/browser/contrib/inline-completions/service/ai-completions.service.js +9 -11
  32. package/lib/browser/contrib/inline-completions/service/ai-completions.service.js.map +1 -1
  33. package/lib/browser/layout/ai-layout.js +1 -1
  34. package/lib/browser/layout/ai-layout.js.map +1 -1
  35. package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
  36. package/lib/browser/layout/tabbar.view.js +2 -2
  37. package/lib/browser/layout/tabbar.view.js.map +1 -1
  38. package/lib/browser/types.d.ts +4 -26
  39. package/lib/browser/types.d.ts.map +1 -1
  40. package/lib/browser/types.js +1 -5
  41. package/lib/browser/types.js.map +1 -1
  42. package/lib/browser/widget/inline-chat/inline-chat-controller.js +1 -1
  43. package/lib/browser/widget/inline-chat/inline-chat-controller.js.map +1 -1
  44. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts +1 -6
  45. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts.map +1 -1
  46. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js +6 -29
  47. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js.map +1 -1
  48. package/lib/browser/widget/inline-chat/inline-chat.handler.d.ts +1 -0
  49. package/lib/browser/widget/inline-chat/inline-chat.handler.d.ts.map +1 -1
  50. package/lib/browser/widget/inline-chat/inline-chat.handler.js +26 -27
  51. package/lib/browser/widget/inline-chat/inline-chat.handler.js.map +1 -1
  52. package/lib/browser/widget/inline-chat/inline-chat.module.less +2 -2
  53. package/lib/browser/widget/inline-chat/inline-chat.service.d.ts +14 -6
  54. package/lib/browser/widget/inline-chat/inline-chat.service.d.ts.map +1 -1
  55. package/lib/browser/widget/inline-chat/inline-chat.service.js +25 -0
  56. package/lib/browser/widget/inline-chat/inline-chat.service.js.map +1 -1
  57. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +18 -15
  58. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
  59. package/lib/browser/widget/inline-chat/inline-content-widget.js +54 -41
  60. package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
  61. package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts +1 -1
  62. package/lib/browser/widget/inline-diff/inline-diff-widget.d.ts.map +1 -1
  63. package/lib/browser/widget/inline-diff/inline-diff-widget.js.map +1 -1
  64. package/lib/browser/widget/light-bulb/index.d.ts.map +1 -1
  65. package/lib/browser/widget/light-bulb/index.js +3 -2
  66. package/lib/browser/widget/light-bulb/index.js.map +1 -1
  67. package/package.json +19 -19
  68. package/src/browser/ai-core.contribution.ts +13 -29
  69. package/src/browser/ai-editor.contribution.ts +29 -104
  70. package/src/browser/contextkey/ai-native.contextkey.service.ts +1 -10
  71. package/src/browser/contrib/code-action/code-action.handler.ts +0 -6
  72. package/src/browser/contrib/inline-completions/completeProvider.ts +21 -27
  73. package/src/browser/contrib/inline-completions/inline-completions.handler.ts +57 -13
  74. package/src/browser/contrib/inline-completions/model/competionModel.ts +1 -0
  75. package/src/browser/contrib/inline-completions/promptCache.ts +1 -1
  76. package/src/browser/contrib/inline-completions/service/ai-completions.service.ts +9 -18
  77. package/src/browser/layout/ai-layout.tsx +1 -1
  78. package/src/browser/layout/tabbar.view.tsx +1 -2
  79. package/src/browser/types.ts +3 -25
  80. package/src/browser/widget/inline-chat/inline-chat-controller.ts +1 -1
  81. package/src/browser/widget/inline-chat/inline-chat.feature.registry.ts +8 -34
  82. package/src/browser/widget/inline-chat/inline-chat.handler.ts +36 -35
  83. package/src/browser/widget/inline-chat/inline-chat.module.less +2 -2
  84. package/src/browser/widget/inline-chat/inline-chat.service.ts +33 -8
  85. package/src/browser/widget/inline-chat/inline-content-widget.tsx +66 -65
  86. package/src/browser/widget/inline-diff/inline-diff-widget.tsx +2 -1
  87. package/src/browser/widget/light-bulb/index.ts +2 -1
  88. package/lib/browser/widget/inline-actions/result-items/index.d.ts +0 -7
  89. package/lib/browser/widget/inline-actions/result-items/index.d.ts.map +0 -1
  90. package/lib/browser/widget/inline-actions/result-items/index.js +0 -31
  91. package/lib/browser/widget/inline-actions/result-items/index.js.map +0 -1
  92. package/lib/browser/widget/inline-hint/inline-hint-line-widget.d.ts +0 -11
  93. package/lib/browser/widget/inline-hint/inline-hint-line-widget.d.ts.map +0 -1
  94. package/lib/browser/widget/inline-hint/inline-hint-line-widget.js +0 -43
  95. package/lib/browser/widget/inline-hint/inline-hint-line-widget.js.map +0 -1
  96. package/lib/browser/widget/inline-hint/inline-hint.handler.d.ts +0 -10
  97. package/lib/browser/widget/inline-hint/inline-hint.handler.d.ts.map +0 -1
  98. package/lib/browser/widget/inline-hint/inline-hint.handler.js +0 -96
  99. package/lib/browser/widget/inline-hint/inline-hint.handler.js.map +0 -1
  100. package/lib/browser/widget/inline-hint/inline-hint.module.less +0 -15
  101. package/lib/browser/widget/inline-input/inline-input-widget.d.ts +0 -11
  102. package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +0 -1
  103. package/lib/browser/widget/inline-input/inline-input-widget.js +0 -77
  104. package/lib/browser/widget/inline-input/inline-input-widget.js.map +0 -1
  105. package/lib/browser/widget/inline-input/inline-input.handler.d.ts +0 -14
  106. package/lib/browser/widget/inline-input/inline-input.handler.d.ts.map +0 -1
  107. package/lib/browser/widget/inline-input/inline-input.handler.js +0 -198
  108. package/lib/browser/widget/inline-input/inline-input.handler.js.map +0 -1
  109. package/lib/browser/widget/inline-input/inline-input.module.less +0 -7
  110. package/lib/browser/widget/inline-input/inline-input.service.d.ts +0 -11
  111. package/lib/browser/widget/inline-input/inline-input.service.d.ts.map +0 -1
  112. package/lib/browser/widget/inline-input/inline-input.service.js +0 -29
  113. package/lib/browser/widget/inline-input/inline-input.service.js.map +0 -1
  114. package/lib/browser/widget/internal.type.d.ts +0 -5
  115. package/lib/browser/widget/internal.type.d.ts.map +0 -1
  116. package/lib/browser/widget/internal.type.js +0 -8
  117. package/lib/browser/widget/internal.type.js.map +0 -1
  118. package/src/browser/widget/inline-actions/result-items/index.tsx +0 -40
  119. package/src/browser/widget/inline-hint/inline-hint-line-widget.tsx +0 -41
  120. package/src/browser/widget/inline-hint/inline-hint.handler.ts +0 -127
  121. package/src/browser/widget/inline-hint/inline-hint.module.less +0 -15
  122. package/src/browser/widget/inline-input/inline-input-widget.tsx +0 -122
  123. package/src/browser/widget/inline-input/inline-input.handler.ts +0 -276
  124. package/src/browser/widget/inline-input/inline-input.module.less +0 -7
  125. package/src/browser/widget/inline-input/inline-input.service.ts +0 -25
  126. package/src/browser/widget/internal.type.ts +0 -4
@@ -1,18 +1,14 @@
1
1
  import { Autowired, Injectable } from '@opensumi/di';
2
2
  import { AINativeConfigService } from '@opensumi/ide-core-browser';
3
3
  import { IBrowserCtxMenu } from '@opensumi/ide-core-browser/lib/menu/next/renderer/ctxmenu/browser';
4
- import { Disposable, Event, IDisposable, InlineChatFeatureRegistryToken, Schemes } from '@opensumi/ide-core-common';
4
+ import { Disposable, Event, IDisposable, Schemes } from '@opensumi/ide-core-common';
5
5
  import { DesignBrowserCtxMenuService } from '@opensumi/ide-design/lib/browser/override/menu.service';
6
- import { EditorCollectionService, IEditorDocumentModelRef } from '@opensumi/ide-editor';
7
6
  import { IEditor, IEditorFeatureContribution } from '@opensumi/ide-editor/lib/browser';
8
- import { BrowserCodeEditor, BrowserDiffEditor } from '@opensumi/ide-editor/lib/browser/editor-collection.service';
7
+ import { BrowserCodeEditor } from '@opensumi/ide-editor/lib/browser/editor-collection.service';
9
8
 
10
9
  import { CodeActionHandler } from './contrib/code-action/code-action.handler';
11
10
  import { InlineCompletionHandler } from './contrib/inline-completions/inline-completions.handler';
12
- import { InlineChatFeatureRegistry } from './widget/inline-chat/inline-chat.feature.registry';
13
11
  import { InlineChatHandler } from './widget/inline-chat/inline-chat.handler';
14
- import { InlineHintHandler } from './widget/inline-hint/inline-hint.handler';
15
- import { InlineInputHandler } from './widget/inline-input/inline-input.handler';
16
12
 
17
13
  @Injectable()
18
14
  export class AIEditorContribution extends Disposable implements IEditorFeatureContribution {
@@ -25,135 +21,64 @@ export class AIEditorContribution extends Disposable implements IEditorFeatureCo
25
21
  @Autowired(InlineChatHandler)
26
22
  private readonly inlineChatHandler: InlineChatHandler;
27
23
 
28
- @Autowired(InlineHintHandler)
29
- private readonly inlineHintHandler: InlineHintHandler;
30
-
31
- @Autowired(InlineInputHandler)
32
- private readonly inlineInputHandler: InlineInputHandler;
33
-
34
24
  @Autowired(CodeActionHandler)
35
25
  private readonly codeActionHandler: CodeActionHandler;
36
26
 
37
27
  @Autowired(InlineCompletionHandler)
38
28
  private readonly inlineCompletionHandler: InlineCompletionHandler;
39
29
 
40
- @Autowired(EditorCollectionService)
41
- private readonly editorCollectionService: EditorCollectionService;
42
-
43
- @Autowired(InlineChatFeatureRegistryToken)
44
- private readonly inlineChatFeatureRegistry: InlineChatFeatureRegistry;
45
-
46
30
  private modelSessionDisposable: Disposable;
47
- private editorReady: boolean = false;
48
- private diffEditorReady: boolean = false;
31
+ private initialized: boolean = false;
49
32
 
50
33
  dispose(): void {
51
34
  super.dispose();
52
- this.editorReady = false;
35
+ this.initialized = false;
53
36
  if (this.modelSessionDisposable) {
54
37
  this.modelSessionDisposable.dispose();
55
38
  }
56
39
  }
57
40
 
58
41
  contribute(editor: IEditor): IDisposable {
59
- if (this.editorReady) {
42
+ if (!(editor instanceof BrowserCodeEditor) || this.initialized) {
60
43
  return this;
61
44
  }
62
- this.handleDiffEditorCreated();
63
- if (editor instanceof BrowserCodeEditor) {
64
- this.disposables.push(
65
- editor.onRefOpen((e) => {
66
- this.disposables.push(...this.handleBrowserEditor(editor, e));
67
- }),
68
- );
69
- }
70
- return this;
71
- }
72
-
73
- private handleDiffEditorCreated() {
74
- Event.once(this.editorCollectionService.onDiffEditorCreate)((editor) => {
75
- this.disposables.push(
76
- editor.onRefOpen((e) => {
77
- this.disposables.push(...this.handleDiffEditor(editor as any, e));
78
- }),
79
- );
80
- });
81
- }
82
-
83
- private handleBrowserEditor(editor: BrowserCodeEditor, e: IEditorDocumentModelRef): IDisposable[] {
84
- const disposables: IDisposable[] = [];
85
- const { monacoEditor } = editor;
86
-
87
- const { uri } = e.instance;
88
- if (uri.codeUri.scheme !== Schemes.file || this.editorReady) {
89
- return disposables;
90
- }
91
45
 
92
- this.editorReady = true;
46
+ this.disposables.push(
47
+ editor.onRefOpen((e) => {
48
+ const { uri } = e.instance;
49
+ if (uri.codeUri.scheme !== Schemes.file || this.initialized) {
50
+ return;
51
+ }
93
52
 
94
- disposables.push(
95
- Event.debounce(
96
- monacoEditor.onWillChangeModel,
97
- (_, e) => e,
98
- 150,
99
- )(() => {
53
+ this.initialized = true;
54
+
55
+ this.addDispose(
56
+ Event.debounce(
57
+ monacoEditor.onWillChangeModel,
58
+ (_, e) => e,
59
+ 150,
60
+ )(() => {
61
+ this.mount(editor);
62
+ }),
63
+ );
100
64
  this.mount(editor);
65
+
66
+ this.addDispose(this.inlineCompletionHandler.registerInlineCompletionFeature(editor));
67
+ this.addDispose(this.inlineChatHandler.registerInlineChatFeature(editor));
101
68
  }),
102
69
  );
103
- this.mount(editor);
104
70
 
105
- disposables.push(...this.registerFeatures(editor));
106
- disposables.push(
71
+ const { monacoEditor } = editor;
72
+
73
+ this.disposables.push(
107
74
  monacoEditor.onDidScrollChange(() => {
108
75
  if (this.ctxMenuRenderer.visible) {
109
76
  this.ctxMenuRenderer.hide(true);
110
77
  }
111
78
  }),
112
79
  );
113
- return disposables;
114
- }
115
-
116
- private handleDiffEditor(editor: BrowserDiffEditor, e: IEditorDocumentModelRef): IDisposable[] {
117
- const disposables: IDisposable[] = [];
118
- const { monacoDiffEditor } = editor;
119
-
120
- const { uri } = e.instance;
121
- if (uri.codeUri.scheme !== Schemes.file || this.diffEditorReady) {
122
- return disposables;
123
- }
124
-
125
- this.diffEditorReady = true;
126
80
 
127
- disposables.push(
128
- Event.debounce(
129
- monacoDiffEditor.onDidUpdateDiff,
130
- (_, e) => e,
131
- 150,
132
- )(() => {
133
- this.mount(editor.modifiedEditor);
134
- this.mount(editor.originalEditor);
135
- }),
136
- );
137
- this.mount(editor.modifiedEditor);
138
- this.mount(editor.originalEditor);
139
-
140
- disposables.push(...this.registerFeatures(editor.modifiedEditor, true));
141
- disposables.push(...this.registerFeatures(editor.originalEditor, true));
142
- return disposables;
143
- }
144
-
145
- private registerFeatures(editor: IEditor, isDiffEditor = false) {
146
- const disposables: IDisposable[] = [];
147
- if (!isDiffEditor) {
148
- disposables.push(this.inlineCompletionHandler.registerInlineCompletionFeature(editor));
149
- }
150
- disposables.push(this.inlineChatHandler.registerInlineChatFeature(editor));
151
-
152
- if (this.inlineChatFeatureRegistry.getInteractiveInputHandler() && !isDiffEditor) {
153
- this.addDispose(this.inlineHintHandler.registerHintLineFeature(editor));
154
- this.addDispose(this.inlineInputHandler.registerInlineInputFeature(editor));
155
- }
156
- return disposables;
81
+ return this;
157
82
  }
158
83
 
159
84
  private async mount(editor: IEditor): Promise<void> {
@@ -1,11 +1,6 @@
1
1
  import { Autowired, Injectable, Optional } from '@opensumi/di';
2
2
  import { IContextKey, IContextKeyService, IScopedContextKeyService } from '@opensumi/ide-core-browser';
3
- import {
4
- InlineChatIsVisible,
5
- InlineCompletionIsTrigger,
6
- InlineHintWidgetIsVisible,
7
- InlineInputWidgetIsVisible,
8
- } from '@opensumi/ide-core-browser/lib/contextkey/ai-native';
3
+ import { InlineChatIsVisible, InlineCompletionIsTrigger } from '@opensumi/ide-core-browser/lib/contextkey/ai-native';
9
4
  import { ContextKeyService } from '@opensumi/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService';
10
5
  import { IContextKeyServiceTarget } from '@opensumi/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey';
11
6
 
@@ -18,14 +13,10 @@ export class AINativeContextKey {
18
13
 
19
14
  public readonly inlineChatIsVisible: IContextKey<boolean>;
20
15
  public readonly inlineCompletionIsTrigger: IContextKey<boolean>;
21
- public readonly inlineHintWidgetIsVisible: IContextKey<boolean>;
22
- public readonly inlineInputWidgetIsVisible: IContextKey<boolean>;
23
16
 
24
17
  constructor(@Optional() dom?: HTMLElement | IContextKeyServiceTarget | ContextKeyService) {
25
18
  this._contextKeyService = this.globalContextKeyService.createScoped(dom);
26
19
  this.inlineChatIsVisible = InlineChatIsVisible.bind(this._contextKeyService);
27
20
  this.inlineCompletionIsTrigger = InlineCompletionIsTrigger.bind(this._contextKeyService);
28
- this.inlineHintWidgetIsVisible = InlineHintWidgetIsVisible.bind(this._contextKeyService);
29
- this.inlineInputWidgetIsVisible = InlineInputWidgetIsVisible.bind(this._contextKeyService);
30
21
  }
31
22
  }
@@ -3,7 +3,6 @@ import { PreferenceService } from '@opensumi/ide-core-browser';
3
3
  import { AINativeSettingSectionsId } from '@opensumi/ide-core-common';
4
4
  import * as monaco from '@opensumi/ide-monaco';
5
5
  import { languageFeaturesService } from '@opensumi/ide-monaco/lib/browser/monaco-api/languages';
6
- import { empty } from '@opensumi/ide-utils/lib/strings';
7
6
 
8
7
  import { LanguageParserService } from '../../languages/service';
9
8
  import { ICodeBlockInfo } from '../../languages/tree-sitter/language-facts/base';
@@ -54,11 +53,6 @@ export class CodeActionHandler extends IAIMonacoContribHandler {
54
53
  return;
55
54
  }
56
55
 
57
- const content = model.getLineContent(range.startLineNumber);
58
- if (content?.trim() === empty) {
59
- return;
60
- }
61
-
62
56
  const needStop = this.intercept(model.uri);
63
57
  if (needStop) {
64
58
  return;
@@ -1,14 +1,20 @@
1
1
  import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
2
2
  import { PreferenceService } from '@opensumi/ide-core-browser';
3
3
  import { AI_INLINE_COMPLETION_REPORTER } from '@opensumi/ide-core-browser/lib/ai-native/command';
4
- import { AINativeSettingSectionsId, DisposableStore, URI, WithEventBus, sleep, uuid } from '@opensumi/ide-core-common';
4
+ import {
5
+ AINativeSettingSectionsId,
6
+ DisposableStore,
7
+ URI,
8
+ WithEventBus,
9
+ raceCancellation,
10
+ sleep,
11
+ uuid,
12
+ } from '@opensumi/ide-core-common';
5
13
  import { IAICompletionResultModel } from '@opensumi/ide-core-common/lib/types/ai-native';
6
14
  import { AISerivceType, IAIReporter } from '@opensumi/ide-core-common/lib/types/ai-native/reporter';
7
15
  import { IEditor } from '@opensumi/ide-editor';
8
16
  import * as monaco from '@opensumi/ide-monaco';
9
17
 
10
- import { AINativeContextKey } from '../../contextkey/ai-native.contextkey.service';
11
-
12
18
  import { DEFAULT_COMPLECTION_MODEL } from './constants';
13
19
  import { CompletionRequestBean, IInlineCompletionCache, InlineCompletionItem } from './model/competionModel';
14
20
  import { PromptCache } from './promptCache';
@@ -159,9 +165,6 @@ export class CompletionRequestTask {
159
165
 
160
166
  // 组装请求参数,向远程发起请求
161
167
  const completionRequestBean = await this.constructRequestBean(context, token);
162
- if (token.isCancellationRequested) {
163
- return [];
164
- }
165
168
  if (this.isCancelFlag) {
166
169
  return [];
167
170
  }
@@ -171,9 +174,10 @@ export class CompletionRequestTask {
171
174
 
172
175
  let rs: IAICompletionResultModel | null;
173
176
  const cacheData = this.promptCache.getCache(completionRequestBean.prompt);
174
- const relationId = this.aiReporter.start(AISerivceType.Completion, { message: AISerivceType.Completion });
175
- this.aiCompletionsService.setLastRelationId(relationId);
177
+ const relationId =
178
+ cacheData?.relationId || this.aiReporter.start(AISerivceType.Completion, { message: AISerivceType.Completion });
176
179
 
180
+ this.aiCompletionsService.setLastRelationId(relationId);
177
181
  // 如果存在缓存
178
182
  if (cacheData) {
179
183
  rs = cacheData;
@@ -200,7 +204,7 @@ export class CompletionRequestTask {
200
204
  this.aiCompletionsService.setLastSessionId(rs.sessionId);
201
205
 
202
206
  // 如果是取消直接返回
203
- if ((rs && rs.isCancel) || this.isCancelFlag) {
207
+ if ((rs && rs.isCancel) || token.isCancellationRequested || this.isCancelFlag) {
204
208
  this.aiCompletionsService.reporterEnd(relationId, {
205
209
  success: true,
206
210
  replytime: Date.now() - requestStartTime,
@@ -212,7 +216,7 @@ export class CompletionRequestTask {
212
216
  }
213
217
 
214
218
  if (rs && rs.codeModelList && rs.codeModelList.length > 0) {
215
- this.promptCache.setCache(completionRequestBean.prompt, rs);
219
+ this.promptCache.setCache(completionRequestBean.prompt, { ...rs, relationId });
216
220
  }
217
221
  // 返回补全结果为空直接返回
218
222
  if (rs.codeModelList.length === 0) {
@@ -266,6 +270,7 @@ export class CompletionRequestTask {
266
270
  position.column + insertText.length + textAfterCursor.length,
267
271
  ),
268
272
  sessionId: rs.sessionId,
273
+ relationId,
269
274
  command: {
270
275
  id: AI_INLINE_COMPLETION_REPORTER.id,
271
276
  title: '',
@@ -323,8 +328,6 @@ export class AIInlineCompletionsProvider extends WithEventBus {
323
328
  @Autowired(PreferenceService)
324
329
  private readonly preferenceService: PreferenceService;
325
330
 
326
- private aiNativeContextKey: AINativeContextKey;
327
-
328
331
  /**
329
332
  * 该补全是否是手动触发
330
333
  */
@@ -353,8 +356,6 @@ export class AIInlineCompletionsProvider extends WithEventBus {
353
356
  }
354
357
 
355
358
  public mountEditor(editor: IEditor): void {
356
- this.aiNativeContextKey = this.injector.get(AINativeContextKey, [(editor.monacoEditor as any)._contextKeyService]);
357
-
358
359
  this.isManual = false;
359
360
  this.isDelEvent = false;
360
361
  this.reqStack = new ReqStack();
@@ -367,10 +368,6 @@ export class AIInlineCompletionsProvider extends WithEventBus {
367
368
  }
368
369
  }
369
370
 
370
- resetContextKey() {
371
- this.aiNativeContextKey.inlineCompletionIsTrigger.reset();
372
- }
373
-
374
371
  /**
375
372
  * 用户触发编辑器后,事件的回调
376
373
  * @param document
@@ -385,8 +382,6 @@ export class AIInlineCompletionsProvider extends WithEventBus {
385
382
  context: monaco.languages.InlineCompletionContext,
386
383
  token: monaco.CancellationToken,
387
384
  ) {
388
- this.aiNativeContextKey.inlineCompletionIsTrigger.set(true);
389
-
390
385
  // bugfix: 修复当鼠标移动到代码补全上会触发一次手势事件,增加防抖,当手势触发后,能够防抖一次
391
386
  if (context.triggerKind === monaco.InlineCompletionTriggerKind.Automatic) {
392
387
  if (
@@ -412,12 +407,6 @@ export class AIInlineCompletionsProvider extends WithEventBus {
412
407
  // 重置防止不触发自动补全事件
413
408
  this.updateIsManual(false);
414
409
 
415
- // 如果用户已取消
416
- if (token?.isCancellationRequested) {
417
- this.aiCompletionsService.updateStatusBarItem('cancelled ', false);
418
- return undefined;
419
- }
420
-
421
410
  // 放入队列
422
411
  const requestImp = this.injector.get(CompletionRequestTask, [model, position, token, _isManual]);
423
412
 
@@ -425,7 +414,12 @@ export class AIInlineCompletionsProvider extends WithEventBus {
425
414
 
426
415
  // 如果是自动补全需要 debounce
427
416
  if (!_isManual) {
428
- await sleep(this.inlineComletionsDebounceTime);
417
+ await raceCancellation(sleep(this.inlineComletionsDebounceTime), token);
418
+ }
419
+
420
+ // 如果用户已取消
421
+ if (token?.isCancellationRequested) {
422
+ return undefined;
429
423
  }
430
424
 
431
425
  const list = await this.reqStack.runReq();
@@ -2,9 +2,13 @@ import debounce from 'lodash/debounce';
2
2
 
3
3
  import { Autowired, Injectable } from '@opensumi/di';
4
4
  import { IDisposable } from '@opensumi/ide-core-browser';
5
- import { Disposable, IEventBus, Sequencer } from '@opensumi/ide-core-common';
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
8
  import { EditorSelectionChangeEvent, IEditor } from '@opensumi/ide-editor/lib/browser';
9
+ import { InlineCompletions, Position, Range } from '@opensumi/ide-monaco';
7
10
  import { monacoApi } from '@opensumi/ide-monaco/lib/browser/monaco-api';
11
+ import { InlineCompletionContextKeys } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys';
8
12
 
9
13
  import { IAIMiddleware } from '../../types';
10
14
  import { IAIMonacoContribHandler } from '../base';
@@ -17,12 +21,21 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
17
21
  @Autowired(IEventBus)
18
22
  private eventBus: IEventBus;
19
23
 
24
+ @Autowired(CommandService)
25
+ private commandService: CommandServiceImpl;
26
+
27
+ @Autowired(CommandRegistry)
28
+ private commandRegistry: CommandRegistryImpl;
29
+
20
30
  @Autowired(AIInlineCompletionsProvider)
21
31
  private readonly aiInlineCompletionsProvider: AIInlineCompletionsProvider;
22
32
 
23
33
  @Autowired(AICompletionsService)
24
34
  private aiCompletionsService: AICompletionsService;
25
35
 
36
+ private sequencer = new Sequencer();
37
+ private preDidShowItems: InlineCompletions | undefined;
38
+
26
39
  public registerInlineCompletionFeature(editor: IEditor): IDisposable {
27
40
  const { monacoEditor } = editor;
28
41
  // 判断用户是否选择了一块区域或者移动光标 取消掉请补全求
@@ -37,9 +50,6 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
37
50
  if (selection.startLineNumber !== selection.endLineNumber || selection.startColumn !== selection.endColumn) {
38
51
  this.aiInlineCompletionsProvider.cancelRequest();
39
52
  }
40
- requestAnimationFrame(() => {
41
- this.aiCompletionsService.setVisibleCompletion(false);
42
- });
43
53
  };
44
54
 
45
55
  const debouncedSelectionChange = debounce(selectionChange, 50, {
@@ -68,12 +78,8 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
68
78
  }
69
79
  }
70
80
  }),
71
- monacoEditor.onWillChangeModel(() => {
72
- this.aiCompletionsService.hideStatusBarItem();
73
- }),
74
81
  monacoEditor.onDidBlurEditorText(() => {
75
- this.aiCompletionsService.hideStatusBarItem();
76
- this.aiCompletionsService.setVisibleCompletion(false);
82
+ this.commandService.executeCommand(AI_INLINE_COMPLETION_VISIBLE.id, false);
77
83
  }),
78
84
  );
79
85
 
@@ -95,13 +101,32 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
95
101
  mountEditor(editor: IEditor) {
96
102
  const toDispose = new Disposable();
97
103
  this.aiInlineCompletionsProvider.mountEditor(editor);
98
- toDispose.addDispose(this.aiInlineCompletionsProvider);
104
+
99
105
  toDispose.addDispose(super.mountEditor(editor));
106
+ toDispose.addDispose(this.aiInlineCompletionsProvider);
107
+
108
+ const inlineVisibleKey = new Set([InlineCompletionContextKeys.inlineSuggestionVisible.key]);
109
+ toDispose.addDispose(
110
+ editor.monacoEditor.contextKeyService.onDidChangeContext((e) => {
111
+ // inline completion 真正消失时
112
+ if (e.affectsSome(inlineVisibleKey)) {
113
+ const inlineSuggestionVisible = InlineCompletionContextKeys.inlineSuggestionVisible.getValue(
114
+ editor.monacoEditor.contextKeyService,
115
+ );
116
+ if (!inlineSuggestionVisible && this.preDidShowItems) {
117
+ runWhenIdle(() => {
118
+ this.preDidShowItems = undefined;
119
+ this.commandService.executeCommand(AI_INLINE_COMPLETION_VISIBLE.id, false);
120
+ });
121
+ }
122
+ }
123
+ }),
124
+ );
100
125
  return toDispose;
101
126
  }
102
127
 
103
128
  doContribute(): IDisposable {
104
- const sequencer = new Sequencer();
129
+ let prePosition: Position | undefined;
105
130
 
106
131
  return monacoApi.languages.registerInlineCompletionsProvider('*', {
107
132
  groupId: 'ai-native-inline-completions',
@@ -111,15 +136,34 @@ export class InlineCompletionHandler extends IAIMonacoContribHandler {
111
136
  return;
112
137
  }
113
138
 
114
- const list = await sequencer.queue(() =>
139
+ let resultList: InlineCompletions;
140
+
141
+ /**
142
+ * 如果新字符在 inline completion 的 ghost text 内,则走缓存,不重新请求
143
+ */
144
+ if (this.preDidShowItems) {
145
+ if (!prePosition) {
146
+ prePosition = position.delta(0, -1);
147
+ }
148
+
149
+ const lineBefore = model.getValueInRange(Range.fromPositions(prePosition, position));
150
+ if (this.preDidShowItems.items[0].insertText.toString().startsWith(lineBefore)) {
151
+ return this.preDidShowItems;
152
+ } else {
153
+ prePosition = undefined;
154
+ }
155
+ }
156
+
157
+ resultList = await this.sequencer.queue(() =>
115
158
  this.aiInlineCompletionsProvider.provideInlineCompletionItems(model, position, context, token),
116
159
  );
117
160
 
118
- return list;
161
+ return resultList;
119
162
  },
120
163
  freeInlineCompletions() {},
121
164
  handleItemDidShow: (completions) => {
122
165
  if (completions.items.length > 0) {
166
+ this.preDidShowItems = completions;
123
167
  this.aiCompletionsService.setVisibleCompletion(true);
124
168
  }
125
169
  },
@@ -78,4 +78,5 @@ export interface CompletionResultModelCache {
78
78
  */
79
79
  export interface InlineCompletionItem extends monaco.languages.InlineCompletion {
80
80
  sessionId: string;
81
+ relationId: string;
81
82
  }
@@ -14,7 +14,7 @@ export class PromptCache {
14
14
  @Autowired(IHashCalculateService)
15
15
  private hashCalculateService: IHashCalculateService;
16
16
 
17
- private cacheMap = new StaleLRUMap<string, IAICompletionResultModel>(15, 10, 60 * 1000);
17
+ private cacheMap = new StaleLRUMap<string, IAICompletionResultModel & { relationId: string }>(15, 10, 60 * 1000);
18
18
 
19
19
  getCache(prompt: string) {
20
20
  if (!isCacheEnable()) {
@@ -4,8 +4,6 @@ import {
4
4
  AIBackSerivcePath,
5
5
  CancellationTokenSource,
6
6
  Disposable,
7
- Emitter,
8
- Event,
9
7
  IAIBackService,
10
8
  IAICompletionOption,
11
9
  IAICompletionResultModel,
@@ -29,14 +27,11 @@ export class AICompletionsService extends Disposable {
29
27
  @Autowired(IAIReporter)
30
28
  private readonly aiReporter: IAIReporter;
31
29
 
32
- private readonly _onVisibleCompletion = new Emitter<boolean>();
33
- public readonly onVisibleCompletion: Event<boolean> = this._onVisibleCompletion.event;
34
-
35
30
  private cancelIndicator = new CancellationTokenSource();
36
31
  // 是否使用默认的补全模型
37
32
  protected isDefaultCompletionModel = true;
38
33
  // 是否显示了 inline 补全
39
- private _isVisibleCompletion = false;
34
+ private isVisibleCompletion = false;
40
35
  // 会话 id
41
36
  private lastSessionId: string;
42
37
  // 统计 id
@@ -54,10 +49,6 @@ export class AICompletionsService extends Disposable {
54
49
  this.lastCompletionUseTime = Date.now() - preTime;
55
50
  }
56
51
 
57
- public get isVisibleCompletion(): boolean {
58
- return this._isVisibleCompletion;
59
- }
60
-
61
52
  public async complete(data: CompletionRequestBean, model, position, token): Promise<IAICompletionResultModel | null> {
62
53
  const doCompletion = async (data: CompletionRequestBean) => {
63
54
  if (!this.aiBackService.requestCompletion) {
@@ -102,28 +93,28 @@ export class AICompletionsService extends Disposable {
102
93
  this.aiBackService.reportCompletion(data);
103
94
  this.reporterEnd(relationId, { success: true, isReceive: accept, renderingTime: data.renderingTime });
104
95
 
105
- this._isVisibleCompletion = false;
96
+ this.isVisibleCompletion = false;
106
97
  }
107
98
 
108
99
  public async reporterEnd(relationId: string, data: CompletionRT) {
109
- this.aiReporter.end(relationId, {
100
+ const reportData = {
110
101
  ...data,
111
102
  isValid: typeof data.renderingTime === 'number' ? data.renderingTime > 750 : false,
112
- });
103
+ };
104
+ this.aiReporter.end(relationId, reportData);
113
105
  }
114
106
 
115
107
  public setVisibleCompletion(visible: boolean) {
116
108
  // 如果之前是 true,现在是 false,说明并没有进行采纳
117
- if (this._isVisibleCompletion === true && visible === false) {
109
+ if (this.isVisibleCompletion === true && visible === false) {
118
110
  this.report({ sessionId: this.lastSessionId, accept: false, relationId: this.lastRelationId });
119
111
  }
120
112
 
121
- this._isVisibleCompletion = visible;
122
-
123
- this._onVisibleCompletion.fire(visible);
124
-
125
113
  if (visible === true) {
114
+ this.isVisibleCompletion = visible;
126
115
  this.recordRenderTime();
116
+ } else {
117
+ this.isVisibleCompletion = false;
127
118
  }
128
119
  }
129
120
 
@@ -10,7 +10,7 @@ export const AILayout = () => {
10
10
 
11
11
  return (
12
12
  <BoxPanel direction='top-to-bottom'>
13
- <SlotRenderer id='top' defaultSize={layout.top?.currentId ? layout.top?.size || 35 : 0} slot='top' />
13
+ <SlotRenderer id='top' defaultSize={layout.top?.currentId ? layout.top?.size || 35 : 0} slot='top' z-index={2} />
14
14
  <SplitPanel
15
15
  id='main-horizontal-ai'
16
16
  flex={1}
@@ -89,7 +89,7 @@ const AILeftTabbarRenderer: React.FC = () => {
89
89
 
90
90
  return (
91
91
  <>
92
- {visibleContainers.length > 0 && <HorizontalVertical margin={'8px auto 0px'} width={'60%'} />}
92
+ <HorizontalVertical margin={'8px auto 0px'} width={'60%'} />
93
93
  {visibleContainers.map((component) => renderContainers(component, handleTabClick, currentContainerId))}
94
94
  </>
95
95
  );
@@ -107,7 +107,6 @@ const AILeftTabbarRenderer: React.FC = () => {
107
107
  ? navMenu.map((menu) => (
108
108
  <EnhanceIconWithCtxMenu
109
109
  key={menu.id}
110
- id={menu.id}
111
110
  wrapperClassName={styles.extra_bottom_icon}
112
111
  iconClass={menu.icon}
113
112
  menuNodes={menu.children}
@@ -29,10 +29,6 @@ interface IBaseInlineChatHandler<T extends any[]> {
29
29
  * 提供 diff editor 的预览策略
30
30
  */
31
31
  providerDiffPreviewStrategy?: (...args: T) => MaybePromise<ChatResponse | InlineChatController>;
32
- /**
33
- * 在 editor 里直接预览输出的结果
34
- */
35
- providerPreviewStrategy?: (...args: T) => MaybePromise<ChatResponse | InlineChatController>;
36
32
  }
37
33
 
38
34
  export type IEditorInlineChatHandler = IBaseInlineChatHandler<[editor: ICodeEditor, token: CancellationToken]>;
@@ -46,13 +42,9 @@ export enum ERunStrategy {
46
42
  */
47
43
  EXECUTE = 'EXECUTE',
48
44
  /**
49
- * 预览 diff,执行后 input 保留,显示 inline diff editor
45
+ * 预览 diff,执行后 input 保留,显示 diff editor
50
46
  */
51
47
  DIFF_PREVIEW = 'DIFF_PREVIEW',
52
- /**
53
- * 预览输出结果,执行后 input 保留,并在 editor 里直接展示输出结果
54
- */
55
- PREVIEW = 'PREVIEW',
56
48
  }
57
49
 
58
50
  /**
@@ -60,7 +52,7 @@ export enum ERunStrategy {
60
52
  */
61
53
  export interface IInteractiveInputRunStrategy {
62
54
  strategy?: ERunStrategy;
63
- handleStrategy?: (editor: ICodeEditor, value: string) => MaybePromise<ERunStrategy>;
55
+ handleStrategy?: (value: string) => MaybePromise<ERunStrategy>;
64
56
  }
65
57
 
66
58
  export interface ITerminalInlineChatHandler {
@@ -69,24 +61,10 @@ export interface ITerminalInlineChatHandler {
69
61
  }
70
62
 
71
63
  export interface IInlineChatFeatureRegistry {
72
- /**
73
- * 注册 editor 内联聊天能力
74
- */
75
64
  registerEditorInlineChat(operational: AIActionItem, handler: IEditorInlineChatHandler): IDisposable;
76
- /**
77
- * 注销 editor 内联聊天能力
78
- */
79
- unregisterEditorInlineChat(operational: AIActionItem): void;
80
- /**
81
- * 注册 terminal 内联功能
82
- */
83
65
  registerTerminalInlineChat(operational: AIActionItem, handler: ITerminalInlineChatHandler): IDisposable;
84
66
  /**
85
- * 注销 terminal 内联功能
86
- */
87
- unregisterTerminalInlineChat(operational: AIActionItem): void;
88
- /**
89
- * proposed api,可能随时都会有变化
67
+ * proposed api
90
68
  */
91
69
  registerInteractiveInput(
92
70
  strategyOptions: IInteractiveInputRunStrategy,