@opensumi/ide-ai-native 3.7.1 → 3.7.2-next-1739859371.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 (162) hide show
  1. package/lib/browser/ai-core.contextkeys.d.ts +1 -0
  2. package/lib/browser/ai-core.contextkeys.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contextkeys.js +1 -0
  4. package/lib/browser/ai-core.contextkeys.js.map +1 -1
  5. package/lib/browser/ai-core.contribution.d.ts +2 -1
  6. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  7. package/lib/browser/ai-core.contribution.js +60 -15
  8. package/lib/browser/ai-core.contribution.js.map +1 -1
  9. package/lib/browser/components/ChatMarkdown.d.ts.map +1 -1
  10. package/lib/browser/components/ChatMarkdown.js.map +1 -1
  11. package/lib/browser/components/WelcomeMsg.js.map +1 -1
  12. package/lib/browser/components/utils.d.ts +2 -2
  13. package/lib/browser/contrib/intelligent-completions/index.d.ts +14 -9
  14. package/lib/browser/contrib/intelligent-completions/index.d.ts.map +1 -1
  15. package/lib/browser/contrib/intelligent-completions/index.js +6 -1
  16. package/lib/browser/contrib/intelligent-completions/index.js.map +1 -1
  17. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts +1 -0
  18. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.d.ts.map +1 -1
  19. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +26 -4
  20. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -1
  21. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts +5 -4
  22. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
  23. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +50 -42
  24. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
  25. package/lib/browser/contrib/intelligent-completions/source/base.d.ts +9 -3
  26. package/lib/browser/contrib/intelligent-completions/source/base.d.ts.map +1 -1
  27. package/lib/browser/contrib/intelligent-completions/source/base.js +21 -3
  28. package/lib/browser/contrib/intelligent-completions/source/base.js.map +1 -1
  29. package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts +10 -3
  30. package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts.map +1 -1
  31. package/lib/browser/contrib/intelligent-completions/source/line-change.source.js +95 -22
  32. package/lib/browser/contrib/intelligent-completions/source/line-change.source.js.map +1 -1
  33. package/lib/browser/contrib/intelligent-completions/source/lint-error.source.d.ts +1 -3
  34. package/lib/browser/contrib/intelligent-completions/source/lint-error.source.d.ts.map +1 -1
  35. package/lib/browser/contrib/intelligent-completions/source/lint-error.source.js +13 -20
  36. package/lib/browser/contrib/intelligent-completions/source/lint-error.source.js.map +1 -1
  37. package/lib/browser/contrib/intelligent-completions/source/typing.source.d.ts +9 -0
  38. package/lib/browser/contrib/intelligent-completions/source/typing.source.d.ts.map +1 -0
  39. package/lib/browser/contrib/intelligent-completions/source/typing.source.js +36 -0
  40. package/lib/browser/contrib/intelligent-completions/source/typing.source.js.map +1 -0
  41. package/lib/browser/contrib/terminal/component/terminal-command-suggest-controller.js +2 -2
  42. package/lib/browser/contrib/terminal/component/terminal-command-suggest-controller.js.map +1 -1
  43. package/lib/browser/index.js +1 -1
  44. package/lib/browser/index.js.map +1 -1
  45. package/lib/browser/languages/tree-sitter/wasm-manager.d.ts.map +1 -1
  46. package/lib/browser/languages/tree-sitter/wasm-manager.js +14 -2
  47. package/lib/browser/languages/tree-sitter/wasm-manager.js.map +1 -1
  48. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  49. package/lib/browser/layout/ai-layout.js +2 -2
  50. package/lib/browser/layout/ai-layout.js.map +1 -1
  51. package/lib/browser/layout/layout.module.less +9 -9
  52. package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
  53. package/lib/browser/layout/tabbar.view.js +5 -6
  54. package/lib/browser/layout/tabbar.view.js.map +1 -1
  55. package/lib/browser/model/enhanceDecorationsCollection.d.ts +14 -10
  56. package/lib/browser/model/enhanceDecorationsCollection.d.ts.map +1 -1
  57. package/lib/browser/model/enhanceDecorationsCollection.js +42 -53
  58. package/lib/browser/model/enhanceDecorationsCollection.js.map +1 -1
  59. package/lib/browser/preferences/schema.d.ts.map +1 -1
  60. package/lib/browser/preferences/schema.js +4 -0
  61. package/lib/browser/preferences/schema.js.map +1 -1
  62. package/lib/browser/types.d.ts +7 -2
  63. package/lib/browser/types.d.ts.map +1 -1
  64. package/lib/browser/types.js.map +1 -1
  65. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.d.ts +2 -1
  66. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.d.ts.map +1 -1
  67. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.js +20 -48
  68. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.js.map +1 -1
  69. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts +3 -13
  70. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts.map +1 -1
  71. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js +24 -72
  72. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js.map +1 -1
  73. package/lib/browser/widget/inline-chat/inline-chat.service.d.ts +1 -6
  74. package/lib/browser/widget/inline-chat/inline-chat.service.d.ts.map +1 -1
  75. package/lib/browser/widget/inline-chat/inline-chat.service.js +5 -17
  76. package/lib/browser/widget/inline-chat/inline-chat.service.js.map +1 -1
  77. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +2 -5
  78. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
  79. package/lib/browser/widget/inline-chat/inline-content-widget.js +17 -42
  80. package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
  81. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +22 -5
  82. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
  83. package/lib/browser/widget/inline-diff/inline-diff-previewer.js +61 -30
  84. package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
  85. package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +8 -12
  86. package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
  87. package/lib/browser/widget/inline-diff/inline-diff.controller.js +68 -96
  88. package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
  89. package/lib/browser/widget/inline-hint/inline-hint.controller.d.ts +0 -1
  90. package/lib/browser/widget/inline-hint/inline-hint.controller.d.ts.map +1 -1
  91. package/lib/browser/widget/inline-hint/inline-hint.controller.js +0 -5
  92. package/lib/browser/widget/inline-hint/inline-hint.controller.js.map +1 -1
  93. package/lib/browser/widget/inline-input/inline-input-widget.d.ts +12 -2
  94. package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
  95. package/lib/browser/widget/inline-input/inline-input-widget.js +26 -18
  96. package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
  97. package/lib/browser/widget/inline-input/inline-input.controller.d.ts +14 -5
  98. package/lib/browser/widget/inline-input/inline-input.controller.d.ts.map +1 -1
  99. package/lib/browser/widget/inline-input/inline-input.controller.js +321 -165
  100. package/lib/browser/widget/inline-input/inline-input.controller.js.map +1 -1
  101. package/lib/browser/widget/inline-input/inline-input.module.less +4 -0
  102. package/lib/browser/widget/inline-input/inline-input.service.d.ts +19 -7
  103. package/lib/browser/widget/inline-input/inline-input.service.d.ts.map +1 -1
  104. package/lib/browser/widget/inline-input/inline-input.service.js +72 -12
  105. package/lib/browser/widget/inline-input/inline-input.service.js.map +1 -1
  106. package/lib/browser/widget/inline-input/model.d.ts +34 -0
  107. package/lib/browser/widget/inline-input/model.d.ts.map +1 -0
  108. package/lib/browser/widget/inline-input/model.js +63 -0
  109. package/lib/browser/widget/inline-input/model.js.map +1 -0
  110. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +8 -19
  111. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  112. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +44 -39
  113. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  114. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +17 -4
  115. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  116. package/lib/browser/widget/inline-stream-diff/live-preview.component.js +37 -5
  117. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  118. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +7 -11
  119. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  120. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +33 -77
  121. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  122. package/lib/common/utils.js +2 -2
  123. package/lib/common/utils.js.map +1 -1
  124. package/package.json +21 -21
  125. package/src/browser/ai-core.contextkeys.ts +3 -0
  126. package/src/browser/ai-core.contribution.ts +68 -17
  127. package/src/browser/components/ChatMarkdown.tsx +1 -1
  128. package/src/browser/components/WelcomeMsg.tsx +1 -1
  129. package/src/browser/contrib/intelligent-completions/index.ts +16 -4
  130. package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +29 -8
  131. package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +86 -55
  132. package/src/browser/contrib/intelligent-completions/source/base.ts +28 -7
  133. package/src/browser/contrib/intelligent-completions/source/line-change.source.ts +129 -22
  134. package/src/browser/contrib/intelligent-completions/source/lint-error.source.ts +19 -31
  135. package/src/browser/contrib/intelligent-completions/source/typing.source.ts +34 -0
  136. package/src/browser/contrib/terminal/component/terminal-command-suggest-controller.tsx +1 -1
  137. package/src/browser/index.ts +2 -2
  138. package/src/browser/languages/tree-sitter/wasm-manager.ts +12 -2
  139. package/src/browser/layout/ai-layout.tsx +5 -2
  140. package/src/browser/layout/layout.module.less +9 -9
  141. package/src/browser/layout/tabbar.view.tsx +10 -8
  142. package/src/browser/model/enhanceDecorationsCollection.ts +62 -77
  143. package/src/browser/preferences/schema.ts +4 -0
  144. package/src/browser/types.ts +5 -3
  145. package/src/browser/widget/inline-chat/inline-chat-editor.controller.ts +29 -64
  146. package/src/browser/widget/inline-chat/inline-chat.feature.registry.ts +23 -90
  147. package/src/browser/widget/inline-chat/inline-chat.service.ts +2 -17
  148. package/src/browser/widget/inline-chat/inline-content-widget.tsx +14 -69
  149. package/src/browser/widget/inline-diff/inline-diff-previewer.ts +87 -32
  150. package/src/browser/widget/inline-diff/inline-diff.controller.ts +90 -114
  151. package/src/browser/widget/inline-hint/inline-hint.controller.ts +1 -7
  152. package/src/browser/widget/inline-input/inline-input-widget.tsx +34 -12
  153. package/src/browser/widget/inline-input/inline-input.controller.ts +454 -242
  154. package/src/browser/widget/inline-input/inline-input.module.less +4 -0
  155. package/src/browser/widget/inline-input/inline-input.service.ts +92 -13
  156. package/src/browser/widget/inline-input/model.ts +74 -0
  157. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +54 -67
  158. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +45 -6
  159. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +40 -112
  160. package/src/common/utils.ts +2 -2
  161. package/lib/browser/model/styles.module.less +0 -7
  162. package/src/browser/model/styles.module.less +0 -7
