@opensumi/ide-ai-native 3.9.1-next-1749540423.0 → 3.9.1-next-1749547010.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 (250) hide show
  1. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  2. package/lib/browser/ai-core.contribution.js +9 -4
  3. package/lib/browser/ai-core.contribution.js.map +1 -1
  4. package/lib/browser/chat/apply.service.d.ts +3 -0
  5. package/lib/browser/chat/apply.service.d.ts.map +1 -1
  6. package/lib/browser/chat/apply.service.js +47 -0
  7. package/lib/browser/chat/apply.service.js.map +1 -1
  8. package/lib/browser/chat/chat-manager.service.d.ts +1 -0
  9. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  10. package/lib/browser/chat/chat-manager.service.js +9 -3
  11. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  12. package/lib/browser/chat/chat-model.d.ts +8 -1
  13. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  14. package/lib/browser/chat/chat-model.js +113 -76
  15. package/lib/browser/chat/chat-model.js.map +1 -1
  16. package/lib/browser/chat/chat-proxy.service.d.ts +0 -2
  17. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  18. package/lib/browser/chat/chat-proxy.service.js +50 -57
  19. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  20. package/lib/browser/chat/chat.feature.registry.d.ts +4 -1
  21. package/lib/browser/chat/chat.feature.registry.d.ts.map +1 -1
  22. package/lib/browser/chat/chat.feature.registry.js +6 -0
  23. package/lib/browser/chat/chat.feature.registry.js.map +1 -1
  24. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  25. package/lib/browser/chat/chat.view.js +50 -10
  26. package/lib/browser/chat/chat.view.js.map +1 -1
  27. package/lib/browser/components/ChatHistory.d.ts.map +1 -1
  28. package/lib/browser/components/ChatHistory.js +2 -1
  29. package/lib/browser/components/ChatHistory.js.map +1 -1
  30. package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
  31. package/lib/browser/components/ChatMentionInput.js +148 -30
  32. package/lib/browser/components/ChatMentionInput.js.map +1 -1
  33. package/lib/browser/components/ChatReply.js +2 -2
  34. package/lib/browser/components/ChatReply.js.map +1 -1
  35. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  36. package/lib/browser/components/ChatToolRender.js +7 -2
  37. package/lib/browser/components/ChatToolRender.js.map +1 -1
  38. package/lib/browser/components/ChatToolRender.module.less +25 -0
  39. package/lib/browser/components/components.module.less +37 -8
  40. package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
  41. package/lib/browser/components/mention-input/mention-input.js +150 -14
  42. package/lib/browser/components/mention-input/mention-input.js.map +1 -1
  43. package/lib/browser/components/mention-input/mention-input.module.less +165 -1
  44. package/lib/browser/components/mention-input/mention-select.d.ts +28 -0
  45. package/lib/browser/components/mention-input/mention-select.d.ts.map +1 -0
  46. package/lib/browser/components/mention-input/mention-select.js +136 -0
  47. package/lib/browser/components/mention-input/mention-select.js.map +1 -0
  48. package/lib/browser/components/mention-input/mention-select.module.less +297 -0
  49. package/lib/browser/components/mention-input/types.d.ts +28 -1
  50. package/lib/browser/components/mention-input/types.d.ts.map +1 -1
  51. package/lib/browser/components/mention-input/types.js +1 -0
  52. package/lib/browser/components/mention-input/types.js.map +1 -1
  53. package/lib/browser/components/utils.d.ts +2 -2
  54. package/lib/browser/context/llm-context.service.d.ts +21 -2
  55. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  56. package/lib/browser/context/llm-context.service.js +162 -20
  57. package/lib/browser/context/llm-context.service.js.map +1 -1
  58. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -1
  59. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -1
  60. package/lib/browser/contrib/intelligent-completions/diff-computer.js +1 -1
  61. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -1
  62. package/lib/browser/contrib/terminal/terminal.feature.registry.js.map +1 -1
  63. package/lib/browser/index.d.ts.map +1 -1
  64. package/lib/browser/index.js +7 -0
  65. package/lib/browser/index.js.map +1 -1
  66. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  67. package/lib/browser/layout/ai-layout.js +6 -4
  68. package/lib/browser/layout/ai-layout.js.map +1 -1
  69. package/lib/browser/layout/tabbar.view.d.ts +1 -1
  70. package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
  71. package/lib/browser/layout/tabbar.view.js +5 -12
  72. package/lib/browser/layout/tabbar.view.js.map +1 -1
  73. package/lib/browser/mcp/base-apply.service.d.ts +5 -4
  74. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  75. package/lib/browser/mcp/base-apply.service.js +23 -5
  76. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  77. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +3 -1
  78. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  79. package/lib/browser/mcp/mcp-server-proxy.service.js +4 -0
  80. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  81. package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
  82. package/lib/browser/mcp/mcp-server.feature.registry.js +7 -1
  83. package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
  84. package/lib/browser/mcp/tools/createNewFileWithText.d.ts +1 -3
  85. package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
  86. package/lib/browser/mcp/tools/createNewFileWithText.js +14 -40
  87. package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
  88. package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -1
  89. package/lib/browser/mcp/tools/fileSearch.js +9 -5
  90. package/lib/browser/mcp/tools/fileSearch.js.map +1 -1
  91. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  92. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
  93. package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -1
  94. package/lib/browser/mcp/tools/grepSearch.js +22 -10
  95. package/lib/browser/mcp/tools/grepSearch.js.map +1 -1
  96. package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.d.ts +15 -0
  97. package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.d.ts.map +1 -0
  98. package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.js +53 -0
  99. package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.js.map +1 -0
  100. package/lib/browser/mcp/tools/handlers/ListDir.js +1 -1
  101. package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
  102. package/lib/browser/mcp/tools/handlers/ReadFile.js +1 -1
  103. package/lib/browser/mcp/tools/handlers/ReadFile.js.map +1 -1
  104. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts +11 -1
  105. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
  106. package/lib/browser/mcp/tools/handlers/RunCommand.js +11 -4
  107. package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
  108. package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
  109. package/lib/browser/mcp/tools/listDir.js +19 -15
  110. package/lib/browser/mcp/tools/listDir.js.map +1 -1
  111. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  112. package/lib/browser/model/msg-history-manager.d.ts +47 -1
  113. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  114. package/lib/browser/model/msg-history-manager.js +127 -2
  115. package/lib/browser/model/msg-history-manager.js.map +1 -1
  116. package/lib/browser/preferences/schema.d.ts.map +1 -1
  117. package/lib/browser/preferences/schema.js +5 -0
  118. package/lib/browser/preferences/schema.js.map +1 -1
  119. package/lib/browser/rules/rules.contribution.d.ts +29 -0
  120. package/lib/browser/rules/rules.contribution.d.ts.map +1 -0
  121. package/lib/browser/rules/rules.contribution.js +94 -0
  122. package/lib/browser/rules/rules.contribution.js.map +1 -0
  123. package/lib/browser/rules/rules.module.less +175 -0
  124. package/lib/browser/rules/rules.service.d.ts +25 -0
  125. package/lib/browser/rules/rules.service.d.ts.map +1 -0
  126. package/lib/browser/rules/rules.service.js +180 -0
  127. package/lib/browser/rules/rules.service.js.map +1 -0
  128. package/lib/browser/rules/rules.view.d.ts +3 -0
  129. package/lib/browser/rules/rules.view.d.ts.map +1 -0
  130. package/lib/browser/rules/rules.view.js +76 -0
  131. package/lib/browser/rules/rules.view.js.map +1 -0
  132. package/lib/browser/types.d.ts +12 -1
  133. package/lib/browser/types.d.ts.map +1 -1
  134. package/lib/browser/types.js.map +1 -1
  135. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  136. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  137. package/lib/common/image-compression.d.ts +25 -0
  138. package/lib/common/image-compression.d.ts.map +1 -0
  139. package/lib/common/image-compression.js +153 -0
  140. package/lib/common/image-compression.js.map +1 -0
  141. package/lib/common/index.d.ts +5 -1
  142. package/lib/common/index.d.ts.map +1 -1
  143. package/lib/common/index.js +2 -0
  144. package/lib/common/index.js.map +1 -1
  145. package/lib/common/llm-context.d.ts +19 -0
  146. package/lib/common/llm-context.d.ts.map +1 -1
  147. package/lib/common/llm-context.js.map +1 -1
  148. package/lib/common/mdc-parser.d.ts +60 -0
  149. package/lib/common/mdc-parser.d.ts.map +1 -0
  150. package/lib/common/mdc-parser.js +246 -0
  151. package/lib/common/mdc-parser.js.map +1 -0
  152. package/lib/common/model.d.ts +1 -0
  153. package/lib/common/model.d.ts.map +1 -1
  154. package/lib/common/model.js.map +1 -1
  155. package/lib/common/prompts/context-prompt-provider.d.ts +0 -2
  156. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  157. package/lib/common/prompts/context-prompt-provider.js +35 -29
  158. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  159. package/lib/common/prompts/system-prompt.d.ts +2 -0
  160. package/lib/common/prompts/system-prompt.d.ts.map +1 -0
  161. package/lib/common/prompts/system-prompt.js +5 -0
  162. package/lib/common/prompts/system-prompt.js.map +1 -0
  163. package/lib/common/types.d.ts +21 -0
  164. package/lib/common/types.d.ts.map +1 -1
  165. package/lib/common/types.js.map +1 -1
  166. package/lib/common/utils.d.ts +1 -0
  167. package/lib/common/utils.d.ts.map +1 -1
  168. package/lib/common/utils.js +5 -2
  169. package/lib/common/utils.js.map +1 -1
  170. package/lib/node/anthropic/anthropic-language-model.d.ts +1 -1
  171. package/lib/node/base-language-model.d.ts +2 -1
  172. package/lib/node/base-language-model.d.ts.map +1 -1
  173. package/lib/node/base-language-model.js +12 -2
  174. package/lib/node/base-language-model.js.map +1 -1
  175. package/lib/node/deepseek/deepseek-language-model.d.ts +1 -1
  176. package/lib/node/mcp/sumi-mcp-server.d.ts +3 -1
  177. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  178. package/lib/node/mcp/sumi-mcp-server.js +7 -1
  179. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  180. package/lib/node/mcp-server-manager-impl.d.ts +3 -1
  181. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  182. package/lib/node/mcp-server-manager-impl.js +14 -2
  183. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  184. package/lib/node/mcp-server.sse.d.ts +187 -1
  185. package/lib/node/mcp-server.sse.d.ts.map +1 -1
  186. package/lib/node/mcp-server.sse.js +2 -2
  187. package/lib/node/mcp-server.sse.js.map +1 -1
  188. package/lib/node/mcp-server.stdio.d.ts +187 -1
  189. package/lib/node/mcp-server.stdio.d.ts.map +1 -1
  190. package/package.json +27 -26
  191. package/src/browser/ai-core.contribution.ts +14 -4
  192. package/src/browser/chat/apply.service.ts +62 -1
  193. package/src/browser/chat/chat-manager.service.ts +16 -7
  194. package/src/browser/chat/chat-model.ts +130 -73
  195. package/src/browser/chat/chat-proxy.service.ts +68 -81
  196. package/src/browser/chat/chat.feature.registry.ts +17 -1
  197. package/src/browser/chat/chat.view.tsx +73 -12
  198. package/src/browser/components/ChatHistory.tsx +2 -1
  199. package/src/browser/components/ChatMentionInput.tsx +180 -35
  200. package/src/browser/components/ChatReply.tsx +4 -4
  201. package/src/browser/components/ChatToolRender.module.less +25 -0
  202. package/src/browser/components/ChatToolRender.tsx +10 -2
  203. package/src/browser/components/components.module.less +37 -8
  204. package/src/browser/components/mention-input/mention-input.module.less +165 -1
  205. package/src/browser/components/mention-input/mention-input.tsx +232 -31
  206. package/src/browser/components/mention-input/mention-select.module.less +297 -0
  207. package/src/browser/components/mention-input/mention-select.tsx +256 -0
  208. package/src/browser/components/mention-input/types.ts +29 -0
  209. package/src/browser/context/llm-context.service.ts +182 -21
  210. package/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts +1 -1
  211. package/src/browser/contrib/intelligent-completions/diff-computer.ts +1 -1
  212. package/src/browser/contrib/terminal/terminal.feature.registry.ts +1 -1
  213. package/src/browser/index.ts +8 -0
  214. package/src/browser/layout/ai-layout.tsx +12 -8
  215. package/src/browser/layout/tabbar.view.tsx +10 -23
  216. package/src/browser/mcp/base-apply.service.ts +30 -10
  217. package/src/browser/mcp/mcp-server-proxy.service.ts +6 -1
  218. package/src/browser/mcp/mcp-server.feature.registry.ts +6 -1
  219. package/src/browser/mcp/tools/createNewFileWithText.ts +17 -46
  220. package/src/browser/mcp/tools/fileSearch.ts +8 -5
  221. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
  222. package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
  223. package/src/browser/mcp/tools/grepSearch.ts +32 -21
  224. package/src/browser/mcp/tools/handlers/CreateNewFileWithText.ts +49 -0
  225. package/src/browser/mcp/tools/handlers/ListDir.ts +2 -2
  226. package/src/browser/mcp/tools/handlers/ReadFile.ts +2 -2
  227. package/src/browser/mcp/tools/handlers/RunCommand.ts +21 -14
  228. package/src/browser/mcp/tools/listDir.ts +15 -12
  229. package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
  230. package/src/browser/model/msg-history-manager.ts +181 -2
  231. package/src/browser/preferences/schema.ts +5 -0
  232. package/src/browser/rules/rules.contribution.ts +105 -0
  233. package/src/browser/rules/rules.module.less +175 -0
  234. package/src/browser/rules/rules.service.ts +189 -0
  235. package/src/browser/rules/rules.view.tsx +127 -0
  236. package/src/browser/types.ts +18 -0
  237. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +0 -1
  238. package/src/common/image-compression.ts +174 -0
  239. package/src/common/index.ts +6 -1
  240. package/src/common/llm-context.ts +23 -0
  241. package/src/common/mdc-parser.ts +295 -0
  242. package/src/common/model.ts +1 -0
  243. package/src/common/prompts/context-prompt-provider.ts +55 -40
  244. package/src/common/prompts/system-prompt.ts +2 -0
  245. package/src/common/types.ts +18 -0
  246. package/src/common/utils.ts +4 -1
  247. package/src/node/base-language-model.ts +11 -14
  248. package/src/node/mcp/sumi-mcp-server.ts +10 -2
  249. package/src/node/mcp-server-manager-impl.ts +17 -2
  250. package/src/node/mcp-server.sse.ts +1 -2
