@opensumi/ide-ai-native 3.7.2-next-1740066619.0 → 3.7.2-next-1740323956.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 +4 -0
  3. package/lib/browser/ai-core.contribution.js.map +1 -1
  4. package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
  5. package/lib/browser/chat/chat-agent.service.js +6 -0
  6. package/lib/browser/chat/chat-agent.service.js.map +1 -1
  7. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  8. package/lib/browser/chat/chat-model.js +5 -23
  9. package/lib/browser/chat/chat-model.js.map +1 -1
  10. package/lib/browser/chat/chat-proxy.service.d.ts +1 -0
  11. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  12. package/lib/browser/chat/chat-proxy.service.js +8 -1
  13. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  14. package/lib/browser/chat/chat.internal.service.d.ts +4 -0
  15. package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
  16. package/lib/browser/chat/chat.internal.service.js +10 -1
  17. package/lib/browser/chat/chat.internal.service.js.map +1 -1
  18. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  19. package/lib/browser/chat/chat.view.js +2 -2
  20. package/lib/browser/chat/chat.view.js.map +1 -1
  21. package/lib/browser/components/ChatContext/index.d.ts.map +1 -1
  22. package/lib/browser/components/ChatContext/index.js +18 -2
  23. package/lib/browser/components/ChatContext/index.js.map +1 -1
  24. package/lib/browser/components/ChatContext/style.module.less +12 -0
  25. package/lib/browser/components/ChatEditor.d.ts +1 -0
  26. package/lib/browser/components/ChatEditor.d.ts.map +1 -1
  27. package/lib/browser/components/ChatEditor.js +3 -3
  28. package/lib/browser/components/ChatEditor.js.map +1 -1
  29. package/lib/browser/components/ChatMarkdown.d.ts +1 -0
  30. package/lib/browser/components/ChatMarkdown.d.ts.map +1 -1
  31. package/lib/browser/components/ChatMarkdown.js +2 -2
  32. package/lib/browser/components/ChatMarkdown.js.map +1 -1
  33. package/lib/browser/components/ChatReply.d.ts.map +1 -1
  34. package/lib/browser/components/ChatReply.js +6 -8
  35. package/lib/browser/components/ChatReply.js.map +1 -1
  36. package/lib/browser/components/ChatToolRender.d.ts +1 -0
  37. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  38. package/lib/browser/components/ChatToolRender.js +25 -7
  39. package/lib/browser/components/ChatToolRender.js.map +1 -1
  40. package/lib/browser/components/components.module.less +3 -2
  41. package/lib/browser/context/llm-context.service.d.ts +1 -0
  42. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  43. package/lib/browser/context/llm-context.service.js +24 -18
  44. package/lib/browser/context/llm-context.service.js.map +1 -1
  45. package/lib/browser/index.d.ts.map +1 -1
  46. package/lib/browser/index.js +11 -12
  47. package/lib/browser/index.js.map +1 -1
  48. package/lib/browser/mcp/base-apply.service.d.ts +67 -0
  49. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -0
  50. package/lib/browser/mcp/base-apply.service.js +290 -0
  51. package/lib/browser/mcp/base-apply.service.js.map +1 -0
  52. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +6 -1
  53. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  54. package/lib/browser/mcp/mcp-server-proxy.service.js +2 -1
  55. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  56. package/lib/browser/mcp/mcp-server.feature.registry.d.ts +5 -1
  57. package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
  58. package/lib/browser/mcp/mcp-server.feature.registry.js +17 -1
  59. package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
  60. package/lib/browser/mcp/tools/components/EditFile.d.ts +3 -0
  61. package/lib/browser/mcp/tools/components/EditFile.d.ts.map +1 -0
  62. package/lib/browser/mcp/tools/components/EditFile.js +101 -0
  63. package/lib/browser/mcp/tools/components/EditFile.js.map +1 -0
  64. package/lib/browser/mcp/tools/components/SearchResult.d.ts +11 -0
  65. package/lib/browser/mcp/tools/components/SearchResult.d.ts.map +1 -0
  66. package/lib/browser/mcp/tools/components/SearchResult.js +60 -0
  67. package/lib/browser/mcp/tools/components/SearchResult.js.map +1 -0
  68. package/lib/browser/mcp/tools/components/index.module.less +132 -0
  69. package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
  70. package/lib/browser/mcp/tools/createNewFileWithText.js +1 -2
  71. package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
  72. package/lib/browser/mcp/tools/{getSelectedText.d.ts → editFile.d.ts} +3 -3
  73. package/lib/browser/mcp/tools/editFile.d.ts.map +1 -0
  74. package/lib/browser/mcp/tools/editFile.js +95 -0
  75. package/lib/browser/mcp/tools/editFile.js.map +1 -0
  76. package/lib/browser/mcp/tools/{findFilesByNameSubstring.d.ts → fileSearch.d.ts} +3 -2
  77. package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -0
  78. package/lib/browser/mcp/tools/fileSearch.js +94 -0
  79. package/lib/browser/mcp/tools/fileSearch.js.map +1 -0
  80. package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
  81. package/lib/browser/mcp/tools/getDiagnosticsByPath.js +1 -2
  82. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  83. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.d.ts.map +1 -1
  84. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js +1 -2
  85. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
  86. package/lib/browser/mcp/tools/{getFileTextByPath.d.ts → grepSearch.d.ts} +4 -3
  87. package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -0
  88. package/lib/browser/mcp/tools/grepSearch.js +118 -0
  89. package/lib/browser/mcp/tools/grepSearch.js.map +1 -0
  90. package/lib/browser/mcp/tools/handlers/EditFile.d.ts +10 -0
  91. package/lib/browser/mcp/tools/handlers/EditFile.d.ts.map +1 -0
  92. package/lib/browser/mcp/tools/handlers/EditFile.js +28 -0
  93. package/lib/browser/mcp/tools/handlers/EditFile.js.map +1 -0
  94. package/lib/browser/mcp/tools/handlers/ReadFile.d.ts +6 -0
  95. package/lib/browser/mcp/tools/handlers/ReadFile.d.ts.map +1 -1
  96. package/lib/browser/mcp/tools/handlers/ReadFile.js +14 -0
  97. package/lib/browser/mcp/tools/handlers/ReadFile.js.map +1 -1
  98. package/lib/browser/mcp/tools/handlers/utils.d.ts +2 -0
  99. package/lib/browser/mcp/tools/handlers/utils.d.ts.map +1 -0
  100. package/lib/browser/mcp/tools/handlers/utils.js +7 -0
  101. package/lib/browser/mcp/tools/handlers/utils.js.map +1 -0
  102. package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
  103. package/lib/browser/mcp/tools/listDir.js +3 -4
  104. package/lib/browser/mcp/tools/listDir.js.map +1 -1
  105. package/lib/browser/mcp/tools/readFile.d.ts.map +1 -1
  106. package/lib/browser/mcp/tools/readFile.js +3 -4
  107. package/lib/browser/mcp/tools/readFile.js.map +1 -1
  108. package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -1
  109. package/lib/browser/mcp/tools/runTerminalCmd.js +1 -2
  110. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  111. package/lib/browser/model/msg-history-manager.d.ts +5 -0
  112. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  113. package/lib/browser/model/msg-history-manager.js +14 -0
  114. package/lib/browser/model/msg-history-manager.js.map +1 -1
  115. package/lib/browser/preferences/schema.d.ts.map +1 -1
  116. package/lib/browser/preferences/schema.js +5 -0
  117. package/lib/browser/preferences/schema.js.map +1 -1
  118. package/lib/browser/types.d.ts +14 -10
  119. package/lib/browser/types.d.ts.map +1 -1
  120. package/lib/browser/types.js +1 -2
  121. package/lib/browser/types.js.map +1 -1
  122. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +1 -0
  123. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  124. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +3 -0
  125. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  126. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +4 -0
  127. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  128. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  129. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  130. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +1 -0
  131. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  132. package/lib/common/index.d.ts +1 -0
  133. package/lib/common/index.d.ts.map +1 -1
  134. package/lib/common/index.js.map +1 -1
  135. package/lib/common/mcp-server-manager.d.ts +1 -1
  136. package/lib/common/mcp-server-manager.d.ts.map +1 -1
  137. package/lib/common/mcp-server-manager.js.map +1 -1
  138. package/lib/common/prompts/context-prompt-provider.d.ts +14 -0
  139. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -0
  140. package/lib/common/prompts/context-prompt-provider.js +38 -0
  141. package/lib/common/prompts/context-prompt-provider.js.map +1 -0
  142. package/lib/common/tool-invocation-registry.d.ts +2 -1
  143. package/lib/common/tool-invocation-registry.d.ts.map +1 -1
  144. package/lib/common/tool-invocation-registry.js.map +1 -1
  145. package/lib/common/utils.d.ts +1 -0
  146. package/lib/common/utils.d.ts.map +1 -1
  147. package/lib/common/utils.js +3 -1
  148. package/lib/common/utils.js.map +1 -1
  149. package/lib/node/base-language-model.d.ts +2 -2
  150. package/lib/node/base-language-model.d.ts.map +1 -1
  151. package/lib/node/base-language-model.js +9 -5
  152. package/lib/node/base-language-model.js.map +1 -1
  153. package/lib/node/mcp/sumi-mcp-server.d.ts +1 -1
  154. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  155. package/lib/node/mcp/sumi-mcp-server.js +5 -2
  156. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  157. package/lib/node/mcp-server-manager-impl.d.ts +1 -1
  158. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  159. package/lib/node/mcp-server-manager-impl.js +6 -5
  160. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  161. package/lib/node/mcp-server.d.ts +2 -2
  162. package/lib/node/mcp-server.d.ts.map +1 -1
  163. package/lib/node/mcp-server.js +2 -1
  164. package/lib/node/mcp-server.js.map +1 -1
  165. package/lib/node/openai/openai-language-model.d.ts +1 -1
  166. package/lib/node/openai/openai-language-model.d.ts.map +1 -1
  167. package/lib/node/openai/openai-language-model.js +2 -2
  168. package/lib/node/openai/openai-language-model.js.map +1 -1
  169. package/package.json +24 -25
  170. package/src/browser/ai-core.contribution.ts +4 -0
  171. package/src/browser/chat/chat-agent.service.ts +7 -0
  172. package/src/browser/chat/chat-model.ts +0 -2
  173. package/src/browser/chat/chat-proxy.service.ts +12 -2
  174. package/src/browser/chat/chat.internal.service.ts +12 -1
  175. package/src/browser/chat/chat.view.tsx +2 -1
  176. package/src/browser/components/ChatContext/index.tsx +19 -3
  177. package/src/browser/components/ChatContext/style.module.less +12 -0
  178. package/src/browser/components/ChatEditor.tsx +13 -10
  179. package/src/browser/components/ChatMarkdown.tsx +3 -1
  180. package/src/browser/components/ChatReply.tsx +8 -15
  181. package/src/browser/components/ChatToolRender.tsx +36 -17
  182. package/src/browser/components/components.module.less +3 -2
  183. package/src/browser/context/llm-context.service.ts +30 -18
  184. package/src/browser/index.ts +11 -12
  185. package/src/browser/mcp/base-apply.service.ts +349 -0
  186. package/src/browser/mcp/mcp-server-proxy.service.ts +4 -2
  187. package/src/browser/mcp/mcp-server.feature.registry.ts +27 -4
  188. package/src/browser/mcp/tools/components/EditFile.tsx +144 -0
  189. package/src/browser/mcp/tools/components/SearchResult.tsx +92 -0
  190. package/src/browser/mcp/tools/components/index.module.less +132 -0
  191. package/src/browser/mcp/tools/createNewFileWithText.ts +1 -2
  192. package/src/browser/mcp/tools/editFile.ts +100 -0
  193. package/src/browser/mcp/tools/fileSearch.ts +99 -0
  194. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -2
  195. package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -2
  196. package/src/browser/mcp/tools/grepSearch.ts +121 -0
  197. package/src/browser/mcp/tools/handlers/EditFile.ts +21 -0
  198. package/src/browser/mcp/tools/handlers/ReadFile.ts +19 -1
  199. package/src/browser/mcp/tools/handlers/utils.ts +3 -0
  200. package/src/browser/mcp/tools/listDir.ts +3 -4
  201. package/src/browser/mcp/tools/readFile.ts +3 -4
  202. package/src/browser/mcp/tools/runTerminalCmd.ts +1 -2
  203. package/src/browser/model/msg-history-manager.ts +19 -0
  204. package/src/browser/preferences/schema.ts +5 -0
  205. package/src/browser/types.ts +15 -11
  206. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +4 -0
  207. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +4 -0
  208. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +1 -0
  209. package/src/common/index.ts +1 -0
  210. package/src/common/mcp-server-manager.ts +18 -13
  211. package/src/common/prompts/context-prompt-provider.ts +46 -0
  212. package/src/common/tool-invocation-registry.ts +122 -124
  213. package/src/common/utils.ts +2 -0
  214. package/src/node/base-language-model.ts +20 -6
  215. package/src/node/mcp/sumi-mcp-server.ts +5 -2
  216. package/src/node/mcp-server-manager-impl.ts +13 -5
  217. package/src/node/mcp-server.ts +3 -2
  218. package/src/node/openai/openai-language-model.ts +2 -2
  219. package/lib/browser/mcp/tools/findFilesByNameSubstring.d.ts.map +0 -1
  220. package/lib/browser/mcp/tools/findFilesByNameSubstring.js +0 -92
  221. package/lib/browser/mcp/tools/findFilesByNameSubstring.js.map +0 -1
  222. package/lib/browser/mcp/tools/getCurrentFilePath.d.ts +0 -8
  223. package/lib/browser/mcp/tools/getCurrentFilePath.d.ts.map +0 -1
  224. package/lib/browser/mcp/tools/getCurrentFilePath.js +0 -49
  225. package/lib/browser/mcp/tools/getCurrentFilePath.js.map +0 -1
  226. package/lib/browser/mcp/tools/getFileTextByPath.d.ts.map +0 -1
  227. package/lib/browser/mcp/tools/getFileTextByPath.js +0 -97
  228. package/lib/browser/mcp/tools/getFileTextByPath.js.map +0 -1
  229. package/lib/browser/mcp/tools/getOpenEditorFileText.d.ts +0 -8
  230. package/lib/browser/mcp/tools/getOpenEditorFileText.d.ts.map +0 -1
  231. package/lib/browser/mcp/tools/getOpenEditorFileText.js +0 -50
  232. package/lib/browser/mcp/tools/getOpenEditorFileText.js.map +0 -1
  233. package/lib/browser/mcp/tools/getSelectedText.d.ts.map +0 -1
  234. package/lib/browser/mcp/tools/getSelectedText.js +0 -57
  235. package/lib/browser/mcp/tools/getSelectedText.js.map +0 -1
  236. package/lib/browser/mcp/tools/replaceOpenEditorFile.d.ts +0 -8
  237. package/lib/browser/mcp/tools/replaceOpenEditorFile.d.ts.map +0 -1
  238. package/lib/browser/mcp/tools/replaceOpenEditorFile.js +0 -79
  239. package/lib/browser/mcp/tools/replaceOpenEditorFile.js.map +0 -1
  240. package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.d.ts +0 -8
  241. package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.d.ts.map +0 -1
  242. package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.js +0 -84
  243. package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.js.map +0 -1
  244. package/src/browser/mcp/tools/findFilesByNameSubstring.ts +0 -93
  245. package/src/browser/mcp/tools/getCurrentFilePath.ts +0 -49
  246. package/src/browser/mcp/tools/getFileTextByPath.ts +0 -97
  247. package/src/browser/mcp/tools/getOpenEditorFileText.ts +0 -50
  248. package/src/browser/mcp/tools/getSelectedText.ts +0 -57
  249. package/src/browser/mcp/tools/replaceOpenEditorFile.ts +0 -80
  250. package/src/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.ts +0 -91
