@opensumi/ide-ai-native 3.9.1-next-1749003325.0 → 3.9.1-next-1749007675.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/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 +8 -3
- package/lib/browser/chat/chat-manager.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts +3 -1
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +48 -17
- 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 +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 +29 -12
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
- package/lib/browser/components/ChatMentionInput.js +30 -141
- package/lib/browser/components/ChatMentionInput.js.map +1 -1
- package/lib/browser/components/ChatToolRender.module.less +0 -1
- package/lib/browser/components/components.module.less +7 -9
- package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
- package/lib/browser/components/mention-input/mention-input.js +14 -161
- 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 -16
- 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/mcp/base-apply.service.d.ts +2 -2
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.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/handlers/ListDir.js.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
- package/lib/browser/model/msg-history-manager.d.ts +39 -1
- package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
- package/lib/browser/model/msg-history-manager.js +170 -3
- 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 +8 -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/index.d.ts +0 -2
- 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/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 -7
- package/lib/common/types.d.ts.map +1 -1
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js.map +1 -1
- package/package.json +24 -25
- package/src/browser/chat/chat-manager.service.ts +15 -6
- package/src/browser/chat/chat-model.ts +56 -19
- package/src/browser/chat/chat-proxy.service.ts +81 -68
- package/src/browser/chat/chat.feature.registry.ts +17 -1
- package/src/browser/chat/chat.view.tsx +28 -22
- package/src/browser/components/ChatMentionInput.tsx +35 -169
- package/src/browser/components/ChatToolRender.module.less +0 -1
- package/src/browser/components/components.module.less +7 -9
- package/src/browser/components/mention-input/mention-input.module.less +1 -165
- package/src/browser/components/mention-input/mention-input.tsx +32 -257
- package/src/browser/components/mention-input/types.ts +0 -16
- 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/mcp/base-apply.service.ts +1 -0
- package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
- package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
- package/src/browser/mcp/tools/handlers/ListDir.ts +1 -1
- package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
- package/src/browser/model/msg-history-manager.ts +230 -3
- package/src/browser/preferences/schema.ts +0 -5
- package/src/browser/types.ts +12 -0
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +1 -0
- package/src/common/index.ts +0 -3
- package/src/common/llm-context.ts +0 -23
- package/src/common/prompts/context-prompt-provider.ts +40 -55
- package/src/common/types.ts +0 -8
- package/src/node/base-language-model.ts +1 -0
- 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/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/MDC_PARSER_README.md +0 -171
- 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/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/MDC_PARSER_README.md +0 -171
- package/src/common/mdc-parser.ts +0 -295
- package/src/common/prompts/system-prompt.ts +0 -2
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import cls from 'classnames';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
import { getSymbolIcon, localize } from '@opensumi/ide-core-browser';
|
|
5
|
-
import { Icon, Popover, PopoverPosition, getIcon } from '@opensumi/ide-core-browser/lib/components';
|
|
4
|
+
import { formatLocalize, getSymbolIcon, localize } from '@opensumi/ide-core-browser';
|
|
5
|
+
import { Icon, Popover, PopoverPosition, Select, getIcon } from '@opensumi/ide-core-browser/lib/components';
|
|
6
6
|
import { EnhanceIcon } from '@opensumi/ide-core-browser/lib/components/ai-native';
|
|
7
7
|
import { URI } from '@opensumi/ide-utils';
|
|
8
8
|
|
|
9
9
|
import { FileContext } from '../../../common/llm-context';
|
|
10
|
-
import { ProjectRule } from '../../../common/types';
|
|
11
10
|
|
|
12
11
|
import styles from './mention-input.module.less';
|
|
13
12
|
import { MentionPanel } from './mention-panel';
|
|
14
|
-
import { ExtendedModelOption, MentionSelect } from './mention-select';
|
|
15
13
|
import {
|
|
16
14
|
FooterButtonPosition,
|
|
17
15
|
MENTION_KEYWORD,
|
|
@@ -69,22 +67,11 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
69
67
|
const [attachedFiles, setAttachedFiles] = React.useState<{
|
|
70
68
|
files: FileContext[];
|
|
71
69
|
folders: FileContext[];
|
|
72
|
-
rules: ProjectRule[];
|
|
73
70
|
}>({
|
|
74
71
|
files: [],
|
|
75
72
|
folders: [],
|
|
76
|
-
rules: [],
|
|
77
73
|
});
|
|
78
74
|
|
|
79
|
-
// 添加用于跟踪 mention_tag 的状态
|
|
80
|
-
const prevMentionTagsRef = React.useRef<
|
|
81
|
-
Array<{
|
|
82
|
-
id: string;
|
|
83
|
-
type: string;
|
|
84
|
-
contextId: string;
|
|
85
|
-
}>
|
|
86
|
-
>([]);
|
|
87
|
-
|
|
88
75
|
const getCurrentItems = (): MentionItem[] => {
|
|
89
76
|
if (mentionState.level === 0) {
|
|
90
77
|
return mentionItems;
|
|
@@ -190,14 +177,14 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
190
177
|
}, [debouncedSecondLevelFilter, mentionState.level, mentionState.parentType]);
|
|
191
178
|
|
|
192
179
|
React.useEffect(() => {
|
|
193
|
-
const disposable = contextService?.onDidContextFilesChangeEvent(({ attached, attachedFolders
|
|
194
|
-
setAttachedFiles({ files: attached, folders: attachedFolders
|
|
180
|
+
const disposable = contextService?.onDidContextFilesChangeEvent(({ attached, attachedFolders }) => {
|
|
181
|
+
setAttachedFiles({ files: attached, folders: attachedFolders });
|
|
195
182
|
});
|
|
196
183
|
|
|
197
184
|
return () => {
|
|
198
185
|
disposable?.dispose();
|
|
199
186
|
};
|
|
200
|
-
}, []);
|
|
187
|
+
}, [contextService]);
|
|
201
188
|
|
|
202
189
|
// 获取光标位置
|
|
203
190
|
const getCursorPosition = (element: HTMLElement): number => {
|
|
@@ -220,45 +207,6 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
220
207
|
setHistoryIndex(-1);
|
|
221
208
|
}
|
|
222
209
|
|
|
223
|
-
// 检测 mention_tag 的删除
|
|
224
|
-
if (editorRef.current) {
|
|
225
|
-
const currentMentionTags = Array.from(editorRef.current.querySelectorAll(`.${styles.mention_tag}`)).map(
|
|
226
|
-
(tag) => ({
|
|
227
|
-
id: tag.getAttribute('data-id') || '',
|
|
228
|
-
type: tag.getAttribute('data-type') || '',
|
|
229
|
-
contextId: tag.getAttribute('data-context-id') || '',
|
|
230
|
-
}),
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
// 找出被删除的 mention_tag
|
|
234
|
-
const deletedTags = prevMentionTagsRef.current.filter(
|
|
235
|
-
(prevTag) =>
|
|
236
|
-
!currentMentionTags.some(
|
|
237
|
-
(currentTag) =>
|
|
238
|
-
currentTag.id === prevTag.id &&
|
|
239
|
-
currentTag.type === prevTag.type &&
|
|
240
|
-
currentTag.contextId === prevTag.contextId,
|
|
241
|
-
),
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
// 清理被删除的 mention_tag 对应的 context
|
|
245
|
-
deletedTags.forEach((deletedTag) => {
|
|
246
|
-
if (deletedTag.contextId) {
|
|
247
|
-
const uri = new URI(deletedTag.contextId);
|
|
248
|
-
if (deletedTag.type === MentionType.FILE) {
|
|
249
|
-
removeContext(MentionType.FILE, uri);
|
|
250
|
-
} else if (deletedTag.type === MentionType.FOLDER) {
|
|
251
|
-
removeContext(MentionType.FOLDER, uri);
|
|
252
|
-
} else if (deletedTag.type === MentionType.RULE) {
|
|
253
|
-
removeContext(MentionType.RULE, uri);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
// 更新 mention_tag 状态
|
|
259
|
-
prevMentionTagsRef.current = currentMentionTags;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
210
|
const selection = window.getSelection();
|
|
263
211
|
if (!selection || !selection.rangeCount || !editorRef.current) {
|
|
264
212
|
return;
|
|
@@ -542,7 +490,7 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
542
490
|
const imageFiles: File[] = [];
|
|
543
491
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
544
492
|
for (let i = 0; i < items.length; i++) {
|
|
545
|
-
if (items[i].kind ===
|
|
493
|
+
if (items[i].kind === 'file' && items[i].type.startsWith('image/')) {
|
|
546
494
|
const file = items[i].getAsFile();
|
|
547
495
|
if (file) {
|
|
548
496
|
imageFiles.push(file);
|
|
@@ -624,16 +572,6 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
624
572
|
if (placeholder && !editorRef.current.textContent) {
|
|
625
573
|
editorRef.current.setAttribute('data-placeholder', placeholder);
|
|
626
574
|
}
|
|
627
|
-
|
|
628
|
-
// 初始化 mention_tag 状态
|
|
629
|
-
const initialMentionTags = Array.from(editorRef.current.querySelectorAll(`.${styles.mention_tag}`)).map(
|
|
630
|
-
(tag) => ({
|
|
631
|
-
id: tag.getAttribute('data-id') || '',
|
|
632
|
-
type: tag.getAttribute('data-type') || '',
|
|
633
|
-
contextId: tag.getAttribute('data-context-id') || '',
|
|
634
|
-
}),
|
|
635
|
-
);
|
|
636
|
-
prevMentionTagsRef.current = initialMentionTags;
|
|
637
575
|
}
|
|
638
576
|
}, [placeholder]);
|
|
639
577
|
|
|
@@ -785,11 +723,6 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
785
723
|
true,
|
|
786
724
|
);
|
|
787
725
|
}
|
|
788
|
-
} else if (item.type === MentionType.RULE) {
|
|
789
|
-
const iconSpan = document.createElement('span');
|
|
790
|
-
iconSpan.className = cls(styles.mention_icon, getIcon('rules'));
|
|
791
|
-
mentionTag.appendChild(iconSpan);
|
|
792
|
-
contextService?.addRuleToContext(new URI(item.contextId), true);
|
|
793
726
|
}
|
|
794
727
|
const workspace = workspaceService?.workspace;
|
|
795
728
|
let relativePath = item.text;
|
|
@@ -889,12 +822,12 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
889
822
|
mentionTag.contentEditable = 'false';
|
|
890
823
|
|
|
891
824
|
// 为 file 和 folder 类型添加图标
|
|
892
|
-
if (item.type ===
|
|
825
|
+
if (item.type === 'file' || item.type === 'folder') {
|
|
893
826
|
// 创建图标容器
|
|
894
827
|
const iconSpan = document.createElement('span');
|
|
895
828
|
iconSpan.className = cls(
|
|
896
829
|
styles.mention_icon,
|
|
897
|
-
item.type ===
|
|
830
|
+
item.type === 'file' ? labelService?.getIcon(new URI(item.text)) : getIcon('folder'),
|
|
898
831
|
);
|
|
899
832
|
mentionTag.appendChild(iconSpan);
|
|
900
833
|
}
|
|
@@ -1050,65 +983,6 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
1050
983
|
contextService?.cleanFileContext();
|
|
1051
984
|
}, [contextService]);
|
|
1052
985
|
|
|
1053
|
-
const handleTitleClick = React.useCallback(() => {
|
|
1054
|
-
if (!editorRef.current) {
|
|
1055
|
-
return;
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
// 聚焦输入框
|
|
1059
|
-
editorRef.current.focus();
|
|
1060
|
-
|
|
1061
|
-
// 获取当前光标位置
|
|
1062
|
-
const selection = window.getSelection();
|
|
1063
|
-
if (!selection) {
|
|
1064
|
-
return;
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
// 在当前位置插入 @ 符号
|
|
1068
|
-
const range = document.createRange();
|
|
1069
|
-
|
|
1070
|
-
// 如果编辑器为空,直接插入
|
|
1071
|
-
if (!editorRef.current.textContent || editorRef.current.textContent.trim() === '') {
|
|
1072
|
-
editorRef.current.innerHTML = '@';
|
|
1073
|
-
range.setStart(editorRef.current.firstChild || editorRef.current, 1);
|
|
1074
|
-
range.setEnd(editorRef.current.firstChild || editorRef.current, 1);
|
|
1075
|
-
} else {
|
|
1076
|
-
// 当输入框有内容时,总是在末尾插入 @ 符号
|
|
1077
|
-
const textNode = document.createTextNode(' @');
|
|
1078
|
-
|
|
1079
|
-
// 移动到编辑器末尾
|
|
1080
|
-
range.selectNodeContents(editorRef.current);
|
|
1081
|
-
range.collapse(false); // 移动到末尾
|
|
1082
|
-
|
|
1083
|
-
// 在末尾插入空格和 @ 符号
|
|
1084
|
-
range.insertNode(textNode);
|
|
1085
|
-
range.setStartAfter(textNode);
|
|
1086
|
-
range.setEndAfter(textNode);
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
// 设置新的光标位置
|
|
1090
|
-
selection.removeAllRanges();
|
|
1091
|
-
selection.addRange(range);
|
|
1092
|
-
|
|
1093
|
-
// 获取插入后的光标位置
|
|
1094
|
-
const newCursorPos = getCursorPosition(editorRef.current);
|
|
1095
|
-
|
|
1096
|
-
// 激活菜单状态
|
|
1097
|
-
setMentionState({
|
|
1098
|
-
active: true,
|
|
1099
|
-
startPos: newCursorPos,
|
|
1100
|
-
filter: '@',
|
|
1101
|
-
position: { top: 0, left: 0 },
|
|
1102
|
-
activeIndex: 0,
|
|
1103
|
-
level: 0,
|
|
1104
|
-
parentType: null,
|
|
1105
|
-
secondLevelFilter: '',
|
|
1106
|
-
inlineSearchActive: false,
|
|
1107
|
-
inlineSearchStartPos: null,
|
|
1108
|
-
loading: false,
|
|
1109
|
-
});
|
|
1110
|
-
}, []);
|
|
1111
|
-
|
|
1112
986
|
const handleStop = React.useCallback(() => {
|
|
1113
987
|
if (onStop) {
|
|
1114
988
|
onStop();
|
|
@@ -1141,7 +1015,7 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
1141
1015
|
);
|
|
1142
1016
|
|
|
1143
1017
|
const hasContext = React.useMemo(
|
|
1144
|
-
() => attachedFiles.files.length > 0 || attachedFiles.folders.length > 0
|
|
1018
|
+
() => attachedFiles.files.length > 0 || attachedFiles.folders.length > 0,
|
|
1145
1019
|
[attachedFiles],
|
|
1146
1020
|
);
|
|
1147
1021
|
|
|
@@ -1163,125 +1037,8 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
1163
1037
|
[footerConfig.disableModelSelector],
|
|
1164
1038
|
);
|
|
1165
1039
|
|
|
1166
|
-
// 转换模型选项为扩展格式
|
|
1167
|
-
const getExtendedModelOptions = React.useMemo((): ExtendedModelOption[] => {
|
|
1168
|
-
// 如果有扩展模型选项,直接使用
|
|
1169
|
-
if (footerConfig.extendedModelOptions) {
|
|
1170
|
-
return footerConfig.extendedModelOptions.map((option) => ({
|
|
1171
|
-
...option,
|
|
1172
|
-
selected: option.value === selectedModel,
|
|
1173
|
-
}));
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
// 否则从基础模型选项转换
|
|
1177
|
-
return (footerConfig.modelOptions || []).map((option): ExtendedModelOption => {
|
|
1178
|
-
const extendedOption: ExtendedModelOption = {
|
|
1179
|
-
...option,
|
|
1180
|
-
};
|
|
1181
|
-
|
|
1182
|
-
// 设置选中状态:如果当前模型匹配选中的模型,则标记为选中
|
|
1183
|
-
extendedOption.selected = option.value === selectedModel;
|
|
1184
|
-
|
|
1185
|
-
return extendedOption;
|
|
1186
|
-
});
|
|
1187
|
-
}, [footerConfig.modelOptions, footerConfig.extendedModelOptions, selectedModel]);
|
|
1188
|
-
|
|
1189
|
-
const removeContext = React.useCallback(
|
|
1190
|
-
(type: MentionType, uri: URI) => {
|
|
1191
|
-
if (type === MentionType.FILE) {
|
|
1192
|
-
contextService?.removeFileFromContext(uri, true);
|
|
1193
|
-
} else if (type === MentionType.FOLDER) {
|
|
1194
|
-
contextService?.removeFolderFromContext(uri);
|
|
1195
|
-
} else if (type === MentionType.RULE) {
|
|
1196
|
-
contextService?.removeRuleFromContext(uri);
|
|
1197
|
-
}
|
|
1198
|
-
},
|
|
1199
|
-
[contextService],
|
|
1200
|
-
);
|
|
1201
|
-
|
|
1202
|
-
const getFileNameFromPath = (path: string) => decodeURIComponent(path.split('/').pop() || 'Unknown Rule');
|
|
1203
|
-
|
|
1204
|
-
const renderContextPreview = React.useCallback(
|
|
1205
|
-
() => (
|
|
1206
|
-
<div className={styles.context_preview_container}>
|
|
1207
|
-
<span
|
|
1208
|
-
className={cls(styles.context_preview_title, hasContext && styles.has_context)}
|
|
1209
|
-
onClick={handleTitleClick}
|
|
1210
|
-
>
|
|
1211
|
-
{!hasContext ? localize('aiNative.chat.context.title') : ''}
|
|
1212
|
-
</span>
|
|
1213
|
-
{attachedFiles.files.map((file, index) => (
|
|
1214
|
-
<div
|
|
1215
|
-
key={`file-${index}`}
|
|
1216
|
-
className={styles.context_preview_item}
|
|
1217
|
-
data-type={MentionType.FILE}
|
|
1218
|
-
onClick={() => contextService?.removeFileFromContext(file.uri, true)}
|
|
1219
|
-
>
|
|
1220
|
-
<Icon
|
|
1221
|
-
iconClass={cls(
|
|
1222
|
-
labelService?.getIcon(file.uri) || MentionType.FILE,
|
|
1223
|
-
styles.context_preview_item_icon,
|
|
1224
|
-
styles.icon,
|
|
1225
|
-
)}
|
|
1226
|
-
/>
|
|
1227
|
-
<Icon
|
|
1228
|
-
iconClass={cls(styles.close_icon, getIcon('close'))}
|
|
1229
|
-
onClick={() => removeContext(MentionType.FILE, file.uri)}
|
|
1230
|
-
/>
|
|
1231
|
-
<span className={styles.context_preview_item_text}>{new URI(file.uri.toString()).displayName}</span>
|
|
1232
|
-
</div>
|
|
1233
|
-
))}
|
|
1234
|
-
|
|
1235
|
-
{attachedFiles.folders.map((folder, index) => (
|
|
1236
|
-
<div
|
|
1237
|
-
key={`folder-${index}`}
|
|
1238
|
-
className={styles.context_preview_item}
|
|
1239
|
-
data-type='folder'
|
|
1240
|
-
onClick={() => contextService?.removeFileFromContext(folder.uri, true)}
|
|
1241
|
-
>
|
|
1242
|
-
<Icon iconClass={cls(getIcon('folder'), styles.context_preview_item_icon, styles.icon)} />
|
|
1243
|
-
<Icon
|
|
1244
|
-
iconClass={cls(styles.close_icon, getIcon('close'))}
|
|
1245
|
-
onClick={() => removeContext(MentionType.FOLDER, folder.uri)}
|
|
1246
|
-
/>
|
|
1247
|
-
<span className={styles.context_preview_item_text}>{new URI(folder.uri.toString()).displayName}</span>
|
|
1248
|
-
</div>
|
|
1249
|
-
))}
|
|
1250
|
-
|
|
1251
|
-
{attachedFiles.rules.map((rule, index) => (
|
|
1252
|
-
<div
|
|
1253
|
-
key={`rule-${index}`}
|
|
1254
|
-
className={styles.context_preview_item}
|
|
1255
|
-
data-type='rule'
|
|
1256
|
-
onClick={() => {
|
|
1257
|
-
// 由于没有专门的删除规则方法,我们重新构建规则列表
|
|
1258
|
-
contextService?.cleanFileContext();
|
|
1259
|
-
// 重新添加除了当前要删除的规则之外的所有上下文
|
|
1260
|
-
attachedFiles.files.forEach((file) => contextService?.addFileToContext(file.uri, file.selection, true));
|
|
1261
|
-
attachedFiles.folders.forEach((folder) => contextService?.addFolderToContext(folder.uri, true));
|
|
1262
|
-
attachedFiles.rules.forEach((r, i) => {
|
|
1263
|
-
if (i !== index) {
|
|
1264
|
-
contextService?.addRuleToContext(new URI(r.path), true);
|
|
1265
|
-
}
|
|
1266
|
-
});
|
|
1267
|
-
}}
|
|
1268
|
-
>
|
|
1269
|
-
<Icon iconClass={cls(getIcon('rules'), styles.context_preview_item_icon, styles.icon)} />
|
|
1270
|
-
<Icon
|
|
1271
|
-
iconClass={cls(styles.close_icon, getIcon('close'))}
|
|
1272
|
-
onClick={() => removeContext(MentionType.RULE, new URI(rule.path))}
|
|
1273
|
-
/>
|
|
1274
|
-
<span className={styles.context_preview_item_text}>{getFileNameFromPath(rule.path)}</span>
|
|
1275
|
-
</div>
|
|
1276
|
-
))}
|
|
1277
|
-
</div>
|
|
1278
|
-
),
|
|
1279
|
-
[handleClearContext, hasContext, attachedFiles, labelService, contextService, handleTitleClick, removeContext],
|
|
1280
|
-
);
|
|
1281
|
-
|
|
1282
1040
|
return (
|
|
1283
1041
|
<div className={styles.input_container}>
|
|
1284
|
-
{renderContextPreview()}
|
|
1285
1042
|
{mentionState.active && (
|
|
1286
1043
|
<div className={styles.mention_panel_container}>
|
|
1287
1044
|
<MentionPanel
|
|
@@ -1311,22 +1068,40 @@ export const MentionInput: React.FC<MentionInputProps> = ({
|
|
|
1311
1068
|
<div className={styles.left_control}>
|
|
1312
1069
|
{footerConfig.showModelSelector &&
|
|
1313
1070
|
renderModelSelectorTip(
|
|
1314
|
-
<
|
|
1315
|
-
options={
|
|
1071
|
+
<Select
|
|
1072
|
+
options={footerConfig.modelOptions || []}
|
|
1316
1073
|
value={selectedModel}
|
|
1317
1074
|
onChange={handleModelChange}
|
|
1318
1075
|
className={styles.model_selector}
|
|
1319
1076
|
size='small'
|
|
1320
1077
|
disabled={footerConfig.disableModelSelector}
|
|
1321
|
-
showThinking={footerConfig.showThinking}
|
|
1322
|
-
thinkingEnabled={footerConfig.thinkingEnabled}
|
|
1323
|
-
onThinkingChange={footerConfig.onThinkingChange}
|
|
1324
1078
|
/>,
|
|
1325
1079
|
)}
|
|
1326
1080
|
{renderButtons(FooterButtonPosition.LEFT)}
|
|
1327
1081
|
</div>
|
|
1328
1082
|
<div className={styles.right_control}>
|
|
1329
1083
|
{renderButtons(FooterButtonPosition.RIGHT)}
|
|
1084
|
+
{hasContext && (
|
|
1085
|
+
<Popover
|
|
1086
|
+
overlayClassName={styles.popover_icon}
|
|
1087
|
+
id={'ai-chat-clear-context'}
|
|
1088
|
+
position={PopoverPosition.top}
|
|
1089
|
+
content={localize('aiNative.chat.context.clear')}
|
|
1090
|
+
>
|
|
1091
|
+
<div className={styles.context_container} onClick={handleClearContext}>
|
|
1092
|
+
<div className={styles.context_icon}>
|
|
1093
|
+
<Icon icon='out-link' />
|
|
1094
|
+
<Icon icon='close' />
|
|
1095
|
+
</div>
|
|
1096
|
+
<div className={styles.context_description}>
|
|
1097
|
+
{formatLocalize(
|
|
1098
|
+
'aiNative.chat.context.description',
|
|
1099
|
+
attachedFiles.files.length + attachedFiles.folders.length,
|
|
1100
|
+
)}
|
|
1101
|
+
</div>
|
|
1102
|
+
</div>
|
|
1103
|
+
</Popover>
|
|
1104
|
+
)}
|
|
1330
1105
|
<Popover
|
|
1331
1106
|
overlayClassName={styles.popover_icon}
|
|
1332
1107
|
id={'ai-chat-send'}
|
|
@@ -46,17 +46,6 @@ export interface MentionState {
|
|
|
46
46
|
interface ModelOption {
|
|
47
47
|
label: string;
|
|
48
48
|
value: string;
|
|
49
|
-
icon?: string;
|
|
50
|
-
iconClass?: string;
|
|
51
|
-
tags?: string[];
|
|
52
|
-
description?: string;
|
|
53
|
-
badge?: string;
|
|
54
|
-
badgeColor?: string;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface ExtendedModelOption extends ModelOption {
|
|
58
|
-
disabled?: boolean;
|
|
59
|
-
selected?: boolean; // 由外部控制选中状态
|
|
60
49
|
}
|
|
61
50
|
|
|
62
51
|
export enum FooterButtonPosition {
|
|
@@ -68,7 +57,6 @@ export enum MentionType {
|
|
|
68
57
|
FILE = 'file',
|
|
69
58
|
FOLDER = 'folder',
|
|
70
59
|
CODE = 'code',
|
|
71
|
-
RULE = 'rule',
|
|
72
60
|
}
|
|
73
61
|
|
|
74
62
|
interface FooterButton {
|
|
@@ -82,14 +70,10 @@ interface FooterButton {
|
|
|
82
70
|
|
|
83
71
|
export interface FooterConfig {
|
|
84
72
|
modelOptions?: ModelOption[];
|
|
85
|
-
extendedModelOptions?: ExtendedModelOption[];
|
|
86
73
|
defaultModel?: string;
|
|
87
74
|
buttons?: FooterButton[];
|
|
88
75
|
showModelSelector?: boolean;
|
|
89
76
|
disableModelSelector?: boolean;
|
|
90
|
-
showThinking?: boolean;
|
|
91
|
-
thinkingEnabled?: boolean;
|
|
92
|
-
onThinkingChange?: (enabled: boolean) => void;
|
|
93
77
|
}
|
|
94
78
|
|
|
95
79
|
export interface MentionInputProps {
|