@@ -10,7 +10,13 @@ import {
10
10
  useInjectable,
11
11
  } from '@opensumi/ide-core-browser';
12
12
  import { Icon, getIcon } from '@opensumi/ide-core-browser/lib/components';
13
- import { AINativeSettingSectionsId, ChatFeatureRegistryToken, URI, localize } from '@opensumi/ide-core-common';
13
+ import {
14
+ AINativeSettingSectionsId,
15
+ ChatFeatureRegistryToken,
16
+ RulesServiceToken,
17
+ URI,
18
+ localize,
19
+ } from '@opensumi/ide-core-common';
14
20
  import { CommandService } from '@opensumi/ide-core-common/lib/command';
15
21
  import { defaultFilesWatcherExcludes } from '@opensumi/ide-core-common/lib/preferences/file-watch';
16
22
  import { WorkbenchEditorService } from '@opensumi/ide-editor';
@@ -18,6 +24,8 @@ import { FileSearchServicePath, IFileSearchService } from '@opensumi/ide-file-se
18
24
  import { OutlineCompositeTreeNode, OutlineTreeNode } from '@opensumi/ide-outline/lib/browser/outline-node.define';
19
25
  import { OutlineTreeService } from '@opensumi/ide-outline/lib/browser/services/outline-tree.service';
