@opensumi/ide-ai-native 3.7.1 → 3.7.2-next-1739848467.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 (167) 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 +6 -5
  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/intelligent-completions.feature.registry.d.ts +4 -0
  26. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts.map +1 -1
  27. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js +7 -0
  28. package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js.map +1 -1
  29. package/lib/browser/contrib/intelligent-completions/source/base.d.ts +9 -3
  30. package/lib/browser/contrib/intelligent-completions/source/base.d.ts.map +1 -1
  31. package/lib/browser/contrib/intelligent-completions/source/base.js +21 -3
  32. package/lib/browser/contrib/intelligent-completions/source/base.js.map +1 -1
  33. package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts +10 -3
  34. package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts.map +1 -1
  35. package/lib/browser/contrib/intelligent-completions/source/line-change.source.js +95 -22
  36. package/lib/browser/contrib/intelligent-completions/source/line-change.source.js.map +1 -1
  37. package/lib/browser/contrib/intelligent-completions/source/lint-error.source.d.ts +1 -3
  38. package/lib/browser/contrib/intelligent-completions/source/lint-error.source.d.ts.map +1 -1
  39. package/lib/browser/contrib/intelligent-completions/source/lint-error.source.js +13 -20
  40. package/lib/browser/contrib/intelligent-completions/source/lint-error.source.js.map +1 -1
  41. package/lib/browser/contrib/intelligent-completions/source/typing.source.d.ts +9 -0
  42. package/lib/browser/contrib/intelligent-completions/source/typing.source.d.ts.map +1 -0
  43. package/lib/browser/contrib/intelligent-completions/source/typing.source.js +36 -0
  44. package/lib/browser/contrib/intelligent-completions/source/typing.source.js.map +1 -0
  45. package/lib/browser/contrib/terminal/component/terminal-command-suggest-controller.js +2 -2
  46. package/lib/browser/contrib/terminal/component/terminal-command-suggest-controller.js.map +1 -1
  47. package/lib/browser/index.js +1 -1
  48. package/lib/browser/index.js.map +1 -1
  49. package/lib/browser/languages/tree-sitter/wasm-manager.d.ts.map +1 -1
  50. package/lib/browser/languages/tree-sitter/wasm-manager.js +14 -2
  51. package/lib/browser/languages/tree-sitter/wasm-manager.js.map +1 -1
  52. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  53. package/lib/browser/layout/ai-layout.js +2 -2
  54. package/lib/browser/layout/ai-layout.js.map +1 -1
  55. package/lib/browser/layout/layout.module.less +9 -9
  56. package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
  57. package/lib/browser/layout/tabbar.view.js +5 -6
  58. package/lib/browser/layout/tabbar.view.js.map +1 -1
  59. package/lib/browser/model/enhanceDecorationsCollection.d.ts +14 -10
  60. package/lib/browser/model/enhanceDecorationsCollection.d.ts.map +1 -1
  61. package/lib/browser/model/enhanceDecorationsCollection.js +42 -53
  62. package/lib/browser/model/enhanceDecorationsCollection.js.map +1 -1
  63. package/lib/browser/preferences/schema.d.ts.map +1 -1
  64. package/lib/browser/preferences/schema.js +4 -0
  65. package/lib/browser/preferences/schema.js.map +1 -1
  66. package/lib/browser/types.d.ts +25 -4
  67. package/lib/browser/types.d.ts.map +1 -1
  68. package/lib/browser/types.js.map +1 -1
  69. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.d.ts +2 -1
  70. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.d.ts.map +1 -1
  71. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.js +21 -49
  72. package/lib/browser/widget/inline-chat/inline-chat-editor.controller.js.map +1 -1
  73. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts +3 -13
  74. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.d.ts.map +1 -1
  75. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js +24 -72
  76. package/lib/browser/widget/inline-chat/inline-chat.feature.registry.js.map +1 -1
  77. package/lib/browser/widget/inline-chat/inline-chat.service.d.ts +1 -6
  78. package/lib/browser/widget/inline-chat/inline-chat.service.d.ts.map +1 -1
  79. package/lib/browser/widget/inline-chat/inline-chat.service.js +5 -17
  80. package/lib/browser/widget/inline-chat/inline-chat.service.js.map +1 -1
  81. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts +2 -5
  82. package/lib/browser/widget/inline-chat/inline-content-widget.d.ts.map +1 -1
  83. package/lib/browser/widget/inline-chat/inline-content-widget.js +17 -42
  84. package/lib/browser/widget/inline-chat/inline-content-widget.js.map +1 -1
  85. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +22 -5
  86. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
  87. package/lib/browser/widget/inline-diff/inline-diff-previewer.js +61 -30
  88. package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
  89. package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +8 -12
  90. package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
  91. package/lib/browser/widget/inline-diff/inline-diff.controller.js +68 -96
  92. package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
  93. package/lib/browser/widget/inline-hint/inline-hint.controller.d.ts +0 -1
  94. package/lib/browser/widget/inline-hint/inline-hint.controller.d.ts.map +1 -1
  95. package/lib/browser/widget/inline-hint/inline-hint.controller.js +0 -5
  96. package/lib/browser/widget/inline-hint/inline-hint.controller.js.map +1 -1
  97. package/lib/browser/widget/inline-input/inline-input-widget.d.ts +12 -2
  98. package/lib/browser/widget/inline-input/inline-input-widget.d.ts.map +1 -1
  99. package/lib/browser/widget/inline-input/inline-input-widget.js +26 -18
  100. package/lib/browser/widget/inline-input/inline-input-widget.js.map +1 -1
  101. package/lib/browser/widget/inline-input/inline-input.controller.d.ts +14 -5
  102. package/lib/browser/widget/inline-input/inline-input.controller.d.ts.map +1 -1
  103. package/lib/browser/widget/inline-input/inline-input.controller.js +321 -165
  104. package/lib/browser/widget/inline-input/inline-input.controller.js.map +1 -1
  105. package/lib/browser/widget/inline-input/inline-input.module.less +4 -0
  106. package/lib/browser/widget/inline-input/inline-input.service.d.ts +19 -7
  107. package/lib/browser/widget/inline-input/inline-input.service.d.ts.map +1 -1
  108. package/lib/browser/widget/inline-input/inline-input.service.js +72 -12
  109. package/lib/browser/widget/inline-input/inline-input.service.js.map +1 -1
  110. package/lib/browser/widget/inline-input/model.d.ts +34 -0
  111. package/lib/browser/widget/inline-input/model.d.ts.map +1 -0
  112. package/lib/browser/widget/inline-input/model.js +63 -0
  113. package/lib/browser/widget/inline-input/model.js.map +1 -0
  114. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +8 -19
  115. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  116. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +44 -39
  117. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  118. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +17 -4
  119. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  120. package/lib/browser/widget/inline-stream-diff/live-preview.component.js +37 -5
  121. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  122. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +7 -11
  123. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  124. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +33 -77
  125. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  126. package/lib/common/utils.js +2 -2
  127. package/lib/common/utils.js.map +1 -1
  128. package/package.json +21 -21
  129. package/src/browser/ai-core.contextkeys.ts +3 -0
  130. package/src/browser/ai-core.contribution.ts +68 -17
  131. package/src/browser/components/ChatMarkdown.tsx +1 -1
  132. package/src/browser/components/WelcomeMsg.tsx +1 -1
  133. package/src/browser/contrib/intelligent-completions/index.ts +16 -4
  134. package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +29 -8
  135. package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +88 -58
  136. package/src/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.ts +11 -0
  137. package/src/browser/contrib/intelligent-completions/source/base.ts +28 -7
  138. package/src/browser/contrib/intelligent-completions/source/line-change.source.ts +129 -22
  139. package/src/browser/contrib/intelligent-completions/source/lint-error.source.ts +19 -31
  140. package/src/browser/contrib/intelligent-completions/source/typing.source.ts +34 -0
  141. package/src/browser/contrib/terminal/component/terminal-command-suggest-controller.tsx +1 -1
  142. package/src/browser/index.ts +2 -2
  143. package/src/browser/languages/tree-sitter/wasm-manager.ts +12 -2
  144. package/src/browser/layout/ai-layout.tsx +5 -2
  145. package/src/browser/layout/layout.module.less +9 -9
  146. package/src/browser/layout/tabbar.view.tsx +10 -8
  147. package/src/browser/model/enhanceDecorationsCollection.ts +62 -77
  148. package/src/browser/preferences/schema.ts +4 -0
  149. package/src/browser/types.ts +40 -5
  150. package/src/browser/widget/inline-chat/inline-chat-editor.controller.ts +30 -65
  151. package/src/browser/widget/inline-chat/inline-chat.feature.registry.ts +23 -90
  152. package/src/browser/widget/inline-chat/inline-chat.service.ts +2 -17
  153. package/src/browser/widget/inline-chat/inline-content-widget.tsx +14 -69
  154. package/src/browser/widget/inline-diff/inline-diff-previewer.ts +87 -32
  155. package/src/browser/widget/inline-diff/inline-diff.controller.ts +90 -114
  156. package/src/browser/widget/inline-hint/inline-hint.controller.ts +1 -7
  157. package/src/browser/widget/inline-input/inline-input-widget.tsx +34 -12
  158. package/src/browser/widget/inline-input/inline-input.controller.ts +454 -242
  159. package/src/browser/widget/inline-input/inline-input.module.less +4 -0
  160. package/src/browser/widget/inline-input/inline-input.service.ts +92 -13
  161. package/src/browser/widget/inline-input/model.ts +74 -0
  162. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +54 -67
  163. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +45 -6
  164. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +40 -112
  165. package/src/common/utils.ts +2 -2
  166. package/lib/browser/model/styles.module.less +0 -7
  167. package/src/browser/model/styles.module.less +0 -7
