@opensumi/ide-ai-native 3.4.4 → 3.4.5-next-1729482152.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.
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +18 -17
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/components/utils.d.ts +2 -2
- package/lib/browser/contrib/inline-completions/inline-completions.controller.d.ts +18 -0
- package/lib/browser/contrib/inline-completions/inline-completions.controller.d.ts.map +1 -0
- package/lib/browser/contrib/{intelligent-completions/intelligent-completions.source.js → inline-completions/inline-completions.controller.js} +48 -38
- package/lib/browser/contrib/inline-completions/inline-completions.controller.js.map +1 -0
- package/lib/browser/contrib/inline-completions/model/competionModel.d.ts +1 -1
- package/lib/browser/contrib/inline-completions/model/competionModel.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js +4 -4
- package/lib/browser/contrib/inline-completions/model/inlineCompletionRequestTask.js.map +1 -1
- package/lib/browser/contrib/inline-completions/prompt/prompt.d.ts +3 -3
- package/lib/browser/contrib/inline-completions/prompt/prompt.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/prompt/prompt.js.map +1 -1
- package/lib/browser/contrib/inline-completions/prompt/tokenizer.d.ts +1 -1
- package/lib/browser/contrib/inline-completions/prompt/tokenizer.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/prompt/tokenizer.js +2 -3
- package/lib/browser/contrib/inline-completions/prompt/tokenizer.js.map +1 -1
- package/lib/browser/contrib/inline-completions/promptCache.d.ts +1 -1
- package/lib/browser/contrib/inline-completions/promptCache.d.ts.map +1 -1
- package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts +1 -1
- package/lib/browser/contrib/inline-completions/service/ai-completions.service.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/{additions-deletions.decoration.d.ts → decoration/additions-deletions.decoration.d.ts} +1 -1
- package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/{additions-deletions.decoration.js → decoration/additions-deletions.decoration.js} +3 -3
- package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -0
- package/lib/browser/contrib/intelligent-completions/{multi-line.decoration.d.ts → decoration/multi-line.decoration.d.ts} +1 -1
- package/lib/browser/contrib/intelligent-completions/decoration/multi-line.decoration.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/{multi-line.decoration.js → decoration/multi-line.decoration.js} +1 -1
- package/lib/browser/contrib/intelligent-completions/decoration/multi-line.decoration.js.map +1 -0
- package/lib/browser/contrib/intelligent-completions/index.d.ts +30 -0
- package/lib/browser/contrib/intelligent-completions/index.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/index.js +8 -0
- package/lib/browser/contrib/intelligent-completions/index.js.map +1 -0
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts +3 -4
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +26 -25
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts +7 -3
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js +12 -3
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/lint-error.source.d.ts +29 -0
- package/lib/browser/contrib/intelligent-completions/lint-error.source.d.ts.map +1 -0
- package/lib/browser/contrib/intelligent-completions/lint-error.source.js +99 -0
- package/lib/browser/contrib/intelligent-completions/lint-error.source.js.map +1 -0
- package/lib/browser/contrib/terminal/decoration/terminal-decoration.d.ts +1 -1
- package/lib/browser/contrib/terminal/decoration/terminal-decoration.d.ts.map +1 -1
- package/lib/browser/contrib/terminal/decoration/terminal-decoration.js.map +1 -1
- package/lib/browser/contrib/terminal/ps1-terminal.service.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +5 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/types.d.ts +13 -3
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/types.js.map +1 -1
- package/lib/browser/widget/inline-diff/index.d.ts +1 -0
- package/lib/browser/widget/inline-diff/index.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/index.js +1 -0
- package/lib/browser/widget/inline-diff/index.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +4 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.js +0 -4
- package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +0 -3
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.js +0 -7
- package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.service.d.ts +10 -0
- package/lib/browser/widget/inline-diff/inline-diff.service.d.ts.map +1 -0
- package/lib/browser/widget/inline-diff/inline-diff.service.js +23 -0
- package/lib/browser/widget/inline-diff/inline-diff.service.js.map +1 -0
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +0 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +5 -3
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +9 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js +10 -3
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +8 -3
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +54 -24
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
- package/lib/browser/widget/rewrite/rewrite-widget.d.ts.map +1 -1
- package/lib/browser/widget/rewrite/rewrite-widget.js +2 -1
- package/lib/browser/widget/rewrite/rewrite-widget.js.map +1 -1
- package/package.json +24 -24
- package/src/browser/ai-core.contribution.ts +23 -17
- package/src/browser/contrib/{intelligent-completions/intelligent-completions.source.ts → inline-completions/inline-completions.controller.ts} +51 -23
- package/src/browser/contrib/inline-completions/model/competionModel.ts +1 -1
- package/src/browser/contrib/inline-completions/model/inlineCompletionRequestTask.ts +5 -5
- package/src/browser/contrib/inline-completions/prompt/prompt.ts +9 -5
- package/src/browser/contrib/inline-completions/prompt/tokenizer.ts +2 -3
- package/src/browser/contrib/inline-completions/promptCache.ts +1 -1
- package/src/browser/contrib/inline-completions/service/ai-completions.service.ts +1 -1
- package/src/browser/contrib/intelligent-completions/{additions-deletions.decoration.ts → decoration/additions-deletions.decoration.ts} +4 -5
- package/src/browser/contrib/intelligent-completions/{multi-line.decoration.ts → decoration/multi-line.decoration.ts} +2 -3
- package/src/browser/contrib/intelligent-completions/index.ts +34 -0
- package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +31 -44
- package/src/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.ts +18 -5
- package/src/browser/contrib/intelligent-completions/lint-error.source.ts +130 -0
- package/src/browser/contrib/terminal/ai-terminal.service.ts +1 -1
- package/src/browser/contrib/terminal/decoration/terminal-decoration.tsx +1 -1
- package/src/browser/contrib/terminal/ps1-terminal.service.tsx +1 -1
- package/src/browser/index.ts +5 -0
- package/src/browser/types.ts +24 -3
- package/src/browser/widget/inline-diff/index.ts +1 -0
- package/src/browser/widget/inline-diff/inline-diff-previewer.ts +5 -3
- package/src/browser/widget/inline-diff/inline-diff.controller.ts +0 -12
- package/src/browser/widget/inline-diff/inline-diff.service.ts +17 -0
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +6 -4
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +15 -0
- package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +72 -26
- package/src/browser/widget/rewrite/rewrite-widget.tsx +2 -1
- package/lib/browser/contrib/intelligent-completions/additions-deletions.decoration.d.ts.map +0 -1
- package/lib/browser/contrib/intelligent-completions/additions-deletions.decoration.js.map +0 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts +0 -15
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.d.ts.map +0 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.js +0 -3
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.js.map +0 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.source.d.ts +0 -15
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.source.d.ts.map +0 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.source.js.map +0 -1
- package/lib/browser/contrib/intelligent-completions/multi-line.decoration.d.ts.map +0 -1
- package/lib/browser/contrib/intelligent-completions/multi-line.decoration.js.map +0 -1
- package/src/browser/contrib/intelligent-completions/intelligent-completions.ts +0 -15
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import debounce from 'lodash/debounce';
|
|
2
2
|
|
|
3
|
-
import { Autowired, INJECTOR_TOKEN, Injectable, Injector, Optional } from '@opensumi/di';
|
|
4
3
|
import { AI_INLINE_COMPLETION_VISIBLE } from '@opensumi/ide-core-browser/lib/ai-native/command';
|
|
5
4
|
import {
|
|
6
5
|
CommandService,
|
|
7
6
|
CommandServiceImpl,
|
|
8
|
-
|
|
7
|
+
IAICompletionOption,
|
|
9
8
|
IDisposable,
|
|
10
9
|
IEventBus,
|
|
10
|
+
IntelligentCompletionsRegistryToken,
|
|
11
11
|
Sequencer,
|
|
12
12
|
runWhenIdle,
|
|
13
13
|
} from '@opensumi/ide-core-common';
|
|
@@ -18,28 +18,40 @@ import { empty } from '@opensumi/ide-utils/lib/strings';
|
|
|
18
18
|
import { InlineCompletionContextKeys } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys';
|
|
19
19
|
|
|
20
20
|
import { IAIInlineCompletionsProvider } from '../../../common';
|
|
21
|
+
import { AINativeContextKey } from '../../contextkey/ai-native.contextkey.service';
|
|
22
|
+
import { BaseAIMonacoEditorController } from '../base';
|
|
23
|
+
import { IIntelligentCompletionsResult } from '../intelligent-completions';
|
|
24
|
+
import { IntelligentCompletionsRegistry } from '../intelligent-completions/intelligent-completions.feature.registry';
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
export class InlineCompletionsController extends BaseAIMonacoEditorController {
|
|
27
|
+
public static readonly ID = 'editor.contrib.ai.inline.completions';
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
public static get(editor: ICodeEditor): InlineCompletionsController | null {
|
|
30
|
+
return editor.getContribution<InlineCompletionsController>(InlineCompletionsController.ID);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private get eventBus(): IEventBus {
|
|
34
|
+
return this.injector.get(IEventBus);
|
|
35
|
+
}
|
|
28
36
|
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
private get commandService(): CommandServiceImpl {
|
|
38
|
+
return this.injector.get(CommandService);
|
|
39
|
+
}
|
|
31
40
|
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
private get aiInlineCompletionsProvider(): IAIInlineCompletionsProvider {
|
|
42
|
+
return this.injector.get(IAIInlineCompletionsProvider);
|
|
43
|
+
}
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
private get intelligentCompletionsRegistry(): IntelligentCompletionsRegistry {
|
|
46
|
+
return this.injector.get(IntelligentCompletionsRegistryToken);
|
|
47
|
+
}
|
|
37
48
|
|
|
49
|
+
private aiNativeContextKey: AINativeContextKey;
|
|
38
50
|
private sequencer = new Sequencer();
|
|
39
51
|
private preDidShowItems: InlineCompletions | undefined;
|
|
40
52
|
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
public mount(): IDisposable {
|
|
54
|
+
this.aiNativeContextKey = this.injector.get(AINativeContextKey, [this.monacoEditor.contextKeyService]);
|
|
43
55
|
|
|
44
56
|
// 判断用户是否选择了一块区域或者移动光标 取消掉请补全请求
|
|
45
57
|
const selectionChange = () => {
|
|
@@ -62,7 +74,7 @@ export class InlineCompletionsSource extends Disposable {
|
|
|
62
74
|
});
|
|
63
75
|
|
|
64
76
|
const inlineVisibleKey = new Set([InlineCompletionContextKeys.inlineSuggestionVisible.key]);
|
|
65
|
-
this.addDispose(
|
|
77
|
+
this.featureDisposable.addDispose(
|
|
66
78
|
this.monacoEditor.contextKeyService.onDidChangeContext((e) => {
|
|
67
79
|
// inline completion 真正消失时
|
|
68
80
|
if (e.affectsSome(inlineVisibleKey)) {
|
|
@@ -79,7 +91,7 @@ export class InlineCompletionsSource extends Disposable {
|
|
|
79
91
|
}),
|
|
80
92
|
);
|
|
81
93
|
|
|
82
|
-
this.addDispose(
|
|
94
|
+
this.featureDisposable.addDispose(
|
|
83
95
|
this.eventBus.on(EditorSelectionChangeEvent, (e) => {
|
|
84
96
|
if (e.payload.source === 'mouse') {
|
|
85
97
|
debouncedSelectionChange();
|
|
@@ -90,7 +102,7 @@ export class InlineCompletionsSource extends Disposable {
|
|
|
90
102
|
}),
|
|
91
103
|
);
|
|
92
104
|
|
|
93
|
-
this.addDispose(
|
|
105
|
+
this.featureDisposable.addDispose(
|
|
94
106
|
this.monacoEditor.onDidChangeModelContent((e) => {
|
|
95
107
|
const changes = e.changes;
|
|
96
108
|
for (const change of changes) {
|
|
@@ -104,17 +116,15 @@ export class InlineCompletionsSource extends Disposable {
|
|
|
104
116
|
}),
|
|
105
117
|
);
|
|
106
118
|
|
|
107
|
-
this.addDispose(
|
|
119
|
+
this.featureDisposable.addDispose(
|
|
108
120
|
this.monacoEditor.onDidBlurEditorText(() => {
|
|
109
121
|
this.commandService.executeCommand(AI_INLINE_COMPLETION_VISIBLE.id, false);
|
|
110
122
|
}),
|
|
111
123
|
);
|
|
112
|
-
}
|
|
113
124
|
|
|
114
|
-
public fetch(): IDisposable {
|
|
115
125
|
let prePosition: Position | undefined;
|
|
116
126
|
|
|
117
|
-
this.addDispose(
|
|
127
|
+
this.featureDisposable.addDispose(
|
|
118
128
|
monacoApi.languages.registerInlineCompletionsProvider('*', {
|
|
119
129
|
groupId: 'ai-native-intelligent-completions',
|
|
120
130
|
provideInlineCompletions: async (model, position, context, token) => {
|
|
@@ -150,6 +160,24 @@ export class InlineCompletionsSource extends Disposable {
|
|
|
150
160
|
}),
|
|
151
161
|
);
|
|
152
162
|
|
|
153
|
-
return this;
|
|
163
|
+
return this.featureDisposable;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public async fetchProvider(bean: IAICompletionOption): Promise<IIntelligentCompletionsResult | undefined> {
|
|
167
|
+
const provider = this.intelligentCompletionsRegistry.getInlineCompletionsProvider();
|
|
168
|
+
if (!provider) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 如果上一次补全结果还在,则不重复请求
|
|
173
|
+
const isVisible = this.aiNativeContextKey.multiLineEditsIsVisible.get();
|
|
174
|
+
if (isVisible) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const position = this.monacoEditor.getPosition()!;
|
|
179
|
+
const inlineCompletionModel = await provider(this.monacoEditor, position, bean, this.token);
|
|
180
|
+
|
|
181
|
+
return inlineCompletionModel;
|
|
154
182
|
}
|
|
155
183
|
}
|
|
@@ -16,9 +16,9 @@ import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
|
16
16
|
import { WorkbenchEditorServiceImpl } from '@opensumi/ide-editor/lib/browser/workbench-editor.service';
|
|
17
17
|
import * as monaco from '@opensumi/ide-monaco';
|
|
18
18
|
|
|
19
|
-
import { IIntelligentCompletionsResult } from '../../intelligent-completions
|
|
20
|
-
import { IntelligentCompletionsController } from '../../intelligent-completions/intelligent-completions.controller';
|
|
19
|
+
import { IIntelligentCompletionsResult } from '../../intelligent-completions';
|
|
21
20
|
import { IntelligentCompletionsRegistry } from '../../intelligent-completions/intelligent-completions.feature.registry';
|
|
21
|
+
import { InlineCompletionsController } from '../inline-completions.controller';
|
|
22
22
|
import { InlineCompletionItem } from '../model/competionModel';
|
|
23
23
|
import { PromptCache } from '../promptCache';
|
|
24
24
|
import { lineBasedPromptProcessor } from '../provider';
|
|
@@ -174,14 +174,14 @@ export class InlineCompletionRequestTask extends Disposable {
|
|
|
174
174
|
} else {
|
|
175
175
|
try {
|
|
176
176
|
this.aiCompletionsService.updateStatusBarItem('running', true);
|
|
177
|
-
const provider = this.intelligentCompletionsRegistry.
|
|
177
|
+
const provider = this.intelligentCompletionsRegistry.getInlineCompletionsProvider();
|
|
178
178
|
if (provider) {
|
|
179
179
|
const editor = this.workbenchEditorService.currentCodeEditor;
|
|
180
180
|
if (!editor) {
|
|
181
181
|
return [];
|
|
182
182
|
}
|
|
183
|
-
const
|
|
184
|
-
completeResult = await
|
|
183
|
+
const inlineCompletionsHandler = InlineCompletionsController.get(editor.monacoEditor);
|
|
184
|
+
completeResult = await inlineCompletionsHandler?.fetchProvider(requestBean);
|
|
185
185
|
} else {
|
|
186
186
|
completeResult = await this.aiCompletionsService.complete(requestBean);
|
|
187
187
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { Tiktoken } from 'js-tiktoken';
|
|
1
|
+
import { Tiktoken } from 'tiktoken/lite';
|
|
3
2
|
|
|
4
3
|
import { Injector } from '@opensumi/di';
|
|
5
4
|
|
|
@@ -59,7 +58,12 @@ export const getMarkerForSnippets = (text: string, language: string) => {
|
|
|
59
58
|
return lines.map((line) => getMarkerByLanguage(line, language)).join('\n');
|
|
60
59
|
};
|
|
61
60
|
|
|
62
|
-
export const getCroppedTextByLine = (
|
|
61
|
+
export const getCroppedTextByLine = (
|
|
62
|
+
text: string,
|
|
63
|
+
maxTokenSize: number,
|
|
64
|
+
textTokens: Uint32Array[],
|
|
65
|
+
reverse = false,
|
|
66
|
+
) => {
|
|
63
67
|
const currentTokenSize = textTokens.reduce((prev, cur) => prev + cur.length, 0);
|
|
64
68
|
if (currentTokenSize < maxTokenSize) {
|
|
65
69
|
return text;
|
|
@@ -110,7 +114,7 @@ export const getCroppedTextByLine = (text: string, maxTokenSize: number, textTok
|
|
|
110
114
|
export const getCroppedText = async (
|
|
111
115
|
text: string,
|
|
112
116
|
maxTokenSize: number,
|
|
113
|
-
textTokens:
|
|
117
|
+
textTokens: Uint32Array[],
|
|
114
118
|
strategy = StrategyType.InterceptBasedOnLine,
|
|
115
119
|
tokenizer: Tiktoken,
|
|
116
120
|
parser?: LanguageParser,
|
|
@@ -118,7 +122,7 @@ export const getCroppedText = async (
|
|
|
118
122
|
reverse = false,
|
|
119
123
|
token?: monaco.CancellationToken,
|
|
120
124
|
): Promise<string> => {
|
|
121
|
-
let tokens:
|
|
125
|
+
let tokens: Uint32Array;
|
|
122
126
|
if (strategy === StrategyType.InterceptBasedOnLine) {
|
|
123
127
|
// 按行进行裁剪
|
|
124
128
|
text = getCroppedTextByLine(text, maxTokenSize, textTokens, reverse);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { Tiktoken, getEncoding } from 'js-tiktoken';
|
|
1
|
+
import { Tiktoken, get_encoding } from 'tiktoken';
|
|
3
2
|
|
|
4
3
|
import { TokenizerName } from '../types';
|
|
5
4
|
|
|
@@ -10,7 +9,7 @@ export const getTokenizer = (tokenizerName = TokenizerName.cl100k_base) => {
|
|
|
10
9
|
if (tokenizer) {
|
|
11
10
|
return tokenizer;
|
|
12
11
|
}
|
|
13
|
-
tokenizer =
|
|
12
|
+
tokenizer = get_encoding('cl100k_base');
|
|
14
13
|
TOKENIZER_CACHE.set(tokenizerName, tokenizer);
|
|
15
14
|
return tokenizer;
|
|
16
15
|
};
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from '@opensumi/ide-core-browser';
|
|
10
10
|
import { IHashCalculateService } from '@opensumi/ide-core-common/lib/hash-calculate/hash-calculate';
|
|
11
11
|
|
|
12
|
-
import { IIntelligentCompletionsResult } from '../intelligent-completions
|
|
12
|
+
import { IIntelligentCompletionsResult } from '../intelligent-completions';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* 缓存服务
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from '@opensumi/ide-core-common';
|
|
16
16
|
import { CompletionRT, IAIReporter } from '@opensumi/ide-core-common/lib/types/ai-native/reporter';
|
|
17
17
|
|
|
18
|
-
import { IIntelligentCompletionsResult } from '../../intelligent-completions
|
|
18
|
+
import { IIntelligentCompletionsResult } from '../../intelligent-completions';
|
|
19
19
|
|
|
20
20
|
@Injectable()
|
|
21
21
|
export class AICompletionsService extends Disposable {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { ICodeEditor, IModelDeltaDecoration, IRange, TrackedRangeStickiness } from '@opensumi/ide-monaco';
|
|
2
2
|
|
|
3
|
-
import { EnhanceDecorationsCollection } from '
|
|
4
|
-
import { REWRITE_DECORATION_INLINE_ADD } from '
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import styles from './intelligent-completions.module.less';
|
|
3
|
+
import { EnhanceDecorationsCollection } from '../../../model/enhanceDecorationsCollection';
|
|
4
|
+
import { REWRITE_DECORATION_INLINE_ADD } from '../../../widget/rewrite/rewrite-widget';
|
|
5
|
+
import { IMultiLineDiffChangeResult } from '../diff-computer';
|
|
6
|
+
import styles from '../intelligent-completions.module.less';
|
|
8
7
|
|
|
9
8
|
export class AdditionsDeletionsDecorationModel {
|
|
10
9
|
private deletionsDecorations: EnhanceDecorationsCollection;
|
|
@@ -4,9 +4,8 @@ import { empty } from '@opensumi/ide-utils/lib/strings';
|
|
|
4
4
|
import { EditOperation } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/editOperation';
|
|
5
5
|
import { LineDecoration } from '@opensumi/monaco-editor-core/esm/vs/editor/common/viewLayout/lineDecorations';
|
|
6
6
|
|
|
7
|
-
import { EnhanceDecorationsCollection } from '
|
|
8
|
-
|
|
9
|
-
import { IMultiLineDiffChangeResult } from './diff-computer';
|
|
7
|
+
import { EnhanceDecorationsCollection } from '../../../model/enhanceDecorationsCollection';
|
|
8
|
+
import { IMultiLineDiffChangeResult } from '../diff-computer';
|
|
10
9
|
|
|
11
10
|
export interface IModificationsInline {
|
|
12
11
|
newValue: string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { IRange, InlineCompletion } from '@opensumi/ide-monaco';
|
|
2
|
+
|
|
3
|
+
import type { ILinterErrorData } from './lint-error.source';
|
|
4
|
+
|
|
5
|
+
export interface IIntelligentCompletionsResult<T = any> {
|
|
6
|
+
readonly items: InlineCompletion[];
|
|
7
|
+
/**
|
|
8
|
+
* 定义的额外信息
|
|
9
|
+
*/
|
|
10
|
+
extra?: T;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export enum ECodeEditsSource {
|
|
14
|
+
LinterErrors = 'lint_errors',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ICodeEditsContextBean {
|
|
18
|
+
typing: ECodeEditsSource.LinterErrors;
|
|
19
|
+
data: ILinterErrorData;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ICodeEdit {
|
|
23
|
+
/**
|
|
24
|
+
* 插入的文本
|
|
25
|
+
*/
|
|
26
|
+
readonly insertText: string;
|
|
27
|
+
/**
|
|
28
|
+
* 替换的文本范围
|
|
29
|
+
*/
|
|
30
|
+
readonly range: IRange;
|
|
31
|
+
}
|
|
32
|
+
export interface ICodeEditsResult {
|
|
33
|
+
readonly items: ICodeEdit[];
|
|
34
|
+
}
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import { Key, KeybindingRegistry, KeybindingScope, PreferenceService } from '@opensumi/ide-core-browser';
|
|
2
2
|
import { MultiLineEditsIsVisible } from '@opensumi/ide-core-browser/lib/contextkey/ai-native';
|
|
3
|
-
import {
|
|
4
|
-
AINativeSettingSectionsId,
|
|
5
|
-
Disposable,
|
|
6
|
-
Event,
|
|
7
|
-
IAICompletionOption,
|
|
8
|
-
IDisposable,
|
|
9
|
-
IntelligentCompletionsRegistryToken,
|
|
10
|
-
runWhenIdle,
|
|
11
|
-
} from '@opensumi/ide-core-common';
|
|
3
|
+
import { AINativeSettingSectionsId, Disposable, Event, IDisposable, runWhenIdle } from '@opensumi/ide-core-common';
|
|
12
4
|
import { ICodeEditor, ICursorPositionChangedEvent, IRange, ITextModel, Range } from '@opensumi/ide-monaco';
|
|
13
5
|
import { empty } from '@opensumi/ide-utils/lib/strings';
|
|
14
6
|
import { autorun, transaction } from '@opensumi/monaco-editor-core/esm/vs/base/common/observable';
|
|
@@ -21,23 +13,24 @@ import {
|
|
|
21
13
|
SuggestItemInfo,
|
|
22
14
|
SuggestWidgetAdaptor,
|
|
23
15
|
} from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider';
|
|
16
|
+
import { SuggestController } from '@opensumi/monaco-editor-core/esm/vs/editor/contrib/suggest/browser/suggestController';
|
|
24
17
|
import { ContextKeyExpr } from '@opensumi/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey';
|
|
25
18
|
|
|
26
19
|
import { AINativeContextKey } from '../../contextkey/ai-native.contextkey.service';
|
|
27
20
|
import { REWRITE_DECORATION_INLINE_ADD, RewriteWidget } from '../../widget/rewrite/rewrite-widget';
|
|
28
21
|
import { BaseAIMonacoEditorController } from '../base';
|
|
29
22
|
|
|
30
|
-
import { AdditionsDeletionsDecorationModel } from './additions-deletions.decoration';
|
|
23
|
+
import { AdditionsDeletionsDecorationModel } from './decoration/additions-deletions.decoration';
|
|
24
|
+
import { MultiLineDecorationModel } from './decoration/multi-line.decoration';
|
|
31
25
|
import {
|
|
32
26
|
IMultiLineDiffChangeResult,
|
|
33
27
|
computeMultiLineDiffChanges,
|
|
34
28
|
mergeMultiLineDiffChanges,
|
|
35
29
|
wordChangesToLineChangesMap,
|
|
36
30
|
} from './diff-computer';
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
import {
|
|
40
|
-
import { MultiLineDecorationModel } from './multi-line.decoration';
|
|
31
|
+
import { LintErrorCodeEditsSource } from './lint-error.source';
|
|
32
|
+
|
|
33
|
+
import { ICodeEditsResult } from '.';
|
|
41
34
|
|
|
42
35
|
export class IntelligentCompletionsController extends BaseAIMonacoEditorController {
|
|
43
36
|
public static readonly ID = 'editor.contrib.ai.intelligent.completions';
|
|
@@ -46,10 +39,6 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
46
39
|
return editor.getContribution<IntelligentCompletionsController>(IntelligentCompletionsController.ID);
|
|
47
40
|
}
|
|
48
41
|
|
|
49
|
-
private get intelligentCompletionsRegistry(): IntelligentCompletionsRegistry {
|
|
50
|
-
return this.injector.get(IntelligentCompletionsRegistryToken);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
42
|
private get model(): ITextModel {
|
|
54
43
|
return this.monacoEditor.getModel()!;
|
|
55
44
|
}
|
|
@@ -129,6 +118,19 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
129
118
|
}
|
|
130
119
|
}),
|
|
131
120
|
);
|
|
121
|
+
|
|
122
|
+
observableDisposable.addDispose(
|
|
123
|
+
autorun((reader) => {
|
|
124
|
+
const state = inlineCompletionsController.model.read(reader)?.state.read(reader);
|
|
125
|
+
const suggestController = SuggestController.get(this.monacoEditor);
|
|
126
|
+
// 当阴影字符超出一行的时候,强制让 suggest 面板向上展示,避免遮挡补全内容
|
|
127
|
+
if (state && state.primaryGhostText?.lineCount >= 2) {
|
|
128
|
+
suggestController?.forceRenderingAbove();
|
|
129
|
+
} else {
|
|
130
|
+
suggestController?.stopForceRenderingAbove();
|
|
131
|
+
}
|
|
132
|
+
}),
|
|
133
|
+
);
|
|
132
134
|
}
|
|
133
135
|
};
|
|
134
136
|
|
|
@@ -169,45 +171,30 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
169
171
|
}
|
|
170
172
|
}
|
|
171
173
|
|
|
172
|
-
public async fetchProvider(
|
|
173
|
-
const provider = this.intelligentCompletionsRegistry.getProvider();
|
|
174
|
-
if (!provider) {
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
|
|
174
|
+
public async fetchProvider(editsResult: ICodeEditsResult): Promise<void> {
|
|
178
175
|
// 如果上一次补全结果还在,则不重复请求
|
|
179
176
|
const isVisible = this.aiNativeContextKey.multiLineEditsIsVisible.get();
|
|
180
177
|
if (isVisible) {
|
|
181
178
|
return;
|
|
182
179
|
}
|
|
183
180
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if (
|
|
188
|
-
intelligentCompletionModel &&
|
|
189
|
-
intelligentCompletionModel.enableMultiLine &&
|
|
190
|
-
intelligentCompletionModel.items.length > 0
|
|
191
|
-
) {
|
|
192
|
-
return this.applyInlineDecorations(intelligentCompletionModel);
|
|
181
|
+
if (editsResult && editsResult.items.length > 0) {
|
|
182
|
+
this.applyInlineDecorations(editsResult);
|
|
193
183
|
}
|
|
194
|
-
|
|
195
|
-
return intelligentCompletionModel;
|
|
196
184
|
}
|
|
197
185
|
|
|
198
|
-
private applyInlineDecorations(completionModel:
|
|
186
|
+
private applyInlineDecorations(completionModel: ICodeEditsResult) {
|
|
199
187
|
const { items } = completionModel;
|
|
200
|
-
|
|
201
|
-
const position = this.monacoEditor.getPosition()!;
|
|
202
|
-
const model = this.monacoEditor.getModel();
|
|
203
188
|
const { range, insertText } = items[0];
|
|
204
|
-
const insertTextString = insertText.toString();
|
|
205
189
|
|
|
206
|
-
//
|
|
190
|
+
// code edits 必须提供 range
|
|
207
191
|
if (!range) {
|
|
208
|
-
return
|
|
192
|
+
return;
|
|
209
193
|
}
|
|
210
194
|
|
|
195
|
+
const position = this.monacoEditor.getPosition()!;
|
|
196
|
+
const model = this.monacoEditor.getModel();
|
|
197
|
+
const insertTextString = insertText.toString();
|
|
211
198
|
const originalContent = model?.getValueInRange(range);
|
|
212
199
|
const eol = this.model.getEOL();
|
|
213
200
|
|
|
@@ -390,7 +377,7 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
390
377
|
}),
|
|
391
378
|
);
|
|
392
379
|
|
|
393
|
-
const
|
|
394
|
-
this.featureDisposable.addDispose(
|
|
380
|
+
const lintErrorCodeEditsSource = this.injector.get(LintErrorCodeEditsSource, [this.monacoEditor, this.token]);
|
|
381
|
+
this.featureDisposable.addDispose(lintErrorCodeEditsSource.mount());
|
|
395
382
|
}
|
|
396
383
|
}
|
package/src/browser/contrib/intelligent-completions/intelligent-completions.feature.registry.ts
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import { Injectable } from '@opensumi/di';
|
|
2
2
|
import { Disposable } from '@opensumi/ide-core-common';
|
|
3
3
|
|
|
4
|
-
import { IIntelligentCompletionProvider, IIntelligentCompletionsRegistry } from '../../types';
|
|
4
|
+
import { ICodeEditsProvider, IIntelligentCompletionProvider, IIntelligentCompletionsRegistry } from '../../types';
|
|
5
5
|
|
|
6
6
|
@Injectable()
|
|
7
7
|
export class IntelligentCompletionsRegistry extends Disposable implements IIntelligentCompletionsRegistry {
|
|
8
|
-
private
|
|
8
|
+
private inlineCompletionsProvider: IIntelligentCompletionProvider | undefined;
|
|
9
|
+
private codeEditsProvider: ICodeEditsProvider | undefined;
|
|
9
10
|
|
|
10
11
|
registerIntelligentCompletionProvider(provider: IIntelligentCompletionProvider): void {
|
|
11
|
-
this.
|
|
12
|
+
this.inlineCompletionsProvider = provider;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
registerInlineCompletionsProvider(provider: IIntelligentCompletionProvider): void {
|
|
16
|
+
this.inlineCompletionsProvider = provider;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
registerCodeEditsProvider(provider: ICodeEditsProvider): void {
|
|
20
|
+
this.codeEditsProvider = provider;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getInlineCompletionsProvider(): IIntelligentCompletionProvider | undefined {
|
|
24
|
+
return this.inlineCompletionsProvider;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getCodeEditsProvider(): ICodeEditsProvider | undefined {
|
|
28
|
+
return this.codeEditsProvider;
|
|
16
29
|
}
|
|
17
30
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Autowired, Injectable, Optional } from '@opensumi/di';
|
|
2
|
+
import {
|
|
3
|
+
CancellationToken,
|
|
4
|
+
Disposable,
|
|
5
|
+
IDisposable,
|
|
6
|
+
IntelligentCompletionsRegistryToken,
|
|
7
|
+
} from '@opensumi/ide-core-common';
|
|
8
|
+
import { ICodeEditor, ICursorPositionChangedEvent, IPosition, Position } from '@opensumi/ide-monaco';
|
|
9
|
+
import { URI } from '@opensumi/ide-monaco/lib/browser/monaco-api';
|
|
10
|
+
import { IWorkspaceService } from '@opensumi/ide-workspace';
|
|
11
|
+
import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
|
|
12
|
+
import {
|
|
13
|
+
IMarker,
|
|
14
|
+
IMarkerService,
|
|
15
|
+
IRelatedInformation,
|
|
16
|
+
MarkerSeverity,
|
|
17
|
+
} from '@opensumi/monaco-editor-core/esm/vs/platform/markers/common/markers';
|
|
18
|
+
|
|
19
|
+
import { IntelligentCompletionsController } from './intelligent-completions.controller';
|
|
20
|
+
import { IntelligentCompletionsRegistry } from './intelligent-completions.feature.registry';
|
|
21
|
+
|
|
22
|
+
import { ECodeEditsSource } from '.';
|
|
23
|
+
|
|
24
|
+
export interface ILinterErrorData {
|
|
25
|
+
relativeWorkspacePath: string;
|
|
26
|
+
errors: Array<IMarkerErrorData>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface IMarkerErrorData {
|
|
30
|
+
message: string;
|
|
31
|
+
range: {
|
|
32
|
+
startPosition: IPosition;
|
|
33
|
+
endPosition: IPosition;
|
|
34
|
+
};
|
|
35
|
+
source: URI;
|
|
36
|
+
severity: string;
|
|
37
|
+
relatedInformation?: IRelatedInformation[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
namespace MarkerErrorData {
|
|
41
|
+
export function toData(marker: IMarker): IMarkerErrorData {
|
|
42
|
+
return {
|
|
43
|
+
message: marker.message,
|
|
44
|
+
range: {
|
|
45
|
+
startPosition: {
|
|
46
|
+
lineNumber: marker.startLineNumber,
|
|
47
|
+
column: marker.startColumn,
|
|
48
|
+
},
|
|
49
|
+
endPosition: {
|
|
50
|
+
lineNumber: marker.endLineNumber,
|
|
51
|
+
column: marker.endColumn,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
source: marker.resource,
|
|
55
|
+
relatedInformation: marker.relatedInformation,
|
|
56
|
+
severity: MarkerSeverity.toString(marker.severity),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@Injectable({ multiple: true })
|
|
62
|
+
export class LintErrorCodeEditsSource extends Disposable {
|
|
63
|
+
@Autowired(IntelligentCompletionsRegistryToken)
|
|
64
|
+
private readonly intelligentCompletionsRegistry: IntelligentCompletionsRegistry;
|
|
65
|
+
|
|
66
|
+
@Autowired(IWorkspaceService)
|
|
67
|
+
private readonly workspaceService: IWorkspaceService;
|
|
68
|
+
|
|
69
|
+
private get model() {
|
|
70
|
+
return this.monacoEditor.getModel();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
constructor(
|
|
74
|
+
@Optional() private readonly monacoEditor: ICodeEditor,
|
|
75
|
+
@Optional() private readonly token: CancellationToken,
|
|
76
|
+
) {
|
|
77
|
+
super();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public mount(): IDisposable {
|
|
81
|
+
let prePosition = this.monacoEditor.getPosition();
|
|
82
|
+
|
|
83
|
+
this.addDispose(
|
|
84
|
+
// 仅在光标的行号发生变化时,才触发
|
|
85
|
+
this.monacoEditor.onDidChangeCursorPosition((event: ICursorPositionChangedEvent) => {
|
|
86
|
+
const currentPosition = event.position;
|
|
87
|
+
if (prePosition && prePosition.lineNumber !== currentPosition.lineNumber) {
|
|
88
|
+
this.doTrigger(currentPosition);
|
|
89
|
+
}
|
|
90
|
+
prePosition = currentPosition;
|
|
91
|
+
}),
|
|
92
|
+
);
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private async doTrigger(position: Position) {
|
|
97
|
+
if (!this.model) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const markerService = StandaloneServices.get(IMarkerService);
|
|
102
|
+
const resource = this.model.uri;
|
|
103
|
+
|
|
104
|
+
let markers = markerService.read({ resource, severities: MarkerSeverity.Error });
|
|
105
|
+
markers = markers.filter((marker) => Math.abs(marker.startLineNumber - position.lineNumber) <= 1);
|
|
106
|
+
|
|
107
|
+
if (markers.length) {
|
|
108
|
+
const provider = this.intelligentCompletionsRegistry.getCodeEditsProvider();
|
|
109
|
+
if (provider) {
|
|
110
|
+
const relativeWorkspacePath = await this.workspaceService.asRelativePath(resource.path);
|
|
111
|
+
const result = await provider(
|
|
112
|
+
this.monacoEditor,
|
|
113
|
+
position,
|
|
114
|
+
{
|
|
115
|
+
typing: ECodeEditsSource.LinterErrors,
|
|
116
|
+
data: {
|
|
117
|
+
relativeWorkspacePath: relativeWorkspacePath?.path ?? resource.path,
|
|
118
|
+
errors: markers.map((marker) => MarkerErrorData.toData(marker)),
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
this.token,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
if (result) {
|
|
125
|
+
IntelligentCompletionsController.get(this.monacoEditor)?.fetchProvider(result);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { IDecoration, IMarker, Terminal } from '@xterm/xterm';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { Root, createRoot } from 'react-dom/client';
|
|
3
|
-
import { IDecoration, IMarker, Terminal } from 'xterm';
|
|
4
4
|
|
|
5
5
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
6
6
|
import { AIActionItem } from '@opensumi/ide-core-browser/lib/components/ai-native';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { IDecoration, IDisposable, IMarker, Terminal } from '@xterm/xterm';
|
|
1
2
|
import domAlign from 'dom-align';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { Root, createRoot } from 'react-dom/client';
|
|
4
|
-
import { IDecoration, IDisposable, IMarker, Terminal } from 'xterm';
|
|
5
5
|
|
|
6
6
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
7
7
|
import { localize } from '@opensumi/ide-core-browser';
|