@@ -58,5 +58,9 @@ export const aiNativePreferenceSchema: PreferenceSchema = {
58
58
  type: 'boolean',
59
59
  default: false,
60
60
  },
61
+ [AINativeSettingSectionsId.CodeEditsTyping]: {
62
+ type: 'boolean',
63
+ default: false,
64
+ },
61
65
  },
62
66
  };
@@ -13,7 +13,7 @@ import {
13
13
  MaybePromise,
14
14
  MergeConflictEditorMode,
15
15
  } from '@opensumi/ide-core-common';
16
- import { ICodeEditor, IRange, ITextModel, NewSymbolNamesProvider, Position } from '@opensumi/ide-monaco';
16
+ import { ICodeEditor, IRange, ISelection, ITextModel, NewSymbolNamesProvider, Position } from '@opensumi/ide-monaco';
17
17
  import { SumiReadableStream } from '@opensumi/ide-utils/lib/stream';
18
18
  import { IMarker } from '@opensumi/monaco-editor-core/esm/vs/platform/markers/common/markers';
19
19
 
@@ -42,9 +42,11 @@ interface IBaseInlineChatHandler<T extends any[]> {
42
42
  providerDiffPreviewStrategy?: (...args: T) => MaybePromise<ChatResponse | InlineChatController>;
43
43
  }