20
26
  import { IMessageService } from '@opensumi/ide-overlay';
27
+ import { IconType } from '@opensumi/ide-theme';
28
+ import { IconService } from '@opensumi/ide-theme/lib/browser';
21
29
  import { IWorkspaceService } from '@opensumi/ide-workspace';
22
30
 
23
31
  import { IChatInternalService } from '../../common';
@@ -25,6 +33,8 @@ import { LLMContextService } from '../../common/llm-context';
25
33
  import { ChatFeatureRegistry } from '../chat/chat.feature.registry';
26
34
  import { ChatInternalService } from '../chat/chat.internal.service';
27
35
  import { MCPConfigCommands } from '../mcp/config/mcp-config.commands';
36
+ import { RulesCommands } from '../rules/rules.contribution';
37
+ import { RulesService } from '../rules/rules.service';
28
38
 
29
39
  import styles from './components.module.less';
30
40
  import { MentionInput } from './mention-input/mention-input';
@@ -72,15 +82,21 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
72
82
  const workspaceService = useInjectable<IWorkspaceService>(IWorkspaceService);
73
83
  const editorService = useInjectable<WorkbenchEditorService>(WorkbenchEditorService);
74
84
  const labelService = useInjectable<LabelService>(LabelService);
85
+ const iconService = useInjectable<IconService>(IconService);
75
86
  const messageService = useInjectable<IMessageService>(IMessageService);
