@opensumi/ide-ai-native 3.7.1-next-1738824147.0 → 3.7.1-next-1738917599.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 (22) hide show
  1. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
  2. package/lib/browser/widget/inline-chat/inline-content-widget.js +0 -5
  3. package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
  4. package/lib/browser/widget/inline-input/inline-input-widget.d.ts +5 -3
  5. package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
  6. package/lib/browser/widget/inline-input/inline-input-widget.js +14 -10
  7. package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
  8. package/lib/browser/widget/inline-input/inline-input.controller.d.ts +3 -0
  9. package/lib/browser/widget/inline-input/inline-input.controller.d.ts.map +1 -1
  10. package/lib/browser/widget/inline-input/inline-input.controller.js +96 -37
  11. package/lib/browser/widget/inline-input/inline-input.controller.js.map +1 -1
  12. package/lib/browser/widget/inline-input/inline-input.module.less +4 -0
  13. package/lib/browser/widget/inline-input/model.d.ts +19 -1
  14. package/lib/browser/widget/inline-input/model.d.ts.map +1 -1
  15. package/lib/browser/widget/inline-input/model.js +39 -1
  16. package/lib/browser/widget/inline-input/model.js.map +1 -1
  17. package/package.json +21 -21
  18. package/src/browser/widget/inline-chat/inline-content-widget.tsx +0 -7
  19. package/src/browser/widget/inline-input/inline-input-widget.tsx +14 -5
  20. package/src/browser/widget/inline-input/inline-input.controller.ts +129 -44
  21. package/src/browser/widget/inline-input/inline-input.module.less +4 -0
  22. package/src/browser/widget/inline-input/model.ts +41 -1
@@ -1,5 +1,5 @@
1
1
  import { MaybePromise } from '@opensumi/ide-core-common';
2
- import { ICodeEditor } from '@opensumi/ide-monaco';
2
+ import { ICodeEditor, IPosition, Selection } from '@opensumi/ide-monaco';
3
3
  import { ERunStrategy, IInteractiveInputHandler } from '../../types';
4
4
  type TRunStrategyFn = (editor: ICodeEditor, value: string) => MaybePromise<ERunStrategy>;
