@opensumi/ide-ai-native 3.9.1-next-1749538805.0 → 3.9.1-next-1749540423.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 +4 -9
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/apply.service.d.ts +0 -3
- package/lib/browser/chat/apply.service.d.ts.map +1 -1
- package/lib/browser/chat/apply.service.js +0 -47
- package/lib/browser/chat/apply.service.js.map +1 -1
- package/lib/browser/chat/chat-manager.service.d.ts +0 -1
- package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-manager.service.js +3 -9
- package/lib/browser/chat/chat-manager.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts +1 -8
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +76 -113
- package/lib/browser/chat/chat-model.js.map +1 -1
- package/lib/browser/chat/chat-proxy.service.d.ts +2 -0
- package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-proxy.service.js +57 -50
- package/lib/browser/chat/chat-proxy.service.js.map +1 -1
- package/lib/browser/chat/chat.feature.registry.d.ts +1 -4
- package/lib/browser/chat/chat.feature.registry.d.ts.map +1 -1
- package/lib/browser/chat/chat.feature.registry.js +0 -6
- package/lib/browser/chat/chat.feature.registry.js.map +1 -1
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +10 -50
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ChatEditor.js +2 -2
- package/lib/browser/components/ChatEditor.js.map +1 -1
- package/lib/browser/components/ChatHistory.d.ts.map +1 -1
- package/lib/browser/components/ChatHistory.js +1 -2
- package/lib/browser/components/ChatHistory.js.map +1 -1
- package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
- package/lib/browser/components/ChatMentionInput.js +30 -148
- package/lib/browser/components/ChatMentionInput.js.map +1 -1
- package/lib/browser/components/ChatReply.js +2 -2
- package/lib/browser/components/ChatReply.js.map +1 -1
- package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
- package/lib/browser/components/ChatToolRender.js +2 -7
- package/lib/browser/components/ChatToolRender.js.map +1 -1
- package/lib/browser/components/ChatToolRender.module.less +0 -25
- package/lib/browser/components/components.module.less +8 -37
- package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
- package/lib/browser/components/mention-input/mention-input.js +14 -150
- package/lib/browser/components/mention-input/mention-input.js.map +1 -1
- package/lib/browser/components/mention-input/mention-input.module.less +1 -165
- package/lib/browser/components/mention-input/types.d.ts +1 -28
- package/lib/browser/components/mention-input/types.d.ts.map +1 -1
- package/lib/browser/components/mention-input/types.js +0 -1
- package/lib/browser/components/mention-input/types.js.map +1 -1
- package/lib/browser/components/utils.d.ts +2 -2
- package/lib/browser/context/llm-context.service.d.ts +2 -21
- package/lib/browser/context/llm-context.service.d.ts.map +1 -1
- package/lib/browser/context/llm-context.service.js +20 -162
- package/lib/browser/context/llm-context.service.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/diff-computer.js +1 -1
- package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -1
- package/lib/browser/contrib/terminal/terminal.feature.registry.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +0 -7
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/layout/ai-layout.d.ts.map +1 -1
- package/lib/browser/layout/ai-layout.js +4 -6
- package/lib/browser/layout/ai-layout.js.map +1 -1
- package/lib/browser/layout/tabbar.view.d.ts +1 -1
- package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
- package/lib/browser/layout/tabbar.view.js +12 -5
- package/lib/browser/layout/tabbar.view.js.map +1 -1
- package/lib/browser/mcp/base-apply.service.d.ts +4 -5
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.js +5 -23
- package/lib/browser/mcp/base-apply.service.js.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts +1 -3
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js +0 -4
- package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js +1 -7
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts +3 -1
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
- package/lib/browser/mcp/tools/createNewFileWithText.js +40 -14
- package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
- package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -1
- package/lib/browser/mcp/tools/fileSearch.js +5 -9
- package/lib/browser/mcp/tools/fileSearch.js.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
- package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -1
- package/lib/browser/mcp/tools/grepSearch.js +10 -22
- package/lib/browser/mcp/tools/grepSearch.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/ListDir.js +1 -1
- package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/ReadFile.js +1 -1
- package/lib/browser/mcp/tools/handlers/ReadFile.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/RunCommand.d.ts +1 -11
- package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
- package/lib/browser/mcp/tools/handlers/RunCommand.js +4 -11
- package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
- package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
- package/lib/browser/mcp/tools/listDir.js +15 -19
- package/lib/browser/mcp/tools/listDir.js.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
- package/lib/browser/model/msg-history-manager.d.ts +1 -47
- package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
- package/lib/browser/model/msg-history-manager.js +2 -127
- package/lib/browser/model/msg-history-manager.js.map +1 -1
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +0 -5
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/types.d.ts +1 -12
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/types.js.map +1 -1
- 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.map +1 -1
- package/lib/common/index.d.ts +1 -5
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +0 -2
- package/lib/common/index.js.map +1 -1
- package/lib/common/llm-context.d.ts +0 -19
- package/lib/common/llm-context.d.ts.map +1 -1
- package/lib/common/llm-context.js.map +1 -1
- package/lib/common/model.d.ts +0 -1
- package/lib/common/model.d.ts.map +1 -1
- package/lib/common/model.js.map +1 -1
- package/lib/common/prompts/context-prompt-provider.d.ts +2 -0
- package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
- package/lib/common/prompts/context-prompt-provider.js +29 -35
- package/lib/common/prompts/context-prompt-provider.js.map +1 -1
- package/lib/common/types.d.ts +0 -21
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/types.js.map +1 -1
- package/lib/common/utils.d.ts +0 -1
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +2 -5
- package/lib/common/utils.js.map +1 -1
- package/lib/node/anthropic/anthropic-language-model.d.ts +1 -1
- package/lib/node/base-language-model.d.ts +1 -2
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js +2 -12
- package/lib/node/base-language-model.js.map +1 -1
- package/lib/node/deepseek/deepseek-language-model.d.ts +1 -1
- package/lib/node/mcp/sumi-mcp-server.d.ts +1 -3
- package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.js +1 -7
- package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
- package/lib/node/mcp-server-manager-impl.d.ts +1 -3
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
- package/lib/node/mcp-server-manager-impl.js +2 -14
- package/lib/node/mcp-server-manager-impl.js.map +1 -1
- package/lib/node/mcp-server.sse.d.ts +1 -187
- package/lib/node/mcp-server.sse.d.ts.map +1 -1
- package/lib/node/mcp-server.sse.js +2 -2
- package/lib/node/mcp-server.sse.js.map +1 -1
- package/lib/node/mcp-server.stdio.d.ts +1 -187
- package/lib/node/mcp-server.stdio.d.ts.map +1 -1
- package/package.json +26 -27
- package/src/browser/ai-core.contribution.ts +4 -14
- package/src/browser/chat/apply.service.ts +1 -62
- package/src/browser/chat/chat-manager.service.ts +7 -16
- package/src/browser/chat/chat-model.ts +73 -130
- package/src/browser/chat/chat-proxy.service.ts +81 -68
- package/src/browser/chat/chat.feature.registry.ts +1 -17
- package/src/browser/chat/chat.view.tsx +12 -73
- package/src/browser/components/ChatEditor.tsx +1 -1
- package/src/browser/components/ChatHistory.tsx +1 -2
- package/src/browser/components/ChatMentionInput.tsx +35 -180
- package/src/browser/components/ChatReply.tsx +4 -4
- package/src/browser/components/ChatToolRender.module.less +0 -25
- package/src/browser/components/ChatToolRender.tsx +2 -10
- package/src/browser/components/components.module.less +8 -37
- package/src/browser/components/mention-input/mention-input.module.less +1 -165
- package/src/browser/components/mention-input/mention-input.tsx +31 -232
- package/src/browser/components/mention-input/types.ts +0 -29
- package/src/browser/context/llm-context.service.ts +21 -182
- package/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts +1 -1
- package/src/browser/contrib/intelligent-completions/diff-computer.ts +1 -1
- package/src/browser/contrib/terminal/terminal.feature.registry.ts +1 -1
- package/src/browser/index.ts +0 -8
- package/src/browser/layout/ai-layout.tsx +8 -12
- package/src/browser/layout/tabbar.view.tsx +23 -10
- package/src/browser/mcp/base-apply.service.ts +10 -30
- package/src/browser/mcp/mcp-server-proxy.service.ts +1 -6
- package/src/browser/mcp/mcp-server.feature.registry.ts +1 -6
- package/src/browser/mcp/tools/createNewFileWithText.ts +46 -17
- package/src/browser/mcp/tools/fileSearch.ts +5 -8
- package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
- package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
- package/src/browser/mcp/tools/grepSearch.ts +21 -32
- package/src/browser/mcp/tools/handlers/ListDir.ts +2 -2
- package/src/browser/mcp/tools/handlers/ReadFile.ts +2 -2
- package/src/browser/mcp/tools/handlers/RunCommand.ts +14 -21
- package/src/browser/mcp/tools/listDir.ts +12 -15
- package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
- package/src/browser/model/msg-history-manager.ts +2 -181
- package/src/browser/preferences/schema.ts +0 -5
- package/src/browser/types.ts +0 -18
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +1 -0
- package/src/common/index.ts +1 -6
- package/src/common/llm-context.ts +0 -23
- package/src/common/model.ts +0 -1
- package/src/common/prompts/context-prompt-provider.ts +40 -55
- package/src/common/types.ts +0 -18
- package/src/common/utils.ts +1 -4
- package/src/node/base-language-model.ts +14 -11
- package/src/node/mcp/sumi-mcp-server.ts +2 -10
- package/src/node/mcp-server-manager-impl.ts +2 -17
- package/src/node/mcp-server.sse.ts +2 -1
- package/lib/browser/components/mention-input/mention-select.d.ts +0 -28
- package/lib/browser/components/mention-input/mention-select.d.ts.map +0 -1
- package/lib/browser/components/mention-input/mention-select.js +0 -136
- package/lib/browser/components/mention-input/mention-select.js.map +0 -1
- package/lib/browser/components/mention-input/mention-select.module.less +0 -297
- package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.d.ts +0 -15
- package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.d.ts.map +0 -1
- package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.js +0 -53
- package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.js.map +0 -1
- package/lib/browser/rules/rules.contribution.d.ts +0 -29
- package/lib/browser/rules/rules.contribution.d.ts.map +0 -1
- package/lib/browser/rules/rules.contribution.js +0 -94
- package/lib/browser/rules/rules.contribution.js.map +0 -1
- package/lib/browser/rules/rules.module.less +0 -175
- package/lib/browser/rules/rules.service.d.ts +0 -25
- package/lib/browser/rules/rules.service.d.ts.map +0 -1
- package/lib/browser/rules/rules.service.js +0 -180
- package/lib/browser/rules/rules.service.js.map +0 -1
- package/lib/browser/rules/rules.view.d.ts +0 -3
- package/lib/browser/rules/rules.view.d.ts.map +0 -1
- package/lib/browser/rules/rules.view.js +0 -76
- package/lib/browser/rules/rules.view.js.map +0 -1
- package/lib/common/image-compression.d.ts +0 -25
- package/lib/common/image-compression.d.ts.map +0 -1
- package/lib/common/image-compression.js +0 -153
- package/lib/common/image-compression.js.map +0 -1
- package/lib/common/mdc-parser.d.ts +0 -60
- package/lib/common/mdc-parser.d.ts.map +0 -1
- package/lib/common/mdc-parser.js +0 -246
- package/lib/common/mdc-parser.js.map +0 -1
- package/lib/common/prompts/system-prompt.d.ts +0 -2
- package/lib/common/prompts/system-prompt.d.ts.map +0 -1
- package/lib/common/prompts/system-prompt.js +0 -5
- package/lib/common/prompts/system-prompt.js.map +0 -1
- package/src/browser/components/mention-input/mention-select.module.less +0 -297
- package/src/browser/components/mention-input/mention-select.tsx +0 -256
- package/src/browser/mcp/tools/handlers/CreateNewFileWithText.ts +0 -49
- package/src/browser/rules/rules.contribution.ts +0 -105
- package/src/browser/rules/rules.module.less +0 -175
- package/src/browser/rules/rules.service.ts +0 -189
- package/src/browser/rules/rules.view.tsx +0 -127
- package/src/common/image-compression.ts +0 -174
- package/src/common/mdc-parser.ts +0 -295
- package/src/common/prompts/system-prompt.ts +0 -2
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { Autowired, Injectable } from '@opensumi/di';
|
|
2
|
-
import { VALIDATE_TYPE } from '@opensumi/ide-components';
|
|
3
|
-
import { AppConfig, PreferenceService } from '@opensumi/ide-core-browser';
|
|
4
|
-
import {
|
|
5
|
-
AINativeSettingSectionsId,
|
|
6
|
-
Disposable,
|
|
7
|
-
Emitter,
|
|
8
|
-
URI,
|
|
9
|
-
formatLocalize,
|
|
10
|
-
localize,
|
|
11
|
-
} from '@opensumi/ide-core-common';
|
|
12
|
-
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
13
|
-
import { IFileServiceClient } from '@opensumi/ide-file-service';
|
|
14
|
-
import { QuickInputService } from '@opensumi/ide-quick-open/lib/browser/quick-input-service';
|
|
15
|
-
import { WorkspaceService } from '@opensumi/ide-workspace/lib/browser/workspace-service';
|
|
16
|
-
import { IWorkspaceService } from '@opensumi/ide-workspace/lib/common';
|
|
17
|
-
|
|
18
|
-
import { IMDCContent, IMDCParseResult, parseMDC, serializeMDC } from '../../common';
|
|
19
|
-
import { ProjectRule } from '../../common/types';
|
|
20
|
-
|
|
21
|
-
@Injectable()
|
|
22
|
-
export class RulesService extends Disposable {
|
|
23
|
-
@Autowired(PreferenceService)
|
|
24
|
-
private readonly preferenceService: PreferenceService;
|
|
25
|
-
|
|
26
|
-
@Autowired(AppConfig)
|
|
27
|
-
private readonly appConfig: AppConfig;
|
|
28
|
-
|
|
29
|
-
@Autowired(IWorkspaceService)
|
|
30
|
-
private readonly workspaceService: WorkspaceService;
|
|
31
|
-
|
|
32
|
-
@Autowired(IFileServiceClient)
|
|
33
|
-
private readonly fileServiceClient: IFileServiceClient;
|
|
34
|
-
|
|
35
|
-
@Autowired(QuickInputService)
|
|
36
|
-
private readonly quickInputService: QuickInputService;
|
|
37
|
-
|
|
38
|
-
@Autowired(WorkbenchEditorService)
|
|
39
|
-
private readonly workbenchEditorService: WorkbenchEditorService;
|
|
40
|
-
|
|
41
|
-
private readonly rulesChangeEventEmitter = new Emitter<void>();
|
|
42
|
-
|
|
43
|
-
private _globalRules: string;
|
|
44
|
-
private _projectRules: ProjectRule[];
|
|
45
|
-
|
|
46
|
-
private _projectRulesPath: string;
|
|
47
|
-
|
|
48
|
-
get onRulesChange() {
|
|
49
|
-
return this.rulesChangeEventEmitter.event;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
get globalRules() {
|
|
53
|
-
if (!this._globalRules) {
|
|
54
|
-
this._globalRules = this.preferenceService.get<string>(AINativeSettingSectionsId.GlobalRules) || '';
|
|
55
|
-
}
|
|
56
|
-
return this._globalRules;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
get projectRules() {
|
|
60
|
-
return this._projectRules || [];
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public async initProjectRules() {
|
|
64
|
-
this.dispose();
|
|
65
|
-
await this.workspaceService.whenReady;
|
|
66
|
-
const workspace = this.workspaceService.workspace;
|
|
67
|
-
// 如果存在 .sumi, 默认从 .sumi 中获取
|
|
68
|
-
const sumiConfigPath = new URI(workspace?.uri)
|
|
69
|
-
.resolve(this.appConfig.preferenceDirName || '.sumi')
|
|
70
|
-
.resolve('rules');
|
|
71
|
-
const cursorConfigPath = new URI(workspace?.uri).resolve('.cursor').resolve('rules');
|
|
72
|
-
if (await this.fileServiceClient.access(sumiConfigPath.codeUri.fsPath)) {
|
|
73
|
-
this._projectRulesPath = sumiConfigPath.codeUri.fsPath;
|
|
74
|
-
} else if (await this.fileServiceClient.access(cursorConfigPath.codeUri.fsPath)) {
|
|
75
|
-
this._projectRulesPath = cursorConfigPath.codeUri.fsPath;
|
|
76
|
-
} else {
|
|
77
|
-
this._projectRulesPath = sumiConfigPath.codeUri.fsPath;
|
|
78
|
-
}
|
|
79
|
-
const watcher = await this.fileServiceClient.watchFileChanges(new URI(this._projectRulesPath));
|
|
80
|
-
this.addDispose(
|
|
81
|
-
watcher.onFilesChanged((changes) => {
|
|
82
|
-
if (
|
|
83
|
-
changes.length > 0 &&
|
|
84
|
-
changes.some((change) => change.uri.endsWith('.mdc') && change.uri.includes('rules'))
|
|
85
|
-
) {
|
|
86
|
-
this.initProjectRules();
|
|
87
|
-
}
|
|
88
|
-
}),
|
|
89
|
-
);
|
|
90
|
-
const dir = await this.fileServiceClient.getFileStat(this._projectRulesPath);
|
|
91
|
-
if (dir && dir.isDirectory) {
|
|
92
|
-
const files = dir.children?.filter((file) => !file.isDirectory && file.uri.endsWith('.mdc'));
|
|
93
|
-
if (files) {
|
|
94
|
-
const rules = await Promise.all(
|
|
95
|
-
files.map(async (file) => {
|
|
96
|
-
const item = await this.fileServiceClient.readFile(file.uri);
|
|
97
|
-
const data = this.parseMDCContent(item.content.toString());
|
|
98
|
-
return {
|
|
99
|
-
path: file.uri,
|
|
100
|
-
...data.frontmatter,
|
|
101
|
-
content: data.content,
|
|
102
|
-
};
|
|
103
|
-
}),
|
|
104
|
-
);
|
|
105
|
-
if (rules.length > 0) {
|
|
106
|
-
this._projectRules = rules;
|
|
107
|
-
this.rulesChangeEventEmitter.fire();
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
this._projectRules = [];
|
|
113
|
-
this.rulesChangeEventEmitter.fire();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async openRule(rule: ProjectRule) {
|
|
117
|
-
this.workbenchEditorService.open(new URI(rule.path));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async createNewRule() {
|
|
121
|
-
let value = await this.quickInputService.open({
|
|
122
|
-
title: localize('ai.native.rules.projectRules.newRule'),
|
|
123
|
-
value: '',
|
|
124
|
-
placeHolder: localize('ai.native.rules.projectRules.newRule.placeholder'),
|
|
125
|
-
validateInput: async (value) => {
|
|
126
|
-
const invalidCharsRegex = /[<>:"/\\|?*\x00-\x1F]/;
|
|
127
|
-
value = value.trim();
|
|
128
|
-
if (value === '') {
|
|
129
|
-
return {
|
|
130
|
-
message: localize('ai.native.rules.projectRules.newRule.error.notEmpty'),
|
|
131
|
-
type: VALIDATE_TYPE.ERROR,
|
|
132
|
-
};
|
|
133
|
-
} else if (invalidCharsRegex.test(value)) {
|
|
134
|
-
return {
|
|
135
|
-
message: localize('ai.native.rules.error.invalidFileName'),
|
|
136
|
-
type: VALIDATE_TYPE.ERROR,
|
|
137
|
-
};
|
|
138
|
-
} else {
|
|
139
|
-
const newRulePath = new URI(this._projectRulesPath).resolve(value + '.mdc');
|
|
140
|
-
const fileExists = this.projectRules.find(
|
|
141
|
-
(rule) => new URI(rule.path).codeUri.fsPath === newRulePath.codeUri.fsPath,
|
|
142
|
-
);
|
|
143
|
-
if (fileExists) {
|
|
144
|
-
return {
|
|
145
|
-
message: formatLocalize('ai.native.rules.error.fileExists', value + '.mdc'),
|
|
146
|
-
type: VALIDATE_TYPE.ERROR,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
value = value?.trim();
|
|
153
|
-
if (value) {
|
|
154
|
-
const newRulePath = new URI(this._projectRulesPath).resolve(value + '.mdc');
|
|
155
|
-
await this.fileServiceClient.createFile(newRulePath.toString(), {
|
|
156
|
-
content: this.serializeMDCContent({
|
|
157
|
-
frontmatter: {
|
|
158
|
-
description: '',
|
|
159
|
-
globs: '',
|
|
160
|
-
alwaysApply: false,
|
|
161
|
-
},
|
|
162
|
-
content: '',
|
|
163
|
-
}),
|
|
164
|
-
});
|
|
165
|
-
this.workbenchEditorService.open(new URI(newRulePath.toString()));
|
|
166
|
-
this.initProjectRules();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
updateGlobalRules(rules: string) {
|
|
171
|
-
this._globalRules = rules;
|
|
172
|
-
this.preferenceService.set(AINativeSettingSectionsId.GlobalRules, rules);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
parseMDCContent(content: string): IMDCParseResult {
|
|
176
|
-
try {
|
|
177
|
-
return parseMDC(content);
|
|
178
|
-
} catch (error) {
|
|
179
|
-
return {
|
|
180
|
-
frontmatter: {},
|
|
181
|
-
content,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
serializeMDCContent(mdcContent: IMDCContent): string {
|
|
187
|
-
return serializeMDC(mdcContent);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import { Icon } from '@opensumi/ide-components';
|
|
4
|
-
import { useInjectable } from '@opensumi/ide-core-browser';
|
|
5
|
-
import { RulesServiceToken, localize } from '@opensumi/ide-core-common';
|
|
6
|
-
|
|
7
|
-
import { ProjectRule } from '../../common/types';
|
|
8
|
-
|
|
9
|
-
import styles from './rules.module.less';
|
|
10
|
-
import { RulesService } from './rules.service';
|
|
11
|
-
|
|
12
|
-
export const RulesView: React.FC = () => {
|
|
13
|
-
const rulesService = useInjectable<RulesService>(RulesServiceToken);
|
|
14
|
-
const [globalRules, setGlobalRules] = useState<string>(rulesService.globalRules as string);
|
|
15
|
-
const [projectRules, setProjectRules] = useState<ProjectRule[]>([]);
|
|
16
|
-
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
setProjectRules(rulesService.projectRules);
|
|
19
|
-
}, [rulesService]);
|
|
20
|
-
|
|
21
|
-
const handleGlobalRulesChange = useCallback(
|
|
22
|
-
(e) => {
|
|
23
|
-
setGlobalRules(e.target.value);
|
|
24
|
-
rulesService.updateGlobalRules(e.target.value);
|
|
25
|
-
},
|
|
26
|
-
[rulesService, globalRules],
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
const handleCreateNewRule = useCallback(() => {
|
|
30
|
-
rulesService.createNewRule();
|
|
31
|
-
}, [rulesService]);
|
|
32
|
-
|
|
33
|
-
const handleOpenRule = useCallback(
|
|
34
|
-
(rule: ProjectRule) => {
|
|
35
|
-
rulesService.openRule(rule);
|
|
36
|
-
},
|
|
37
|
-
[rulesService],
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
const getFileNameFromPath = (path: string) => decodeURIComponent(path.split('/').pop() || path);
|
|
41
|
-
|
|
42
|
-
const hasWarning = (rule: ProjectRule) => !rule.description && !rule.alwaysApply && !rule.globs;
|
|
43
|
-
|
|
44
|
-
const getAppliesToText = (rule: ProjectRule) => {
|
|
45
|
-
if (rule.globs) {
|
|
46
|
-
if (Array.isArray(rule.globs)) {
|
|
47
|
-
return `Applies to: ${rule.globs.join(', ')}`;
|
|
48
|
-
} else {
|
|
49
|
-
return `Applies to: ${rule.globs}`;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return '';
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
const disposable = rulesService.onRulesChange(() => {
|
|
57
|
-
setProjectRules(rulesService.projectRules);
|
|
58
|
-
});
|
|
59
|
-
return () => {
|
|
60
|
-
disposable.dispose();
|
|
61
|
-
};
|
|
62
|
-
}, []);
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<div className={styles.container}>
|
|
66
|
-
<div className={styles.header}>
|
|
67
|
-
<div>
|
|
68
|
-
<h2 className={styles.title}>{localize('ai.native.rules.title')}</h2>
|
|
69
|
-
<p className={styles.description}>{localize('ai.native.rules.description')}</p>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
<div className={styles.user_rules}>
|
|
73
|
-
<div className={styles.user_rules_header}>
|
|
74
|
-
<h3 className={styles.title}>{localize('ai.native.rules.userRules.title')}</h3>
|
|
75
|
-
<p className={styles.description}>{localize('ai.native.rules.userRules.description')}</p>
|
|
76
|
-
</div>
|
|
77
|
-
<div className={styles.user_rules_content}>
|
|
78
|
-
<textarea
|
|
79
|
-
rows={6}
|
|
80
|
-
placeholder={localize('ai.native.rules.userRules.placeholder')}
|
|
81
|
-
value={globalRules}
|
|
82
|
-
onChange={handleGlobalRulesChange}
|
|
83
|
-
style={{ resize: 'none' }}
|
|
84
|
-
/>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
<div className={styles.project_rules}>
|
|
88
|
-
<div className={styles.project_rules_header}>
|
|
89
|
-
<div className={styles.project_rules_header_left}>
|
|
90
|
-
<h3 className={styles.title}>
|
|
91
|
-
{localize('ai.native.rules.projectRules.title')}
|
|
92
|
-
<button className={styles.actionButton} onClick={handleCreateNewRule}>
|
|
93
|
-
<Icon icon='plus' className={styles.actionButtonIcon} />
|
|
94
|
-
{localize('ai.native.rules.projectRules.newRule')}
|
|
95
|
-
</button>
|
|
96
|
-
</h3>
|
|
97
|
-
<p className={styles.description}>{localize('ai.native.rules.projectRules.description')}</p>
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
<div className={styles.project_rules_content}>
|
|
101
|
-
{projectRules.length > 0 ? (
|
|
102
|
-
<div className={styles.project_rules_list}>
|
|
103
|
-
{projectRules.map((rule, index) => (
|
|
104
|
-
<div key={index} className={styles.rule_item} onClick={() => handleOpenRule(rule)}>
|
|
105
|
-
<div className={styles.rule_item_left}>
|
|
106
|
-
<div className={styles.rule_filename}>{getFileNameFromPath(rule.path)}</div>
|
|
107
|
-
{rule.description && <div className={styles.rule_description}>{rule.description}</div>}
|
|
108
|
-
{hasWarning(rule) && (
|
|
109
|
-
<div className={styles.rule_warning}>
|
|
110
|
-
This rule may never be used since it has no description or auto attachments
|
|
111
|
-
</div>
|
|
112
|
-
)}
|
|
113
|
-
</div>
|
|
114
|
-
<div className={styles.rule_item_right}>
|
|
115
|
-
{getAppliesToText(rule) && <div className={styles.rule_applies_to}>{getAppliesToText(rule)}</div>}
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
))}
|
|
119
|
-
</div>
|
|
120
|
-
) : (
|
|
121
|
-
<div className={styles.empty_state}>{localize('ai.native.rules.projectRules.empty')}</div>
|
|
122
|
-
)}
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
</div>
|
|
126
|
-
);
|
|
127
|
-
};
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import { isObject } from '@opensumi/ide-utils';
|
|
2
|
-
|
|
3
|
-
import { IMCPToolResult, IMCPToolResultContent } from './types';
|
|
4
|
-
|
|
5
|
-
export interface ImageCompressionOptions {
|
|
6
|
-
maxSizeKB?: number;
|
|
7
|
-
quality?: number;
|
|
8
|
-
maxWidth?: number;
|
|
9
|
-
maxHeight?: number;
|
|
10
|
-
mimeType?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const DEFAULT_OPTIONS: Required<ImageCompressionOptions> = {
|
|
14
|
-
maxSizeKB: 500, // 500KB
|
|
15
|
-
quality: 0.8,
|
|
16
|
-
maxWidth: 1920,
|
|
17
|
-
maxHeight: 1080,
|
|
18
|
-
mimeType: 'image/jpeg',
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 获取 base64 图像的大小(KB)
|
|
23
|
-
*/
|
|
24
|
-
export function getBase64ImageSize(base64String: string): number {
|
|
25
|
-
if (!base64String) {
|
|
26
|
-
return 0;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// 移除 data URL 前缀
|
|
30
|
-
const base64Data = base64String.split(',')[1] || base64String;
|
|
31
|
-
|
|
32
|
-
// Base64 编码后的大小约为原始大小的 4/3
|
|
33
|
-
const sizeInBytes = (base64Data.length * 3) / 4;
|
|
34
|
-
return sizeInBytes / 1024; // 转换为 KB
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 使用 Canvas API 进行真正的图像压缩
|
|
39
|
-
*/
|
|
40
|
-
export function compressBase64Image(base64String: string, options: ImageCompressionOptions = {}): Promise<string> {
|
|
41
|
-
return new Promise((resolve) => {
|
|
42
|
-
try {
|
|
43
|
-
// 输入验证
|
|
44
|
-
if (!base64String || typeof base64String !== 'string') {
|
|
45
|
-
resolve(base64String || '');
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (!base64String.startsWith('data:') && options.mimeType) {
|
|
49
|
-
base64String = `data:${options.mimeType};base64,${base64String}`;
|
|
50
|
-
}
|
|
51
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
52
|
-
const currentSize = getBase64ImageSize(base64String);
|
|
53
|
-
// 如果图像已经小于目标大小,直接返回
|
|
54
|
-
if (currentSize <= opts.maxSizeKB) {
|
|
55
|
-
resolve(base64String);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
// 创建图像对象
|
|
59
|
-
const img = new Image();
|
|
60
|
-
img.onload = () => {
|
|
61
|
-
try {
|
|
62
|
-
// 计算新的尺寸,保持宽高比
|
|
63
|
-
let { width, height } = img;
|
|
64
|
-
// 处理极小图片
|
|
65
|
-
if (width <= 1 || height <= 1) {
|
|
66
|
-
resolve(base64String);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const aspectRatio = width / height;
|
|
70
|
-
if (width > opts.maxWidth) {
|
|
71
|
-
width = opts.maxWidth;
|
|
72
|
-
height = width / aspectRatio;
|
|
73
|
-
}
|
|
74
|
-
if (height > opts.maxHeight) {
|
|
75
|
-
height = opts.maxHeight;
|
|
76
|
-
width = height * aspectRatio;
|
|
77
|
-
}
|
|
78
|
-
const canvas = document.createElement('canvas');
|
|
79
|
-
const ctx = canvas.getContext('2d');
|
|
80
|
-
if (!ctx) {
|
|
81
|
-
resolve(base64String);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
canvas.width = Math.round(width);
|
|
85
|
-
canvas.height = Math.round(height);
|
|
86
|
-
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
87
|
-
let compressedBase64 = canvas.toDataURL(opts.mimeType, opts.quality);
|
|
88
|
-
let compressedSize = getBase64ImageSize(compressedBase64);
|
|
89
|
-
let currentQuality = opts.quality;
|
|
90
|
-
let attempts = 0;
|
|
91
|
-
const maxAttempts = 5;
|
|
92
|
-
while (compressedSize > opts.maxSizeKB && attempts < maxAttempts) {
|
|
93
|
-
currentQuality *= 0.6;
|
|
94
|
-
compressedBase64 = canvas.toDataURL(opts.mimeType, currentQuality);
|
|
95
|
-
compressedSize = getBase64ImageSize(compressedBase64);
|
|
96
|
-
attempts++;
|
|
97
|
-
}
|
|
98
|
-
const [, base64] = compressedBase64.split(',');
|
|
99
|
-
resolve(base64);
|
|
100
|
-
} catch (error) {
|
|
101
|
-
// 压缩失败,返回原始图像
|
|
102
|
-
resolve(base64String);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
img.onerror = () => {
|
|
106
|
-
// 图像加载失败,返回原始字符串
|
|
107
|
-
resolve(base64String);
|
|
108
|
-
};
|
|
109
|
-
img.src = base64String;
|
|
110
|
-
} catch (error) {
|
|
111
|
-
resolve(base64String);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* 压缩内容数组格式的工具结果
|
|
118
|
-
*/
|
|
119
|
-
export async function compressContentArrayResult(
|
|
120
|
-
result: IMCPToolResult,
|
|
121
|
-
options: ImageCompressionOptions = {},
|
|
122
|
-
): Promise<IMCPToolResult> {
|
|
123
|
-
if (!result || !result.content || !Array.isArray(result.content)) {
|
|
124
|
-
return result;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const compressedContent = await Promise.all(
|
|
128
|
-
result.content.map(async (item) => {
|
|
129
|
-
if (item.type === 'image') {
|
|
130
|
-
let compressedData: string;
|
|
131
|
-
// 检测环境
|
|
132
|
-
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
133
|
-
compressedData = await compressBase64Image(item.data, {
|
|
134
|
-
...options,
|
|
135
|
-
mimeType: item.mimeType,
|
|
136
|
-
});
|
|
137
|
-
} else {
|
|
138
|
-
compressedData = item.data;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return {
|
|
142
|
-
...item,
|
|
143
|
-
data: compressedData,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
return item;
|
|
147
|
-
}),
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
return {
|
|
151
|
-
...result,
|
|
152
|
-
content: compressedContent,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* 智能压缩工具结果,支持多种格式
|
|
158
|
-
*/
|
|
159
|
-
export async function compressToolResultSmart(
|
|
160
|
-
result: IMCPToolResult,
|
|
161
|
-
options: ImageCompressionOptions = {},
|
|
162
|
-
): Promise<any> {
|
|
163
|
-
if (
|
|
164
|
-
result &&
|
|
165
|
-
isObject(result) &&
|
|
166
|
-
result.content &&
|
|
167
|
-
Array.isArray(result.content) &&
|
|
168
|
-
result.content.some((item: IMCPToolResultContent) => item.type === 'image')
|
|
169
|
-
) {
|
|
170
|
-
return await compressContentArrayResult(result, options);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return result;
|
|
174
|
-
}
|