76
87
  const chatFeatureRegistry = useInjectable<ChatFeatureRegistry>(ChatFeatureRegistryToken);
77
88
  const outlineTreeService = useInjectable<OutlineTreeService>(OutlineTreeService);
78
89
  const prevOutlineItems = useRef<MentionItem[]>([]);
79
90
  const preferenceService = useInjectable<PreferenceService>(PreferenceService);
91
+ const rulesService = useInjectable<RulesService>(RulesServiceToken);
80
92
  const handleShowMCPConfig = React.useCallback(() => {
81
93
  commandService.executeCommand(MCPConfigCommands.OPEN_MCP_CONFIG.id);
82
94
  }, [commandService]);
83
95
 
96
+ const handleShowRules = React.useCallback(() => {
97
+ commandService.executeCommand(RulesCommands.OPEN_RULES_FILE.id);
98
+ }, [commandService]);
99
+
84
100
  useEffect(() => {
85
101
  if (props.value !== value) {
86
102
  setValue(props.value || '');
@@ -107,6 +123,55 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
107
123
  [outlineTreeService],
108
124
  );
109
125
 
126
+ // 拆分目录路径为多个层级的辅助函数
127
+ const expandFolderPaths = async (folderPaths: string[], workspaceRootPath: string): Promise<MentionItem[]> => {
128
+ const expandedPaths = new Set<string>();
129
+ const workspaceUri = new URI(workspaceRootPath);
130
+
131
+ // 将所有路径展开为多层级
132
+ for (const folderPath of folderPaths) {
133
+ const uri = new URI(folderPath);
134
+ const relativePath = await workspaceService.asRelativePath(uri);
135
+
136
+ if (relativePath?.path) {
137
+ const pathSegments = relativePath.path.split('/').filter(Boolean);
138
+
139
+ // 为每个层级创建路径
140
+ for (let i = 0; i < pathSegments.length; i++) {
141
+ const segmentPath = pathSegments.slice(0, i + 1).join('/');
142
+ const fullPath = workspaceUri.resolve(segmentPath).codeUri.fsPath;
143
+
144
+ // 避免添加工作区本身或其上级目录
145
+ if (fullPath !== workspaceRootPath && !workspaceRootPath.startsWith(fullPath)) {
146
+ expandedPaths.add(fullPath);
147
+ }
148
+ }
149
+ } else {
150
+ // 如果无法获取相对路径,直接添加(但仍要过滤工作区路径)
151
+ if (folderPath !== workspaceRootPath && !workspaceRootPath.startsWith(folderPath)) {
152
+ expandedPaths.add(folderPath);
153
+ }
154
+ }
155
+ }
156
+
157
+ // 转换为 MentionItem 格式
158
+ return Promise.all(
159
+ Array.from(expandedPaths).map(async (folderPath) => {
160
+ const uri = new URI(folderPath);
161
+ const relativePath = await workspaceService.asRelativePath(uri);
162
+ return {
163
+ id: uri.codeUri.fsPath,
164
+ type: MentionType.FOLDER,
165
+ text: uri.displayName,
166
+ value: uri.codeUri.fsPath,
167
+ description: relativePath?.root ? relativePath.path : '',
168
+ contextId: uri.codeUri.fsPath,
169
+ icon: getIcon('folder'),
170
+ };
171
+ }),
172
+ );
173
+ };
174
+
110
175
  // 默认菜单项
111
176
  const defaultMenuItems: MentionItem[] = [
112
177
  {
@@ -214,21 +279,7 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
214
279
  .filter((folder) => folder !== workspaceService.workspace?.uri.toString() && folder !== '/'),
215
280
  ),
216
281
  );
217
- folders = await Promise.all(
218
- recentFolder.map(async (folder) => {
219
- const uri = new URI(folder);
220
- const relativePath = await workspaceService.asRelativePath(uri);
221
- return {
222
- id: uri.codeUri.fsPath,
223
- type: MentionType.FOLDER,
224
- text: uri.displayName,
225
- value: uri.codeUri.fsPath,
226
- description: relativePath?.root ? relativePath.path : '',
227
- contextId: uri.codeUri.fsPath,
228
- icon: getIcon('folder'),
229
- };
230
- }),
231
- );
282
+ folders = await expandFolderPaths(recentFolder, workspaceService.workspace?.uri.toString() || '');
232
283
  } else {
233
284
  const rootUris = (await workspaceService.roots).map((root) => new URI(root.uri).codeUri.fsPath.toString());
234
285
  const files = await searchService.find(searchText, {
@@ -246,22 +297,11 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
246
297
  .filter((folder) => folder !== workspaceService.workspace?.uri.toString()),
247
298
  ),
248
299
  );
249
- return Promise.all(
250
- folders.map(async (folder) => {
251
- const uri = new URI(folder);
252
- return {
253
- id: uri.codeUri.fsPath,
254
- type: MentionType.FOLDER,
255
- text: uri.displayName,
256
- value: uri.codeUri.fsPath,
257
- description: (await workspaceService.asRelativePath(uri.parent))?.path || '',
258
- contextId: uri.codeUri.fsPath,
259
- icon: getIcon('folder'),
260
- };
261
- }),
262
- );
300
+ return await expandFolderPaths(folders, workspaceService.workspace?.uri.toString() || '');
263
301
  }
264
- return folders.filter((folder) => folder.id !== new URI(workspaceService.workspace?.uri).codeUri.fsPath);
302
+ return folders
303
+ .filter(Boolean)
304
+ .filter((folder) => folder.id !== new URI(workspaceService.workspace?.uri).codeUri.fsPath);
265
305
  },
