@opensumi/ide-ai-native 3.9.1-next-1749452811.0 → 3.9.1-next-1749538805.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 +9 -4
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/apply.service.d.ts +3 -0
- package/lib/browser/chat/apply.service.d.ts.map +1 -1
- package/lib/browser/chat/apply.service.js +47 -0
- package/lib/browser/chat/apply.service.js.map +1 -1
- package/lib/browser/chat/chat-manager.service.d.ts +1 -0
- package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-manager.service.js +9 -3
- package/lib/browser/chat/chat-manager.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts +8 -1
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +113 -76
- package/lib/browser/chat/chat-model.js.map +1 -1
- package/lib/browser/chat/chat-proxy.service.d.ts +0 -2
- package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-proxy.service.js +50 -57
- package/lib/browser/chat/chat-proxy.service.js.map +1 -1
- package/lib/browser/chat/chat.feature.registry.d.ts +4 -1
- package/lib/browser/chat/chat.feature.registry.d.ts.map +1 -1
- package/lib/browser/chat/chat.feature.registry.js +6 -0
- 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 +50 -10
- 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 +2 -1
- 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 +148 -30
- 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 +7 -2
- package/lib/browser/components/ChatToolRender.js.map +1 -1
- package/lib/browser/components/ChatToolRender.module.less +25 -0
- package/lib/browser/components/components.module.less +37 -8
- package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
- package/lib/browser/components/mention-input/mention-input.js +150 -14
- package/lib/browser/components/mention-input/mention-input.js.map +1 -1
- package/lib/browser/components/mention-input/mention-input.module.less +165 -1
- package/lib/browser/components/mention-input/mention-select.d.ts +28 -0
- package/lib/browser/components/mention-input/mention-select.d.ts.map +1 -0
- package/lib/browser/components/mention-input/mention-select.js +136 -0
- package/lib/browser/components/mention-input/mention-select.js.map +1 -0
- package/lib/browser/components/mention-input/mention-select.module.less +297 -0
- package/lib/browser/components/mention-input/types.d.ts +28 -1
- package/lib/browser/components/mention-input/types.d.ts.map +1 -1
- package/lib/browser/components/mention-input/types.js +1 -0
- 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 +21 -2
- package/lib/browser/context/llm-context.service.d.ts.map +1 -1
- package/lib/browser/context/llm-context.service.js +162 -20
- 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 +7 -0
- 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 +6 -4
- 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 +5 -12
- package/lib/browser/layout/tabbar.view.js.map +1 -1
- package/lib/browser/mcp/base-apply.service.d.ts +5 -4
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.js +23 -5
- package/lib/browser/mcp/base-apply.service.js.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts +3 -1
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js +4 -0
- 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 +7 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts +1 -3
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
- package/lib/browser/mcp/tools/createNewFileWithText.js +14 -40
- 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 +9 -5
- 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 +22 -10
- package/lib/browser/mcp/tools/grepSearch.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.d.ts +15 -0
- package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.d.ts.map +1 -0
- package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.js +53 -0
- package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.js.map +1 -0
- 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 +11 -1
- package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
- package/lib/browser/mcp/tools/handlers/RunCommand.js +11 -4
- 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 +19 -15
- 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 +47 -1
- package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
- package/lib/browser/model/msg-history-manager.js +127 -2
- 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 +5 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/rules/rules.contribution.d.ts +29 -0
- package/lib/browser/rules/rules.contribution.d.ts.map +1 -0
- package/lib/browser/rules/rules.contribution.js +94 -0
- package/lib/browser/rules/rules.contribution.js.map +1 -0
- package/lib/browser/rules/rules.module.less +175 -0
- package/lib/browser/rules/rules.service.d.ts +25 -0
- package/lib/browser/rules/rules.service.d.ts.map +1 -0
- package/lib/browser/rules/rules.service.js +180 -0
- package/lib/browser/rules/rules.service.js.map +1 -0
- package/lib/browser/rules/rules.view.d.ts +3 -0
- package/lib/browser/rules/rules.view.d.ts.map +1 -0
- package/lib/browser/rules/rules.view.js +76 -0
- package/lib/browser/rules/rules.view.js.map +1 -0
- package/lib/browser/types.d.ts +12 -1
- 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/image-compression.d.ts +25 -0
- package/lib/common/image-compression.d.ts.map +1 -0
- package/lib/common/image-compression.js +153 -0
- package/lib/common/image-compression.js.map +1 -0
- package/lib/common/index.d.ts +5 -1
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +2 -0
- package/lib/common/index.js.map +1 -1
- package/lib/common/llm-context.d.ts +19 -0
- package/lib/common/llm-context.d.ts.map +1 -1
- package/lib/common/llm-context.js.map +1 -1
- package/lib/common/mdc-parser.d.ts +60 -0
- package/lib/common/mdc-parser.d.ts.map +1 -0
- package/lib/common/mdc-parser.js +246 -0
- package/lib/common/mdc-parser.js.map +1 -0
- package/lib/common/model.d.ts +1 -0
- 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 +0 -2
- package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
- package/lib/common/prompts/context-prompt-provider.js +35 -29
- package/lib/common/prompts/context-prompt-provider.js.map +1 -1
- package/lib/common/prompts/system-prompt.d.ts +2 -0
- package/lib/common/prompts/system-prompt.d.ts.map +1 -0
- package/lib/common/prompts/system-prompt.js +5 -0
- package/lib/common/prompts/system-prompt.js.map +1 -0
- package/lib/common/types.d.ts +21 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/types.js.map +1 -1
- package/lib/common/utils.d.ts +1 -0
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +5 -2
- 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 +2 -1
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js +12 -2
- 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 +3 -1
- package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.js +7 -1
- package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
- package/lib/node/mcp-server-manager-impl.d.ts +3 -1
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
- package/lib/node/mcp-server-manager-impl.js +14 -2
- package/lib/node/mcp-server-manager-impl.js.map +1 -1
- package/lib/node/mcp-server.sse.d.ts +187 -1
- 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 +187 -1
- package/lib/node/mcp-server.stdio.d.ts.map +1 -1
- package/package.json +27 -26
- package/src/browser/ai-core.contribution.ts +14 -4
- package/src/browser/chat/apply.service.ts +62 -1
- package/src/browser/chat/chat-manager.service.ts +16 -7
- package/src/browser/chat/chat-model.ts +130 -73
- package/src/browser/chat/chat-proxy.service.ts +68 -81
- package/src/browser/chat/chat.feature.registry.ts +17 -1
- package/src/browser/chat/chat.view.tsx +73 -12
- package/src/browser/components/ChatEditor.tsx +1 -1
- package/src/browser/components/ChatHistory.tsx +2 -1
- package/src/browser/components/ChatMentionInput.tsx +180 -35
- package/src/browser/components/ChatReply.tsx +4 -4
- package/src/browser/components/ChatToolRender.module.less +25 -0
- package/src/browser/components/ChatToolRender.tsx +10 -2
- package/src/browser/components/components.module.less +37 -8
- package/src/browser/components/mention-input/mention-input.module.less +165 -1
- package/src/browser/components/mention-input/mention-input.tsx +232 -31
- package/src/browser/components/mention-input/mention-select.module.less +297 -0
- package/src/browser/components/mention-input/mention-select.tsx +256 -0
- package/src/browser/components/mention-input/types.ts +29 -0
- package/src/browser/context/llm-context.service.ts +182 -21
- 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 +8 -0
- package/src/browser/layout/ai-layout.tsx +12 -8
- package/src/browser/layout/tabbar.view.tsx +10 -23
- package/src/browser/mcp/base-apply.service.ts +30 -10
- package/src/browser/mcp/mcp-server-proxy.service.ts +6 -1
- package/src/browser/mcp/mcp-server.feature.registry.ts +6 -1
- package/src/browser/mcp/tools/createNewFileWithText.ts +17 -46
- package/src/browser/mcp/tools/fileSearch.ts +8 -5
- 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 +32 -21
- package/src/browser/mcp/tools/handlers/CreateNewFileWithText.ts +49 -0
- 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 +21 -14
- package/src/browser/mcp/tools/listDir.ts +15 -12
- package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
- package/src/browser/model/msg-history-manager.ts +181 -2
- package/src/browser/preferences/schema.ts +5 -0
- package/src/browser/rules/rules.contribution.ts +105 -0
- package/src/browser/rules/rules.module.less +175 -0
- package/src/browser/rules/rules.service.ts +189 -0
- package/src/browser/rules/rules.view.tsx +127 -0
- package/src/browser/types.ts +18 -0
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +0 -1
- package/src/common/image-compression.ts +174 -0
- package/src/common/index.ts +6 -1
- package/src/common/llm-context.ts +23 -0
- package/src/common/mdc-parser.ts +295 -0
- package/src/common/model.ts +1 -0
- package/src/common/prompts/context-prompt-provider.ts +55 -40
- package/src/common/prompts/system-prompt.ts +2 -0
- package/src/common/types.ts +18 -0
- package/src/common/utils.ts +4 -1
- package/src/node/base-language-model.ts +11 -14
- package/src/node/mcp/sumi-mcp-server.ts +10 -2
- package/src/node/mcp-server-manager-impl.ts +17 -2
- package/src/node/mcp-server.sse.ts +1 -2
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
};
|
package/src/browser/types.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { ZodSchema } from 'zod';
|
|
|
5
5
|
import { AIActionItem } from '@opensumi/ide-core-browser/lib/components/ai-native/index';
|
|
6
6
|
import {
|
|
7
7
|
CancellationToken,
|
|
8
|
+
ChatMessageRole,
|
|
8
9
|
ChatResponse,
|
|
9
10
|
Deferred,
|
|
10
11
|
IAICompletionOption,
|
|
@@ -134,6 +135,8 @@ export interface IChatFeatureRegistry {
|
|
|
134
135
|
registerImageUploadProvider(provider: IImageUploadProvider): void;
|
|
135
136
|
registerWelcome(content: IChatWelcomeMessageContent | React.ReactNode, sampleQuestions?: ISampleQuestions[]): void;
|
|
136
137
|
registerSlashCommand(command: IChatSlashCommandItem, handler: IChatSlashCommandHandler): void;
|
|
138
|
+
|
|
139
|
+
registerMessageSummaryProvider(provider: IMessageSummaryProvider): void;
|
|
137
140
|
}
|
|
138
141
|
|
|
139
142
|
export type ChatWelcomeRender = (props: {
|
|
@@ -298,6 +301,21 @@ export interface IImageUploadProvider {
|
|
|
298
301
|
imageUpload(file: File): Promise<DataContent | URL>;
|
|
299
302
|
}
|
|
300
303
|
|
|
304
|
+
export interface IMessageSummaryProvider {
|
|
305
|
+
getMessageSummary(
|
|
306
|
+
messages: Array<{
|
|
307
|
+
role: ChatMessageRole;
|
|
308
|
+
content: string;
|
|
309
|
+
}>,
|
|
310
|
+
): Promise<string | undefined>;
|
|
311
|
+
generateMemorizedMessage(
|
|
312
|
+
messages: Array<{
|
|
313
|
+
role: ChatMessageRole;
|
|
314
|
+
content: string;
|
|
315
|
+
}>,
|
|
316
|
+
): Promise<string | undefined>;
|
|
317
|
+
}
|
|
318
|
+
|
|
301
319
|
export const AINativeCoreContribution = Symbol('AINativeCoreContribution');
|
|
302
320
|
|
|
303
321
|
export interface AINativeCoreContribution {
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
Position,
|
|
14
14
|
} from '@opensumi/ide-monaco';
|
|
15
15
|
import { ReactInlineContentWidget } from '@opensumi/ide-monaco/lib/browser/ai-native/BaseInlineContentWidget';
|
|
16
|
-
import { URI } from '@opensumi/ide-monaco/lib/browser/monaco-api';
|
|
17
16
|
import { ContentWidgetPositionPreference } from '@opensumi/ide-monaco/lib/browser/monaco-exports/editor';
|
|
18
17
|
import { EditorOption } from '@opensumi/monaco-editor-core/esm/vs/editor/common/config/editorOptions';
|
|
19
18
|
import { IScrollEvent } from '@opensumi/monaco-editor-core/esm/vs/editor/common/editorCommon';
|
|
@@ -0,0 +1,174 @@
|
|
|
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
|
+
}
|
package/src/common/index.ts
CHANGED
|
@@ -15,8 +15,9 @@ import {
|
|
|
15
15
|
import { DESIGN_MENUBAR_CONTAINER_VIEW_ID } from '@opensumi/ide-design/lib/common/constants';
|
|
16
16
|
import { IPosition, ITextModel, InlineCompletionContext } from '@opensumi/ide-monaco/lib/common';
|
|
17
17
|
|
|
18
|
+
import { ImageCompressionOptions } from './image-compression';
|
|
18
19
|
import { IMCPServer, MCPServerDescription } from './mcp-server-manager';
|
|
19
|
-
import { IPartialEditEvent, MCPTool } from './types';
|
|
20
|
+
import { IMCPToolResult, IPartialEditEvent, MCPTool } from './types';
|
|
20
21
|
|
|
21
22
|
import type { CoreMessage } from 'ai';
|
|
22
23
|
|
|
@@ -152,6 +153,7 @@ export interface ISumiMCPServerBackend {
|
|
|
152
153
|
$removeServer(name: string): void;
|
|
153
154
|
$syncServer(name: string): Promise<void>;
|
|
154
155
|
$getMCPServerByName(name: string): IMCPServer | undefined;
|
|
156
|
+
$compressToolResult(result: IMCPToolResult, options: ImageCompressionOptions): Promise<IMCPToolResult>;
|
|
155
157
|
}
|
|
156
158
|
|
|
157
159
|
export const SumiMCPServerProxyServicePath = 'SumiMCPServerProxyServicePath';
|
|
@@ -331,3 +333,6 @@ export interface IInlineDiffService {
|
|
|
331
333
|
}
|
|
332
334
|
|
|
333
335
|
export const InlineDiffServiceToken = Symbol('InlineDiffService');
|
|
336
|
+
|
|
337
|
+
export * from './tool-invocation-registry';
|
|
338
|
+
export * from './mdc-parser';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Event, URI } from '@opensumi/ide-core-common/lib/utils';
|
|
2
2
|
|
|
3
|
+
import { ProjectRule } from './types';
|
|
4
|
+
|
|
3
5
|
export interface LLMContextService {
|
|
4
6
|
/**
|
|
5
7
|
* 开始自动收集
|
|
@@ -21,6 +23,11 @@ export interface LLMContextService {
|
|
|
21
23
|
*/
|
|
22
24
|
addFolderToContext(uri: URI, isManual?: boolean): void;
|
|
23
25
|
|
|
26
|
+
/**
|
|
27
|
+
* 添加规则到 context 中
|
|
28
|
+
*/
|
|
29
|
+
addRuleToContext(uri: URI, isManual?: boolean): void;
|
|
30
|
+
|
|
24
31
|
/**
|
|
25
32
|
* 清除上下文
|
|
26
33
|
*/
|
|
@@ -33,6 +40,7 @@ export interface LLMContextService {
|
|
|
33
40
|
viewed: FileContext[];
|
|
34
41
|
attached: FileContext[];
|
|
35
42
|
attachedFolders: FileContext[];
|
|
43
|
+
attachedRules: ProjectRule[];
|
|
36
44
|
version: number;
|
|
37
45
|
}>;
|
|
38
46
|
|
|
@@ -42,6 +50,18 @@ export interface LLMContextService {
|
|
|
42
50
|
*/
|
|
43
51
|
removeFileFromContext(uri: URI, isManual?: boolean): void;
|
|
44
52
|
|
|
53
|
+
/**
|
|
54
|
+
* 从 context 中移除文件夹
|
|
55
|
+
* @param uri URI
|
|
56
|
+
*/
|
|
57
|
+
removeFolderFromContext(uri: URI): void;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 从 context 中移除规则
|
|
61
|
+
* @param uri URI
|
|
62
|
+
*/
|
|
63
|
+
removeRuleFromContext(uri: URI): void;
|
|
64
|
+
|
|
45
65
|
/** 导出为可序列化格式 */
|
|
46
66
|
serialize(): Promise<SerializedContext>;
|
|
47
67
|
}
|
|
@@ -58,12 +78,15 @@ export interface AttachFileContext {
|
|
|
58
78
|
lineErrors: string[];
|
|
59
79
|
path: string;
|
|
60
80
|
language: string;
|
|
81
|
+
selection?: [number, number];
|
|
61
82
|
}
|
|
62
83
|
|
|
63
84
|
export interface SerializedContext {
|
|
64
85
|
recentlyViewFiles: string[];
|
|
65
86
|
attachedFiles: Array<AttachFileContext>;
|
|
66
87
|
attachedFolders: string[];
|
|
88
|
+
attachedRules: string[];
|
|
89
|
+
globalRules: string[];
|
|
67
90
|
}
|
|
68
91
|
|
|
69
92
|
export enum LLM_CONTEXT_KEY {
|