@@ -7,7 +7,6 @@ import {
7
7
  Disposable,
8
8
  IAIReporter,
9
9
  IDisposable,
10
- MaybePromise,
11
10
  uuid,
12
11
  } from '@opensumi/ide-core-common';
13
12
  import { CancellationTokenSource, ICodeEditor } from '@opensumi/ide-monaco';
@@ -37,14 +36,26 @@ export class CodeEditsContextBean extends Disposable {
37
36
  return this.raw;
38
37
  }
39
38
 
39
+ public get typing() {
40
+ return this.raw.typing;
41
+ }
42
+
40
43
  public get position() {
41
44
  return this.raw.position;
42
45
  }
43
46
 
47
+ public get data() {
48
+ return this.raw.data;
49
+ }
50
+
44
51
  public get token() {
45
52
  return this.source.token;
46
53
  }
47
54
 
55
+ public joinData(data: ICodeEditsContextBean['data']) {
56
+ this.raw.data = { ...this.data, ...data };
57
+ }
58
+
48
59
  public reporterStart() {
49
60
  return this.source.reporterStart();
50
61
  }
@@ -69,8 +80,6 @@ export abstract class BaseCodeEditsSource extends Disposable {
69
80
  private cancellationTokenSource = new CancellationTokenSource();
70
81
  private readonly relationID = observableValue<string | undefined>(this, undefined);
71
82
 
72
- protected abstract doTrigger(...args: any[]): MaybePromise<void>;
73
-
74
83
  public readonly codeEditsContextBean = disposableObservableValue<CodeEditsContextBean | undefined>(this, undefined);
75
84
  public abstract priority: number;
76
85
  public abstract mount(): IDisposable;
@@ -100,9 +109,9 @@ export abstract class BaseCodeEditsSource extends Disposable {
100
109
  });