266
306
  },
267
307
  {
@@ -312,13 +352,111 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
312
352
  }
313
353
  },
314
354
  },
315
- ];
355
+ {
356
+ id: MentionType.RULE,
357
+ type: MentionType.RULE,
358
+ text: 'Rule',
359
+ icon: getIcon('rules'),
360
+ getHighestLevelItems: () => [],
361
+ getItems: async (searchText: string) => {
362
+ const rules = await rulesService.projectRules;
363
+ const mappedRules = rules.map((rule) => {
364
+ const uri = new URI(rule.path);
365
+ return {
366
+ id: uri.codeUri.fsPath,
367
+ type: MentionType.RULE,
368
+ text: uri.displayName,
369
+ value: uri.codeUri.fsPath,
370
+ contextId: uri.codeUri.fsPath,
371
+ description: rule.description,
372
+ icon: getIcon('rules'),
373
+ };
374
+ });
375
+
376
+ if (!searchText) {
377
+ return mappedRules.slice(0, 10);
378
+ }
379
+
380
+ const lowerSearchText = searchText.toLocaleLowerCase();
381
+ return mappedRules
382
+ .filter((rule) => rule.text.toLocaleLowerCase().includes(lowerSearchText))
383
+ .sort((a, b) => {
384
+ const aTextLower = a.text.toLocaleLowerCase();
385
+ const bTextLower = b.text.toLocaleLowerCase();
386
+ const aDescLower = a.description?.toLocaleLowerCase() || '';
387
+ const bDescLower = b.description?.toLocaleLowerCase() || '';
388
+
389
+ // 优先级:文件名包含搜索文本 > 描述包含搜索文本
390
+ const aTextMatch = aTextLower.includes(lowerSearchText);
391
+ const bTextMatch = bTextLower.includes(lowerSearchText);
392
+ const aDescMatch = aDescLower.includes(lowerSearchText);
393
+ const bDescMatch = bDescLower.includes(lowerSearchText);
394
+
395
+ if (aTextMatch && bTextMatch) {
396
+ // 如果都匹配文件名,按文件名字母序排序
397
+ return aTextLower.localeCompare(bTextLower);
398
+ }
399
+ if (aTextMatch && !bTextMatch) {
400
+ return -1;
401
+ }
402
+ if (!aTextMatch && bTextMatch) {
403
+ return 1;
404
+ }
405
+
406
+ // 如果文件名都不匹配,比较描述
407
+ if (aDescMatch && bDescMatch) {
408
+ return aTextLower.localeCompare(bTextLower);
409
+ }
410
+ if (aDescMatch && !bDescMatch) {
411
+ return -1;
412
+ }
413
+ if (!aDescMatch && bDescMatch) {
414
+ return 1;
415
+ }
316
416
 
417
+ // 如果都不匹配,按文件名字母序排序
418
+ return aTextLower.localeCompare(bTextLower);
419
+ })
420
+ .slice(0, 10);
421
+ },
422
+ },
423
+ ];
317
424
  const defaultMentionInputFooterOptions: FooterConfig = useMemo(
318
425
  () => ({
319
426
  modelOptions: [
320
- { label: 'QWQ 32B', value: 'qwq-32b' },
321
- { label: 'DeepSeek R1', value: 'deepseek-r1' },
427
+ {
428
+ value: 'qwen-plus-latest',
429
+ label: 'Qwen 3',
430
+ iconClass: iconService.fromIcon(
431
+ '',
432
+ 'https://img.alicdn.com/imgextra/i3/O1CN01LFMrZj28YrnrzeebY_!!6000000007945-55-tps-16-16.svg',
433
+ IconType.Background,
434
+ ),
435
+ tags: ['思考链', '擅长代码'],
436
+ description: '高性能代码模型,支持思考链',
437
+ },
438
+ {
439
+ label: 'Claude 4 Sonnet',
440
+ value: 'claude_sonnet4',
441
+ iconClass: iconService.fromIcon(
442
+ '',
443
+ 'https://img.alicdn.com/imgextra/i3/O1CN01p0mziz1Nsl40lp1HO_!!6000000001626-55-tps-92-65.svg',
444
+ IconType.Background,
445
+ ),
446
+ tags: ['多模态', '长上下文理解', '思考模式'],
447
+ description: '高性能模型,支持多模态输入',
448
+ },
449
+ {
450
+ label: 'DeepSeek R1',
451
+ value: 'DeepSeek-R1-0528',
452
+ iconClass: iconService.fromIcon(
453
+ '',
454
+ 'https://img.alicdn.com/imgextra/i3/O1CN01ClcK2w1JwdxcbAB3a_!!6000000001093-55-tps-30-30.svg',
455
+ IconType.Background,
456
+ ),
457
+ tags: ['思考模式', '长上下文理解'],
458
+ description: '专业创作,支持多模态输入',
459
+ },
322
460
  ],
323
461
  defaultModel:
324
462
  props.sessionModelId || preferenceService.get<string>(AINativeSettingSectionsId.ModelID) || 'deepseek-r1',
@@ -330,6 +468,13 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
330
468
  onClick: handleShowMCPConfig,
331
469
  position: FooterButtonPosition.LEFT,
332
470
  },
471
+ {
472
+ id: 'rules',
473
+ icon: 'rules',
474
+ title: 'Rules',
475
+ onClick: handleShowRules,
476
+ position: FooterButtonPosition.LEFT,
477
+ },
333
478
  {
334
479
  id: 'upload-image',
335
480
  icon: 'image',
@@ -352,7 +497,7 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
352
497
  showModelSelector: true,
353
498
  disableModelSelector: props.disableModelSelector,
354
499
  }),
355
- [handleShowMCPConfig, props.disableModelSelector, props.sessionModelId],
500
+ [iconService, handleShowMCPConfig, handleShowRules, props.disableModelSelector, props.sessionModelId],
356
501
  );