5
5
  export declare class InteractiveInputModel {
@@ -12,5 +12,23 @@ export declare class InteractiveInputModel {
12
12
  strategyHandler(): TRunStrategyFn;
13
13
  dispose(): void;
14
14
  }
15
+ export declare class InlineInputWidgetStoreInEmptyLine {
16
+ private position;
17
+ private value?;
18
+ constructor(position: IPosition, value?: string | undefined);
19
+ getPosition(): IPosition;
20
+ setPosition(position: IPosition): void;
21
+ getValue(): string | undefined;
22
+ setValue(value: string): void;
23
+ }
24
+ export declare class InlineInputWidgetStoreInSelection {
25
+ private selection;
26
+ private value?;
27
+ constructor(selection: Selection, value?: string | undefined);
28
+ getSelection(): Selection;
29
+ setSelection(selection: Selection): void;
30
+ getValue(): string | undefined;
31
+ setValue(value: string): void;
32
+ }
15
33
  export {};
16
34
  //# sourceMappingURL=model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../src/browser/widget/inline-input/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAQ,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAErE,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,KAAK,YAAY,CAAC,YAAY,CAAC,CAAC;AAEzF,qBAAa,qBAAqB;IAChC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAgD;IAEjE,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,gBAAgB,CAAiB;IAElC,UAAU,CAAC,CAAC,EAAE,wBAAwB,GAAG,IAAI;IAI7C,OAAO,IAAI,wBAAwB,GAAG,SAAS;IAI/C,kBAAkB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI;IAI5C,eAAe,IAAI,cAAc;IAIjC,OAAO,IAAI,IAAI;CAGvB"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../src/browser/widget/inline-input/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAQ,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAErE,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,KAAK,YAAY,CAAC,YAAY,CAAC,CAAC;AAEzF,qBAAa,qBAAqB;IAChC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAgD;IAEjE,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,gBAAgB,CAAiB;IAElC,UAAU,CAAC,CAAC,EAAE,wBAAwB,GAAG,IAAI;IAI7C,OAAO,IAAI,wBAAwB,GAAG,SAAS;IAI/C,kBAAkB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI;IAI5C,eAAe,IAAI,cAAc;IAIjC,OAAO,IAAI,IAAI;CAGvB;AAED,qBAAa,iCAAiC;IAChC,OAAO,CAAC,QAAQ;IAAa,OAAO,CAAC,KAAK,CAAC;gBAAnC,QAAQ,EAAE,SAAS,EAAU,KAAK,CAAC,EAAE,MAAM,YAAA;IAExD,WAAW,IAAI,SAAS;IAIxB,WAAW,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI;IAItC,QAAQ,IAAI,MAAM,GAAG,SAAS;IAI9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAGrC;AAED,qBAAa,iCAAiC;IAChC,OAAO,CAAC,SAAS;IAAa,OAAO,CAAC,KAAK,CAAC;gBAApC,SAAS,EAAE,SAAS,EAAU,KAAK,CAAC,EAAE,MAAM,YAAA;IAEzD,YAAY,IAAI,SAAS;IAIzB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAIxC,QAAQ,IAAI,MAAM,GAAG,SAAS;IAI9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAGrC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InteractiveInputModel = void 0;
3
+ exports.InlineInputWidgetStoreInSelection = exports.InlineInputWidgetStoreInEmptyLine = exports.InteractiveInputModel = void 0;
4
4
  const ai_native_1 = require("@opensumi/ide-core-browser/lib/components/ai-native");
5
5
  const ide_core_common_1 = require("@opensumi/ide-core-common");
6
6
  class InteractiveInputModel {
@@ -22,4 +22,42 @@ class InteractiveInputModel {
22
22
  }
23
23
  exports.InteractiveInputModel = InteractiveInputModel;
24
24
  InteractiveInputModel.ID = `${ai_native_1.InteractiveInput.displayName}:${(0, ide_core_common_1.uuid)(4)}`;
25
+ class InlineInputWidgetStoreInEmptyLine {
26
+ constructor(position, value) {
27
+ this.position = position;
28
+ this.value = value;
29
+ }
30
+ getPosition() {
31
+ return this.position;
32
+ }
33
+ setPosition(position) {
34
+ this.position = position;
35
+ }
36
+ getValue() {
37
+ return this.value;
38
+ }
39
+ setValue(value) {
40
+ this.value = value;
41
+ }
42
+ }
43
+ exports.InlineInputWidgetStoreInEmptyLine = InlineInputWidgetStoreInEmptyLine;
44
+ class InlineInputWidgetStoreInSelection {
45
+ constructor(selection, value) {
46
+ this.selection = selection;
47
+ this.value = value;
48
+ }
49
+ getSelection() {
50
+ return this.selection;
51
+ }
52
+ setSelection(selection) {
53
+ this.selection = selection;
54
+ }
55
+ getValue() {
56
+ return this.value;
57
+ }
58
+ setValue(value) {
59
+ this.value = value;
60
+ }
61
+ }
62
+ exports.InlineInputWidgetStoreInSelection = InlineInputWidgetStoreInSelection;
25
63
  //# sourceMappingURL=model.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../src/browser/widget/inline-input/model.ts"],"names":[],"mappings":";;;AAAA,mFAAuF;AACvF,+DAA+D;AAO/D,MAAa,qBAAqB;IAMzB,UAAU,CAAC,CAA2B;QAC3C,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACpB,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAEM,kBAAkB,CAAC,EAAkB;QAC1C,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC7B,CAAC;IAEM,eAAe;QACpB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;;AAxBH,sDAyBC;AAxBQ,wBAAE,GAAW,GAAG,4BAAgB,CAAC,WAAW,IAAI,IAAA,sBAAI,EAAC,CAAC,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../src/browser/widget/inline-input/model.ts"],"names":[],"mappings":";;;AAAA,mFAAuF;AACvF,+DAA+D;AAO/D,MAAa,qBAAqB;IAMzB,UAAU,CAAC,CAA2B;QAC3C,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACpB,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAEM,kBAAkB,CAAC,EAAkB;QAC1C,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC7B,CAAC;IAEM,eAAe;QACpB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;;AAxBH,sDAyBC;AAxBQ,wBAAE,GAAW,GAAG,4BAAgB,CAAC,WAAW,IAAI,IAAA,sBAAI,EAAC,CAAC,CAAC,EAAE,CAAC;AA0BnE,MAAa,iCAAiC;IAC5C,YAAoB,QAAmB,EAAU,KAAc;QAA3C,aAAQ,GAAR,QAAQ,CAAW;QAAU,UAAK,GAAL,KAAK,CAAS;IAAG,CAAC;IAE5D,WAAW;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAEM,WAAW,CAAC,QAAmB;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEM,QAAQ,CAAC,KAAa;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAlBD,8EAkBC;AAED,MAAa,iCAAiC;IAC5C,YAAoB,SAAoB,EAAU,KAAc;QAA5C,cAAS,GAAT,SAAS,CAAW;QAAU,UAAK,GAAL,KAAK,CAAS;IAAG,CAAC;IAE7D,YAAY;QACjB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEM,YAAY,CAAC,SAAoB;QACtC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEM,QAAQ,CAAC,KAAa;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAlBD,8EAkBC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensumi/ide-ai-native",
3
- "version": "3.7.1-next-1738824147.0",
3
+ "version": "3.7.1-next-1738917599.0",
4
4
  "files": [
5
5
  "lib",
6
6
  "src"
@@ -19,24 +19,24 @@
19
19
  "url": "git@github.com:opensumi/core.git"
20
20
  },
21
21
  "dependencies": {
22
- "@opensumi/ide-components": "3.7.1-next-1738824147.0",
23
- "@opensumi/ide-core-common": "3.7.1-next-1738824147.0",
24
- "@opensumi/ide-core-node": "3.7.1-next-1738824147.0",
25
- "@opensumi/ide-debug": "3.7.1-next-1738824147.0",
26
- "@opensumi/ide-design": "3.7.1-next-1738824147.0",
27
- "@opensumi/ide-editor": "3.7.1-next-1738824147.0",
28
- "@opensumi/ide-file-service": "3.7.1-next-1738824147.0",
29
- "@opensumi/ide-file-tree-next": "3.7.1-next-1738824147.0",
30
- "@opensumi/ide-main-layout": "3.7.1-next-1738824147.0",
31
- "@opensumi/ide-markers": "3.7.1-next-1738824147.0",
32
- "@opensumi/ide-menu-bar": "3.7.1-next-1738824147.0",
33
- "@opensumi/ide-monaco": "3.7.1-next-1738824147.0",
34
- "@opensumi/ide-overlay": "3.7.1-next-1738824147.0",
35
- "@opensumi/ide-preferences": "3.7.1-next-1738824147.0",
36
- "@opensumi/ide-terminal-next": "3.7.1-next-1738824147.0",
37
- "@opensumi/ide-theme": "3.7.1-next-1738824147.0",
38
- "@opensumi/ide-utils": "3.7.1-next-1738824147.0",
39
- "@opensumi/ide-workspace": "3.7.1-next-1738824147.0",
22
+ "@opensumi/ide-components": "3.7.1-next-1738917599.0",
23
+ "@opensumi/ide-core-common": "3.7.1-next-1738917599.0",
24
+ "@opensumi/ide-core-node": "3.7.1-next-1738917599.0",
25
+ "@opensumi/ide-debug": "3.7.1-next-1738917599.0",
26
+ "@opensumi/ide-design": "3.7.1-next-1738917599.0",
27
+ "@opensumi/ide-editor": "3.7.1-next-1738917599.0",
28
+ "@opensumi/ide-file-service": "3.7.1-next-1738917599.0",
29
+ "@opensumi/ide-file-tree-next": "3.7.1-next-1738917599.0",
30
+ "@opensumi/ide-main-layout": "3.7.1-next-1738917599.0",
31
+ "@opensumi/ide-markers": "3.7.1-next-1738917599.0",
32
+ "@opensumi/ide-menu-bar": "3.7.1-next-1738917599.0",
33
+ "@opensumi/ide-monaco": "3.7.1-next-1738917599.0",
34
+ "@opensumi/ide-overlay": "3.7.1-next-1738917599.0",
35
+ "@opensumi/ide-preferences": "3.7.1-next-1738917599.0",
36
+ "@opensumi/ide-terminal-next": "3.7.1-next-1738917599.0",
37
+ "@opensumi/ide-theme": "3.7.1-next-1738917599.0",
38
+ "@opensumi/ide-utils": "3.7.1-next-1738917599.0",
39
+ "@opensumi/ide-workspace": "3.7.1-next-1738917599.0",
40
40
  "@xterm/xterm": "5.5.0",
41
41
  "ansi-regex": "^2.0.0",
42
42
  "dom-align": "^1.7.0",
@@ -46,7 +46,7 @@
46
46
  "web-tree-sitter": "0.22.6"
47
47
  },
48
48
  "devDependencies": {
49
- "@opensumi/ide-core-browser": "3.7.1-next-1738824147.0"
49
+ "@opensumi/ide-core-browser": "3.7.1-next-1738917599.0"
50
50
  },
51
- "gitHead": "02602f682849bbc5a11335109cfbe6501c268990"
51
+ "gitHead": "888e545820c021e6148e4ff7ef72dfc8dbd9527e"
52
52
  }
@@ -151,13 +151,6 @@ export class AIInlineContentWidget extends ReactInlineContentWidget {
151
151
  super(editor);
152
152
 
153
153
  this.aiNativeContextKey = this.injector.get(AINativeContextKey, [this.editor.contextKeyService]);
154
- this.addDispose(
155
- this.editor.onDidLayoutChange(() => {
156
- if (this.isOutOfArea()) {
157
- this.dispose();
158
- }
159
- }),
160
- );
161
154
  }
162
155
 
163
156
  public launchChatStatus(status: EInlineChatStatus) {
@@ -21,10 +21,12 @@ interface IInlineInputWidgetRenderProps {
21
21
  onInteractiveInputSend?: (value: string) => void;
22
22
  onChatStatus: Event<EInlineChatStatus>;
23
23
  onResultClick: (k: EResultKind) => void;
24
+ onValueChange?: (value: string) => void;
24
25
  }
25
26
 
26
27
  const InlineInputWidgetRender = (props: IInlineInputWidgetRenderProps) => {
27
- const { defaultValue, onClose, onInteractiveInputSend, onLayoutChange, onChatStatus, onResultClick } = props;
28
+ const { defaultValue, onClose, onInteractiveInputSend, onLayoutChange, onChatStatus, onResultClick, onValueChange } =
29
+ props;
28
30
  const [status, setStatus] = useState<EInlineChatStatus>(EInlineChatStatus.READY);
29
31
  const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
30
32
 
@@ -69,6 +71,7 @@ const InlineInputWidgetRender = (props: IInlineInputWidgetRenderProps) => {
69
71
  <InteractiveInput
70
72
  autoFocus
71
73
  defaultValue={defaultValue}
74
+ onValueChange={onValueChange}
72
75
  onHeightChange={(height) => onLayoutChange(height)}
73
76
  size='small'
74
77
  placeholder={localize('aiNative.inline.chat.input.placeholder.default')}
@@ -82,16 +85,19 @@ const InlineInputWidgetRender = (props: IInlineInputWidgetRenderProps) => {
82
85
  };
83
86
 
84
87
  @Injectable({ multiple: true })
85
- export class InlineInputChatWidget extends AIInlineContentWidget {
88
+ export class InlineInputWidget extends AIInlineContentWidget {
86
89
  allowEditorOverflow = true;
87
90
  positionPreference = [ContentWidgetPositionPreference.ABOVE];
88
91
 
89
- protected readonly _onInteractiveInputValue = new Emitter<string>();
90
- public readonly onInteractiveInputValue = this._onInteractiveInputValue.event;
92
+ protected readonly _onSend = new Emitter<string>();
93
+ public readonly onSend = this._onSend.event;
91
94
 
92
95
  protected readonly _onClose = new Emitter<void>();
93
96
  public readonly onClose = this._onClose.event;
94
97
 
98
+ protected readonly _onValueChange = new Emitter<string>();
99
+ public readonly onValueChange = this._onValueChange.event;
100
+
95
101
  constructor(protected readonly editor: IMonacoCodeEditor, protected readonly defaultValue?: string) {
96
102
  super(editor);
97
103
  }
@@ -115,9 +121,12 @@ export class InlineInputChatWidget extends AIInlineContentWidget {
115
121
  onLayoutChange={() => {
116
122
  this.editor.layoutContentWidget(this);
117
123
  }}
124
+ onValueChange={(value) => {
125
+ this._onValueChange.fire(value);
126
+ }}
118
127
  onInteractiveInputSend={(value) => {
119
128
  this.launchChatStatus(EInlineChatStatus.THINKING);
120
- this._onInteractiveInputValue.fire(value);
129
+ this._onSend.fire(value);
121
130
  }}
122
131
  onResultClick={(k: EResultKind) => {
123
132
  this._onResultClick.fire(k);
@@ -15,6 +15,13 @@ import {
15
15
  import { EditorGroupCloseEvent } from '@opensumi/ide-editor/lib/browser';
16
16
  import * as monaco from '@opensumi/ide-monaco';
17
17
  import { ICodeEditor } from '@opensumi/ide-monaco';
18
+ import {
19
+ IObservable,
20
+ ISettableObservable,
21
+ autorun,
22
+ observableFromEvent,
23
+ observableValue,
24
+ } from '@opensumi/ide-monaco/lib/common/observable';
18
25
  import { MessageService } from '@opensumi/ide-overlay/lib/browser/message.service';
19
26
  import { EditOperation } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/editOperation';
20
27
  import { LineRange } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/lineRange';
@@ -28,11 +35,10 @@ import { EInlineChatStatus, EResultKind } from '../inline-chat/inline-chat.servi
28
35
  import { InlineDiffController } from '../inline-diff';
29
36
  import { InlineInputPreviewDecorationID } from '../internal.type';
30
37
 
31
-
32
- import { InlineInputChatWidget } from './inline-input-widget';
38
+ import { InlineInputWidget } from './inline-input-widget';
33
39
  import styles from './inline-input.module.less';
34
40
  import { InlineInputService } from './inline-input.service';
35
-
41
+ import { InlineInputWidgetStoreInEmptyLine, InlineInputWidgetStoreInSelection } from './model';
36
42
  @Injectable()
37
43
  export class InlineInputController extends BaseAIMonacoEditorController {
38
44
  public static readonly ID = 'editor.contrib.ai.inline.input';
@@ -61,11 +67,25 @@ export class InlineInputController extends BaseAIMonacoEditorController {
61
67
  private inputDisposable: Disposable;
62
68
  private aiNativeContextKey: AINativeContextKey;
63
69
 
70
+ private inputValue: ISettableObservable<string>;
71
+ private modelChangeObs: IObservable<monaco.editor.ITextModel, unknown>;
72
+ private inlineInputWidgetStore = new Map<
73
+ string,
74
+ InlineInputWidgetStoreInEmptyLine | InlineInputWidgetStoreInSelection | null
75
+ >();
76
+
64
77
  mount(): IDisposable {
65
78
  this.inputDisposable = new Disposable();
66
79
  this.aiNativeContextKey = this.injector.get(AINativeContextKey, [this.monacoEditor.contextKeyService]);
67
80
  this.inlineDiffController = InlineDiffController.get(this.monacoEditor)!;
68
81
 
82
+ this.inputValue = observableValue(this, '');
83
+ this.modelChangeObs = observableFromEvent<monaco.editor.ITextModel>(
84
+ this,
85
+ this.monacoEditor.onDidChangeModel,
86
+ () => this.monacoEditor.getModel()!,
87
+ );
88
+
69
89
  this.featureDisposable.addDispose(
70
90
  /**
71
91
  * 如果在流式过程中,直接关闭了当前文件,则需要销毁 diff previewer 并隐藏 input,恢复原始代码
@@ -92,10 +112,7 @@ export class InlineInputController extends BaseAIMonacoEditorController {
92
112
  );
93
113
 
94
114
  this.featureDisposable.addDispose(
95
- Event.any<any>(
96
- this.inlineInputService.onHidden,
97
- this.monacoEditor.onWillChangeModel,
98
- )(() => {
115
+ this.inlineInputService.onHidden(() => {
99
116
  this.hideInput();
100
117
  }),
101
118
  );
@@ -120,6 +137,27 @@ export class InlineInputController extends BaseAIMonacoEditorController {
120
137
  }),
121
138
  );
122
139
 
140
+ this.featureDisposable.addDispose(
141
+ autorun((reader) => {
142
+ const model = this.modelChangeObs.read(reader);
143
+ if (!model) {
144
+ return;
145
+ }
146
+
147
+ const storeData = this.inlineInputWidgetStore.get(model.id);
148
+ if (!storeData) {
149
+ this.hideInput();
150
+ return;
151
+ }
152
+
153
+ if (storeData instanceof InlineInputWidgetStoreInEmptyLine) {
154
+ this.showInputInEmptyLine(storeData.getPosition(), this.monacoEditor, storeData.getValue());
155
+ } else if (storeData instanceof InlineInputWidgetStoreInSelection) {
156
+ this.showInputInSelection(storeData.getSelection(), this.monacoEditor, storeData.getValue());
157
+ }
158
+ }),
159
+ );
160
+
123
161
  this.featureDisposable.addDispose(this.inputDisposable);
124
162
 
125
163
  return this.featureDisposable;
@@ -131,6 +169,7 @@ export class InlineInputController extends BaseAIMonacoEditorController {
131
169
  }
132
170
 
133
171
  private hideInput() {
172
+ this.inlineInputWidgetStore.delete(this.monacoEditor.getModel()!.id);
134
173
  this.inputDisposable.dispose();
135
174
  }
136
175
 
@@ -146,15 +185,16 @@ export class InlineInputController extends BaseAIMonacoEditorController {
146
185
  return;
147
186
  }
148
187
 
188
+ this.inputValue.set(defaultValue || '', undefined);
189
+ this.inlineInputWidgetStore.set(model.id, new InlineInputWidgetStoreInEmptyLine(position, defaultValue));
190
+
149
191
  if (this.inputDisposable) {
150
192
  this.inputDisposable.dispose();
151
193
  this.inputDisposable = new Disposable();
152
194
  }
153
195
 
154
196
  const collection = monacoEditor.createDecorationsCollection();
155
- const inlineInputChatWidget = this.injector.get(InlineInputChatWidget, [monacoEditor, defaultValue]);
156
-
157
- let inputValue = defaultValue;
197
+ const inlineInputWidget = this.injector.get(InlineInputWidget, [monacoEditor, this.inputValue.get()]);
158
198
 
159
199
  // 仅在空行情况下增加装饰逻辑
160
200
  collection.append([
@@ -173,12 +213,12 @@ export class InlineInputController extends BaseAIMonacoEditorController {
173
213
  let preLineRange: LineRange;
174
214
  if (decorationRange) {
175
215
  preLineRange = LineRange.fromRange(decorationRange);
176
- inlineInputChatWidget.show({ position: decorationRange.getStartPosition() });
216
+ inlineInputWidget.show({ position: decorationRange.getStartPosition() });
177
217
  this.aiNativeContextKey.inlineInputWidgetIsVisible.set(true);
178
218
  }
179
219
 
180
220
  this.inputDisposable.addDispose(
181
- inlineInputChatWidget.onDispose(() => {
221
+ inlineInputWidget.onDispose(() => {
182
222
  this.cancelToken();
183
223
  collection.clear();
184
224
  this.aiNativeContextKey.inlineInputWidgetIsVisible.set(false);
@@ -186,7 +226,18 @@ export class InlineInputController extends BaseAIMonacoEditorController {
186
226
  );
187
227
 
188
228
  this.inputDisposable.addDispose(
189
- inlineInputChatWidget.onResultClick(async (kind: EResultKind) => {
229
+ inlineInputWidget.onValueChange((value) => {
230
+ this.inputValue.set(value, undefined);
231
+
232
+ const storeData = this.inlineInputWidgetStore.get(model.id);
233
+ if (storeData instanceof InlineInputWidgetStoreInEmptyLine) {
234
+ storeData.setValue(value);
235
+ }
236
+ }),
237
+ );
238
+
239
+ this.inputDisposable.addDispose(
240
+ inlineInputWidget.onResultClick(async (kind: EResultKind) => {
190
241
  const clear = () => {
191
242
  const curPosi = collection.getRange(0)!;
192
243
 
@@ -211,7 +262,7 @@ export class InlineInputController extends BaseAIMonacoEditorController {
211
262
  */
212
263
  const curPosi = collection.getRange(0)!;
213
264
  const curPosition = curPosi.getStartPosition();
214
- this.showInputInEmptyLine(curPosition, monacoEditor, inputValue);
265
+ this.showInputInEmptyLine(curPosition, monacoEditor, this.inputValue.get());
215
266
  });
216
267
  break;
217
268
 
@@ -234,18 +285,18 @@ export class InlineInputController extends BaseAIMonacoEditorController {
234
285
  const range = collection.getRange(0)!;
235
286
  const curLineRange = LineRange.fromRange(range);
236
287
  if (!preLineRange.equals(curLineRange)) {
237
- inlineInputChatWidget.setOptions({
288
+ inlineInputWidget.setOptions({
238
289
  position: range.getStartPosition(),
239
290
  });
240
291
 
241
- inlineInputChatWidget.layoutContentWidget();
292
+ inlineInputWidget.layoutContentWidget();
242
293
  }
243
294
  preLineRange = curLineRange;
244
295
  }),
245
296
  );
246
297
 
247
298
  this.inputDisposable.addDispose(
248
- inlineInputChatWidget.onClose(() => {
299
+ inlineInputWidget.onClose(() => {
249
300
  const isStreaming = this.aiNativeContextKey.inlineInputWidgetIsStreaming.get();
250
301
  if (isStreaming) {
251
302
  this.cancelToken();
@@ -256,8 +307,7 @@ export class InlineInputController extends BaseAIMonacoEditorController {
256
307
  );
257
308
 
258
309
  this.inputDisposable.addDispose(
259
- inlineInputChatWidget.onInteractiveInputValue(async (value) => {
260
- inputValue = value;
310
+ inlineInputWidget.onSend(async (value) => {
261
311
  monacoEditor.focus();
262
312
 
263
313
  const handler = this.inlineInputService.getInteractiveInputHandler();
@@ -267,13 +317,13 @@ export class InlineInputController extends BaseAIMonacoEditorController {
267
317
  return;
268
318
  }
269
319
 
270
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.THINKING);
320
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.THINKING);
271
321
 
272
322
  const strategy = await this.inlineInputService.getInteractiveInputStrategyHandler()(monacoEditor, value);
273
323
 
274
324
  if (strategy === ERunStrategy.EXECUTE && handler.execute) {
275
325
  handler.execute(monacoEditor, value, this.token);
276
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.DONE);
326
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.DONE);
277
327
  this.hideInput();
278
328
  return;
279
329
  }
@@ -282,7 +332,7 @@ export class InlineInputController extends BaseAIMonacoEditorController {
282
332
  const previewResponse = await handler.providePreviewStrategy(monacoEditor, value, this.token);
283
333
 
284
334
  if (CancelResponse.is(previewResponse)) {
285
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.READY);
335
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.READY);
286
336
  this.hideInput();
287
337
  return;
288
338
  }
@@ -315,17 +365,17 @@ export class InlineInputController extends BaseAIMonacoEditorController {
315
365
  }),
316
366
  controller.onError((error) => {
317
367
  this.aiNativeContextKey.inlineInputWidgetIsStreaming.set(false);
318
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.ERROR);
368
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.ERROR);
319
369
  }),
320
370
  controller.onAbort(() => {
321
371
  this.aiNativeContextKey.inlineInputWidgetIsStreaming.set(false);
322
372
  model.pushStackElement();
323
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.DONE);
373
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.DONE);
324
374
  }),
325
375
  controller.onEnd(() => {
326
376
  this.aiNativeContextKey.inlineInputWidgetIsStreaming.set(false);
327
377
  model.pushStackElement();
328
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.DONE);
378
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.DONE);
329
379
  }),
330
380
  ]);
331
381
 
@@ -335,7 +385,7 @@ export class InlineInputController extends BaseAIMonacoEditorController {
335
385
  }),
336
386
  );
337
387
 
338
- this.inputDisposable.addDispose(inlineInputChatWidget);
388
+ this.inputDisposable.addDispose(inlineInputWidget);
339
389
  }
340
390
 
341
391
  private async showInputInSelection(selection: monaco.Selection, monacoEditor: ICodeEditor, defaultValue?: string) {
@@ -344,24 +394,59 @@ export class InlineInputController extends BaseAIMonacoEditorController {
344
394
  this.inputDisposable = new Disposable();
345
395
  }
346
396
 
347
- monacoEditor.setSelection(selection);
397
+ const model = monacoEditor.getModel();
398
+ if (!model) {
399
+ return;
400
+ }
348
401
 
349
- const inlineInputChatWidget = this.injector.get(InlineInputChatWidget, [monacoEditor, defaultValue]);
350
- inlineInputChatWidget.show({ selection });
402
+ this.inputValue.set(defaultValue || '', undefined);
403
+ this.inlineInputWidgetStore.set(model.id, new InlineInputWidgetStoreInSelection(selection, defaultValue));
404
+
405
+ const decorationsCollection = monacoEditor.createDecorationsCollection();
406
+ decorationsCollection.set([
407
+ {
408
+ range: monaco.Range.fromPositions(
409
+ { lineNumber: selection.startLineNumber, column: 1 },
410
+ {
411
+ lineNumber: selection.endLineNumber,
412
+ column: monacoEditor.getModel()!.getLineMaxColumn(selection.endLineNumber),
413
+ },
414
+ ),
415
+ options: ModelDecorationOptions.register({
416
+ description: InlineInputPreviewDecorationID,
417
+ isWholeLine: true,
418
+ className: styles.input_decoration_pending_container,
419
+ }),
420
+ },
421
+ ]);
422
+
423
+ const inlineInputWidget = this.injector.get(InlineInputWidget, [monacoEditor, this.inputValue.get()]);
424
+ inlineInputWidget.show({ selection });
351
425
 
352
426
  this.aiNativeContextKey.inlineInputWidgetIsVisible.set(true);
353
427
  this.inlineDiffController.destroyPreviewer(monacoEditor.getModel()?.uri.toString());
354
- let inputValue = defaultValue;
355
428
 
356
429
  this.inputDisposable.addDispose(
357
- inlineInputChatWidget.onDispose(() => {
430
+ inlineInputWidget.onDispose(() => {
358
431
  this.cancelToken();
432
+ decorationsCollection.clear();
359
433
  this.aiNativeContextKey.inlineInputWidgetIsVisible.set(false);
360
434
  }),
361
435
  );
362
436
 
363
437
  this.inputDisposable.addDispose(
364
- inlineInputChatWidget.onClose(() => {
438
+ inlineInputWidget.onValueChange((value) => {
439
+ this.inputValue.set(value, undefined);
440
+
441
+ const storeData = this.inlineInputWidgetStore.get(model.id);
442
+ if (storeData instanceof InlineInputWidgetStoreInSelection) {
443
+ storeData.setValue(value);
444
+ }
445
+ }),
446
+ );
447
+
448
+ this.inputDisposable.addDispose(
449
+ inlineInputWidget.onClose(() => {
365
450
  const isStreaming = this.aiNativeContextKey.inlineInputWidgetIsStreaming.get();
366
451
  if (isStreaming) {
367
452
  this.cancelToken();
@@ -372,9 +457,9 @@ export class InlineInputController extends BaseAIMonacoEditorController {
372
457
  );
373
458
 
374
459
  this.inputDisposable.addDispose(
375
- inlineInputChatWidget.onInteractiveInputValue(async (value) => {
376
- inputValue = value;
460
+ inlineInputWidget.onSend(async (value) => {
377
461
  monacoEditor.focus();
462
+ decorationsCollection.clear();
378
463
 
379
464
  const handler = this.inlineInputService.getInteractiveInputHandler();
380
465
 
@@ -382,7 +467,7 @@ export class InlineInputController extends BaseAIMonacoEditorController {
382
467
  return;
383
468
  }
384
469
 
385
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.THINKING);
470
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.THINKING);
386
471
 
387
472
  const strategy = await this.inlineInputService.getInteractiveInputStrategyHandler()(monacoEditor, value);
388
473
 
@@ -394,7 +479,7 @@ export class InlineInputController extends BaseAIMonacoEditorController {
394
479
  const previewResponse = await handler.providePreviewStrategy(monacoEditor, value, this.token);
395
480
 
396
481
  if (CancelResponse.is(previewResponse)) {
397
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.READY);
482
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.READY);
398
483
  this.hideInput();
399
484
  return;
400
485
  }
@@ -410,15 +495,15 @@ export class InlineInputController extends BaseAIMonacoEditorController {
410
495
  }),
411
496
  chatResponse.onError((error) => {
412
497
  this.aiNativeContextKey.inlineInputWidgetIsStreaming.set(false);
413
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.ERROR);
498
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.ERROR);
414
499
  }),
415
500
  chatResponse.onAbort(() => {
416
501
  this.aiNativeContextKey.inlineInputWidgetIsStreaming.set(false);
417
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.DONE);
502
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.DONE);
418
503
  }),
419
504
  chatResponse.onEnd(() => {
420
505
  this.aiNativeContextKey.inlineInputWidgetIsStreaming.set(false);
421
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.DONE);
506
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.DONE);
422
507
  }),
423
508
  ]);
424
509
 
@@ -428,28 +513,28 @@ export class InlineInputController extends BaseAIMonacoEditorController {
428
513
  crossSelection,
429
514
  chatResponse,
430
515
  });
431
- diffPreviewer.mount(inlineInputChatWidget);
516
+ diffPreviewer.mount(inlineInputWidget);
432
517
  }
433
518
  } else {
434
- inlineInputChatWidget.launchChatStatus(EInlineChatStatus.READY);
519
+ inlineInputWidget.launchChatStatus(EInlineChatStatus.READY);
435
520
  this.hideInput();
436
521
  }
437
522
  }),
438
523
  );
439
524
 
440
525
  this.inputDisposable.addDispose(
441
- inlineInputChatWidget.onResultClick((kind: EResultKind) => {
526
+ inlineInputWidget.onResultClick((kind: EResultKind) => {
442
527
  this.inlineDiffController.handleAction(kind);
443
528
  this.hideInput();
444
529
 
445
530
  if (kind === EResultKind.REGENERATE) {
446
531
  requestAnimationFrame(() => {
447
- this.showInputInSelection(selection, monacoEditor, inputValue);
532
+ this.showInputInSelection(selection, monacoEditor, this.inputValue.get());
448
533
  });
449
534
  }
450
535
  }),
451
536
  );
452
537
 
453
- this.inputDisposable.addDispose(inlineInputChatWidget);
538
+ this.inputDisposable.addDispose(inlineInputWidget);
454
539
  }
455
540
  }
@@ -5,3 +5,7 @@
5
5
  .input_wrapper {
6
6
  transform: translateY(-4px);
7
7
  }
8
+
9
+ .input_decoration_pending_container {
10
+ background-color: var(--vscode-diffEditor-unchangedCodeBackground);
11
+ }