@opensumi/ide-ai-native 3.9.1-next-1748944723.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 -176
  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 -274
  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 -174
  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 -174
  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,142 +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 renderContextPreview = React.useCallback(
1203
- () => (
1204
- <div className={styles.context_preview_container}>
1205
- <span
1206
- className={cls(styles.context_preview_title, hasContext && styles.has_context)}
1207
- onClick={handleTitleClick}
1208
- >
1209
- {!hasContext ? localize('aiNative.chat.context.title') : ''}
1210
- </span>
1211
- {attachedFiles.files.map((file, index) => (
1212
- <div
1213
- key={`file-${index}`}
1214
- className={styles.context_preview_item}
1215
- data-type={MentionType.FILE}
1216
- onClick={() => contextService?.removeFileFromContext(file.uri, true)}
1217
- >
1218
- <Icon
1219
- iconClass={cls(
1220
- labelService?.getIcon(file.uri) || MentionType.FILE,
1221
- styles.context_preview_item_icon,
1222
- styles.icon,
1223
- )}
1224
- />
1225
- <Icon
1226
- iconClass={cls(styles.close_icon, getIcon('close'))}
1227
- onClick={() => removeContext(MentionType.FILE, file.uri)}
1228
- />
1229
- <span className={styles.context_preview_item_text}>
1230
- {workspaceService?.workspace
1231
- ? file.uri.toString().replace(workspaceService.workspace.uri.toString(), '').slice(1)
1232
- : file.uri.toString()}
1233
- </span>
1234
- </div>
1235
- ))}
1236
-
1237
- {attachedFiles.folders.map((folder, index) => (
1238
- <div
1239
- key={`folder-${index}`}
1240
- className={styles.context_preview_item}
1241
- data-type='folder'
1242
- onClick={() => contextService?.removeFileFromContext(folder.uri, true)}
1243
- >
1244
- <Icon iconClass={cls(getIcon('folder'), styles.context_preview_item_icon, styles.icon)} />
1245
- <Icon
1246
- iconClass={cls(styles.close_icon, getIcon('close'))}
1247
- onClick={() => removeContext(MentionType.FOLDER, folder.uri)}
1248
- />
1249
- <span className={styles.context_preview_item_text}>
1250
- {workspaceService?.workspace
1251
- ? folder.uri.toString().replace(workspaceService.workspace.uri.toString(), '').slice(1)
1252
- : folder.uri.toString()}
1253
- </span>
1254
- </div>
1255
- ))}
1256
-
1257
- {attachedFiles.rules.map((rule, index) => (
1258
- <div
1259
- key={`rule-${index}`}
1260
- className={styles.context_preview_item}
1261
- data-type='rule'
1262
- onClick={() => {
1263
- // 由于没有专门的删除规则方法,我们重新构建规则列表
1264
- contextService?.cleanFileContext();
1265
- // 重新添加除了当前要删除的规则之外的所有上下文
1266
- attachedFiles.files.forEach((file) => contextService?.addFileToContext(file.uri, file.selection, true));
1267
- attachedFiles.folders.forEach((folder) => contextService?.addFolderToContext(folder.uri, true));
1268
- attachedFiles.rules.forEach((r, i) => {
1269
- if (i !== index) {
1270
- contextService?.addRuleToContext(new URI(r.path), true);
1271
- }
1272
- });
1273
- }}
1274
- >
1275
- <Icon iconClass={cls(getIcon('rules'), styles.context_preview_item_icon, styles.icon)} />
1276
- <Icon
1277
- iconClass={cls(styles.close_icon, getIcon('close'))}
1278
- onClick={() => removeContext(MentionType.RULE, new URI(rule.path))}
1279
- />
1280
- <span className={styles.context_preview_item_text}>
1281
- {rule.path.split('/').pop()?.replace('.mdc', '') || 'Unknown Rule'}
1282
- </span>
1283
- </div>
1284
- ))}
1285
- </div>
1286
- ),
1287
- [
1288
- handleClearContext,
1289
- hasContext,
1290
- attachedFiles,
1291
- workspaceService,
1292
- labelService,
1293
- contextService,
1294
- handleTitleClick,
1295
- removeContext,
1296
- ],
1297
- );
1298
-
1299
1040
  return (
1300
1041
  <div className={styles.input_container}>
1301
- {renderContextPreview()}
1302
1042
  {mentionState.active && (
1303
1043
  <div className={styles.mention_panel_container}>
1304
1044
  <MentionPanel
@@ -1328,22 +1068,40 @@ export const MentionInput: React.FC<MentionInputProps> = ({
1328
1068
  <div className={styles.left_control}>
1329
1069
  {footerConfig.showModelSelector &&
1330
1070
  renderModelSelectorTip(
1331
- <MentionSelect
1332
- options={getExtendedModelOptions}
1071
+ <Select
1072
+ options={footerConfig.modelOptions || []}
1333
1073
  value={selectedModel}
1334
1074
  onChange={handleModelChange}
1335
1075
  className={styles.model_selector}
1336
1076
  size='small'
1337
1077
  disabled={footerConfig.disableModelSelector}
1338
- showThinking={footerConfig.showThinking}
1339
- thinkingEnabled={footerConfig.thinkingEnabled}
1340
- onThinkingChange={footerConfig.onThinkingChange}
1341
1078
  />,
1342
1079
  )}
1343
1080
  {renderButtons(FooterButtonPosition.LEFT)}
1344
1081
  </div>
1345
1082
  <div className={styles.right_control}>
1346
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
+ )}
1347
1105
  <Popover
1348
1106
  overlayClassName={styles.popover_icon}
1349
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 {