44
44
 
45
- export type IEditorInlineChatHandler = IBaseInlineChatHandler<[editor: ICodeEditor, token: CancellationToken]>;
45
+ export type IEditorInlineChatHandler = IBaseInlineChatHandler<
46
+ [editor: ICodeEditor, selection: ISelection, token: CancellationToken]
47
+ >;
46
48
  export type IInteractiveInputHandler = IBaseInlineChatHandler<
47
- [editor: ICodeEditor, value: string, token: CancellationToken]
49
+ [editor: ICodeEditor, selection: ISelection, value: string, token: CancellationToken]
48
50
  >;
49
51
 
50
52
  export enum ERunStrategy {
@@ -15,6 +15,7 @@ import {
15
15
  Disposable,
16
16
  ErrorResponse,
17
17
  Event,
18
+ FRAME_THREE,
18
19
  IAIReporter,
19
20
  IDisposable,
20
21
  ILogServiceClient,
@@ -30,14 +31,14 @@ import * as monaco from '@opensumi/ide-monaco';
30
31
  import { ICodeEditor } from '@opensumi/ide-monaco';
31
32
  import { monacoApi } from '@opensumi/ide-monaco/lib/browser/monaco-api';
32
33
 
34
+ import { AINativeContextKey } from '../../ai-core.contextkeys';
33
35
  import { BaseAIMonacoEditorController } from '../../contrib/base';
34
36
  import { CodeActionService } from '../../contrib/code-action/code-action.service';
35
- import { ERunStrategy } from '../../types';
36
37
  import { InlineDiffController } from '../inline-diff/inline-diff.controller';
37
38
 
38
39
  import { InlineChatController } from './inline-chat-controller';
39
40
  import { InlineChatFeatureRegistry } from './inline-chat.feature.registry';
40
- import { AIInlineChatService, EInlineChatStatus, EResultKind } from './inline-chat.service';
41
+ import { EInlineChatStatus, EResultKind, InlineChatService } from './inline-chat.service';
41
42
  import { AIInlineContentWidget } from './inline-content-widget';
42
43
 
43
44
  export class InlineChatEditorController extends BaseAIMonacoEditorController {
@@ -51,7 +52,7 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
51
52
  return this.injector.get(AINativeConfigService);
52
53
  }
53
54
 
54
- private get aiInlineChatService(): AIInlineChatService {
55
+ private get aiInlineChatService(): InlineChatService {
55
56
  return this.injector.get(IAIInlineChatService);
56
57
  }
57
58
 
@@ -86,11 +87,13 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
86
87
  private aiInlineContentWidget: AIInlineContentWidget;
87
88
  private aiInlineChatDisposable: Disposable = new Disposable();
88
89
  private aiInlineChatOperationDisposable: Disposable = new Disposable();
90
+ private aiNativeContextKey: AINativeContextKey;
89
91
  private inlineChatInUsing = false;
90
92
 
91
93
  private inlineDiffController: InlineDiffController;
92
94
 
93
95
  mount(): IDisposable {
96
+ this.aiNativeContextKey = this.injector.get(AINativeContextKey, [this.monacoEditor.contextKeyService]);
94
97
  this.inlineDiffController = InlineDiffController.get(this.monacoEditor)!;
95
98
 
96
99
  if (!this.monacoEditor) {
@@ -178,7 +181,7 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
178
181
  Event.debounce(
179
182
  Event.any<any>(this.monacoEditor.onDidChangeCursorSelection, this.monacoEditor.onMouseUp),
180
183
  (_, e) => e,
181
- 100,
184
+ FRAME_THREE,
182
185
  )(() => {
183
186
  if (!prefInlineChatAutoVisible || !needShowInlineChat) {
184
187
  return;
@@ -197,7 +200,7 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
197
200
  return this.featureDisposable;
198
201
  }
199
202
 
200
- private disposeAllWidget() {
203
+ public disposeAllWidget() {
201
204
  [this.aiInlineContentWidget, this.aiInlineChatDisposable, this.aiInlineChatOperationDisposable].forEach(
202
205
  (widget) => {
203
206
  widget?.dispose();
@@ -224,9 +227,21 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
224
227
  return;
225
228
  }
226
229
 
230
+ // 如果 inline input 正在展示,则不展示 inline chat
231
+ const isInlineInputVisible = this.aiNativeContextKey.inlineInputWidgetIsVisible.get();
232
+ if (isInlineInputVisible) {
233
+ return;
234
+ }
235
+
236
+ const isInlineStreaming = this.aiNativeContextKey.inlineInputWidgetIsStreaming.get();
237
+ if (isInlineStreaming) {
238
+ return;
239
+ }
240
+
227
241
  if (!this.aiNativeConfigService.capabilities.supportsInlineChat) {
228
242
  return;
229
243
  }
244
+
230
245
  if (this.inlineChatInUsing) {
231
246
  return;
232
247
  }
@@ -243,12 +258,6 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
243
258
 
244
259
  this.showInlineContentWidget(monacoEditor, selection);
245
260
 
246
- this.aiInlineChatDisposable.addDispose(
247
- this.inlineChatFeatureRegistry.onChatClick(() => {
248
- this.aiInlineChatService.launchInputVisible(true);
249
- }),
250
- );
251
-
252
261
  this.aiInlineChatDisposable.addDispose(
253
262
  this.aiInlineContentWidget.onActionClick(({ actionId, source }) => {
254
263
  const handler = this.inlineChatFeatureRegistry.getEditorHandler(actionId);
@@ -271,7 +280,7 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
271
280
  return undefined;
272
281
  }
273
282
 
274
- return strategy.bind(this, monacoEditor, this.token);
283
+ return strategy.bind(this, monacoEditor, crossSelection, this.token);
275
284
  };
276
285
 
277
286
  this.runAction({
@@ -288,7 +297,7 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
288
297
  });
289
298
  return relationId;
290
299
  },
291
- execute: handler.execute ? handler.execute!.bind(this, monacoEditor, this.token) : undefined,
300
+ execute: handler.execute ? handler.execute!.bind(this, monacoEditor, crossSelection, this.token) : undefined,
292
301
  providerPreview: previewer(),
293
302
  extraData: {
294
303
  actionSource: source === 'codeAction' ? ActionSourceEnum.CodeAction : ActionSourceEnum.InlineChat,
@@ -297,49 +306,6 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
297
306
  });
298
307
  }),
299
308
  );
300
-
301
- this.aiInlineChatDisposable.addDispose(
302
- this.aiInlineContentWidget.onInteractiveInputValue(async (value) => {
303
- const handler = this.inlineChatFeatureRegistry.getInteractiveInputHandler();
304
-
305
- if (!handler) {
306
- return;
307
- }
308
-
309
- const strategy = await this.inlineChatFeatureRegistry.getInteractiveInputStrategyHandler()(monacoEditor, value);
310
-
311
- const crossSelection = this.getCrossSelection(monacoEditor);
312
- if (!crossSelection) {
313
- return;
314
- }
315
-
316
- this.runAction({
317
- monacoEditor,
318
- crossSelection,
319
- reporterFn: () => {
320
- const relationId = this.aiReporter.start(AIServiceType.InlineChatInput, {
321
- message: value,
322
- type: AIServiceType.InlineChatInput,
323
- source: 'input',
324
- actionSource: ActionSourceEnum.InlineChatInput,
325
- });
326
- return relationId;
327
- },
328
- execute:
329
- handler.execute && strategy === ERunStrategy.EXECUTE
330
- ? handler.execute!.bind(this, monacoEditor, value, this.token)
331
- : undefined,
332
- providerPreview:
333
- handler.providePreviewStrategy && strategy === ERunStrategy.PREVIEW
334
- ? handler.providePreviewStrategy.bind(this, monacoEditor, value, this.token)
335
- : undefined,
336
- extraData: {
337
- actionSource: ActionSourceEnum.InlineChatInput,
338
- actionType: strategy,
339
- },
340
- });
341
- }),
342
- );
343
309
  }
344
310
 
345
311
  private getCrossSelection(monacoEditor: monaco.ICodeEditor) {
@@ -480,7 +446,7 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
480
446
  }
481
447
 
482
448
  const diffPreviewer = this.inlineDiffController.showPreviewerByStream(monacoEditor, options);
483
- diffPreviewer.mount(this.aiInlineContentWidget);
449
+ diffPreviewer.mountWidget(this.aiInlineContentWidget);
484
450
  }
485
451
 
486
452
  private ensureInlineChatVisible(monacoEditor: monaco.ICodeEditor, crossSelection: monaco.Selection) {
@@ -506,7 +472,6 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
506
472
  const { monacoEditor, strategy, crossSelection, relationId, isRetry, actionType, actionSource } = params;
507
473
  const model = monacoEditor.getModel();
508
474
 
509
- this.inlineDiffController.destroyPreviewer(model!.uri.toString());
510
475
  this.aiInlineChatOperationDisposable.dispose();
511
476
 
512
477
  this.ensureInlineChatVisible(monacoEditor, crossSelection);
@@ -543,12 +508,6 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
543
508
  return;
544
509
  }
545
510
 
546
- this.visibleDiffWidget({
547
- monacoEditor,
548
- options: { crossSelection, chatResponse: response },
549
- reportInfo: { relationId, startTime, isRetry, actionType, actionSource },
550
- });
551
-
552
511
  this.aiInlineChatOperationDisposable.addDispose([
553
512
  this.aiInlineContentWidget.onResultClick((kind: EResultKind) => {
554
513
  const modifyContent = this.inlineDiffController.getModifyContent();
@@ -614,6 +573,12 @@ export class InlineChatEditorController extends BaseAIMonacoEditorController {
614
573
  });
615
574
  }),
616
575
  ]);
576
+
577
+ this.visibleDiffWidget({
578
+ monacoEditor,
579
+ options: { crossSelection, chatResponse: response },
580
+ reportInfo: { relationId, startTime, isRetry, actionType, actionSource },
581
+ });
617
582
  }
618
583
 
619
584
  public async runAction(params: {
@@ -2,48 +2,18 @@ import { Autowired, Injectable } from '@opensumi/di';
2
2
  import { KeybindingRegistry, Logger } from '@opensumi/ide-core-browser';
3
3
  import { AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE } from '@opensumi/ide-core-browser/lib/ai-native/command';
4
4
  import { AIActionItem } from '@opensumi/ide-core-browser/lib/components/ai-native';
5
- import { InteractiveInput } from '@opensumi/ide-core-browser/lib/components/ai-native/interactive-input/index';
6
- import { Disposable, Emitter, Event, IDisposable, MaybePromise, isUndefined, uuid } from '@opensumi/ide-core-common';
7
- import { ICodeEditor } from '@opensumi/ide-monaco';
5
+ import { Disposable, Event, IDisposable, formatLocalize, isUndefined } from '@opensumi/ide-core-common';
8
6
 
9
7
  import { CodeActionService } from '../../contrib/code-action/code-action.service';
10
8
  import {
11
- ERunStrategy,
12
9
  IEditorInlineChatHandler,
13
10
  IInlineChatFeatureRegistry,
14
11
  IInteractiveInputHandler,
15
12
  IInteractiveInputRunStrategy,
16
13
  ITerminalInlineChatHandler,
17
14
  } from '../../types';
18
-
19
- type TRunStrategyFn = (editor: ICodeEditor, value: string) => MaybePromise<ERunStrategy>;
20
-
21
- class InteractiveInputModel {
22
- static ID: string = `${InteractiveInput.displayName}:${uuid(4)}`;
23
-
24
- private _handler: IInteractiveInputHandler | undefined;
25
- private _strategyHandler: TRunStrategyFn;
26
-
27
- public setHandler(h: IInteractiveInputHandler): void {
28
- this._handler = h;
29
- }
30
-
31
- public handler(): IInteractiveInputHandler | undefined {
32
- return this._handler;
33
- }
34
-
35
- public setStrategyHandler(fn: TRunStrategyFn): void {
36
- this._strategyHandler = fn;
37
- }
38
-
39
- public strategyHandler(): TRunStrategyFn {
40
- return this._strategyHandler;
41
- }
42
-
43
- public dispose(): void {
44
- this._handler = undefined;
45
- }
46
- }
15
+ import { InlineInputService } from '../inline-input/inline-input.service';
16
+ import { InteractiveInputModel } from '../inline-input/model';
47
17
 
48
18
  @Injectable()
49
19
  export class InlineChatFeatureRegistry extends Disposable implements IInlineChatFeatureRegistry {
@@ -53,6 +23,9 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
53
23
  @Autowired(CodeActionService)
54
24
  private readonly codeActionService: CodeActionService;
55
25
 
26
+ @Autowired(InlineInputService)
27
+ private readonly inlineInputService: InlineInputService;
28
+
56
29
  @Autowired(KeybindingRegistry)
57
30
  private readonly keybindingRegistry: KeybindingRegistry;
58
31
 
@@ -60,11 +33,6 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
60
33
  private editorHandlerMap: Map<string, IEditorInlineChatHandler> = new Map();
61
34
  private terminalHandlerMap: Map<string, ITerminalInlineChatHandler> = new Map();
62
35
 
63
- private interactiveInputModel: InteractiveInputModel = new InteractiveInputModel();
64
-
65
- public readonly _onChatClick = new Emitter<void>();
66
- public readonly onChatClick: Event<void> = this._onChatClick.event;
67
-
68
36
  override dispose() {
69
37
  super.dispose();
70
38
  this.actionsMap.clear();
@@ -72,10 +40,6 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
72
40
  this.terminalHandlerMap.clear();
73
41
  }
74
42
 
75
- private updateActions(id: string, operational: AIActionItem): void {
76
- this.actionsMap.set(id, operational);
77
- }
78
-
79
43
  private collectActions(operational: AIActionItem): boolean {
80
44
  const { id } = operational;
81
45
 
@@ -102,10 +66,6 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
102
66
  this.codeActionService.deleteCodeActionById(operational.id);
103
67
  }
104
68
 
105
- public getInteractiveInputId(): string {
106
- return InteractiveInputModel.ID;
107
- }
108
-
109
69
  public registerEditorInlineChat(operational: AIActionItem, handler: IEditorInlineChatHandler): IDisposable {
110
70
  const isCollect = this.collectActions(operational);
111
71
 
@@ -151,29 +111,23 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
151
111
  runStrategy: IInteractiveInputRunStrategy,
152
112
  handler: IInteractiveInputHandler,
153
113
  ): IDisposable {
154
- this.interactiveInputModel.setHandler(handler);
155
-
156
- if (runStrategy.handleStrategy) {
157
- this.interactiveInputModel.setStrategyHandler(runStrategy.handleStrategy);
158
- } else {
159
- this.interactiveInputModel.setStrategyHandler(() => runStrategy.strategy || ERunStrategy.EXECUTE);
160
- }
161
-
162
114
  const doCollect = () => {
163
- const keybindingStr = String(this.getSequenceKeyString());
164
- if (keybindingStr) {
165
- const operational: AIActionItem = {
166
- id: InteractiveInputModel.ID,
167
- name: `Chat(${keybindingStr.toLocaleUpperCase()})`,
168
- renderType: 'button',
169
- order: Number.MAX_SAFE_INTEGER,
170
- };
171
-
172
- if (this.actionsMap.has(operational.id)) {
173
- this.updateActions(operational.id, operational);
174
- } else {
175
- this.collectActions(operational);
176
- }
115
+ const keybindingStr = String(this.inlineInputService.getSequenceKeyString());
116
+ if (!keybindingStr) {
117
+ return;
118
+ }
119
+
120
+ const operational: AIActionItem = {
121
+ id: InteractiveInputModel.ID,
122
+ name: formatLocalize('aiNative.inline.chat.operate.chat.title', keybindingStr.toLocaleUpperCase()),
123
+ renderType: 'button',
124
+ order: Number.MAX_SAFE_INTEGER,
125
+ };
126
+
127
+ if (this.actionsMap.has(operational.id)) {
128
+ this.actionsMap.set(operational.id, operational);
129
+ } else {
130
+ this.collectActions(operational);
177
131
  }
178
132
  };
179
133
 
@@ -185,28 +139,7 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
185
139
 
186
140
  doCollect();
187
141
 
188
- return {
189
- dispose: () => {
190
- this.interactiveInputModel.dispose();
191
- },
192
- };
193
- }
194
-
195
- private getSequenceKeyString() {
196
- const keybindings = this.keybindingRegistry.getKeybindingsForCommand(AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE.id);
197
- const resolved = keybindings[0]?.resolved;
198
- if (!resolved) {
199
- return '';
200
- }
201
- return this.keybindingRegistry.acceleratorForSequence(resolved, '+');
202
- }
203
-
204
- public getInteractiveInputHandler(): IInteractiveInputHandler | undefined {
205
- return this.interactiveInputModel.handler();
206
- }
207
-
208
- public getInteractiveInputStrategyHandler(): TRunStrategyFn {
209
- return this.interactiveInputModel.strategyHandler();
142
+ return this.inlineInputService.registerInlineInput(runStrategy, handler);
210
143
  }
211
144
 
212
145
  public getEditorActionButtons(): AIActionItem[] {
@@ -1,19 +1,11 @@
1
1
  import { Injectable } from '@opensumi/di';
2
2
  import { IAIInlineChatService } from '@opensumi/ide-core-browser';
3
- import { Emitter, Event, runWhenIdle } from '@opensumi/ide-core-common';
3
+ import { Emitter, Event } from '@opensumi/ide-core-common';
4
4
 
5
5
  export { EInlineChatStatus, EResultKind } from '../../../common';
6
6
 
7
7
  @Injectable({ multiple: false })
8
- export class AIInlineChatService implements IAIInlineChatService {
9
- private _interactiveInputVisible: boolean = false;
10
- public get interactiveInputVisible(): boolean {
11
- return this._interactiveInputVisible;
12
- }
13
-
14
- public readonly _onInteractiveInputVisible = new Emitter<boolean>();
15
- public readonly onInteractiveInputVisible: Event<boolean> = this._onInteractiveInputVisible.event;
16
-
8
+ export class InlineChatService implements IAIInlineChatService {
17
9
  public readonly _onInlineChatVisible = new Emitter<boolean>();
18
10
  public readonly onInlineChatVisible: Event<boolean> = this._onInlineChatVisible.event;
19
11
 
@@ -23,11 +15,4 @@ export class AIInlineChatService implements IAIInlineChatService {
23
15
  public fireThumbsEvent(isThumbsUp: boolean) {
24
16
  this._onThumbs.fire(isThumbsUp);
25
17
  }
26
-
27
- public launchInputVisible(v: boolean) {
28
- return runWhenIdle(() => {
29
- this._interactiveInputVisible = v;
30
- this._onInteractiveInputVisible.fire(v);
31
- });
32
- }
33
18
  }
@@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
4
4
  import { IAIInlineChatService, StackingLevel, useInjectable } from '@opensumi/ide-core-browser';
5
5
  import { AIAction } from '@opensumi/ide-core-browser/lib/components/ai-native';
6
- import { InteractiveInput } from '@opensumi/ide-core-browser/lib/components/ai-native/interactive-input/index';
7
6
  import { MenuNode } from '@opensumi/ide-core-browser/lib/menu/next/base';
8
7
  import {
9
8
  AIInlineChatContentWidgetId,
@@ -11,7 +10,6 @@ import {
11
10
  Emitter,
12
11
  Event,
13
12
  InlineChatFeatureRegistryToken,
14
- localize,
15
13
  runWhenIdle,
16
14
  } from '@opensumi/ide-core-common';
17
15
  import * as monaco from '@opensumi/ide-monaco';
@@ -23,38 +21,32 @@ import {
23
21
 
24
22
  import { AINativeContextKey } from '../../ai-core.contextkeys';
25
23
  import { InlineResultAction } from '../inline-actions/result-items/index';
24
+ import { InlineInputService } from '../inline-input/inline-input.service';
25
+ import { InteractiveInputModel } from '../inline-input/model';
26
26
 
27
27
  import { InlineChatFeatureRegistry } from './inline-chat.feature.registry';
28
28
  import styles from './inline-chat.module.less';
29
- import { AIInlineChatService, EInlineChatStatus, EResultKind } from './inline-chat.service';
29
+ import { EInlineChatStatus, EResultKind, InlineChatService } from './inline-chat.service';
30
30
 
31
31
  import type { ICodeEditor as IMonacoCodeEditor } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
32
32
 
33
33
  interface IAIInlineChatControllerProps {
34
34
  onClickActions: (id: string) => void;
35
- onLayoutChange: (height: number) => void;
36
35
  onClose?: () => void;
37
- onInteractiveInputSend?: (value: string) => void;
38
36
  onChatStatus: Event<EInlineChatStatus>;
39
37
  onResultClick: (k: EResultKind) => void;
40
38
  }
41
39
 
42
40
  const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
43
- const { onClickActions, onClose, onInteractiveInputSend, onLayoutChange, onChatStatus, onResultClick } = props;
44
- const aiInlineChatService: AIInlineChatService = useInjectable(IAIInlineChatService);
41
+ const { onClickActions, onClose, onChatStatus, onResultClick } = props;
42
+ const aiInlineChatService: InlineChatService = useInjectable(IAIInlineChatService);
45
43
  const inlineChatFeatureRegistry: InlineChatFeatureRegistry = useInjectable(InlineChatFeatureRegistryToken);
44
+
46
45
  const [status, setStatus] = useState<EInlineChatStatus>(EInlineChatStatus.READY);
47
- const [interactiveInputVisible, setInteractiveInputVisible] = useState<boolean>(false);
48
46
  useEffect(() => {
49
47
  const dis = new Disposable();
50
48
  dis.addDispose(onChatStatus((s) => setStatus(s)));
51
49
 
52
- dis.addDispose(
53
- aiInlineChatService.onInteractiveInputVisible((v) => {
54
- setInteractiveInputVisible(v);
55
- }),
56
- );
57
-
58
50
  return () => {
59
51
  dis.dispose();
60
52
  };
@@ -82,13 +74,6 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
82
74
  onClose?.();
83
75
  }, [onClose]);
84
76
 
85
- const handleInteractiveInputSend = useCallback(
86
- (value: string) => {
87
- onInteractiveInputSend?.(value);
88
- },
89
- [onInteractiveInputSend],
90
- );
91
-
92
77
  const moreOperation = useMemo(
93
78
  () =>
94
79
  inlineChatFeatureRegistry.getEditorActionMenus().map(
@@ -105,24 +90,6 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
105
90
  [inlineChatFeatureRegistry],
106
91
  );
107
92
 
108
- const customOperationRender = useMemo(() => {
109
- if (!interactiveInputVisible) {
110
- return null;
111
- }
112
-
113
- return (
114
- <InteractiveInput
115
- autoFocus
116
- onHeightChange={(height) => onLayoutChange(height)}
117
- size='small'
118
- placeholder={localize('aiNative.inline.chat.input.placeholder.default')}
119
- width={320}
120
- disabled={isLoading}
121
- onSend={handleInteractiveInputSend}
122
- />
123
- );
124
- }, [isLoading, interactiveInputVisible]);
125
-
126
93
  const renderContent = useCallback(() => {
127
94
  if (operationList.length === 0 && moreOperation.length === 0) {
128
95
  return null;
@@ -143,11 +110,9 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
143
110
  onClickItem={handleClickActions}
144
111
  onClose={handleClose}
145
112
  loading={isLoading}
146
- loadingShowOperation={interactiveInputVisible}
147
- customOperationRender={customOperationRender}
148
113
  />
149
114
  );
150
- }, [operationList, moreOperation, customOperationRender, onResultClick, status, interactiveInputVisible]);
115
+ }, [operationList, moreOperation, onResultClick, status]);
151
116
 
152
117
  return <div className={styles.inline_chat_controller_box}>{renderContent()}</div>;
153
118
  };
@@ -159,28 +124,20 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
159
124
  @Autowired(INJECTOR_TOKEN)
160
125
  private readonly injector: Injector;
161
126
 
162
- @Autowired(InlineChatFeatureRegistryToken)
163
- private readonly inlineChatFeatureRegistry: InlineChatFeatureRegistry;
127
+ @Autowired(InlineInputService)
128
+ protected readonly inlineInputService: InlineInputService;
164
129
 
165
130
  private readonly aiNativeContextKey: AINativeContextKey;
166
131
 
167
132
  private readonly _onActionClickEmitter = new Emitter<{ actionId: string; source: string }>();
168
133
  public readonly onActionClick = this._onActionClickEmitter.event;
169
134
 
170
- protected readonly _onInteractiveInputValue = new Emitter<string>();
171
- public readonly onInteractiveInputValue = this._onInteractiveInputValue.event;
172
-
173
135
  protected readonly _onStatusChange = new Emitter<EInlineChatStatus>();
174
136
  public readonly onStatusChange: Event<EInlineChatStatus> = this._onStatusChange.event;
175
137
 
176
138
  protected readonly _onResultClick = new Emitter<EResultKind>();
177
139
  public readonly onResultClick: Event<EResultKind> = this._onResultClick.event;
178
140
 
179
- protected _interactiveInputValue: string;
180
- public get interactiveInputValue(): string {
181
- return this._interactiveInputValue;
182
- }
183
-
184
141
  protected _status: EInlineChatStatus = EInlineChatStatus.READY;
185
142
  public get status(): EInlineChatStatus {
186
143
  return this._status;
@@ -194,13 +151,6 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
194
151
  super(editor);
195
152
 
196
153
  this.aiNativeContextKey = this.injector.get(AINativeContextKey, [this.editor.contextKeyService]);
197
- this.addDispose(
198
- this.editor.onDidLayoutChange(() => {
199
- if (this.isOutOfArea()) {
200
- this.dispose();
201
- }
202
- }),
203
- );
204
154
  }
205
155
 
206
156
  public launchChatStatus(status: EInlineChatStatus) {
@@ -216,8 +166,11 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
216
166
  }
217
167
 
218
168
  public clickActionId(actionId: string, source: string): void {
219
- if (actionId === this.inlineChatFeatureRegistry.getInteractiveInputId()) {
220
- this.inlineChatFeatureRegistry._onChatClick.fire();
169
+ if (actionId === InteractiveInputModel.ID && this.options?.selection) {
170
+ // 隐藏当前的 inline chat widget
171
+ this.hide();
172
+ // 显示 inline input widget
173
+ this.inlineInputService.visibleBySelection(this.options.selection);
221
174
  return;
222
175
  }
223
176
 
@@ -230,14 +183,6 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
230
183
  onClickActions={(id) => this.clickActionId(id, 'widget')}
231
184
  onClose={() => this.dispose()}
232
185
  onChatStatus={this.onStatusChange.bind(this)}
233
- onLayoutChange={() => {
234
- this.editor.layoutContentWidget(this);
235
- }}
236
- onInteractiveInputSend={(value) => {
237
- this.launchChatStatus(EInlineChatStatus.THINKING);
238
- this._interactiveInputValue = value;
239
- this._onInteractiveInputValue.fire(value);
240
- }}
241
186
  onResultClick={(kind: EResultKind) => {
242
187
  this._onResultClick.fire(kind);
243
188
  }}