@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.
Files changed (146) hide show
  1. package/lib/browser/chat/chat-manager.service.d.ts +1 -0
  2. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  3. package/lib/browser/chat/chat-manager.service.js +8 -3
  4. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  5. package/lib/browser/chat/chat-model.d.ts +3 -1
  6. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  7. package/lib/browser/chat/chat-model.js +48 -17
  8. package/lib/browser/chat/chat-model.js.map +1 -1
  9. package/lib/browser/chat/chat-proxy.service.d.ts +2 -0
  10. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-proxy.service.js +57 -50
  12. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  13. package/lib/browser/chat/chat.feature.registry.d.ts +4 -1
  14. package/lib/browser/chat/chat.feature.registry.d.ts.map +1 -1
  15. package/lib/browser/chat/chat.feature.registry.js +6 -0
  16. package/lib/browser/chat/chat.feature.registry.js.map +1 -1
  17. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  18. package/lib/browser/chat/chat.view.js +29 -12
  19. package/lib/browser/chat/chat.view.js.map +1 -1
  20. package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
  21. package/lib/browser/components/ChatMentionInput.js +30 -141
  22. package/lib/browser/components/ChatMentionInput.js.map +1 -1
  23. package/lib/browser/components/ChatToolRender.module.less +0 -1
  24. package/lib/browser/components/components.module.less +7 -9
  25. package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
  26. package/lib/browser/components/mention-input/mention-input.js +14 -161
  27. package/lib/browser/components/mention-input/mention-input.js.map +1 -1
  28. package/lib/browser/components/mention-input/mention-input.module.less +1 -165
  29. package/lib/browser/components/mention-input/types.d.ts +1 -16
  30. package/lib/browser/components/mention-input/types.d.ts.map +1 -1
  31. package/lib/browser/components/mention-input/types.js +0 -1
  32. package/lib/browser/components/mention-input/types.js.map +1 -1
  33. package/lib/browser/components/utils.d.ts +2 -2
  34. package/lib/browser/context/llm-context.service.d.ts +2 -21
  35. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  36. package/lib/browser/context/llm-context.service.js +20 -162
  37. package/lib/browser/context/llm-context.service.js.map +1 -1
  38. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -1
  39. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -1
  40. package/lib/browser/contrib/intelligent-completions/diff-computer.js +1 -1
  41. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -1
  42. package/lib/browser/contrib/terminal/terminal.feature.registry.js.map +1 -1
  43. package/lib/browser/index.d.ts.map +1 -1
  44. package/lib/browser/index.js +0 -7
  45. package/lib/browser/index.js.map +1 -1
  46. package/lib/browser/mcp/base-apply.service.d.ts +2 -2
  47. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  48. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  49. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  50. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
  51. package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
  52. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  53. package/lib/browser/model/msg-history-manager.d.ts +39 -1
  54. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  55. package/lib/browser/model/msg-history-manager.js +170 -3
  56. package/lib/browser/model/msg-history-manager.js.map +1 -1
  57. package/lib/browser/preferences/schema.d.ts.map +1 -1
  58. package/lib/browser/preferences/schema.js +0 -5
  59. package/lib/browser/preferences/schema.js.map +1 -1
  60. package/lib/browser/types.d.ts +8 -1
  61. package/lib/browser/types.d.ts.map +1 -1
  62. package/lib/browser/types.js.map +1 -1
  63. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  64. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  65. package/lib/common/index.d.ts +0 -2
  66. package/lib/common/index.d.ts.map +1 -1
  67. package/lib/common/index.js +0 -2
  68. package/lib/common/index.js.map +1 -1
  69. package/lib/common/llm-context.d.ts +0 -19
  70. package/lib/common/llm-context.d.ts.map +1 -1
  71. package/lib/common/llm-context.js.map +1 -1
  72. package/lib/common/prompts/context-prompt-provider.d.ts +2 -0
  73. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  74. package/lib/common/prompts/context-prompt-provider.js +29 -35
  75. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  76. package/lib/common/types.d.ts +0 -7
  77. package/lib/common/types.d.ts.map +1 -1
  78. package/lib/node/base-language-model.d.ts.map +1 -1
  79. package/lib/node/base-language-model.js.map +1 -1
  80. package/package.json +24 -25
  81. package/src/browser/chat/chat-manager.service.ts +15 -6
  82. package/src/browser/chat/chat-model.ts +56 -19
  83. package/src/browser/chat/chat-proxy.service.ts +81 -68
  84. package/src/browser/chat/chat.feature.registry.ts +17 -1
  85. package/src/browser/chat/chat.view.tsx +28 -22
  86. package/src/browser/components/ChatMentionInput.tsx +35 -169
  87. package/src/browser/components/ChatToolRender.module.less +0 -1
  88. package/src/browser/components/components.module.less +7 -9
  89. package/src/browser/components/mention-input/mention-input.module.less +1 -165
  90. package/src/browser/components/mention-input/mention-input.tsx +32 -257
  91. package/src/browser/components/mention-input/types.ts +0 -16
  92. package/src/browser/context/llm-context.service.ts +21 -182
  93. package/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts +1 -1
  94. package/src/browser/contrib/intelligent-completions/diff-computer.ts +1 -1
  95. package/src/browser/contrib/terminal/terminal.feature.registry.ts +1 -1
  96. package/src/browser/index.ts +0 -8
  97. package/src/browser/mcp/base-apply.service.ts +1 -0
  98. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
  99. package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
  100. package/src/browser/mcp/tools/handlers/ListDir.ts +1 -1
  101. package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
  102. package/src/browser/model/msg-history-manager.ts +230 -3
  103. package/src/browser/preferences/schema.ts +0 -5
  104. package/src/browser/types.ts +12 -0
  105. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +1 -0
  106. package/src/common/index.ts +0 -3
  107. package/src/common/llm-context.ts +0 -23
  108. package/src/common/prompts/context-prompt-provider.ts +40 -55
  109. package/src/common/types.ts +0 -8
  110. package/src/node/base-language-model.ts +1 -0
  111. package/lib/browser/components/mention-input/mention-select.d.ts +0 -28
  112. package/lib/browser/components/mention-input/mention-select.d.ts.map +0 -1
  113. package/lib/browser/components/mention-input/mention-select.js +0 -136
  114. package/lib/browser/components/mention-input/mention-select.js.map +0 -1
  115. package/lib/browser/components/mention-input/mention-select.module.less +0 -297
  116. package/lib/browser/rules/rules.contribution.d.ts +0 -29
  117. package/lib/browser/rules/rules.contribution.d.ts.map +0 -1
  118. package/lib/browser/rules/rules.contribution.js +0 -94
  119. package/lib/browser/rules/rules.contribution.js.map +0 -1
  120. package/lib/browser/rules/rules.module.less +0 -175
  121. package/lib/browser/rules/rules.service.d.ts +0 -25
  122. package/lib/browser/rules/rules.service.d.ts.map +0 -1
  123. package/lib/browser/rules/rules.service.js +0 -180
  124. package/lib/browser/rules/rules.service.js.map +0 -1
  125. package/lib/browser/rules/rules.view.d.ts +0 -3
  126. package/lib/browser/rules/rules.view.d.ts.map +0 -1
  127. package/lib/browser/rules/rules.view.js +0 -76
  128. package/lib/browser/rules/rules.view.js.map +0 -1
  129. package/lib/common/MDC_PARSER_README.md +0 -171
  130. package/lib/common/mdc-parser.d.ts +0 -60
  131. package/lib/common/mdc-parser.d.ts.map +0 -1
  132. package/lib/common/mdc-parser.js +0 -246
  133. package/lib/common/mdc-parser.js.map +0 -1
  134. package/lib/common/prompts/system-prompt.d.ts +0 -2
  135. package/lib/common/prompts/system-prompt.d.ts.map +0 -1
  136. package/lib/common/prompts/system-prompt.js +0 -5
  137. package/lib/common/prompts/system-prompt.js.map +0 -1
  138. package/src/browser/components/mention-input/mention-select.module.less +0 -297
  139. package/src/browser/components/mention-input/mention-select.tsx +0 -256
  140. package/src/browser/rules/rules.contribution.ts +0 -105
  141. package/src/browser/rules/rules.module.less +0 -175
  142. package/src/browser/rules/rules.service.ts +0 -189
  143. package/src/browser/rules/rules.view.tsx +0 -127
  144. package/src/common/MDC_PARSER_README.md +0 -171
  145. package/src/common/mdc-parser.ts +0 -295
  146. 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, attachedRules }) => {
194
- setAttachedFiles({ files: attached, folders: attachedFolders, rules: attachedRules });
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 === MentionType.FILE && items[i].type.startsWith('image/')) {
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 === MentionType.FILE || item.type === 'folder') {
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 === MentionType.FILE ? labelService?.getIcon(new URI(item.text)) : getIcon('folder'),
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 || attachedFiles.rules.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
- <MentionSelect
1315
- options={getExtendedModelOptions}
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 {