357
502
 
358
503
  const handleStop = useCallback(() => {
@@ -342,10 +342,10 @@ export const ChatReply = (props: IChatReplyProps) => {
342
342
  }}
343
343
  >
344
344
  <Icon iconClass='codicon codicon-sparkle' />
345
- {localize('aiNative.chat.thinking')}
346
- {isThinking ? (
347
- <Loading />
348
- ) : collapseThinkingIndexSet.has(index) ? (
345
+ <span style={{ marginLeft: 4 }} className={isThinking ? styles.shiny_text : ''}>
346
+ {localize('aiNative.chat.thinking')}
347
+ </span>
348
+ {isThinking ? null : collapseThinkingIndexSet.has(index) ? (
349
349
  <Icon iconClass='codicon codicon-chevron-right' />
350
350
  ) : (
351
351
  <Icon iconClass='codicon codicon-chevron-down' />
@@ -23,6 +23,7 @@
23
23
  display: flex;
24
24
  align-items: center;
25
25
  font-weight: 500;
26
+ width: calc(100% - 20px);
26
27
  color: var(--design-text-foreground);
27
28
  }
28
29
 
@@ -34,6 +35,30 @@
34
35
  margin-left: 5px;
35
36
  font-size: 11px;
36
37
  color: var(--descriptionForeground);
38
+ width: calc(100% - 36px);
39
+ display: flex;
40
+ align-items: center;
41
+ justify-content: flex-start;
42
+
43
+ .tool_prefix {
44
+ color: var(--design-text-placeholderForeground);
45
+ margin-right: 10px;
46
+ flex-shrink: 0;
47
+ }
48
+
49
+ .tool_name {
50
+ opacity: 0.8;
51
+ font-size: 9px;
52
+ flex: 1;
53
+ text-overflow: ellipsis;
54
+ direction: rtl;
55
+ unicode-bidi: plaintext;
56
+ overflow: hidden;
57
+ white-space: nowrap;
58
+ display: inline-block;
59
+ margin-right: 10px;
60
+ text-align: left;
61
+ }
37
62
  }
38
63
 
39
64
  .expand_icon {
@@ -7,6 +7,7 @@ import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
7
7
  import { IChatToolContent, uuid } from '@opensumi/ide-core-common';
8
8
  import { localize } from '@opensumi/ide-core-common/lib/localize';
9
9
 
10
+ import { TOOL_NAME_SEPARATOR } from '../../common/utils';
10
11
  import { IMCPServerRegistry, TokenMCPServerRegistry } from '../types';
11
12
 
12
13
  import { CodeEditorWithHighlight } from './ChatEditor';
@@ -21,7 +22,9 @@ export const ChatToolRender = (props: { value: IChatToolContent['content']; mess
21
22
  if (!value || !value.function || !value.id) {
22
23
  return null;
23
24
  }
24
- const label = mcpServerFeatureRegistry.getMCPTool(value.function.name)?.label || value.function.name;
25
+ const toolName = mcpServerFeatureRegistry.getMCPTool(value.function.name)?.label || value.function.name;
26
+ const parts = toolName.split(TOOL_NAME_SEPARATOR);
27
+ const label = parts.length >= 3 ? parts[2] : toolName;
25
28
 
26
29
  const ToolComponent = mcpServerFeatureRegistry.getToolComponent(value.function.name);
27
30
 
@@ -72,7 +75,12 @@ export const ChatToolRender = (props: { value: IChatToolContent['content']; mess
72
75
  <div className={styles.tool_name}>
73
76
  <Icon iconClass={`codicon codicon-chevron-${isExpanded ? 'down' : 'right'}`} />
74
77
  <Icon size='small' iconClass={cls('codicon codicon-tools', styles.tool_icon)} />
75
- <span className={styles.tool_label}>{label}</span>
78
+ <span className={styles.tool_label}>
79
+ <span className={styles.tool_prefix}>Called MCP Tool</span>
80
+ <span className={styles.tool_name} title={label}>
81
+ {label}
82
+ </span>
83
+ </span>
76
84
  </div>
77
85
  {value.state && (
78
86
  <div className={styles.tool_state}>
@@ -524,7 +524,6 @@
524
524
  display: flex;
525
525
  font-size: 11px;
526
526
  align-items: center;
527
- min-width: 150px;
528
527
  }
529
528
 
530
529
  .mcp_desc {
@@ -585,7 +584,6 @@
585
584
  .reasoning_content {
586
585
  padding: 8px 12px;
587
586
  margin-top: 4px;
588
- border-left: 2px solid var(--descriptionForeground);
589
587
  color: var(--descriptionForeground);
590
588
  background: var(--design-block-background);
591
589
  border-radius: 4px;
@@ -597,8 +595,8 @@
597
595
  align-items: center;
598
596
  padding: 0 4px;
599
597
  margin: 0 2px;
600
- background: var(--badge-background);
601
- color: var(--badge-foreground);
598
+ background-color: var(--chat-slashCommandBackground);
599
+ color: var(--chat-slashCommandForeground);
602
600
  border-radius: 3px;
603
601
  vertical-align: middle;
604
602
  font-size: 12px;
@@ -609,10 +607,6 @@
609
607
  margin-right: 3px;
610
608
  }
611
609
  }
612
- &:hover {
613
- background-color: var(--chat-slashCommandBackground);
614
- color: var(--chat-slashCommandForeground);
615
- }
616
610
  }
617
611
 
618
612
  .attachment_text {
@@ -620,6 +614,13 @@
620
614
  vertical-align: middle;
621
615
  font-size: 12px;
622
616
  word-break: break-all;
617
+ max-width: 100px;
618
+ text-overflow: ellipsis;
619
+ direction: rtl;
620
+ unicode-bidi: plaintext;
621
+ overflow: hidden;
622
+ white-space: nowrap;
623
+ display: inline-block;
623
624
  }
624
625
 
625
626
  .thumbnail_container {
@@ -672,3 +673,31 @@
672
673
  border-radius: 3px;
673
674
  overflow: hidden;
674
675
  }
676
+
677
+ .shiny_text {
678
+ color: #b5b5b5a4; /* Adjust this color to change intensity/style */
679
+ background: linear-gradient(
680
+ 120deg,
681
+ rgba(255, 255, 255, 0) 40%,
682
+ rgba(255, 255, 255, 0.8) 50%,
683
+ rgba(255, 255, 255, 0) 60%
684
+ );
685
+ background-size: 200% 100%;
686
+ -webkit-background-clip: text;
687
+ background-clip: text;
688
+ display: inline-block;
689
+ animation: shine 5s linear infinite;
690
+ }
691
+
692
+ @keyframes shine {
693
+ 0% {
694
+ background-position: 100%;
695
+ }
696
+ 100% {
697
+ background-position: -100%;
698
+ }
699
+ }
700
+
701
+ .shiny_text.disabled {
702
+ animation: none;
703
+ }
@@ -6,7 +6,6 @@
6
6
 
7
7
  .model_selector {
8
8
  margin-right: 5px;
9
- min-width: 150px;
10
9
  }
11
10
 
12
11
  .editor_area {
@@ -29,7 +28,9 @@
29
28
  word-break: break-word;
30
29
 
31
30
  .mention_tag {
31
+ height: 20px;
32
32
  margin: 0 2px;
33
+ margin-top: -3px;
33
34
  vertical-align: middle;
34
35
  }
35
36
  }
@@ -95,11 +96,13 @@
95
96
  .stop_logo {
96
97
  background-color: var(--badge-background);
97
98
  color: var(--badge-foreground);
99
+
98
100
  .stop_logo_icon {
99
101
  line-height: 16px;
100
102
  color: var(--kt-dangerButton-background);
101
103
  }
102
104
  }
105
+
103
106
  .send_logo {
104
107
  &:hover {
105
108
  background-color: var(--kt-primaryButton-background);
@@ -140,31 +143,38 @@
140
143
  display: flex;
141
144
  justify-content: center;
142
145
  }
146
+
143
147
  .context_container {
144
148
  display: flex;
145
149
  align-items: center;
146
150
  justify-content: center;
147
151
  cursor: pointer;
152
+
148
153
  .context_icon {
149
154
  flex-grow: 0;
150
155
  flex-shrink: 0;
156
+
151
157
  :global(.kt-icon) {
152
158
  font-size: 12px;
153
159
  }
160
+
154
161
  :global(.kticon-close) {
155
162
  display: none;
156
163
  }
157
164
  }
165
+
158
166
  &:hover {
159
167
  .context_icon {
160
168
  :global(.kticon-close) {
161
169
  display: block;
162
170
  }
171
+
163
172
  :global(.kticon-out-link) {
164
173
  display: none;
165
174
  }
166
175
  }
167
176
  }
177
+
168
178
  .context_description {
169
179
  flex: 1;
170
180
  margin-left: 3px;
@@ -254,6 +264,7 @@
254
264
  display: inline;
255
265
  flex: 1;
256
266
  direction: rtl;
267
+ unicode-bidi: plaintext;
257
268
  text-overflow: ellipsis;
258
269
  overflow: hidden;
259
270
  white-space: nowrap;
@@ -341,6 +352,10 @@
341
352
  justify-content: center;
342
353
  margin-right: 3px;
343
354
  font-size: 12px;
355
+ &::before {
356
+ font-size: 12px;
357
+ background-size: 12px !important;
358
+ }
344
359
  }
345
360
 
346
361
  .empty_state {
@@ -404,3 +419,152 @@
404
419
  color: #666;
405
420
  font-style: italic;
406
421
  }
422
+
423
+ .context_preview_container {
424
+ background-color: var(--kt-editorWidget-background);
425
+ border: 1px solid var(--kt-editorWidget-border);
426
+ margin: 0 16px;
427
+ animation: slideIn 0.3s ease-out;
428
+ display: flex;
429
+ flex-wrap: wrap;
430
+ gap: 4px;
431
+ align-items: flex-start;
432
+ margin-bottom: 3px;
433
+ width: calc(100% - 32px);
434
+ }
435
+
436
+ .context_preview_title {
437
+ cursor: pointer;
438
+ display: flex;
439
+ align-items: center;
440
+ justify-content: center;
441
+ padding: 2px 3px;
442
+ height: 18px;
443
+ width: auto;
444
+ box-sizing: border-box;
445
+ border-radius: 4px;
446
+ border: 1px solid color-mix(in srgb, var(--editor-foreground) 10%, transparent);
447
+ outline: none;
448
+ flex-shrink: 0;
449
+ color: var(--descriptionForeground);
450
+ font-size: 11px;
451
+
452
+ &::before {
453
+ content: '@';
454
+ margin-right: 4px;
455
+ }
456
+ &.has_context {
457
+ width: 18px;
458
+ &::before {
459
+ content: '@';
460
+ margin-right: 0;
461
+ }
462
+ }
463
+
464
+ &:hover {
465
+ color: var(--badge-foreground);
466
+ }
467
+ }
468
+
469
+ .context_preview_item {
470
+ cursor: pointer;
471
+ display: flex;
472
+ align-items: center;
473
+ justify-content: flex-start;
474
+ padding: 2px 4px;
475
+ height: 18px;
476
+ width: auto;
477
+ min-width: fit-content;
478
+ max-width: 300px;
479
+ box-sizing: border-box;
480
+ border-radius: 4px;
481
+ border: 1px solid color-mix(in srgb, var(--badge-background) 30%, transparent);
482
+ outline: none;
483
+ flex: 0 1 auto;
484
+ margin-left: 3px;
485
+
486
+ .icon {
487
+ width: 12px !important;
488
+ height: 12px !important;
489
+ line-height: 12px !important;
490
+ margin-right: 2px;
491
+ flex-shrink: 0;
492
+ }
493
+
494
+ .close_icon {
495
+ margin-right: 2px;
496
+ display: none !important;
497
+ width: 12px !important;
498
+ height: 12px !important;
499
+ line-height: 12px !important;
500
+ flex-shrink: 0;
501
+ opacity: 0.8;
502
+
503
+ &:hover {
504
+ opacity: 1;
505
+ }
506
+ }
507
+
508
+ &:hover {
509
+ opacity: 1;
510
+ .icon {
511
+ display: none;
512
+ }
513
+ .close_icon {
514
+ display: inline-block !important;
515
+ font-size: 12px !important;
516
+ }
517
+ }
518
+ }
519
+
520
+ .context_preview_item_icon {
521
+ display: flex;
522
+ align-items: center;
523
+ justify-content: center;
524
+ flex-shrink: 0;
525
+ opacity: 0.8;
526
+ &::before {
527
+ background-position: 2px !important;
528
+ font-size: 12px;
529
+ background-size: 11px !important;
530
+ }
531
+ }
532
+
533
+ .context_preview_item_text {
534
+ flex: 1;
535
+ overflow: hidden;
536
+ text-overflow: ellipsis;
537
+ color: var(--descriptionForeground);
538
+ white-space: nowrap;
539
+ font-weight: 400;
540
+ line-height: 1.2;
541
+ font-size: 11px;
542
+ max-width: 200px;
543
+ }
544
+
545
+ .context_preview_item_remove {
546
+ cursor: pointer;
547
+ opacity: 0.5;
548
+ font-size: 12px;
549
+ margin-left: 4px;
550
+ padding: 2px;
551
+ border-radius: 50%;
552
+ display: flex;
553
+ align-items: center;
554
+ justify-content: center;
555
+ flex-shrink: 0;
556
+ transition: all 0.2s ease;
557
+ width: 16px;
558
+ height: 16px;
559
+
560
+ &:hover {
561
+ opacity: 1;
562
+ background-color: var(--kt-dangerButton-background);
563
+ color: var(--kt-dangerButton-foreground);
564
+ transform: scale(1.1);
565
+ }
566
+
567
+ &:active {
568
+ transform: scale(0.9);
569
+ }
570
+ }