@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
@@ -86,7 +86,7 @@ export class InlineChatController {
86
86
  listenReadable<IChatProgress>(stream, {
87
87
  onData: (data) => {
88
88
  reply.updateMessage(this.fencedCodeBlocks((data as IChatContent).content));
89
- this._onData.fireAndAwait(reply);
89
+ this._onData.fire(reply);
90
90
  },
91
91
  onEnd: () => {
92
92
  this.isInCodeBlock = false;
@@ -1,10 +1,8 @@
1
1
  import { Autowired, Injectable } from '@opensumi/di';
2
- import { KeybindingRegistry, Logger } from '@opensumi/ide-core-browser';
3
- import { AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE } from '@opensumi/ide-core-browser/lib/ai-native/command';
2
+ import { Logger, SpecialCases } from '@opensumi/ide-core-browser';
4
3
  import { AIActionItem } from '@opensumi/ide-core-browser/lib/components/ai-native';
5
4
  import { InteractiveInput } from '@opensumi/ide-core-browser/lib/components/ai-native/interactive-input/index';
6
5
  import { Disposable, Emitter, Event, IDisposable, MaybePromise, isUndefined, uuid } from '@opensumi/ide-core-common';
7
- import { ICodeEditor } from '@opensumi/ide-monaco';
8
6
 
9
7
  import { CodeActionService } from '../../contrib/code-action/code-action.service';
10
8
  import {
@@ -16,7 +14,7 @@ import {
16
14
  ITerminalInlineChatHandler,
17
15
  } from '../../types';
18
16
 
19
- type TRunStrategyFn = (editor: ICodeEditor, value: string) => MaybePromise<ERunStrategy>;
17
+ type TRunStrategyFn = (value: string) => MaybePromise<ERunStrategy>;
20
18
 
21
19
  class InteractiveInputModel {
22
20
  static ID: string = `${InteractiveInput.displayName}:${uuid(4)}`;
@@ -53,9 +51,6 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
53
51
  @Autowired(CodeActionService)
54
52
  private readonly codeActionService: CodeActionService;
55
53
 
56
- @Autowired(KeybindingRegistry)
57
- private readonly keybindingRegistry: KeybindingRegistry;
58
-
59
54
  private actionsMap: Map<string, AIActionItem> = new Map();
60
55
  private editorHandlerMap: Map<string, IEditorInlineChatHandler> = new Map();
61
56
  private terminalHandlerMap: Map<string, ITerminalInlineChatHandler> = new Map();
@@ -117,10 +112,6 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
117
112
  };
118
113
  }
119
114
 
120
- public unregisterEditorInlineChat(operational: AIActionItem) {
121
- return this.removeCollectedActions(operational);
122
- }
123
-
124
115
  public registerTerminalInlineChat(operational: AIActionItem, handler: ITerminalInlineChatHandler): IDisposable {
125
116
  const isCollect = this.collectActions(operational);
126
117
 
@@ -139,10 +130,6 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
139
130
  };
140
131
  }
141
132
 
142
- public unregisterTerminalInlineChat(operational: AIActionItem) {
143
- return this.removeCollectedActions(operational);
144
- }
145
-
146
133
  public registerInteractiveInput(
147
134
  runStrategy: IInteractiveInputRunStrategy,
148
135
  handler: IInteractiveInputHandler,
@@ -155,16 +142,12 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
155
142
  this.interactiveInputModel.setStrategyHandler(() => runStrategy.strategy || ERunStrategy.EXECUTE);
156
143
  }
157
144
 
158
- const keybindingStr = String(this.getSequenceKeyString());
159
-
160
- if (keybindingStr) {
161
- this.collectActions({
162
- id: InteractiveInputModel.ID,
163
- name: `Chat(${keybindingStr.toLocaleUpperCase()})`,
164
- renderType: 'button',
165
- order: Number.MAX_SAFE_INTEGER,
166
- });
167
- }
145
+ this.collectActions({
146
+ id: InteractiveInputModel.ID,
147
+ name: `Chat(${SpecialCases.MACMETA}+K)`,
148
+ renderType: 'button',
149
+ order: Number.MAX_SAFE_INTEGER,
150
+ });
168
151
 
169
152
  return {
170
153
  dispose: () => {
@@ -173,15 +156,6 @@ export class InlineChatFeatureRegistry extends Disposable implements IInlineChat
173
156
  };
174
157
  }
175
158
 
176
- private getSequenceKeyString() {
177
- const keybindings = this.keybindingRegistry.getKeybindingsForCommand(AI_INLINE_CHAT_INTERACTIVE_INPUT_VISIBLE.id);
178
- const resolved = keybindings[0]?.resolved;
179
- if (!resolved) {
180
- return '';
181
- }
182
- return this.keybindingRegistry.acceleratorForSequence(resolved, '+');
183
- }
184
-
185
159
  public getInteractiveInputHandler(): IInteractiveInputHandler | undefined {
186
160
  return this.interactiveInputModel.handler();
187
161
  }
@@ -33,7 +33,7 @@ import { InlineDiffWidget } from '../inline-diff/inline-diff-widget';
33
33
 
34
34
  import { InlineChatController } from './inline-chat-controller';
35
35
  import { InlineChatFeatureRegistry } from './inline-chat.feature.registry';
36
- import { AIInlineChatService, EInlineChatStatus, EResultKind } from './inline-chat.service';
36
+ import { AIInlineChatService, EInlineChatStatus } from './inline-chat.service';
37
37
  import { AIInlineContentWidget } from './inline-content-widget';
38
38
 
39
39
  @Injectable()
@@ -79,6 +79,11 @@ export class InlineChatHandler extends Disposable {
79
79
  this.logger = this.loggerManagerClient.getLogger(SupportLogNamespace.Browser);
80
80
  }
81
81
 
82
+ contribute(editor: IEditor): IDisposable {
83
+ this.registerInlineChatFeature(editor);
84
+ return this;
85
+ }
86
+
82
87
  private cancelToken() {
83
88
  this.cancelIndicator.cancel();
84
89
  this.cancelIndicator = new CancellationTokenSource();
@@ -169,9 +174,8 @@ export class InlineChatHandler extends Disposable {
169
174
  }
170
175
 
171
176
  if (
172
- this.aiInlineContentWidget &&
173
- this.aiInlineContentWidget.status !== EInlineChatStatus.READY &&
174
- this.aiInlineContentWidget.status !== EInlineChatStatus.ERROR
177
+ this.aiInlineChatService.status !== EInlineChatStatus.READY &&
178
+ this.aiInlineChatService.status !== EInlineChatStatus.ERROR
175
179
  ) {
176
180
  return;
177
181
  }
@@ -204,9 +208,13 @@ export class InlineChatHandler extends Disposable {
204
208
  return;
205
209
  }
206
210
 
211
+ this.aiInlineChatDisposed.addDispose(this.aiInlineChatService.launchChatStatus(EInlineChatStatus.READY));
212
+
207
213
  this.aiInlineContentWidget = this.injector.get(AIInlineContentWidget, [monacoEditor]);
208
214
 
209
- this.aiInlineContentWidget.show({ selection });
215
+ this.aiInlineContentWidget.show({
216
+ selection,
217
+ });
210
218
 
211
219
  this.aiInlineChatDisposed.addDispose(
212
220
  this.inlineChatFeatureRegistry.onChatClick(() => {
@@ -249,7 +257,7 @@ export class InlineChatHandler extends Disposable {
249
257
  return;
250
258
  }
251
259
 
252
- const strategy = await this.inlineChatFeatureRegistry.getInteractiveInputStrategyHandler()(monacoEditor, value);
260
+ const strategy = await this.inlineChatFeatureRegistry.getInteractiveInputStrategyHandler()(value);
253
261
 
254
262
  this.runInlineChatAction(
255
263
  monacoEditor,
@@ -293,7 +301,7 @@ export class InlineChatHandler extends Disposable {
293
301
  ): void {
294
302
  const { relationId, message, startTime, isRetry, isStop } = reportInfo;
295
303
 
296
- this.aiInlineChatDisposed.addDispose(this.aiInlineContentWidget.launchChatStatus(status));
304
+ this.aiInlineChatDisposed.addDispose(this.aiInlineChatService.launchChatStatus(status));
297
305
  this.aiReporter.end(relationId, {
298
306
  message,
299
307
  success: status !== EInlineChatStatus.ERROR,
@@ -455,15 +463,11 @@ export class InlineChatHandler extends Disposable {
455
463
  relationId: string,
456
464
  isRetry: boolean,
457
465
  ) {
458
- if (!this.aiInlineContentWidget) {
459
- return;
460
- }
461
-
462
466
  const model = monacoEditor.getModel();
463
467
 
464
468
  this.aiDiffWidget?.dispose();
465
469
  this.aiInlineChatOperationDisposed.dispose();
466
- this.aiInlineChatDisposed.addDispose(this.aiInlineContentWidget.launchChatStatus(EInlineChatStatus.THINKING));
470
+ this.aiInlineChatDisposed.addDispose(this.aiInlineChatService.launchChatStatus(EInlineChatStatus.THINKING));
467
471
 
468
472
  const startTime = Date.now();
469
473
 
@@ -499,16 +503,14 @@ export class InlineChatHandler extends Disposable {
499
503
  );
500
504
 
501
505
  this.aiInlineChatOperationDisposed.addDispose([
502
- this.aiInlineContentWidget.onResultClick((kind: EResultKind) => {
503
- if (kind === EResultKind.ACCEPT) {
504
- this.aiReporter.end(relationId, { message: 'accept', success: true, isReceive: true });
505
- const newValue = this.aiDiffWidget?.getModifiedModel()?.getValue() || '';
506
-
507
- monacoEditor.getModel()?.pushEditOperations(null, [{ range: crossSelection, text: newValue }], () => null);
508
- runWhenIdle(() => {
509
- this.disposeAllWidget();
510
- });
511
- }
506
+ this.aiInlineChatService.onAccept(() => {
507
+ this.aiReporter.end(relationId, { message: 'accept', success: true, isReceive: true });
508
+ const newValue = this.aiDiffWidget?.getModifiedModel()?.getValue() || '';
509
+
510
+ monacoEditor.getModel()?.pushEditOperations(null, [{ range: crossSelection, text: newValue }], () => null);
511
+ runWhenIdle(() => {
512
+ this.disposeAllWidget();
513
+ });
512
514
  }),
513
515
  this.aiInlineChatService.onThumbs((isLike: boolean) => {
514
516
  this.aiReporter.end(relationId, { isLike });
@@ -558,19 +560,18 @@ export class InlineChatHandler extends Disposable {
558
560
  );
559
561
 
560
562
  this.aiInlineChatDisposed.addDispose([
561
- this.aiInlineContentWidget.onResultClick(async (kind: EResultKind) => {
562
- if (kind === EResultKind.DISCARD) {
563
- this.aiReporter.end(relationId, { message: 'discard', success: true, isDrop: true });
564
- this.disposeAllWidget();
565
- } else if (kind === EResultKind.REGENERATE) {
566
- await this.handleDiffPreviewStrategy(
567
- monacoEditor,
568
- providerDiffPreviewStrategy,
569
- crossSelection,
570
- relationId,
571
- true,
572
- );
573
- }
563
+ this.aiInlineChatService.onDiscard(() => {
564
+ this.aiReporter.end(relationId, { message: 'discard', success: true, isDrop: true });
565
+ this.disposeAllWidget();
566
+ }),
567
+ this.aiInlineChatService.onRegenerate(async () => {
568
+ await this.handleDiffPreviewStrategy(
569
+ monacoEditor,
570
+ providerDiffPreviewStrategy,
571
+ crossSelection,
572
+ relationId,
573
+ true,
574
+ );
574
575
  }),
575
576
  ]);
576
577
  }
@@ -2,6 +2,6 @@
2
2
  min-width: initial !important;
3
3
  }
4
4
 
5
- .inline_chat_controller_box {
6
- padding: 6px;
5
+ .ai_inline_error_result_panel {
6
+ padding: 8px;
7
7
  }
@@ -1,6 +1,6 @@
1
- import { Injectable } from '@opensumi/di';
1
+ import { Autowired, 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 { AIBackSerivcePath, Emitter, Event, IAIBackService, runWhenIdle } from '@opensumi/ide-core-common';
4
4
 
5
5
  export const enum EInlineChatStatus {
6
6
  READY,
@@ -9,14 +9,16 @@ export const enum EInlineChatStatus {
9
9
  ERROR,
10
10
  }
11
11
 
12
- export const enum EResultKind {
13
- ACCEPT = 'ACCEPT',
14
- DISCARD = 'DISCARD',
15
- REGENERATE = 'REGENERATE',
16
- }
17
-
18
12
  @Injectable({ multiple: false })
19
13
  export class AIInlineChatService implements IAIInlineChatService {
14
+ @Autowired(AIBackSerivcePath)
15
+ aiBackService: IAIBackService;
16
+
17
+ private _status: EInlineChatStatus = EInlineChatStatus.READY;
18
+ public get status(): EInlineChatStatus {
19
+ return this._status;
20
+ }
21
+
20
22
  private _interactiveInputVisible: boolean = false;
21
23
  public get interactiveInputVisible(): boolean {
22
24
  return this._interactiveInputVisible;
@@ -28,6 +30,18 @@ export class AIInlineChatService implements IAIInlineChatService {
28
30
  public readonly _onInlineChatVisible = new Emitter<boolean>();
29
31
  public readonly onInlineChatVisible: Event<boolean> = this._onInlineChatVisible.event;
30
32
 
33
+ private readonly _onChatStatus = new Emitter<EInlineChatStatus>();
34
+ public readonly onChatStatus: Event<EInlineChatStatus> = this._onChatStatus.event;
35
+
36
+ public readonly _onAccept = new Emitter<void>();
37
+ public readonly onAccept: Event<void> = this._onAccept.event;
38
+
39
+ public readonly _onDiscard = new Emitter<void>();
40
+ public readonly onDiscard: Event<void> = this._onDiscard.event;
41
+
42
+ public readonly _onRegenerate = new Emitter<void>();
43
+ public readonly onRegenerate: Event<void> = this._onRegenerate.event;
44
+
31
45
  private readonly _onThumbs = new Emitter<boolean>();
32
46
  public readonly onThumbs: Event<boolean> = this._onThumbs.event;
33
47
 
@@ -35,6 +49,17 @@ export class AIInlineChatService implements IAIInlineChatService {
35
49
  this._onThumbs.fire(isThumbsUp);
36
50
  }
37
51
 
52
+ public isLoading(): boolean {
53
+ return this._status === EInlineChatStatus.THINKING;
54
+ }
55
+
56
+ public launchChatStatus(status: EInlineChatStatus) {
57
+ return runWhenIdle(() => {
58
+ this._status = status;
59
+ this._onChatStatus.fire(status);
60
+ });
61
+ }
62
+
38
63
  public launchInputVisible(v: boolean) {
39
64
  return runWhenIdle(() => {
40
65
  this._interactiveInputVisible = v;
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
4
4
  import { IAIInlineChatService, StackingLevelStr, useInjectable } from '@opensumi/ide-core-browser';
@@ -10,10 +10,8 @@ import {
10
10
  AIInlineChatContentWidgetId,
11
11
  Disposable,
12
12
  Emitter,
13
- Event,
14
13
  InlineChatFeatureRegistryToken,
15
14
  localize,
16
- runWhenIdle,
17
15
  } from '@opensumi/ide-core-common';
18
16
  import * as monaco from '@opensumi/ide-monaco';
19
17
  import { monacoBrowser } from '@opensumi/ide-monaco/lib/browser';
@@ -23,40 +21,42 @@ import {
23
21
  } from '@opensumi/ide-monaco/lib/browser/ai-native/BaseInlineContentWidget';
24
22
 
25
23
  import { AINativeContextKey } from '../../contextkey/ai-native.contextkey.service';
26
- import { InlineResultAction } from '../inline-actions/result-items/index';
27
24
 
28
25
  import { InlineChatFeatureRegistry } from './inline-chat.feature.registry';
29
26
  import styles from './inline-chat.module.less';
30
- import { AIInlineChatService, EInlineChatStatus, EResultKind } from './inline-chat.service';
27
+ import { AIInlineChatService, EInlineChatStatus } from './inline-chat.service';
31
28
 
32
29
  import type { ICodeEditor as IMonacoCodeEditor } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
33
30
 
34
- interface IAIInlineOperationProps {
31
+ export interface IAIInlineOperationProps {
35
32
  handleActions: (id: string) => void;
36
33
  status: EInlineChatStatus;
37
34
  onClose?: () => void;
38
35
  }
39
36
 
40
- interface IAIInlineChatControllerProps {
37
+ export interface IAIInlineChatControllerProps {
41
38
  onClickActions: (id: string) => void;
42
39
  onLayoutChange: (height: number) => void;
43
40
  onClose?: () => void;
44
41
  onInteractiveInputSend?: (value: string) => void;
45
- onChatStatus: Event<EInlineChatStatus>;
46
- onResultClick: (k: EResultKind) => void;
47
42
  }
48
43
 
49
- const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
50
- const { onClickActions, onClose, onInteractiveInputSend, onLayoutChange, onChatStatus, onResultClick } = props;
44
+ export const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
45
+ const { onClickActions, onClose, onInteractiveInputSend, onLayoutChange } = props;
51
46
  const aiInlineChatService: AIInlineChatService = useInjectable(IAIInlineChatService);
52
47
  const inlineChatFeatureRegistry: InlineChatFeatureRegistry = useInjectable(InlineChatFeatureRegistryToken);
53
48
  const [status, setStatus] = useState<EInlineChatStatus>(EInlineChatStatus.READY);
54
- const [inputValue, setInputValue] = useState<string>('');
55
49
  const [interactiveInputVisible, setInteractiveInputVisible] = useState<boolean>(false);
56
50
 
51
+ const interactiveInputRef = useRef<HTMLTextAreaElement | null>(null);
52
+
57
53
  useEffect(() => {
58
54
  const dis = new Disposable();
59
- dis.addDispose(onChatStatus((s) => setStatus(s)));
55
+ dis.addDispose(
56
+ aiInlineChatService.onChatStatus((status) => {
57
+ setStatus(status);
58
+ }),
59
+ );
60
60
 
61
61
  dis.addDispose(
62
62
  aiInlineChatService.onInteractiveInputVisible((v) => {
@@ -67,19 +67,52 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
67
67
  return () => {
68
68
  dis.dispose();
69
69
  };
70
- }, [onChatStatus, aiInlineChatService]);
70
+ }, []);
71
+
72
+ useEffect(() => {
73
+ if (interactiveInputVisible === true && interactiveInputRef.current) {
74
+ interactiveInputRef.current.focus();
75
+ }
76
+ }, [interactiveInputVisible, interactiveInputRef]);
71
77
 
72
78
  useEffect(() => {
73
79
  if (status === EInlineChatStatus.ERROR) {
74
80
  onClose?.();
75
81
  }
76
- }, [onClose]);
82
+ }, [status, onClose]);
77
83
 
78
84
  const isLoading = useMemo(() => status === EInlineChatStatus.THINKING, [status]);
79
85
  const isDone = useMemo(() => status === EInlineChatStatus.DONE, [status]);
80
86
  const isError = useMemo(() => status === EInlineChatStatus.ERROR, [status]);
81
87
  const operationList = useMemo(() => inlineChatFeatureRegistry.getEditorActionButtons(), [inlineChatFeatureRegistry]);
82
88
 
89
+ const iconResultItems = useMemo(
90
+ () => [
91
+ {
92
+ icon: 'check',
93
+ text: localize('aiNative.inline.chat.operate.check.title'),
94
+ onClick: () => {
95
+ aiInlineChatService._onAccept.fire();
96
+ },
97
+ },
98
+ {
99
+ icon: 'discard',
100
+ text: localize('aiNative.operate.discard.title'),
101
+ onClick: () => {
102
+ aiInlineChatService._onDiscard.fire();
103
+ },
104
+ },
105
+ {
106
+ icon: 'afresh',
107
+ text: localize('aiNative.operate.afresh.title'),
108
+ onClick: () => {
109
+ aiInlineChatService._onRegenerate.fire();
110
+ },
111
+ },
112
+ ],
113
+ [],
114
+ );
115
+
83
116
  const handleClickActions = useCallback(
84
117
  (id: string) => {
85
118
  onClickActions?.(id);
@@ -94,6 +127,7 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
94
127
  const handleInteractiveInputSend = useCallback(
95
128
  (value: string) => {
96
129
  onInteractiveInputSend?.(value);
130
+ aiInlineChatService.launchChatStatus(EInlineChatStatus.THINKING);
97
131
  },
98
132
  [onInteractiveInputSend],
99
133
  );
@@ -114,10 +148,6 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
114
148
  [inlineChatFeatureRegistry],
115
149
  );
116
150
 
117
- const handleValueChange = useCallback((value) => {
118
- setInputValue(value);
119
- }, []);
120
-
121
151
  const customOperationRender = useMemo(() => {
122
152
  if (!interactiveInputVisible) {
123
153
  return null;
@@ -125,18 +155,16 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
125
155
 
126
156
  return (
127
157
  <InteractiveInput
128
- autoFocus
158
+ ref={interactiveInputRef}
129
159
  onHeightChange={(height) => onLayoutChange(height)}
130
160
  size='small'
131
161
  placeholder={localize('aiNative.inline.chat.input.placeholder.default')}
132
162
  width={320}
133
163
  disabled={isLoading}
134
- value={inputValue}
135
- onValueChange={handleValueChange}
136
164
  onSend={handleInteractiveInputSend}
137
165
  />
138
166
  );
139
- }, [isLoading, interactiveInputVisible, inputValue]);
167
+ }, [isLoading, interactiveInputVisible]);
140
168
 
141
169
  const renderContent = useCallback(() => {
142
170
  if (operationList.length === 0 && moreOperation.length === 0) {
@@ -148,7 +176,11 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
148
176
  }
149
177
 
150
178
  if (isDone) {
151
- return <InlineResultAction onResultClick={onResultClick} />;
179
+ return (
180
+ <ContentWidgetContainerPanel style={{ transform: 'translateY(4px)' }}>
181
+ <AIInlineResult iconItems={iconResultItems} />
182
+ </ContentWidgetContainerPanel>
183
+ );
152
184
  }
153
185
 
154
186
  return (
@@ -162,13 +194,9 @@ const AIInlineChatController = (props: IAIInlineChatControllerProps) => {
162
194
  customOperationRender={customOperationRender}
163
195
  />
164
196
  );
165
- }, [operationList, moreOperation, customOperationRender, onResultClick, status, interactiveInputVisible]);
197
+ }, [operationList, moreOperation, customOperationRender, iconResultItems, status, interactiveInputVisible]);
166
198
 
167
- return (
168
- <div className={styles.inline_chat_controller_box} style={isDone ? { transform: 'translateY(-15px)' } : {}}>
169
- {renderContent()}
170
- </div>
171
- );
199
+ return <div style={isDone ? { transform: 'translateY(-15px)' } : {}}>{renderContent()}</div>;
172
200
  };
173
201
 
174
202
  @Injectable({ multiple: true })
@@ -176,6 +204,9 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
176
204
  @Autowired(INJECTOR_TOKEN)
177
205
  private readonly injector: Injector;
178
206
 
207
+ @Autowired(IAIInlineChatService)
208
+ private aiInlineChatService: AIInlineChatService;
209
+
179
210
  @Autowired(InlineChatFeatureRegistryToken)
180
211
  private readonly inlineChatFeatureRegistry: InlineChatFeatureRegistry;
181
212
 
@@ -186,25 +217,9 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
186
217
  private readonly _onActionClickEmitter = new Emitter<{ actionId: string; source: string }>();
187
218
  public readonly onActionClick = this._onActionClickEmitter.event;
188
219
 
189
- protected readonly _onInteractiveInputValue = new Emitter<string>();
220
+ private readonly _onInteractiveInputValue = new Emitter<string>();
190
221
  public readonly onInteractiveInputValue = this._onInteractiveInputValue.event;
191
222
 
192
- protected readonly _onStatusChange = new Emitter<EInlineChatStatus>();
193
- public readonly onStatusChange: Event<EInlineChatStatus> = this._onStatusChange.event;
194
-
195
- protected readonly _onResultClick = new Emitter<EResultKind>();
196
- public readonly onResultClick: Event<EResultKind> = this._onResultClick.event;
197
-
198
- protected _interactiveInputValue: string;
199
- public get interactiveInputValue(): string {
200
- return this._interactiveInputValue;
201
- }
202
-
203
- protected _status: EInlineChatStatus = EInlineChatStatus.READY;
204
- public get status(): EInlineChatStatus {
205
- return this._status;
206
- }
207
-
208
223
  constructor(protected readonly editor: IMonacoCodeEditor) {
209
224
  super(editor);
210
225
 
@@ -218,15 +233,8 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
218
233
  );
219
234
  }
220
235
 
221
- public launchChatStatus(status: EInlineChatStatus) {
222
- return runWhenIdle(() => {
223
- this._status = status;
224
- this._onStatusChange.fire(status);
225
- });
226
- }
227
-
228
236
  override dispose(): void {
229
- this.launchChatStatus(EInlineChatStatus.READY);
237
+ this.aiInlineChatService.launchChatStatus(EInlineChatStatus.READY);
230
238
  super.dispose();
231
239
  }
232
240
 
@@ -244,18 +252,10 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
244
252
  <AIInlineChatController
245
253
  onClickActions={(id) => this.clickActionId(id, 'widget')}
246
254
  onClose={() => this.dispose()}
247
- onChatStatus={this.onStatusChange.bind(this)}
248
255
  onLayoutChange={() => {
249
256
  this.editor.layoutContentWidget(this);
250
257
  }}
251
- onInteractiveInputSend={(value) => {
252
- this.launchChatStatus(EInlineChatStatus.THINKING);
253
- this._interactiveInputValue = value;
254
- this._onInteractiveInputValue.fire(value);
255
- }}
256
- onResultClick={(kind: EResultKind) => {
257
- this._onResultClick.fire(kind);
258
- }}
258
+ onInteractiveInputSend={(value) => this._onInteractiveInputValue.fire(value)}
259
259
  />
260
260
  );
261
261
  }
@@ -268,6 +268,7 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
268
268
  override getDomNode(): HTMLElement {
269
269
  const domNode = super.getDomNode();
270
270
  requestAnimationFrame(() => {
271
+ domNode.style.padding = '6px';
271
272
  domNode.style.zIndex = StackingLevelStr.OverlayTop;
272
273
  });
273
274
  return domNode;
@@ -411,7 +412,7 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
411
412
  * 2. 靠近光标处周围没有字符的空白区域作为要显示的区域
412
413
  * 3. 显示的区域方向在右侧,左侧不考虑
413
414
  */
414
- protected computePosition(selection: monaco.Selection): monaco.editor.IContentWidgetPosition | null {
415
+ private computePosition(selection: monaco.Selection): monaco.editor.IContentWidgetPosition | null {
415
416
  const startPosition = selection.getStartPosition();
416
417
  const endPosition = selection.getEndPosition();
417
418
  const model = this.editor.getModel();
@@ -4,8 +4,9 @@ import ReactDOMClient from 'react-dom/client';
4
4
 
5
5
  import { Autowired, Injectable } from '@opensumi/di';
6
6
  import { AppConfig, ConfigProvider, Emitter, Event, MonacoService, useInjectable } from '@opensumi/ide-core-browser';
7
- import * as monaco from '@opensumi/ide-monaco';
8
7
  import { ICodeEditor } from '@opensumi/ide-monaco';
8
+ import * as monaco from '@opensumi/ide-monaco';
9
+ import { monaco as monacoApi } from '@opensumi/ide-monaco/lib/browser/monaco-api';
9
10
  import { IDiffEditorOptions } from '@opensumi/ide-monaco/lib/browser/monaco-api/editor';
10
11
  import { ILanguageSelection } from '@opensumi/monaco-editor-core/esm/vs/editor/common/languages/language';
11
12
  import { ITextModel } from '@opensumi/monaco-editor-core/esm/vs/editor/common/model';
@@ -1,5 +1,6 @@
1
1
  import { asClassNameArrayWrapper } from '@opensumi/ide-core-browser';
2
- import { Codicon, Sumicon } from '@opensumi/ide-core-common/lib/codicons';
2
+ import { Sumicon } from '@opensumi/ide-core-common/lib/codicons';
3
+ import { Codicon } from '@opensumi/monaco-editor-core/esm/vs/base/common/codicons';
3
4
  import { ThemeIcon } from '@opensumi/monaco-editor-core/esm/vs/base/common/themables';
4
5
  import {
5
6
  LightBulbState,
@@ -1,7 +0,0 @@
1
- import React from 'react';
2
- import { EResultKind } from '../../inline-chat/inline-chat.service';
3
- export interface IInlineResultActionProps {
4
- onResultClick: (k: EResultKind) => void;
5
- }
6
- export declare const InlineResultAction: ({ onResultClick }: IInlineResultActionProps) => React.JSX.Element;
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/browser/widget/inline-actions/result-items/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAMvC,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAEpE,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,kBAAkB,sBAAuB,wBAAwB,sBA2B7E,CAAC"}
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InlineResultAction = void 0;
4
- const tslib_1 = require("tslib");
5
- const react_1 = tslib_1.__importStar(require("react"));
6
- const containerPanel_1 = require("@opensumi/ide-core-browser/lib/components/ai-native/content-widget/containerPanel");
7
- const index_1 = require("@opensumi/ide-core-browser/lib/components/ai-native/index");
8
- const ide_core_common_1 = require("@opensumi/ide-core-common");
9
- const InlineResultAction = ({ onResultClick }) => {
10
- const iconResultItems = (0, react_1.useMemo)(() => [
11
- {
12
- icon: 'check',
13
- text: (0, ide_core_common_1.localize)('aiNative.inline.chat.operate.check.title'),
14
- onClick: () => onResultClick("ACCEPT" /* EResultKind.ACCEPT */),
15
- },
16
- {
17
- icon: 'discard',
18
- text: (0, ide_core_common_1.localize)('aiNative.operate.discard.title'),
19
- onClick: () => onResultClick("DISCARD" /* EResultKind.DISCARD */),
20
- },
21
- {
22
- icon: 'afresh',
23
- text: (0, ide_core_common_1.localize)('aiNative.operate.afresh.title'),
24
- onClick: () => onResultClick("REGENERATE" /* EResultKind.REGENERATE */),
25
- },
26
- ], [onResultClick]);
27
- return (react_1.default.createElement(containerPanel_1.ContentWidgetContainerPanel, { style: { transform: 'translateY(4px)' } },
28
- react_1.default.createElement(index_1.AIInlineResult, { iconItems: iconResultItems })));
29
- };
30
- exports.InlineResultAction = InlineResultAction;
31
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/browser/widget/inline-actions/result-items/index.tsx"],"names":[],"mappings":";;;;AAAA,uDAAuC;AAEvC,sHAAgI;AAChI,qFAA2F;AAC3F,+DAAqD;AAQ9C,MAAM,kBAAkB,GAAG,CAAC,EAAE,aAAa,EAA4B,EAAE,EAAE;IAChF,MAAM,eAAe,GAAG,IAAA,eAAO,EAC7B,GAAG,EAAE,CAAC;QACJ;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,IAAA,0BAAQ,EAAC,0CAA0C,CAAC;YAC1D,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,mCAAoB;SACjD;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,IAAA,0BAAQ,EAAC,gCAAgC,CAAC;YAChD,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,qCAAqB;SAClD;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,IAAA,0BAAQ,EAAC,+BAA+B,CAAC;YAC/C,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,2CAAwB;SACrD;KACF,EACD,CAAC,aAAa,CAAC,CAChB,CAAC;IAEF,OAAO,CACL,8BAAC,4CAA2B,IAAC,KAAK,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE;QAClE,8BAAC,sBAAc,IAAC,SAAS,EAAE,eAAe,GAAI,CAClB,CAC/B,CAAC;AACJ,CAAC,CAAC;AA3BW,QAAA,kBAAkB,sBA2B7B"}