101
110
  }
102
111
 
103
- protected setBean(bean: ICodeEditsContextBean) {
112
+ protected setBean(bean: Omit<ICodeEditsContextBean, 'position'>) {
104
113
  transaction((tx) => {
105
- const context = new CodeEditsContextBean(bean, this);
114
+ const context = new CodeEditsContextBean({ ...bean, position: this.monacoEditor.getPosition()! }, this);
106
115
  this.codeEditsContextBean.set(context, tx);
107
116
  });
108
117
  }
@@ -112,7 +121,7 @@ export abstract class BaseCodeEditsSource extends Disposable {
112
121
  if (context) {
113
122
  const relationID = this.aiReporter.start(AIServiceType.CodeEdits, {
114
123
  type: AIServiceType.CodeEdits,
115
- actionSource: context?.bean.typing,
124
+ actionSource: context?.typing,
116
125
  });
117
126
 
118
127
  transaction((tx) => {
@@ -168,11 +177,23 @@ export class CodeEditsSourceCollection extends Disposable {
168
177
 
169
178
  for (const source of lastSources) {
170
179
  const value = source.codeEditsContextBean.get();
180
+ if (!value) {
181
+ return;
182
+ }
183
+
184
+ if (!contextBean) {
185
+ contextBean = value;
186
+ }
171
187
 
172
- if (value && value.priority >= highestPriority) {
188
+ if (value.priority >= highestPriority) {
173
189
  highestPriority = value.priority;
190
+
191
+ value.joinData(contextBean.data);
174
192
  contextBean = value;
175
193
  }
194
+
195
+ // 将多个 source 的 data 合并到一起
196
+ contextBean.joinData(value.data);
176
197
  }
177
198
 
178
199
  transaction((tx) => {
@@ -1,6 +1,15 @@
1
1
  import { Injectable } from '@opensumi/di';
2
2
  import { AINativeSettingSectionsId, ECodeEditsSourceTyping, IDisposable } from '@opensumi/ide-core-common';
3
- import { ICursorPositionChangedEvent, Position } from '@opensumi/ide-monaco';
3
+ import { ICursorPositionChangedEvent, IModelContentChangedEvent } from '@opensumi/ide-monaco';
4
+ import {
5
+ autorunDelta,
6
+ derived,
7
+ derivedHandleChanges,
8
+ observableFromEvent,
9
+ onObservableChange,
10
+ } from '@opensumi/ide-monaco/lib/common/observable';
11
+
12
+ import { IntelligentCompletionsController } from '../intelligent-completions.controller';
4
13
 
5
14
  import { BaseCodeEditsSource } from './base';
6
15
 
@@ -9,39 +18,137 @@ export interface ILineChangeData {
9
18
  preLineNumber?: number;
10
19
  }
11
20
 
21
+ const DEPRECATED_LIMIT = 5;
22
+ const CONTENT_CHANGE_VALID_TIME = 60 * 1000;
23
+
12
24
  @Injectable({ multiple: true })
13
25
  export class LineChangeCodeEditsSource extends BaseCodeEditsSource {
14
- public priority = 2;
26
+ public priority = 1;
27
+
28
+ /**
29
+ * 在当前文件,计算弃用上次 edit 时的次数是否超过了阈值 {@link DEPRECATED_LIMIT} 次,超过则不会触发
30
+ * 1. 直接 esc 弃用
31
+ * 2. 用户再次移动光标位置致使补全消失也视为弃用
32
+ */
33
+ private readonly deprecatedStore = new Map<string, number>();
34
+
35
+ private readonly positionChangeObs = observableFromEvent<ICursorPositionChangedEvent>(
36
+ this,
37
+ this.monacoEditor.onDidChangeCursorPosition,
38
+ (event: ICursorPositionChangedEvent) => event,
39
+ );
40
+
41
+ private readonly contentChangeObs = observableFromEvent<IModelContentChangedEvent>(
42
+ this,
43
+ this.monacoEditor.onDidChangeModelContent,
44
+ (event: IModelContentChangedEvent) => event,
45
+ );
46
+
47
+ private readonly latestContentChangeTimeObs = derivedHandleChanges(
48
+ {
49
+ owner: this,
50
+ createEmptyChangeSummary: () => ({ latestContentChangeTime: 0 }),
51
+ handleChange: (context, changeSummary) => {
52
+ if (context.didChange(this.contentChangeObs)) {
53
+ changeSummary.latestContentChangeTime = Date.now();
54
+ }
55
+ return true;
56
+ },
57
+ },
58
+ (reader, changeSummary) => {
59
+ this.contentChangeObs.read(reader);
60
+ return changeSummary.latestContentChangeTime;
61
+ },
62
+ );
63
+
64
+ private readonly isAllowTriggerObs = derived((reader) => {
65
+ this.positionChangeObs.read(reader);
66
+ const latestContentChangeTime = this.latestContentChangeTimeObs.read(reader);
67
+
68
+ const isLineChangeEnabled = this.preferenceService.getValid(AINativeSettingSectionsId.CodeEditsLineChange, false);
15
69
 
16
- private prePosition = this.monacoEditor.getPosition();
70
+ /**
71
+ * 配置开关
72
+ */
73
+ if (!isLineChangeEnabled) {
74
+ return false;
75
+ }
76
+
77
+ /**
78
+ * 弃用次数规则的限制
79
+ */
80
+ const deprecatedCount = this.deprecatedStore.get(this.model?.id || '');
81
+ if (deprecatedCount && deprecatedCount >= DEPRECATED_LIMIT) {
82
+ return false;
83
+ }
84
+
85
+ /**
86
+ * 1. 未编辑过代码不触发
87
+ * 2. 编辑过代码后,60 内没有再次编辑也不触发
88
+ */
89
+ if (
90
+ latestContentChangeTime === 0 ||
91
+ (latestContentChangeTime && Date.now() - latestContentChangeTime > CONTENT_CHANGE_VALID_TIME)
92
+ ) {
93
+ return false;
94
+ }
95
+
96
+ return true;
97
+ });
17
98
 
18
99
  public mount(): IDisposable {
19
100
  this.addDispose(
20
- this.monacoEditor.onDidChangeCursorPosition((event: ICursorPositionChangedEvent) => {
21
- const currentPosition = event.position;
22
- if (this.prePosition && this.prePosition.lineNumber !== currentPosition.lineNumber) {
23
- this.doTrigger(currentPosition);
24
- this.prePosition = currentPosition;
101
+ autorunDelta(this.positionChangeObs, ({ lastValue, newValue }, reader) => {
102
+ const isAllowTriggerObs = this.isAllowTriggerObs.read(reader);
103
+ if (!isAllowTriggerObs) {
104
+ return false;
105
+ }
106
+
107
+ const prePosition = lastValue?.position;
108
+ const currentPosition = newValue?.position;
109
+ if (prePosition && prePosition.lineNumber !== currentPosition?.lineNumber) {
110
+ this.setBean({
111
+ typing: ECodeEditsSourceTyping.LineChange,
112
+ data: {
113
+ [ECodeEditsSourceTyping.LineChange]: {
114
+ preLineNumber: prePosition.lineNumber,
115
+ currentLineNumber: currentPosition.lineNumber,
116
+ },
117
+ },
118
+ });
25
119
  }
26
120
  }),
27
121
  );
28
- return this;
29
- }
30
122
 
31
- protected doTrigger(position: Position) {
32
- const isLineChangeEnabled = this.preferenceService.getValid(AINativeSettingSectionsId.CodeEditsLineChange, false);
123
+ const discard = IntelligentCompletionsController.get(this.monacoEditor)?.discard;
124
+ const accept = IntelligentCompletionsController.get(this.monacoEditor)?.accept;
125
+ if (discard) {
126
+ this.addDispose(
127
+ onObservableChange(discard, (isValid: boolean) => {
128
+ const modelId = this.model?.id;
129
+ if (!modelId || !isValid) {
130
+ return;
131
+ }
33
132
 
34
- if (!isLineChangeEnabled || !position) {
35
- return;
133
+ const count = this.deprecatedStore.get(modelId) || 0;
134
+ this.deprecatedStore.set(modelId, count + 1);
135
+ }),
136
+ );
36
137
  }
37
138
 
38
- this.setBean({
39
- typing: ECodeEditsSourceTyping.LineChange,
40
- position,
41
- data: {
42
- preLineNumber: this.prePosition?.lineNumber,
43
- currentLineNumber: position.lineNumber,
44
- },
45
- });
139
+ if (accept) {
140
+ this.addDispose(
141
+ onObservableChange(accept, () => {
142
+ const modelId = this.model?.id;
143
+ if (!modelId) {
144
+ return;
145
+ }
146
+
147
+ this.deprecatedStore.delete(modelId);
148
+ }),
149
+ );
150
+ }
151
+
152
+ return this;
46
153
  }
47
154
  }
@@ -1,14 +1,8 @@
1
- import { Autowired, Injectable } from '@opensumi/di';
2
- import {
3
- AINativeSettingSectionsId,
4
- ECodeEditsSourceTyping,
5
- Event,
6
- FRAME_THREE,
7
- IDisposable,
8
- } from '@opensumi/ide-core-common';
1
+ import { Injectable } from '@opensumi/di';
2
+ import { AINativeSettingSectionsId, ECodeEditsSourceTyping, IDisposable } from '@opensumi/ide-core-common';
9
3
  import { ICursorPositionChangedEvent, IPosition, Position } from '@opensumi/ide-monaco';
10
4
  import { URI } from '@opensumi/ide-monaco/lib/browser/monaco-api';
11
- import { IWorkspaceService } from '@opensumi/ide-workspace';
5
+ import { autorunDelta, observableFromEvent } from '@opensumi/ide-monaco/lib/common/observable';
12
6
  import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
13
7
  import {
14
8
  IMarker,
@@ -20,7 +14,6 @@ import {
20
14
  import { BaseCodeEditsSource } from './base';
21
15
 
22
16
  export interface ILinterErrorData {
23
- relativeWorkspacePath: string;
24
17
  errors: Array<IMarkerErrorData>;
25
18
  }
26
19
 
@@ -58,22 +51,19 @@ namespace MarkerErrorData {
58
51
 
59
52
  @Injectable({ multiple: true })
60
53
  export class LintErrorCodeEditsSource extends BaseCodeEditsSource {
61
- public priority = 1;
62
-
63
- @Autowired(IWorkspaceService)
64
- private readonly workspaceService: IWorkspaceService;
54
+ public priority = 0;
65
55
 
66
56
  public mount(): IDisposable {
67
- let prePosition = this.monacoEditor.getPosition();
57
+ const positionChangeObs = observableFromEvent<ICursorPositionChangedEvent>(
58
+ this,
59
+ this.monacoEditor.onDidChangeCursorPosition,
60
+ (event: ICursorPositionChangedEvent) => event,
61
+ );
68
62
 
69
63
  this.addDispose(
70
- // 仅在光标的行号发生变化时,才触发
71
- Event.debounce(
72
- this.monacoEditor.onDidChangeCursorPosition,
73
- (_, e) => e,
74
- FRAME_THREE,
75
- )(async (event: ICursorPositionChangedEvent) => {
76
- const currentPosition = event.position;
64
+ autorunDelta(positionChangeObs, ({ lastValue, newValue }) => {
65
+ const prePosition = lastValue?.position;
66
+ const currentPosition = newValue?.position;
77
67
 
78
68
  // 如果是 selection 则不触发
79
69
  const selection = this.monacoEditor.getSelection();
@@ -81,16 +71,16 @@ export class LintErrorCodeEditsSource extends BaseCodeEditsSource {
81
71
  return;
82
72
  }
83
73
 
84
- if (prePosition && prePosition.lineNumber !== currentPosition.lineNumber) {
85
- await this.doTrigger(currentPosition);
74
+ // 仅在光标的行号发生变化时,才触发
75
+ if (prePosition && prePosition.lineNumber !== currentPosition?.lineNumber) {
76
+ this.doTrigger(currentPosition);
86
77
  }
87
- prePosition = currentPosition;
88
78
  }),
89
79
  );
90
80
  return this;
91
81
  }
92
82
 
93
- protected async doTrigger(position: Position) {
83
+ protected doTrigger(position: Position) {
94
84
  const isLintErrorsEnabled = this.preferenceService.getValid(AINativeSettingSectionsId.CodeEditsLintErrors, false);
95
85
 
96
86
  if (!isLintErrorsEnabled || !this.model) {
@@ -104,14 +94,12 @@ export class LintErrorCodeEditsSource extends BaseCodeEditsSource {
104
94
  markers = markers.filter((marker) => Math.abs(marker.startLineNumber - position.lineNumber) <= 1);
105
95
 
106
96
  if (markers.length) {
107
- const relativeWorkspacePath = await this.workspaceService.asRelativePath(resource.path);
108
-
109
97
  this.setBean({
110
98
  typing: ECodeEditsSourceTyping.LinterErrors,
111
- position,
112
99
  data: {
113
- relativeWorkspacePath: relativeWorkspacePath?.path ?? resource.path,
114
- errors: markers.map((marker) => MarkerErrorData.toData(marker)),
100
+ [ECodeEditsSourceTyping.LinterErrors]: {
101
+ errors: markers.map((marker) => MarkerErrorData.toData(marker)),
102
+ },
115
103
  },
116
104
  });
117
105
  }
@@ -0,0 +1,34 @@
1
+ import { Injectable } from '@opensumi/di';
2
+ import { AINativeSettingSectionsId, ECodeEditsSourceTyping, IDisposable } from '@opensumi/ide-core-common';
3
+ import { IModelContentChangedEvent } from '@opensumi/ide-monaco';
4
+
5
+ import { BaseCodeEditsSource } from './base';
6
+
7
+ @Injectable({ multiple: true })
8
+ export class TypingCodeEditsSource extends BaseCodeEditsSource {
9
+ public priority = 2;
10
+
11
+ public mount(): IDisposable {
12
+ this.addDispose(
13
+ this.monacoEditor.onDidChangeModelContent((event: IModelContentChangedEvent) => {
14
+ this.doTrigger(event);
15
+ }),
16
+ );
17
+ return this;
18
+ }
19
+
20
+ protected async doTrigger(data: IModelContentChangedEvent) {
21
+ const isTypingEnabled = this.preferenceService.getValid(AINativeSettingSectionsId.CodeEditsTyping, false);
22
+
23
+ if (!isTypingEnabled || !this.model) {
24
+ return;
25
+ }
26
+
27
+ this.setBean({
28
+ typing: ECodeEditsSourceTyping.Typing,
29
+ data: {
30
+ [ECodeEditsSourceTyping.Typing]: data,
31
+ },
32
+ });
33
+ }
34
+ }
@@ -1,4 +1,4 @@
1
- import { debounce } from 'lodash';
1
+ import debounce from 'lodash/debounce';
2
2
  import React, { useCallback, useEffect, useRef, useState } from 'react';
3
3
 
4
4
  import { Emitter, localize } from '@opensumi/ide-core-browser';
@@ -46,7 +46,7 @@ import { LanguageParserService } from './languages/service';
46
46
  import { AINativePreferencesContribution } from './preferences';
47
47
  import { AINativeCoreContribution } from './types';
48
48
  import { InlineChatFeatureRegistry } from './widget/inline-chat/inline-chat.feature.registry';
49
- import { AIInlineChatService } from './widget/inline-chat/inline-chat.service';
49
+ import { InlineChatService } from './widget/inline-chat/inline-chat.service';
50
50
  import { InlineDiffService } from './widget/inline-diff';
51
51
 
52
52
  @Injectable()
@@ -90,7 +90,7 @@ export class AINativeModule extends BrowserModule {
90
90
  },
91
91
  {
92
92
  token: IAIInlineChatService,
93
- useClass: AIInlineChatService,
93
+ useClass: InlineChatService,
94
94
  },
95
95
  {
96
96
  token: IChatManagerService,
@@ -29,7 +29,12 @@ export class WasmModuleManager {
29
29
 
30
30
  async initParser() {
31
31
  const baseUrl = await this.resolvedResourceUriDeferred.promise;
32
- const wasmPath = `${baseUrl}/tree-sitter.wasm`;
32
+ let wasmPath;
33
+ if (baseUrl.endsWith('/')) {
34
+ wasmPath = `${baseUrl}tree-sitter.wasm`;
35
+ } else {
36
+ wasmPath = `${baseUrl}/tree-sitter.wasm`;
37
+ }
33
38
  if (!this.parserInitialized) {
34
39
  await Parser.init({
35
40
  locateFile: () => wasmPath,
@@ -45,7 +50,12 @@ export class WasmModuleManager {
45
50
  const deferred = new Deferred<ArrayBuffer>();
46
51
  this.cachedRuntime.set(language, deferred);
47
52
  const baseUrl = await this.resolvedResourceUriDeferred.promise;
48
- const wasmUrl = `${baseUrl}/tree-sitter-${language}.wasm`;
53
+ let wasmUrl;
54
+ if (baseUrl.endsWith('/')) {
55
+ wasmUrl = `${baseUrl}tree-sitter-${language}.wasm`;
56
+ } else {
57
+ wasmUrl = `${baseUrl}/tree-sitter-${language}.wasm`;
58
+ }
49
59
  fetch(wasmUrl)
50
60
  .then((res) => res.arrayBuffer())
51
61
  .then((buffer) => {
@@ -10,11 +10,14 @@ export const AILayout = () => {
10
10
  const { layout } = getStorageValue();
11
11
  const designLayoutConfig = useInjectable(DesignLayoutConfig);
12
12
 
13
- const defaultRightSize = useMemo(() => designLayoutConfig.useMergeRightWithLeftPanel ? 0 : 49, [designLayoutConfig.useMergeRightWithLeftPanel]);
13
+ const defaultRightSize = useMemo(
14
+ () => (designLayoutConfig.useMergeRightWithLeftPanel ? 0 : 49),
15
+ [designLayoutConfig.useMergeRightWithLeftPanel],
16
+ );
14
17
 
15
18
  return (
16
19
  <BoxPanel direction='top-to-bottom'>
17
- <SlotRenderer id='top' defaultSize={layout.top?.currentId ? layout.top?.size || 35 : 0} slot='top' />
20
+ <SlotRenderer id='top' defaultSize={layout.top?.currentId ? layout.top?.size || 32 : 32} slot='top' />
18
21
  <SplitPanel
19
22
  id='main-horizontal-ai'
20
23
  flex={1}
@@ -119,20 +119,20 @@
119
119
  border: none;
120
120
  }
121
121
 
122
+ .header {
123
+ height: 36px;
124
+ display: flex;
125
+ align-items: center;
126
+ justify-content: space-between;
127
+ padding: 0 10px;
128
+ background-color: var(--editorGroupHeader-tabsBackground);
129
+ }
130
+
122
131
  .right_slot_container_wrap {
123
132
  height: 100%;
124
133
  display: flex;
125
134
  flex-direction: column;
126
135
 
127
- .header {
128
- height: 36px;
129
- display: flex;
130
- align-items: center;
131
- justify-content: space-between;
132
- padding: 0 10px;
133
- background-color: var(--editorGroupHeader-tabsBackground);
134
- }
135
-
136
136
  .container {
137
137
  flex: 1;
138
138
  }
@@ -174,16 +174,18 @@ export const AIRightTabRenderer = ({
174
174
  return (
175
175
  <ContainerView
176
176
  {...props}
177
+ customTitleBar={
178
+ <div className={styles.header}>
179
+ <span className={styles.title}>{options && options.title}</span>
180
+ <div className={styles.side}>
181
+ <EnhancePopover id={'ai_right_panel_header_close'} title={localize('editor.title.context.close')}>
182
+ <EnhanceIcon icon='close' onClick={handleClose} />
183
+ </EnhancePopover>
184
+ </div>
185
+ </div>
186
+ }
177
187
  renderContainerWrap={({ children }) => (
178
188
  <div className={styles.right_slot_container_wrap}>
179
- <div className={styles.header}>
180
- <span className={styles.title}>{options && options.title}</span>
181
- <div className={styles.side}>
182
- <EnhancePopover id={'ai_right_panel_header_close'} title={localize('editor.title.context.close')}>
183
- <EnhanceIcon icon='close' onClick={handleClose} />
184
- </EnhancePopover>
185
- </div>
186
- </div>
187
189
  <div className={styles.container}>{children}</div>
188
190
  </div>
189
191
  )}