@@ -27,6 +27,12 @@ export class ChatInternalService extends Disposable {
27
27
  private readonly _onChangeSession = new Emitter<string>();
28
28
  public readonly onChangeSession: Event<string> = this._onChangeSession.event;
29
29
 
30
+ private readonly _onCancelRequest = new Emitter<void>();
31
+ public readonly onCancelRequest: Event<void> = this._onCancelRequest.event;
32
+
33
+ private readonly _onRegenerateRequest = new Emitter<void>();
34
+ public readonly onRegenerateRequest: Event<void> = this._onRegenerateRequest.event;
35
+
30
36
  private _latestRequestId: string;
31
37
  public get latestRequestId(): string {
32
38
  return this._latestRequestId;
@@ -52,11 +58,16 @@ export class ChatInternalService extends Disposable {
52
58
  }
53
59
 
54
60
  sendRequest(request: ChatRequestModel, regenerate = false) {
55
- return this.chatManagerService.sendRequest(this.#sessionModel.sessionId, request, regenerate);
61
+ const result = this.chatManagerService.sendRequest(this.#sessionModel.sessionId, request, regenerate);
62
+ if (regenerate) {
63
+ this._onRegenerateRequest.fire();
64
+ }
65
+ return result;
56
66
  }
57
67
 
58
68
  cancelRequest() {
59
69
  this.chatManagerService.cancelRequest(this.#sessionModel.sessionId);
70
+ this._onCancelRequest.fire();
60
71
  }
61
72
 
62
73
  clearSessionModel() {
@@ -40,6 +40,7 @@ import {
40
40
  TokenMCPServerProxyService,
41
41
  } from '../../common';
42
42
  import { LLMContextService, LLMContextServiceToken } from '../../common/llm-context';
43
+ import { ChatAgentPromptProvider } from '../../common/prompts/context-prompt-provider';
43
44
  import { ChatContext } from '../components/ChatContext';
44
45
  import { CodeBlockWrapperInput } from '../components/ChatEditor';
45
46
  import { ChatInput } from '../components/ChatInput';
@@ -50,7 +51,7 @@ import { MessageData, createMessageByAI, createMessageByUser } from '../componen
50
51
  import { WelcomeMessage } from '../components/WelcomeMsg';
51
52
  import { MCPServerProxyService } from '../mcp/mcp-server-proxy.service';
52
53
  import { MCPToolsDialog } from '../mcp/mcp-tools-dialog.view';
53
- import { ChatAgentPromptProvider, ChatViewHeaderRender, TSlashCommandCustomRender } from '../types';
54
+ import { ChatViewHeaderRender, TSlashCommandCustomRender } from '../types';
54
55
 
55
56
  import { ChatRequestModel, ChatSlashCommandItemModel } from './chat-model';
56
57
  import { ChatProxyService } from './chat-proxy.service';
@@ -18,6 +18,11 @@ import { FileContext, LLMContextService, LLMContextServiceToken } from '../../..
18
18
  import { ContextSelector } from './ContextSelector';
19
19
  import styles from './style.module.less';
20
20
 
21
+ const getCollapsedHeight = () => ({ height: 0, opacity: 0 });
22
+ const getRealHeight = (node) => ({ height: node.scrollHeight, opacity: 1 });
23
+ const getCurrentHeight = (node) => ({ height: node.offsetHeight });
24
+ const skipOpacityTransition = (_, event) => (event as TransitionEvent).propertyName === 'height';
25
+
21
26
  export const ChatContext = memo(() => {
22
27
  const [addedFiles, updateAddedFiles] = useState<FileContext[]>([]);
23
28
  const [contextOverlay, toggleContextOverlay] = useState(false);
@@ -76,13 +81,24 @@ export const ChatContext = memo(() => {
76
81
  <Collapse
77
82
  // @ts-ignore
78
83
  expandIcon={({ isActive }) => (isActive ? <Icon icon='down' /> : <Icon icon='right' />)}
79
- defaultActiveKey={['context-panel']}
80
- onChange={() => {}}
84
+ openMotion={{
85
+ motionName: 'rc-collapse-motion',
86
+ onEnterStart: getCollapsedHeight,
87
+ onEnterActive: getRealHeight,
88
+ onLeaveStart: getCurrentHeight,
89
+ onLeaveActive: getCollapsedHeight,
90
+ onEnterEnd: skipOpacityTransition,
91
+ onLeaveEnd: skipOpacityTransition,
92
+ motionDeadline: 100,
93
+ leavedClassName: styles.collapse_hide,
94
+ }}
81
95
  >
82
96
  <Panel
83
97
  header={
84
98
  <div className={styles.context_header}>
85
- <h3 className={styles.chat_context_title}>Context</h3>
99
+ <h3 className={styles.chat_context_title}>
100
+ Context {addedFiles.length > 0 ? ` (${addedFiles.length} files)` : ''}
101
+ </h3>
86
102
  <Popover
87
103
  overlayClassName={styles.popover_icon}
88
104
  id={'ai-context-header-clear'}
@@ -5,6 +5,7 @@
5
5
  padding: 10px;
6
6
  border-radius: 4px;
7
7
  border: 1px solid var(--design-borderColor);
8
+ user-select: none;
8
9
 
9
10
  :global(.rc-collapse) {
10
11
  background-color: transparent !important;
@@ -19,6 +20,16 @@
19
20
 
20
21
  :global(.rc-collapse-expand-icon) {
21
22
  line-height: 1;
23
+
24
+ :global(.kt-icon) {
25
+ display: flex;
26
+ justify-content: center;
27
+ align-items: center;
28
+ }
29
+ }
30
+
31
+ .collapse_hide {
32
+ display: none;
22
33
  }
23
34
 
24
35
  :global(.rc-collapse-header) {
@@ -63,6 +74,7 @@
63
74
  .context_list {
64
75
  font-size: 12px;
65
76
  overflow-y: auto;
77
+ user-select: none;
66
78
 
67
79
  .list_desc {
68
80
  margin: 0px 10px;
@@ -31,9 +31,10 @@ interface Props {
31
31
  language?: string;
32
32
  agentId?: string;
33
33
  command?: string;
34
+ hideInsert?: boolean;
34
35
  }
35
36
  export const CodeEditorWithHighlight = (props: Props) => {
36
- const { input, language, relationId, agentId, command } = props;
37
+ const { input, language, relationId, agentId, command, hideInsert } = props;
37
38
  const ref = React.useRef<HTMLDivElement | null>(null);
38
39
  const monacoCommandRegistry = useInjectable<MonacoCommandRegistry>(MonacoCommandRegistry);
39
40
  const clipboardService = useInjectable<IClipboardService>(IClipboardService);
@@ -101,15 +102,17 @@ export const CodeEditorWithHighlight = (props: Props) => {
101
102
  return (
102
103
  <div className={styles.monaco_wrapper}>
103
104
  <div className={styles.action_toolbar}>
104
- <Popover id={`ai-chat-inser-${useUUID}`} title={localize('aiNative.chat.code.insert')}>
105
- <EnhanceIcon
106
- className={getIcon('insert')}
107
- onClick={() => handleInsert()}
108
- tabIndex={0}
109
- role='button'
110
- ariaLabel={localize('aiNative.chat.code.insert')}
111
- />
112
- </Popover>
105
+ {!hideInsert && (
106
+ <Popover id={`ai-chat-inser-${useUUID}`} title={localize('aiNative.chat.code.insert')}>
107
+ <EnhanceIcon
108
+ className={getIcon('insert')}
109
+ onClick={() => handleInsert()}
110
+ tabIndex={0}
111
+ role='button'
112
+ ariaLabel={localize('aiNative.chat.code.insert')}
113
+ />
114
+ </Popover>
115
+ )}
113
116
  <Popover
114
117
  id={`ai-chat-copy-${useUUID}`}
115
118
  title={localize(isCoping ? 'aiNative.chat.code.copy.success' : 'aiNative.chat.code.copy')}
@@ -17,6 +17,7 @@ interface MarkdownProps {
17
17
  className?: string;
18
18
  fillInIncompleteTokens?: boolean; // 补齐不完整的 token,如代码块或表格
19
19
  markedOptions?: IMarkedOptions;
20
+ hideInsert?: boolean;
20
21
  }
21
22
 
22
23
  export const ChatMarkdown = (props: MarkdownProps) => {
@@ -42,13 +43,14 @@ export const ChatMarkdown = (props: MarkdownProps) => {
42
43
  <div className={styles.code}>
43
44
  <ConfigProvider value={appConfig}>
44
45
  <div className={styles.code_block}>
45
- <div className={styles.code_language}>{language}</div>
46
+ <div className={cls(styles.code_language, 'language-badge')}>{language}</div>
46
47
  <CodeEditorWithHighlight
47
48
  input={code as string}
48
49
  language={language}
49
50
  relationId={props.relationId || ''}
50
51
  agentId={props.agentId}
51
52
  command={props.command}
53
+ hideInsert={props.hideInsert}
52
54
  />
53
55
  </div>
54
56
  </ConfigProvider>
@@ -149,8 +149,8 @@ const TreeRenderer = (props: { treeData: IChatResponseProgressFileTreeData }) =>
149
149
  );
150
150
  };
151
151
 
152
- const ToolCallRender = (props: { toolCall: IChatToolContent['content'] }) => {
153
- const { toolCall } = props;
152
+ const ToolCallRender = (props: { toolCall: IChatToolContent['content']; messageId?: string }) => {
153
+ const { toolCall, messageId } = props;
154
154
  const chatAgentViewService = useInjectable<IChatAgentViewService>(ChatAgentViewServiceToken);
155
155
  const [node, setNode] = useState<React.JSX.Element | null>(null);
156
156
 
@@ -158,7 +158,7 @@ const ToolCallRender = (props: { toolCall: IChatToolContent['content'] }) => {
158
158
  const config = chatAgentViewService.getChatComponent('toolCall');
159
159
  if (config) {
160
160
  const { component: Component, initialProps } = config;
161
- setNode(<Component {...initialProps} value={toolCall} />);
161
+ setNode(<Component {...initialProps} value={toolCall} messageId={messageId} />);
162
162
  return;
163
163
  }
164
164
  setNode(
@@ -169,14 +169,14 @@ const ToolCallRender = (props: { toolCall: IChatToolContent['content'] }) => {
169
169
  );
170
170
  const deferred = chatAgentViewService.getChatComponentDeferred('toolCall')!;
171
171
  deferred.promise.then(({ component: Component, initialProps }) => {
172
- setNode(<Component {...initialProps} value={toolCall} />);
172
+ setNode(<Component {...initialProps} value={toolCall} messageId={messageId} />);
173
173
  });
174
174
  }, [toolCall.state]);
175
175
 
176
176
  return node;
177
177
  };
178
178
 
179
- const ComponentRender = (props: { component: string; value?: unknown }) => {
179
+ const ComponentRender = (props: { component: string; value?: unknown; messageId?: string }) => {
180
180
  const chatAgentViewService = useInjectable<IChatAgentViewService>(ChatAgentViewServiceToken);
181
181
  const [node, setNode] = useState<React.JSX.Element | null>(null);
182
182
 
@@ -184,7 +184,7 @@ const ComponentRender = (props: { component: string; value?: unknown }) => {
184
184
  const config = chatAgentViewService.getChatComponent(props.component);
185
185
  if (config) {
186
186
  const { component: Component, initialProps } = config;
187
- setNode(<Component {...initialProps} value={props.value} />);
187
+ setNode(<Component {...initialProps} value={props.value} messageId={props.messageId} />);
188
188
  return;
189
189
  }
190
190
  setNode(
@@ -224,7 +224,6 @@ export const ChatReply = (props: IChatReplyProps) => {
224
224
  const chatApiService = useInjectable<ChatService>(ChatServiceToken);
225
225
  const chatAgentService = useInjectable<IChatAgentService>(IChatAgentService);
226
226
  const chatRenderRegistry = useInjectable<ChatRenderRegistry>(ChatRenderRegistryToken);
227
-
228
227
  useEffect(() => {
229
228
  const disposableCollection = new DisposableCollection();
230
229
 
@@ -298,12 +297,6 @@ export const ChatReply = (props: IChatReplyProps) => {
298
297
  </div>
299
298
  );
300
299
 
301
- const renderComponent = (componentId: string, value: unknown) => (
302
- <ComponentRender component={componentId} value={value} />
303
- );
304
-
305
- const renderToolCall = (toolCall: IChatToolContent['content']) => <ToolCallRender toolCall={toolCall} />;
306
-
307
300
  const contentNode = React.useMemo(
308
301
  () =>
309
302
  request.response.responseContents.map((item, index) => {
@@ -313,9 +306,9 @@ export const ChatReply = (props: IChatReplyProps) => {
313
306
  } else if (item.kind === 'treeData') {
314
307
  node = renderTreeData(item.treeData);
315
308
  } else if (item.kind === 'component') {
316
- node = renderComponent(item.component, item.value);
309
+ node = <ComponentRender component={item.component} value={item.value} messageId={msgId} />;
317
310
  } else if (item.kind === 'toolCall') {
318
- node = renderToolCall(item.content);
311
+ node = <ToolCallRender toolCall={item.content} messageId={msgId} />;
319
312
  } else {
320
313
  node = renderMarkdown(item.content);
321
314
  }
@@ -1,20 +1,27 @@
1
1
  import cls from 'classnames';
2
2
  import React, { useState } from 'react';
3
3
 
4
+ import { useInjectable } from '@opensumi/ide-core-browser';
4
5
  import { Icon } from '@opensumi/ide-core-browser/lib/components';
5
6
  import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
6
7
  import { IChatToolContent, uuid } from '@opensumi/ide-core-common';
7
8
 
9
+ import { IMCPServerRegistry, TokenMCPServerRegistry } from '../types';
10
+
8
11
  import { CodeEditorWithHighlight } from './ChatEditor';
9
12
  import styles from './ChatToolRender.module.less';
10
13
 
11
- export const ChatToolRender = (props: { value: IChatToolContent['content'] }) => {
12
- const { value } = props;
14
+ export const ChatToolRender = (props: { value: IChatToolContent['content']; messageId?: string }) => {
15
+ const { value, messageId } = props;
13
16
  const [isExpanded, setIsExpanded] = useState(false);
17
+ const mcpServerFeatureRegistry = useInjectable<IMCPServerRegistry>(TokenMCPServerRegistry);
14
18
 
15
19
  if (!value || !value.function || !value.id) {
16
20
  return null;
17
21
  }
22
+ const label = mcpServerFeatureRegistry.getMCPTool(value.function.name)?.label || value.function.name;
23
+
24
+ const ToolComponent = mcpServerFeatureRegistry.getToolComponent(value.function.name);
18
25
 
19
26
  const getStateInfo = (state?: string): { label: string; icon: React.ReactNode } => {
20
27
  switch (state) {
@@ -22,11 +29,22 @@ export const ChatToolRender = (props: { value: IChatToolContent['content'] }) =>
22
29
  case 'streaming':
23
30
  return { label: 'Generating', icon: <Loading /> };
24
31
  case 'complete':
25
- return { label: 'Complete', icon: <Icon iconClass="codicon codicon-check" /> };
32
+ return { label: 'Complete', icon: <Icon iconClass='codicon codicon-check' /> };
26
33
  case 'result':
27
- return { label: 'Result Ready', icon: <Icon iconClass="codicon codicon-check-all" /> };
34
+ return { label: 'Result Ready', icon: <Icon iconClass='codicon codicon-check-all' /> };
28
35
  default:
29
- return { label: state || 'Unknown', icon: <Icon iconClass="codicon codicon-question" /> };
36
+ return { label: state || 'Unknown', icon: <Icon iconClass='codicon codicon-question' /> };
37
+ }
38
+ };
39
+ const getParsedArgs = () => {
40
+ try {
41
+ // TODO: 流式输出中function_call的参数还不完整,需要等待complete状态
42
+ if (value.state !== 'complete' && value.state !== 'result') {
43
+ return {};
44
+ }
45
+ return JSON.parse(value.function?.arguments || '{}');
46
+ } catch (error) {
47
+ return {};
30
48
  }
31
49
  };
32
50
 
@@ -36,12 +54,21 @@ export const ChatToolRender = (props: { value: IChatToolContent['content'] }) =>
36
54
 
37
55
  const stateInfo = getStateInfo(value.state);
38
56
 
39
- return (
57
+ return ToolComponent && (value.state === 'complete' || value.state === 'result') ? (
58
+ <ToolComponent
59
+ state={value.state}
60
+ args={getParsedArgs()}
61
+ result={value.result}
62
+ index={value.index}
63
+ messageId={messageId}
64
+ toolCallId={value.id}
65
+ />
66
+ ) : (
40
67
  <div className={styles['chat-tool-render']}>
41
68
  <div className={styles['tool-header']} onClick={toggleExpand}>
42
69
  <div className={styles['tool-name']}>
43
70
  <span className={cls(styles['expand-icon'], { [styles.expanded]: isExpanded })}>▶</span>
44
- {value?.function?.name}
71
+ {label}
45
72
  </div>
46
73
  {value.state && (
47
74
  <div className={styles['tool-state']}>
@@ -54,21 +81,13 @@ export const ChatToolRender = (props: { value: IChatToolContent['content'] }) =>
54
81
  {value?.function?.arguments && (
55
82
  <div className={styles['tool-arguments']}>
56
83
  <div className={styles['section-label']}>Arguments</div>
57
- <CodeEditorWithHighlight
58
- input={value?.function?.arguments}
59
- language={'json'}
60
- relationId={uuid(4)}
61
- />
84
+ <CodeEditorWithHighlight input={value?.function?.arguments} language={'json'} relationId={uuid(4)} />
62
85
  </div>
63
86
  )}
64
87
  {value?.result && (
65
88
  <div className={styles['tool-result']}>
66
89
  <div className={styles['section-label']}>Result</div>
67
- <CodeEditorWithHighlight
68
- input={value.result}
69
- language={'json'}
70
- relationId={uuid(4)}
71
- />
90
+ <CodeEditorWithHighlight input={value.result} language={'json'} relationId={uuid(4)} />
72
91
  </div>
73
92
  )}
74
93
  </div>
@@ -253,7 +253,7 @@
253
253
  .editor {
254
254
  border-radius: 8px;
255
255
  font-size: 12px;
256
- padding: 32px 8px 8px 8px;
256
+ padding: 28px 8px 8px 8px;
257
257
  line-height: 18px;
258
258
  &::-webkit-scrollbar {
259
259
  width: auto;
@@ -265,7 +265,7 @@
265
265
  display: flex;
266
266
  position: absolute;
267
267
  right: 8px;
268
- top: 6px;
268
+ top: 2px;
269
269
  z-index: 100;
270
270
  height: 20px;
271
271
  align-items: center;
@@ -300,6 +300,7 @@
300
300
  background-color: var(--design-language-background);
301
301
  border-radius: 8px 0px 8px 0;
302
302
  color: var(--design-text-foreground);
303
+ font-size: 12px;
303
304
  }
304
305
  }
305
306
 
@@ -27,32 +27,40 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
27
27
 
28
28
  private isAutoCollecting = false;
29
29
 
30
- private contextFiles: Map<string, FileContext> = new Map();
30
+ private contextFiles: FileContext[] = [];
31
+
32
+ private maxFiles: number = 10; // 上下文的最大长度限制
31
33
 
32
34
  private onDidContextFilesChangeEmitter = new Emitter<FileContext[]>();
33
35
  onDidContextFilesChangeEvent = this.onDidContextFilesChangeEmitter.event;
34
36
 
35
37
  addFileToContext(uri: URI, selection?: [number, number], isManual = true): void {
36
- this.contextFiles.set(uri.toString(), {
37
- uri,
38
- selection,
39
- isManual,
40
- });
38
+ this.removeFileFromContext(uri);
39
+
40
+ this.contextFiles.push({ uri, selection, isManual });
41
+
42
+ if (this.contextFiles.length > this.maxFiles) {
43
+ this.contextFiles.shift();
44
+ }
45
+
41
46
  this.onDidContextFilesChangeEmitter.fire(this.getAllContextFiles());
42
47
  }
43
48
 
44
49
  cleanFileContext() {
45
- this.contextFiles.clear();
50
+ this.contextFiles = [];
46
51
  this.onDidContextFilesChangeEmitter.fire(this.getAllContextFiles());
47
52
  }
48
53
 
49
54
  private getAllContextFiles() {
50
- return Array.from(this.contextFiles.values());
55
+ return [...this.contextFiles];
51
56
  }
52
57
 
53
58
  removeFileFromContext(uri: URI): void {
54
- this.contextFiles.delete(uri.toString());
55
- this.onDidContextFilesChangeEmitter.fire(this.getAllContextFiles());
59
+ const index = this.contextFiles.findIndex((file) => file.uri.toString() === uri.toString());
60
+ if (index > -1) {
61
+ this.contextFiles.splice(index, 1);
62
+ this.onDidContextFilesChangeEmitter.fire(this.getAllContextFiles());
63
+ }
56
64
  }
57
65
 
58
66
  startAutoCollection(): void {
@@ -65,18 +73,16 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
65
73
  }
66
74
 
67
75
  private startAutoCollectionInternal(): void {
68
- // 文件打开
69
76
  this.disposables.push(
70
77
  this.eventBus.on(EditorDocumentModelCreationEvent, (event) => {
71
78
  if (event.payload.uri.scheme !== 'file') {
72
79
  return;
73
80
  }
74
- // TODO: 是否自动添加文件到上下文?
81
+ // FIXME: 暂时不自动添加
75
82
  // this.addFileToContext(event.payload.uri);
76
83
  }),
77
84
  );
78
85
 
79
- // 删除
80
86
  this.disposables.push(
81
87
  this.eventBus.on(EditorDocumentModelRemovalEvent, (event) => {
82
88
  if (event.payload.scheme !== 'file') {
@@ -85,16 +91,15 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
85
91
  }),
86
92
  );
87
93
 
88
- // 保存
89
94
  this.disposables.push(
90
95
  this.eventBus.on(EditorDocumentModelSavedEvent, (event) => {
91
96
  if (event.payload.scheme !== 'file') {
92
97
  return;
93
98
  }
99
+ // TODO: 保存文件的逻辑
94
100
  }),
95
101
  );
96
102
 
97
- // 光标选中
98
103
  this.disposables.push(
99
104
  this.eventBus.on(EditorSelectionChangeEvent, (event) => {
100
105
  if (event.payload.selections.length > 0) {
@@ -102,9 +107,9 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
102
107
  event.payload.selections[0].selectionStartLineNumber,
103
108
  event.payload.selections[0].positionLineNumber,
104
109
  ].sort() as [number, number];
110
+
105
111
  if (selection[0] === selection[1]) {
106
- // TODO: 是否自动添加文件到上下文?
107
- // this.addFileToContext(event.payload.editorUri, undefined);
112
+ this.addFileToContext(event.payload.editorUri, undefined);
108
113
  } else {
109
114
  this.addFileToContext(
110
115
  event.payload.editorUri,
@@ -124,8 +129,15 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
124
129
  const files = this.getAllContextFiles();
125
130
  const recentlyViewFiles = files
126
131
  .filter((v) => !v.selection)
127
- .map((file) => URI.file(this.appConfig.workspaceDir).relative(file.uri)!.toString())
132
+ .map((file) => {
133
+ const relativePath = URI.file(this.appConfig.workspaceDir).relative(file.uri);
134
+ if (relativePath) {
135
+ return relativePath.toString();
136
+ }
137
+ return file.uri.parent.toString();
138
+ })
128
139
  .filter(Boolean);
140
+
129
141
  const attachedFiles = files
130
142
  .filter((v) => v.selection)
131
143
  .map((file) => {
@@ -30,6 +30,7 @@ import {
30
30
  } from '../common';
31
31
  import { LLMContextServiceToken } from '../common/llm-context';
32
32
  import { MCPServerManager, MCPServerManagerPath } from '../common/mcp-server-manager';
33
+ import { ChatAgentPromptProvider, DefaultChatAgentPromptProvider } from '../common/prompts/context-prompt-provider';
33
34
 
34
35
  import { AINativeBrowserContribution } from './ai-core.contribution';
35
36
  import { ChatAgentService } from './chat/chat-agent.service';
@@ -57,16 +58,13 @@ import { LanguageParserService } from './languages/service';
57
58
  import { MCPServerProxyService } from './mcp/mcp-server-proxy.service';
58
59
  import { MCPServerRegistry } from './mcp/mcp-server.feature.registry';
59
60
  import { CreateNewFileWithTextTool } from './mcp/tools/createNewFileWithText';
60
- import { FindFilesByNameSubstringTool } from './mcp/tools/findFilesByNameSubstring';
61
- import { GetCurrentFilePathTool } from './mcp/tools/getCurrentFilePath';
61
+ import { EditFileTool } from './mcp/tools/editFile';
62
+ import { FileSearchTool } from './mcp/tools/fileSearch';
62
63
  import { GetDiagnosticsByPathTool } from './mcp/tools/getDiagnosticsByPath';
63
- import { GetFileTextByPathTool } from './mcp/tools/getFileTextByPath';
64
64
  import { GetOpenEditorFileDiagnosticsTool } from './mcp/tools/getOpenEditorFileDiagnostics';
65
- import { GetOpenEditorFileTextTool } from './mcp/tools/getOpenEditorFileText';
66
- import { GetSelectedTextTool } from './mcp/tools/getSelectedText';
65
+ import { GrepSearchTool } from './mcp/tools/grepSearch';
67
66
  import { ListDirTool } from './mcp/tools/listDir';
68
67
  import { ReadFileTool } from './mcp/tools/readFile';
69
- import { ReplaceOpenEditorFileByDiffPreviewerTool } from './mcp/tools/replaceOpenEditorFileByDiffPreviewer';
70
68
  import { RunTerminalCommandTool } from './mcp/tools/runTerminalCmd';
71
69
  import { AINativePreferencesContribution } from './preferences';
72
70
  import { AINativeCoreContribution, MCPServerContribution, TokenMCPServerRegistry } from './types';
@@ -97,16 +95,13 @@ export class AINativeModule extends BrowserModule {
97
95
  // MCP Server Contributions START
98
96
  ListDirTool,
99
97
  ReadFileTool,
98
+ EditFileTool,
100
99
  CreateNewFileWithTextTool,
101
- GetSelectedTextTool,
102
100
  GetOpenEditorFileDiagnosticsTool,
103
- GetOpenEditorFileTextTool,
104
- GetFileTextByPathTool,
105
- GetCurrentFilePathTool,
106
- FindFilesByNameSubstringTool,
101
+ FileSearchTool,
102
+ GrepSearchTool,
107
103
  GetDiagnosticsByPathTool,
108
104
  RunTerminalCommandTool,
109
- ReplaceOpenEditorFileByDiffPreviewerTool,
110
105
  // MCP Server Contributions END
111
106
 
112
107
  // Context Service
@@ -196,6 +191,10 @@ export class AINativeModule extends BrowserModule {
196
191
  token: InlineDiffService,
197
192
  useClass: InlineDiffService,
198
193
  },
194
+ {
195
+ token: ChatAgentPromptProvider,
196
+ useClass: DefaultChatAgentPromptProvider,
197
+ },
199
198
  ];
200
199
 
201
200
  backServices = [