@opensumi/ide-ai-native 3.8.1-next-1741250387.0 → 3.8.1-next-1741251026.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 (325) hide show
  1. package/lib/browser/ai-core.contextkeys.d.ts +1 -1
  2. package/lib/browser/ai-core.contextkeys.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contextkeys.js +1 -1
  4. package/lib/browser/ai-core.contextkeys.js.map +1 -1
  5. package/lib/browser/ai-core.contribution.d.ts +5 -0
  6. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  7. package/lib/browser/ai-core.contribution.js +71 -9
  8. package/lib/browser/ai-core.contribution.js.map +1 -1
  9. package/lib/browser/chat/chat-agent.service.d.ts +11 -3
  10. package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-agent.service.js +43 -5
  12. package/lib/browser/chat/chat-agent.service.js.map +1 -1
  13. package/lib/browser/chat/chat-manager.service.d.ts +1 -0
  14. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  15. package/lib/browser/chat/chat-manager.service.js +6 -8
  16. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  17. package/lib/browser/chat/chat-model.d.ts +4 -1
  18. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  19. package/lib/browser/chat/chat-model.js +57 -2
  20. package/lib/browser/chat/chat-model.js.map +1 -1
  21. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  22. package/lib/browser/chat/chat-proxy.service.js +13 -6
  23. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  24. package/lib/browser/chat/chat.api.service.d.ts +1 -2
  25. package/lib/browser/chat/chat.api.service.d.ts.map +1 -1
  26. package/lib/browser/chat/chat.api.service.js +0 -4
  27. package/lib/browser/chat/chat.api.service.js.map +1 -1
  28. package/lib/browser/chat/chat.internal.service.d.ts +2 -0
  29. package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
  30. package/lib/browser/chat/chat.internal.service.js +3 -0
  31. package/lib/browser/chat/chat.internal.service.js.map +1 -1
  32. package/lib/browser/chat/chat.module.less +1 -2
  33. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  34. package/lib/browser/chat/chat.view.js +46 -29
  35. package/lib/browser/chat/chat.view.js.map +1 -1
  36. package/lib/browser/components/ChatContext/index.js +2 -2
  37. package/lib/browser/components/ChatContext/index.js.map +1 -1
  38. package/lib/browser/components/ChatInput.d.ts.map +1 -1
  39. package/lib/browser/components/ChatInput.js +29 -1
  40. package/lib/browser/components/ChatInput.js.map +1 -1
  41. package/lib/browser/components/ChatReply.js +6 -1
  42. package/lib/browser/components/ChatReply.js.map +1 -1
  43. package/lib/browser/components/ChatThinking.d.ts +0 -2
  44. package/lib/browser/components/ChatThinking.d.ts.map +1 -1
  45. package/lib/browser/components/ChatThinking.js +2 -10
  46. package/lib/browser/components/ChatThinking.js.map +1 -1
  47. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  48. package/lib/browser/components/ChatToolRender.js +2 -3
  49. package/lib/browser/components/ChatToolRender.js.map +1 -1
  50. package/lib/browser/components/WelcomeMsg.js +1 -1
  51. package/lib/browser/components/WelcomeMsg.js.map +1 -1
  52. package/lib/browser/components/chat-history.module.less +2 -1
  53. package/lib/browser/components/components.module.less +22 -0
  54. package/lib/browser/context/llm-context.service.d.ts +18 -5
  55. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  56. package/lib/browser/context/llm-context.service.js +80 -47
  57. package/lib/browser/context/llm-context.service.js.map +1 -1
  58. package/lib/browser/contrib/inline-completions/inline-completions.controller.js +1 -1
  59. package/lib/browser/contrib/inline-completions/inline-completions.controller.js.map +1 -1
  60. package/lib/browser/contrib/inline-completions/prompt/matcher.js +2 -2
  61. package/lib/browser/contrib/inline-completions/prompt/similarSnippets.d.ts +1 -1
  62. package/lib/browser/contrib/inline-completions/prompt/similarSnippets.js +2 -2
  63. package/lib/browser/contrib/intelligent-completions/index.d.ts +2 -1
  64. package/lib/browser/contrib/intelligent-completions/index.d.ts.map +1 -1
  65. package/lib/browser/contrib/intelligent-completions/index.js +4 -1
  66. package/lib/browser/contrib/intelligent-completions/index.js.map +1 -1
  67. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +2 -2
  68. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -1
  69. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
  70. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +6 -5
  71. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
  72. package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.d.ts.map +1 -1
  73. package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js +4 -2
  74. package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js.map +1 -1
  75. package/lib/browser/contrib/intelligent-completions/view/default.d.ts.map +1 -1
  76. package/lib/browser/contrib/intelligent-completions/view/default.js +23 -11
  77. package/lib/browser/contrib/intelligent-completions/view/default.js.map +1 -1
  78. package/lib/browser/index.d.ts.map +1 -1
  79. package/lib/browser/index.js +4 -0
  80. package/lib/browser/index.js.map +1 -1
  81. package/lib/browser/layout/layout.module.less +4 -4
  82. package/lib/browser/mcp/base-apply.service.d.ts +26 -11
  83. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  84. package/lib/browser/mcp/base-apply.service.js +255 -103
  85. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  86. package/lib/browser/mcp/config/components/mcp-config.module.less +178 -0
  87. package/lib/browser/mcp/config/components/mcp-config.view.d.ts +3 -0
  88. package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -0
  89. package/lib/browser/mcp/config/components/mcp-config.view.js +150 -0
  90. package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -0
  91. package/lib/browser/mcp/config/components/mcp-server-form.d.ts +16 -0
  92. package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +1 -0
  93. package/lib/browser/mcp/config/components/mcp-server-form.js +84 -0
  94. package/lib/browser/mcp/config/components/mcp-server-form.js.map +1 -0
  95. package/lib/browser/mcp/config/components/mcp-server-form.module.less +78 -0
  96. package/lib/browser/mcp/config/mcp-config.commands.d.ts +10 -0
  97. package/lib/browser/mcp/config/mcp-config.commands.d.ts.map +1 -0
  98. package/lib/browser/mcp/config/mcp-config.commands.js +35 -0
  99. package/lib/browser/mcp/config/mcp-config.commands.js.map +1 -0
  100. package/lib/browser/mcp/config/mcp-config.contribution.d.ts +16 -0
  101. package/lib/browser/mcp/config/mcp-config.contribution.d.ts.map +1 -0
  102. package/lib/browser/mcp/config/mcp-config.contribution.js +62 -0
  103. package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -0
  104. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +6 -0
  105. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  106. package/lib/browser/mcp/mcp-server-proxy.service.js +10 -1
  107. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  108. package/lib/browser/mcp/mcp-server.feature.registry.d.ts +8 -0
  109. package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
  110. package/lib/browser/mcp/mcp-server.feature.registry.js +28 -3
  111. package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
  112. package/lib/browser/mcp/tools/components/EditFile.d.ts.map +1 -1
  113. package/lib/browser/mcp/tools/components/EditFile.js +15 -9
  114. package/lib/browser/mcp/tools/components/EditFile.js.map +1 -1
  115. package/lib/browser/mcp/tools/components/ExpandableFileList.d.ts +13 -0
  116. package/lib/browser/mcp/tools/components/ExpandableFileList.d.ts.map +1 -0
  117. package/lib/browser/mcp/tools/components/{SearchResult.js → ExpandableFileList.js} +29 -19
  118. package/lib/browser/mcp/tools/components/ExpandableFileList.js.map +1 -0
  119. package/lib/browser/mcp/tools/components/Terminal.d.ts.map +1 -1
  120. package/lib/browser/mcp/tools/components/Terminal.js +10 -2
  121. package/lib/browser/mcp/tools/components/Terminal.js.map +1 -1
  122. package/lib/browser/mcp/tools/components/index.module.less +4 -0
  123. package/lib/browser/mcp/tools/createNewFileWithText.d.ts +1 -0
  124. package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
  125. package/lib/browser/mcp/tools/createNewFileWithText.js +19 -11
  126. package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
  127. package/lib/browser/mcp/tools/fileSearch.d.ts +1 -0
  128. package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -1
  129. package/lib/browser/mcp/tools/fileSearch.js +14 -5
  130. package/lib/browser/mcp/tools/fileSearch.js.map +1 -1
  131. package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
  132. package/lib/browser/mcp/tools/getDiagnosticsByPath.js +1 -0
  133. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  134. package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -1
  135. package/lib/browser/mcp/tools/grepSearch.js +6 -3
  136. package/lib/browser/mcp/tools/grepSearch.js.map +1 -1
  137. package/lib/browser/mcp/tools/handlers/EditFile.js +1 -1
  138. package/lib/browser/mcp/tools/handlers/EditFile.js.map +1 -1
  139. package/lib/browser/mcp/tools/handlers/ListDir.d.ts +1 -0
  140. package/lib/browser/mcp/tools/handlers/ListDir.d.ts.map +1 -1
  141. package/lib/browser/mcp/tools/handlers/ListDir.js +3 -0
  142. package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
  143. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
  144. package/lib/browser/mcp/tools/handlers/RunCommand.js +2 -0
  145. package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
  146. package/lib/browser/mcp/tools/listDir.d.ts +1 -0
  147. package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
  148. package/lib/browser/mcp/tools/listDir.js +35 -4
  149. package/lib/browser/mcp/tools/listDir.js.map +1 -1
  150. package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -1
  151. package/lib/browser/mcp/tools/runTerminalCmd.js +1 -0
  152. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  153. package/lib/browser/model/msg-history-manager.d.ts +2 -2
  154. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  155. package/lib/browser/model/msg-history-manager.js +4 -10
  156. package/lib/browser/model/msg-history-manager.js.map +1 -1
  157. package/lib/browser/preferences/schema.d.ts.map +1 -1
  158. package/lib/browser/preferences/schema.js +22 -2
  159. package/lib/browser/preferences/schema.js.map +1 -1
  160. package/lib/browser/types.d.ts +4 -0
  161. package/lib/browser/types.d.ts.map +1 -1
  162. package/lib/browser/widget/inline-chat/inline-chat-controller.d.ts.map +1 -1
  163. package/lib/browser/widget/inline-chat/inline-chat-controller.js +6 -1
  164. package/lib/browser/widget/inline-chat/inline-chat-controller.js.map +1 -1
  165. package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts.map +1 -1
  166. package/lib/browser/widget/inline-diff/inline-diff-manager.js +68 -8
  167. package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +1 -1
  168. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +10 -4
  169. package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
  170. package/lib/browser/widget/inline-diff/inline-diff-previewer.js +14 -3
  171. package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
  172. package/lib/browser/widget/inline-diff/inline-diff-widget.module.less +25 -4
  173. package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +3 -3
  174. package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
  175. package/lib/browser/widget/inline-diff/inline-diff.controller.js +10 -5
  176. package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
  177. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +46 -17
  178. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  179. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +110 -53
  180. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  181. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +4 -0
  182. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  183. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +26 -1
  184. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  185. package/lib/common/index.d.ts +13 -4
  186. package/lib/common/index.d.ts.map +1 -1
  187. package/lib/common/index.js +5 -1
  188. package/lib/common/index.js.map +1 -1
  189. package/lib/common/llm-context.d.ts +13 -9
  190. package/lib/common/llm-context.d.ts.map +1 -1
  191. package/lib/common/llm-context.js.map +1 -1
  192. package/lib/common/mcp-server-manager.d.ts +17 -1
  193. package/lib/common/mcp-server-manager.d.ts.map +1 -1
  194. package/lib/common/mcp-server-manager.js.map +1 -1
  195. package/lib/common/model.d.ts +12 -0
  196. package/lib/common/model.d.ts.map +1 -0
  197. package/lib/common/model.js +83 -0
  198. package/lib/common/model.js.map +1 -0
  199. package/lib/common/prompts/context-prompt-provider.d.ts +4 -3
  200. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  201. package/lib/common/prompts/context-prompt-provider.js +33 -22
  202. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  203. package/lib/common/tool-invocation-registry.d.ts +2 -2
  204. package/lib/common/tool-invocation-registry.d.ts.map +1 -1
  205. package/lib/common/tool-invocation-registry.js +1 -1
  206. package/lib/common/tool-invocation-registry.js.map +1 -1
  207. package/lib/common/types.d.ts +8 -0
  208. package/lib/common/types.d.ts.map +1 -1
  209. package/lib/common/utils.d.ts.map +1 -1
  210. package/lib/common/utils.js +2 -1
  211. package/lib/common/utils.js.map +1 -1
  212. package/lib/node/anthropic/anthropic-language-model.d.ts +3 -1
  213. package/lib/node/anthropic/anthropic-language-model.d.ts.map +1 -1
  214. package/lib/node/anthropic/anthropic-language-model.js +6 -2
  215. package/lib/node/anthropic/anthropic-language-model.js.map +1 -1
  216. package/lib/node/base-language-model.d.ts +6 -3
  217. package/lib/node/base-language-model.d.ts.map +1 -1
  218. package/lib/node/base-language-model.js +14 -31
  219. package/lib/node/base-language-model.js.map +1 -1
  220. package/lib/node/deepseek/deepseek-language-model.d.ts +3 -1
  221. package/lib/node/deepseek/deepseek-language-model.d.ts.map +1 -1
  222. package/lib/node/deepseek/deepseek-language-model.js +6 -2
  223. package/lib/node/deepseek/deepseek-language-model.js.map +1 -1
  224. package/lib/node/mcp/sumi-mcp-server.d.ts +17 -3
  225. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  226. package/lib/node/mcp/sumi-mcp-server.js +59 -6
  227. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  228. package/lib/node/mcp-server-manager-impl.d.ts +4 -3
  229. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  230. package/lib/node/mcp-server-manager-impl.js +26 -6
  231. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  232. package/lib/node/mcp-server.d.ts +5 -16
  233. package/lib/node/mcp-server.d.ts.map +1 -1
  234. package/lib/node/mcp-server.js +12 -6
  235. package/lib/node/mcp-server.js.map +1 -1
  236. package/lib/node/openai/openai-language-model.d.ts +4 -2
  237. package/lib/node/openai/openai-language-model.d.ts.map +1 -1
  238. package/lib/node/openai/openai-language-model.js +6 -4
  239. package/lib/node/openai/openai-language-model.js.map +1 -1
  240. package/lib/node/openai-compatible/openai-compatible-language-model.d.ts +10 -0
  241. package/lib/node/openai-compatible/openai-compatible-language-model.d.ts.map +1 -0
  242. package/lib/node/openai-compatible/openai-compatible-language-model.js +32 -0
  243. package/lib/node/openai-compatible/openai-compatible-language-model.js.map +1 -0
  244. package/package.json +27 -26
  245. package/src/browser/ai-core.contextkeys.ts +3 -3
  246. package/src/browser/ai-core.contribution.ts +89 -12
  247. package/src/browser/chat/chat-agent.service.ts +53 -9
  248. package/src/browser/chat/chat-manager.service.ts +10 -8
  249. package/src/browser/chat/chat-model.ts +63 -5
  250. package/src/browser/chat/chat-proxy.service.ts +16 -8
  251. package/src/browser/chat/chat.api.service.ts +1 -5
  252. package/src/browser/chat/chat.internal.service.ts +4 -0
  253. package/src/browser/chat/chat.module.less +1 -2
  254. package/src/browser/chat/chat.view.tsx +63 -69
  255. package/src/browser/components/ChatContext/index.tsx +2 -2
  256. package/src/browser/components/ChatInput.tsx +81 -6
  257. package/src/browser/components/ChatReply.tsx +6 -6
  258. package/src/browser/components/ChatThinking.tsx +3 -9
  259. package/src/browser/components/ChatToolRender.tsx +1 -2
  260. package/src/browser/components/WelcomeMsg.tsx +1 -1
  261. package/src/browser/components/chat-history.module.less +2 -1
  262. package/src/browser/components/components.module.less +22 -0
  263. package/src/browser/context/llm-context.service.ts +93 -54
  264. package/src/browser/contrib/inline-completions/inline-completions.controller.ts +1 -1
  265. package/src/browser/contrib/inline-completions/prompt/matcher.ts +2 -2
  266. package/src/browser/contrib/inline-completions/prompt/similarSnippets.ts +2 -2
  267. package/src/browser/contrib/intelligent-completions/index.ts +5 -1
  268. package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +3 -3
  269. package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +7 -6
  270. package/src/browser/contrib/intelligent-completions/view/code-edits-previewer.ts +4 -2
  271. package/src/browser/contrib/intelligent-completions/view/default.ts +34 -19
  272. package/src/browser/index.ts +4 -0
  273. package/src/browser/layout/layout.module.less +4 -4
  274. package/src/browser/mcp/base-apply.service.ts +306 -109
  275. package/src/browser/mcp/config/components/mcp-config.module.less +178 -0
  276. package/src/browser/mcp/config/components/mcp-config.view.tsx +215 -0
  277. package/src/browser/mcp/config/components/mcp-server-form.module.less +78 -0
  278. package/src/browser/mcp/config/components/mcp-server-form.tsx +144 -0
  279. package/src/browser/mcp/config/mcp-config.commands.ts +29 -0
  280. package/src/browser/mcp/config/mcp-config.contribution.ts +65 -0
  281. package/src/browser/mcp/mcp-server-proxy.service.ts +14 -2
  282. package/src/browser/mcp/mcp-server.feature.registry.ts +35 -4
  283. package/src/browser/mcp/tools/components/EditFile.tsx +16 -9
  284. package/src/browser/mcp/tools/components/ExpandableFileList.tsx +133 -0
  285. package/src/browser/mcp/tools/components/Terminal.tsx +13 -2
  286. package/src/browser/mcp/tools/components/index.module.less +4 -0
  287. package/src/browser/mcp/tools/createNewFileWithText.ts +21 -12
  288. package/src/browser/mcp/tools/fileSearch.ts +14 -4
  289. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -0
  290. package/src/browser/mcp/tools/grepSearch.ts +6 -3
  291. package/src/browser/mcp/tools/handlers/EditFile.ts +1 -1
  292. package/src/browser/mcp/tools/handlers/ListDir.ts +4 -0
  293. package/src/browser/mcp/tools/handlers/RunCommand.ts +2 -0
  294. package/src/browser/mcp/tools/listDir.ts +36 -5
  295. package/src/browser/mcp/tools/runTerminalCmd.ts +1 -0
  296. package/src/browser/model/msg-history-manager.ts +5 -11
  297. package/src/browser/preferences/schema.ts +22 -2
  298. package/src/browser/types.ts +1 -0
  299. package/src/browser/widget/inline-chat/inline-chat-controller.ts +5 -1
  300. package/src/browser/widget/inline-diff/inline-diff-manager.tsx +143 -21
  301. package/src/browser/widget/inline-diff/inline-diff-previewer.ts +25 -7
  302. package/src/browser/widget/inline-diff/inline-diff-widget.module.less +25 -4
  303. package/src/browser/widget/inline-diff/inline-diff.controller.ts +16 -8
  304. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +139 -68
  305. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +30 -1
  306. package/src/common/index.ts +15 -4
  307. package/src/common/llm-context.ts +10 -4
  308. package/src/common/mcp-server-manager.ts +17 -1
  309. package/src/common/model.ts +90 -0
  310. package/src/common/prompts/context-prompt-provider.ts +38 -29
  311. package/src/common/tool-invocation-registry.ts +2 -2
  312. package/src/common/types.ts +8 -0
  313. package/src/common/utils.ts +3 -1
  314. package/src/node/anthropic/anthropic-language-model.ts +7 -2
  315. package/src/node/base-language-model.ts +25 -38
  316. package/src/node/deepseek/deepseek-language-model.ts +7 -2
  317. package/src/node/mcp/sumi-mcp-server.ts +67 -9
  318. package/src/node/mcp-server-manager-impl.ts +30 -9
  319. package/src/node/mcp-server.ts +11 -14
  320. package/src/node/openai/openai-language-model.ts +8 -4
  321. package/src/node/openai-compatible/openai-compatible-language-model.ts +30 -0
  322. package/lib/browser/mcp/tools/components/SearchResult.d.ts +0 -11
  323. package/lib/browser/mcp/tools/components/SearchResult.d.ts.map +0 -1
  324. package/lib/browser/mcp/tools/components/SearchResult.js.map +0 -1
  325. package/src/browser/mcp/tools/components/SearchResult.tsx +0 -92
@@ -1,17 +1,30 @@
1
1
  import { createPatch } from 'diff';
2
2
 
3
3
  import { Autowired } from '@opensumi/di';
4
- import { AppConfig, IChatProgress, IMarker, MarkerSeverity, OnEvent, WithEventBus } from '@opensumi/ide-core-browser';
4
+ import {
5
+ AIServiceType,
6
+ ActionSourceEnum,
7
+ ActionTypeEnum,
8
+ AppConfig,
9
+ IAIReporter,
10
+ IChatProgress,
11
+ IMarker,
12
+ MarkerSeverity,
13
+ OnEvent,
14
+ WithEventBus,
15
+ } from '@opensumi/ide-core-browser';
5
16
  import { WorkbenchEditorService } from '@opensumi/ide-editor';
6
17
  import {
7
18
  EditorGroupCloseEvent,
8
19
  EditorGroupOpenEvent,
20
+ IEditorDocumentModelService,
9
21
  RegisterEditorSideComponentEvent,
10
22
  } from '@opensumi/ide-editor/lib/browser';
11
23
  import { IMarkerService } from '@opensumi/ide-markers';
12
- import { ICodeEditor, Position, Range, Selection, SelectionDirection } from '@opensumi/ide-monaco';
13
- import { Deferred, Emitter, URI, path } from '@opensumi/ide-utils';
24
+ import { ICodeEditor, ITextModel, Position, Range, Selection, SelectionDirection } from '@opensumi/ide-monaco';
25
+ import { Deferred, DisposableMap, Emitter, IDisposable, URI, path } from '@opensumi/ide-utils';
14
26
  import { SumiReadableStream } from '@opensumi/ide-utils/lib/stream';
27
+ import { EditOperation } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/editOperation';
15
28
 
16
29
  import { IChatInternalService } from '../../common';
17
30
  import { CodeBlockData, CodeBlockStatus } from '../../common/types';
@@ -23,15 +36,9 @@ import {
23
36
  InlineDiffService,
24
37
  LiveInlineDiffPreviewer,
25
38
  } from '../widget/inline-diff';
26
- import { InlineStreamDiffHandler } from '../widget/inline-stream-diff/inline-stream-diff.handler';
27
-
28
- import { FileHandler } from './tools/handlers/ReadFile';
39
+ import { BaseInlineStreamDiffHandler } from '../widget/inline-stream-diff/inline-stream-diff.handler';
29
40
 
30
- // 提供代码块的唯一索引,迭代轮次,生成状态管理(包括取消),关联文件位置这些信息的记录,后续并行 apply 的支持
31
41
  export abstract class BaseApplyService extends WithEventBus {
32
- @Autowired(FileHandler)
33
- protected fileHandler: FileHandler;
34
-
35
42
  @Autowired(IChatInternalService)
36
43
  protected chatInternalService: ChatInternalService;
37
44
 
@@ -47,14 +54,41 @@ export abstract class BaseApplyService extends WithEventBus {
47
54
  @Autowired(IMarkerService)
48
55
  private readonly markerService: IMarkerService;
49
56
 
57
+ @Autowired(IEditorDocumentModelService)
58
+ private readonly editorDocumentModelService: IEditorDocumentModelService;
59
+
60
+ @Autowired(IAIReporter)
61
+ private readonly aiReporter: IAIReporter;
62
+
50
63
  private onCodeBlockUpdateEmitter = new Emitter<CodeBlockData>();
51
64
  public onCodeBlockUpdate = this.onCodeBlockUpdateEmitter.event;
52
65
 
66
+ private currentSessionId?: string;
67
+
53
68
  constructor() {
54
69
  super();
55
70
  this.addDispose(
56
71
  this.chatInternalService.onCancelRequest(() => {
57
- this.cancelAllApply();
72
+ const currentMessageId = this.chatInternalService.sessionModel.history.lastMessageId;
73
+ if (!currentMessageId) {
74
+ return;
75
+ }
76
+ const codeBlockMap = this.getMessageCodeBlocks(currentMessageId);
77
+ if (!codeBlockMap) {
78
+ return;
79
+ }
80
+ Object.values(codeBlockMap).forEach((blockData) => {
81
+ this.cancelApply(blockData);
82
+ });
83
+ }),
84
+ );
85
+ this.currentSessionId = this.chatInternalService.sessionModel.sessionId;
86
+ this.addDispose(
87
+ this.chatInternalService.onChangeSession((sessionId) => {
88
+ if (sessionId !== this.currentSessionId) {
89
+ this.cancelAllApply();
90
+ this.currentSessionId = sessionId;
91
+ }
58
92
  }),
59
93
  );
60
94
  this.addDispose(
@@ -70,6 +104,11 @@ export abstract class BaseApplyService extends WithEventBus {
70
104
  });
71
105
  }),
72
106
  );
107
+ this.addDispose(
108
+ this.chatInternalService.onWillClearSession((sessionId) => {
109
+ this.cancelAllApply(sessionId);
110
+ }),
111
+ );
73
112
  }
74
113
 
75
114
  private getMessageCodeBlocks(
@@ -85,46 +124,80 @@ export abstract class BaseApplyService extends WithEventBus {
85
124
  return message?.codeBlockMap;
86
125
  }
87
126
 
88
- private activePreviewer: BaseInlineDiffPreviewer<InlineStreamDiffHandler> | undefined;
127
+ private activePreviewerMap = this.registerDispose(
128
+ new DisposableMap<string, BaseInlineDiffPreviewer<BaseInlineStreamDiffHandler>>(),
129
+ );
130
+
131
+ private editorListenerMap = this.registerDispose(new DisposableMap<string, IDisposable>());
89
132
 
90
133
  @OnEvent(EditorGroupCloseEvent)
91
134
  onEditorGroupClose(event: EditorGroupCloseEvent) {
92
- if (this.activePreviewer?.getNode()?.uri.path.toString() === event.payload.resource.uri.path.toString()) {
93
- this.activePreviewer.dispose();
94
- this.activePreviewer = undefined;
135
+ const relativePath = path.relative(this.appConfig.workspaceDir, event.payload.resource.uri.path.toString());
136
+ const activePreviewer = this.activePreviewerMap.get(relativePath);
137
+ if (activePreviewer) {
138
+ this.activePreviewerMap.disposeKey(relativePath);
95
139
  }
140
+ this.editorListenerMap.disposeKey(event.payload.resource.uri.toString());
96
141
  }
97
142
 
98
143
  @OnEvent(EditorGroupOpenEvent)
99
144
  async onEditorGroupOpen(event: EditorGroupOpenEvent) {
100
- if (!this.chatInternalService.sessionModel.history.getMessages().length) {
145
+ const relativePath = path.relative(this.appConfig.workspaceDir, event.payload.resource.uri.path.toString());
146
+ if (
147
+ this.duringApply ||
148
+ this.activePreviewerMap.has(relativePath) ||
149
+ !this.chatInternalService.sessionModel.history.getMessages().length
150
+ ) {
101
151
  return;
102
152
  }
103
- const relativePath = path.relative(this.appConfig.workspaceDir, event.payload.resource.uri.path.toString());
104
- const filePendingApplies = Object.values(
105
- this.getMessageCodeBlocks(this.chatInternalService.sessionModel.history.lastMessageId!) || {},
106
- ).filter((block) => block.relativePath === relativePath && block.status === 'pending');
107
- // TODO: 刷新后重新应用,事件无法恢复 & 恢复继续请求,需要改造成批量apply形式
108
- // TODO: 暂时只支持 pending 串行的 apply,后续支持批量apply后统一accept
109
- if (filePendingApplies.length > 0) {
110
- this.renderApplyResult(filePendingApplies[0], filePendingApplies[0].updatedCode!);
153
+ const filePendingApplies =
154
+ this.getUriCodeBlocks(event.payload.resource.uri)?.filter((block) => block.status === 'pending') || [];
155
+ // 使用最后一个版本内容渲染 apply 内容
156
+ if (filePendingApplies.length > 0 && filePendingApplies[0].updatedCode) {
157
+ const editor = event.payload.group.codeEditor.monacoEditor;
158
+ this.renderApplyResult(editor, filePendingApplies[0], filePendingApplies[0].updatedCode);
111
159
  }
112
160
  }
113
161
 
114
- getUriPendingCodeBlock(uri: URI): CodeBlockData | undefined {
115
- const messageId = this.chatInternalService.sessionModel.history.lastMessageId;
116
- if (!messageId) {
162
+ get currentPreviewer() {
163
+ const currentUri = this.editorService.currentEditor?.currentUri;
164
+ if (!currentUri) {
117
165
  return undefined;
118
166
  }
119
- const codeBlockMap = this.getMessageCodeBlocks(messageId);
120
- if (!codeBlockMap) {
121
- return undefined;
167
+ return this.activePreviewerMap.get(path.relative(this.appConfig.workspaceDir, currentUri.path.toString()));
168
+ }
169
+
170
+ /**
171
+ * 获取指定uri的 code block,按version降序排序
172
+ */
173
+ getUriCodeBlocks(uri: URI): CodeBlockData[] | undefined {
174
+ const sessionCodeBlocks = this.getSessionCodeBlocks();
175
+ const relativePath = path.relative(this.appConfig.workspaceDir, uri.path.toString());
176
+ return sessionCodeBlocks
177
+ .filter((block) => block.relativePath === relativePath)
178
+ .sort((a, b) => b.version - a.version);
179
+ }
180
+
181
+ getPendingPaths(sessionId?: string): string[] {
182
+ const sessionCodeBlocks = this.getSessionCodeBlocks(sessionId);
183
+ return sessionCodeBlocks.filter((block) => block.status === 'pending').map((block) => block.relativePath);
184
+ }
185
+
186
+ protected getSessionCodeBlocks(sessionId?: string) {
187
+ sessionId = sessionId || this.chatInternalService.sessionModel.sessionId;
188
+ const sessionModel = this.chatInternalService.getSession(sessionId);
189
+ if (!sessionModel) {
190
+ throw new Error(`Session ${sessionId} not found`);
122
191
  }
123
- return Object.values(codeBlockMap).find(
124
- (block) =>
125
- block.relativePath === path.relative(this.appConfig.workspaceDir, uri.path.toString()) &&
126
- block.status === 'pending',
127
- );
192
+ const sessionAdditionals = sessionModel.history.sessionAdditionals;
193
+ return Array.from(sessionAdditionals.values())
194
+ .map((additional) => (additional.codeBlockMap || {}) as { [toolCallId: string]: CodeBlockData })
195
+ .reduce((acc, cur) => {
196
+ Object.values(cur).forEach((block) => {
197
+ acc.push(block);
198
+ });
199
+ return acc;
200
+ }, [] as CodeBlockData[]);
128
201
  }
129
202
 
130
203
  getCodeBlock(toolCallId: string, messageId?: string): CodeBlockData | undefined {
@@ -139,11 +212,8 @@ export abstract class BaseApplyService extends WithEventBus {
139
212
  return codeBlockMap[toolCallId];
140
213
  }
141
214
 
142
- protected updateCodeBlock(codeBlock: CodeBlockData, messageId?: string) {
143
- messageId = messageId || this.chatInternalService.sessionModel.history.lastMessageId;
144
- if (!messageId) {
145
- throw new Error('Message ID is required');
146
- }
215
+ protected updateCodeBlock(codeBlock: CodeBlockData) {
216
+ const messageId = codeBlock.messageId;
147
217
  const codeBlockMap = this.getMessageCodeBlocks(messageId);
148
218
  if (!codeBlockMap) {
149
219
  throw new Error('Code block not found');
@@ -155,9 +225,12 @@ export abstract class BaseApplyService extends WithEventBus {
155
225
  this.onCodeBlockUpdateEmitter.fire(codeBlock);
156
226
  }
157
227
 
158
- registerCodeBlock(relativePath: string, content: string, toolCallId: string): CodeBlockData {
228
+ async registerCodeBlock(relativePath: string, content: string, toolCallId: string): Promise<CodeBlockData> {
159
229
  const lastMessageId = this.chatInternalService.sessionModel.history.lastMessageId!;
160
- const savedCodeBlockMap = this.getMessageCodeBlocks(lastMessageId) || {};
230
+ const uriCodeBlocks = this.getUriCodeBlocks(URI.file(path.join(this.appConfig.workspaceDir, relativePath)));
231
+ const originalModelRef = await this.editorDocumentModelService.createModelReference(
232
+ URI.file(path.join(this.appConfig.workspaceDir, relativePath)),
233
+ );
161
234
  const newBlock: CodeBlockData = {
162
235
  codeEdit: content,
163
236
  relativePath,
@@ -166,11 +239,13 @@ export abstract class BaseApplyService extends WithEventBus {
166
239
  version: 1,
167
240
  createdAt: Date.now(),
168
241
  toolCallId,
242
+ messageId: lastMessageId,
243
+ // TODO: 支持range
244
+ originalCode: originalModelRef.instance.getText(),
169
245
  };
170
- const samePathCodeBlocks = Object.values(savedCodeBlockMap).filter((block) => block.relativePath === relativePath);
171
- if (samePathCodeBlocks.length > 0) {
172
- newBlock.version = samePathCodeBlocks.length;
173
- for (const block of samePathCodeBlocks.sort((a, b) => b.version - a.version)) {
246
+ if (uriCodeBlocks?.length) {
247
+ newBlock.version = uriCodeBlocks.length;
248
+ for (const block of uriCodeBlocks) {
174
249
  // 如果连续的上一个同文件apply结果存在LintError,则iterationCount++
175
250
  if (block.relativePath === relativePath && block.applyResult?.diagnosticInfos?.length) {
176
251
  newBlock.iterationCount++;
@@ -179,6 +254,7 @@ export abstract class BaseApplyService extends WithEventBus {
179
254
  }
180
255
  }
181
256
  }
257
+ const savedCodeBlockMap = this.getMessageCodeBlocks(lastMessageId) || {};
182
258
  savedCodeBlockMap[toolCallId] = newBlock;
183
259
  this.chatInternalService.sessionModel.history.setMessageAdditional(lastMessageId, {
184
260
  codeBlockMap: savedCodeBlockMap,
@@ -187,21 +263,45 @@ export abstract class BaseApplyService extends WithEventBus {
187
263
  return newBlock;
188
264
  }
189
265
 
266
+ private duringApply?: boolean;
267
+
190
268
  /**
191
269
  * Apply changes of a code block
192
270
  */
193
271
  async apply(codeBlock: CodeBlockData): Promise<CodeBlockData> {
194
272
  try {
273
+ this.duringApply = true;
195
274
  if (codeBlock.iterationCount > 3) {
196
275
  throw new Error('Lint error max iteration count exceeded');
197
276
  }
198
- const fastApplyFileResult = await this.doApply(codeBlock);
277
+ // 新建文件场景,直接返回codeEdit
278
+ const fastApplyFileResult = !codeBlock.originalCode
279
+ ? {
280
+ result: codeBlock.codeEdit,
281
+ }
282
+ : await this.doApply(codeBlock);
199
283
  if (!fastApplyFileResult.stream && !fastApplyFileResult.result) {
200
284
  throw new Error('No apply content provided');
201
285
  }
202
286
 
287
+ if (this.activePreviewerMap.has(codeBlock.relativePath)) {
288
+ // 有正在进行的 apply,则取消(但不更新block状态,只清理副作用)
289
+ this.cancelApply(codeBlock, true);
290
+ }
203
291
  // trigger diffPreivewer & return expected diff result directly
292
+ const result = await this.editorService.open(
293
+ URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)),
294
+ );
295
+ if (!result) {
296
+ throw new Error('Failed to open file');
297
+ }
298
+ if (typeof fastApplyFileResult.result === 'string') {
299
+ codeBlock.updatedCode = fastApplyFileResult.result;
300
+ codeBlock.status = 'pending';
301
+ this.updateCodeBlock(codeBlock);
302
+ }
204
303
  const applyResult = await this.renderApplyResult(
304
+ result.group.codeEditor.monacoEditor,
205
305
  codeBlock,
206
306
  (fastApplyFileResult.result || fastApplyFileResult.stream)!,
207
307
  fastApplyFileResult.range,
@@ -217,31 +317,37 @@ export abstract class BaseApplyService extends WithEventBus {
217
317
  codeBlock.status = 'failed';
218
318
  this.updateCodeBlock(codeBlock);
219
319
  throw err;
320
+ } finally {
321
+ this.duringApply = false;
220
322
  }
221
323
  }
222
324
 
223
325
  async renderApplyResult(
326
+ editor: ICodeEditor,
224
327
  codeBlock: CodeBlockData,
225
328
  updatedContentOrStream: string | SumiReadableStream<IChatProgress>,
226
329
  range?: Range,
227
330
  ): Promise<{ diff: string; diagnosticInfos: IMarker[] } | undefined> {
228
- const { relativePath } = codeBlock;
229
- const openResult = await this.editorService.open(URI.file(path.join(this.appConfig.workspaceDir, relativePath)));
230
- if (!openResult) {
231
- throw new Error('Failed to open editor');
232
- }
233
- const editor = openResult.group.codeEditor.monacoEditor;
331
+ const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
234
332
  const inlineDiffController = InlineDiffController.get(editor)!;
235
- codeBlock.status = 'pending';
236
- // 强刷展示 manager 视图
237
- this.eventBus.fire(new RegisterEditorSideComponentEvent());
238
- this.updateCodeBlock(codeBlock);
239
-
240
- const fullOriginalContent = editor.getModel()!.getValue();
241
- range = range || editor.getModel()?.getFullModelRange()!;
242
- // const savedRangeContent = editor.getModel()!.getValueInRange(range);
333
+ range = range || editor.getModel()!.getFullModelRange();
243
334
 
244
335
  if (typeof updatedContentOrStream === 'string') {
336
+ const editorCurrentContent = editor.getModel()!.getValue();
337
+ const uri = URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath));
338
+ const document = this.editorDocumentModelService.getModelReference(uri);
339
+ if (editorCurrentContent !== updatedContentOrStream || document?.instance.dirty) {
340
+ editor.getModel()?.pushEditOperations([], [EditOperation.replace(range, updatedContentOrStream)], () => null);
341
+ await this.editorService.save(uri);
342
+ }
343
+ const uriPendingCodeBlocks = this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending');
344
+ const earlistPendingCodeBlock = uriPendingCodeBlocks?.[uriPendingCodeBlocks.length - 1];
345
+ if ((earlistPendingCodeBlock?.originalCode || codeBlock.originalCode) === updatedContentOrStream) {
346
+ codeBlock.status = 'cancelled';
347
+ this.updateCodeBlock(codeBlock);
348
+ deferred.resolve();
349
+ return;
350
+ }
245
351
  // Create diff previewer
246
352
  const previewer = inlineDiffController.createDiffPreviewer(
247
353
  editor,
@@ -249,18 +355,38 @@ export abstract class BaseApplyService extends WithEventBus {
249
355
  {
250
356
  disposeWhenEditorClosed: true,
251
357
  renderRemovedWidgetImmediately: true,
358
+ reverse: true,
252
359
  },
253
360
  ) as LiveInlineDiffPreviewer;
254
- // TODO: 支持多个diffPreviewer
255
- this.activePreviewer = previewer;
256
- codeBlock.updatedCode = updatedContentOrStream;
257
- previewer.setValue(updatedContentOrStream);
361
+ this.activePreviewerMap.set(codeBlock.relativePath, previewer);
362
+ // 新建文件场景,为避免model为空,加一个空行
363
+ previewer.setValue(earlistPendingCodeBlock?.originalCode || codeBlock.originalCode || '\n');
364
+ // 强刷展示 manager 视图
365
+ this.eventBus.fire(new RegisterEditorSideComponentEvent());
366
+
367
+ this.listenPartialEdit(editor.getModel()!, codeBlock).then((result) => {
368
+ if (result) {
369
+ codeBlock.applyResult = result;
370
+ }
371
+ this.updateCodeBlock(codeBlock);
372
+ this.editorService.save(URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)));
373
+ });
374
+
375
+ const { diff, rangesFromDiffHunk } = this.getDiffResult(
376
+ codeBlock.originalCode,
377
+ codeBlock.updatedCode || updatedContentOrStream,
378
+ codeBlock.relativePath,
379
+ );
380
+ const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
381
+ deferred.resolve({
382
+ diff,
383
+ diagnosticInfos,
384
+ });
258
385
  } else {
259
386
  const controller = new InlineChatController();
260
387
  controller.mountReadable(updatedContentOrStream);
261
- const inlineDiffHandler = InlineDiffController.get(editor)!;
262
388
 
263
- this.activePreviewer = inlineDiffHandler.showPreviewerByStream(editor, {
389
+ const previewer = inlineDiffController.showPreviewerByStream(editor, {
264
390
  crossSelection: Selection.fromRange(range, SelectionDirection.LTR),
265
391
  chatResponse: controller,
266
392
  previewerOptions: {
@@ -268,39 +394,68 @@ export abstract class BaseApplyService extends WithEventBus {
268
394
  renderRemovedWidgetImmediately: false,
269
395
  },
270
396
  }) as LiveInlineDiffPreviewer;
397
+
271
398
  this.addDispose(
272
- this.activePreviewer.getNode()!.onDiffFinished((diffModel) => {
399
+ controller.onError((err) => {
400
+ deferred.reject(err);
401
+ }),
402
+ );
403
+ this.addDispose(
404
+ controller.onAbort(() => {
405
+ deferred.reject(new Error('Apply aborted'));
406
+ }),
407
+ );
408
+ this.addDispose(
409
+ // 流式输出结束后,转为直接输出逻辑
410
+ previewer.getNode()!.onDiffFinished(async (diffModel) => {
273
411
  codeBlock.updatedCode = diffModel.newFullRangeTextLines.join('\n');
412
+ // TODO: 添加 reapply
413
+ // 实际应用结果为空,则取消
414
+ if (codeBlock.updatedCode === codeBlock.originalCode) {
415
+ codeBlock.status = 'failed';
416
+ this.updateCodeBlock(codeBlock);
417
+ previewer.dispose();
418
+ deferred.reject(new Error('no changes applied'));
419
+ return;
420
+ }
421
+ codeBlock.status = 'pending';
274
422
  this.updateCodeBlock(codeBlock);
423
+ previewer.dispose();
424
+ const result = await this.renderApplyResult(editor, codeBlock, codeBlock.updatedCode);
425
+ deferred.resolve(result);
275
426
  }),
276
427
  );
428
+ this.activePreviewerMap.set(codeBlock.relativePath, previewer);
277
429
  }
278
-
279
- return this.listenPartialEdit(editor, codeBlock, fullOriginalContent);
430
+ return deferred.promise;
280
431
  }
281
432
 
282
433
  /**
283
434
  * Cancel an ongoing apply operation
284
435
  */
285
- cancelApply(blockData: CodeBlockData): void {
436
+ cancelApply(blockData: CodeBlockData, keepStatus?: boolean): void {
286
437
  if (blockData.status === 'generating' || blockData.status === 'pending') {
287
- if (this.activePreviewer) {
288
- this.activePreviewer.getNode()?.livePreviewDiffDecorationModel.discardUnProcessed();
289
- this.activePreviewer.dispose();
438
+ // 先取消掉相关的监听器
439
+ this.editorListenerMap.disposeKey(
440
+ URI.file(path.join(this.appConfig.workspaceDir, blockData.relativePath)).toString(),
441
+ );
442
+ if (this.activePreviewerMap.has(blockData.relativePath)) {
443
+ this.activePreviewerMap
444
+ .get(blockData.relativePath)
445
+ ?.getNode()
446
+ ?.livePreviewDiffDecorationModel.discardUnProcessed();
447
+ this.activePreviewerMap.disposeKey(blockData.relativePath);
448
+ }
449
+ if (!keepStatus) {
450
+ blockData.status = 'cancelled';
451
+ this.updateCodeBlock(blockData);
290
452
  }
291
- blockData.status = 'cancelled';
292
- this.updateCodeBlock(blockData);
293
453
  }
294
454
  }
295
455
 
296
- // TODO: 目前的设计下,有一个工具 apply 没返回,是不会触发下一个的(cursor 是会全部自动 apply 的),所以这个方法目前还没有必要
297
- cancelAllApply(): void {
298
- const messageId = this.chatInternalService.sessionModel.history.lastMessageId!;
299
- const codeBlockMap = this.getMessageCodeBlocks(messageId);
300
- if (!codeBlockMap) {
301
- return;
302
- }
303
- Object.values(codeBlockMap).forEach((blockData) => {
456
+ cancelAllApply(sessionId?: string): void {
457
+ const sessionCodeBlocks = this.getSessionCodeBlocks(sessionId);
458
+ sessionCodeBlocks.forEach((blockData) => {
304
459
  this.cancelApply(blockData);
305
460
  });
306
461
  }
@@ -323,11 +478,13 @@ export abstract class BaseApplyService extends WithEventBus {
323
478
  }
324
479
 
325
480
  processAll(uri: URI, type: 'accept' | 'reject'): void {
326
- const codeBlock = this.getUriPendingCodeBlock(uri);
327
- if (!codeBlock) {
481
+ const codeBlocks = this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending');
482
+ if (!codeBlocks?.length) {
328
483
  throw new Error('No pending code block found');
329
484
  }
330
- const decorationModel = this.activePreviewer?.getNode()?.livePreviewDiffDecorationModel;
485
+ const decorationModel = this.activePreviewerMap
486
+ .get(codeBlocks[0].relativePath)
487
+ ?.getNode()?.livePreviewDiffDecorationModel;
331
488
  if (!decorationModel) {
332
489
  throw new Error('No active previewer found');
333
490
  }
@@ -337,49 +494,89 @@ export abstract class BaseApplyService extends WithEventBus {
337
494
  decorationModel.discardUnProcessed();
338
495
  }
339
496
  this.editorService.save(uri);
340
- codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
341
- this.updateCodeBlock(codeBlock);
497
+ codeBlocks.forEach((codeBlock) => {
498
+ codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
499
+ // TODO: 批量更新
500
+ this.updateCodeBlock(codeBlock);
501
+ });
342
502
  }
343
503
 
344
- protected listenPartialEdit(editor: ICodeEditor, codeBlock: CodeBlockData, fullOriginalContent: string) {
504
+ protected listenPartialEdit(model: ITextModel, codeBlock: CodeBlockData) {
345
505
  const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
506
+ const uriString = model.uri.toString();
346
507
  const toDispose = this.inlineDiffService.onPartialEdit((event) => {
347
508
  // TODO 支持自动保存
348
- if (event.totalPartialEditCount === event.resolvedPartialEditCount) {
509
+ if (
510
+ event.totalPartialEditCount === event.resolvedPartialEditCount &&
511
+ event.uri.path === model.uri.path.toString()
512
+ ) {
349
513
  if (event.acceptPartialEditCount > 0) {
350
514
  codeBlock.status = 'success';
351
- const appliedResult = editor.getModel()!.getValue();
352
- const diffResult = createPatch(codeBlock.relativePath, fullOriginalContent, appliedResult)
353
- .split('\n')
354
- .slice(4)
355
- .join('\n');
356
- const rangesFromDiffHunk = diffResult
357
- .split('\n')
358
- .map((line) => {
359
- if (line.startsWith('@@')) {
360
- const [, , , start, end] = line.match(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/)!;
361
- return new Range(parseInt(start, 10), 0, parseInt(end, 10), 0);
362
- }
363
- return null;
364
- })
365
- .filter((range) => range !== null);
366
- const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
515
+ const appliedResult = model.getValue();
516
+ const { diff, rangesFromDiffHunk } = this.getDiffResult(
517
+ codeBlock.originalCode,
518
+ appliedResult,
519
+ codeBlock.relativePath,
520
+ );
521
+ const diagnosticInfos = this.getDiagnosticInfos(model.uri.toString(), rangesFromDiffHunk);
367
522
  // 移除开头的几个固定信息,避免浪费 tokens
523
+ this.aiReporter.send({
524
+ msgType: AIServiceType.Chat,
525
+ actionType: ActionTypeEnum.Accept,
526
+ actionSource: ActionSourceEnum.Chat,
527
+ sessionId: this.chatInternalService.sessionModel.sessionId,
528
+ isReceive: true,
529
+ isDrop: false,
530
+ code: codeBlock.codeEdit,
531
+ message: JSON.stringify({
532
+ diff,
533
+ diagnosticInfos,
534
+ }),
535
+ });
368
536
  deferred.resolve({
369
- diff: diffResult,
537
+ diff,
370
538
  diagnosticInfos,
371
539
  });
372
540
  } else {
373
541
  // 用户全部取消
374
542
  codeBlock.status = 'cancelled';
375
543
  deferred.resolve();
544
+ this.aiReporter.send({
545
+ msgType: AIServiceType.Chat,
546
+ actionType: ActionTypeEnum.Discard,
547
+ actionSource: ActionSourceEnum.Chat,
548
+ sessionId: this.chatInternalService.sessionModel.sessionId,
549
+ isReceive: false,
550
+ isDrop: true,
551
+ code: codeBlock.codeEdit,
552
+ originCode: codeBlock.originalCode,
553
+ });
376
554
  }
377
- toDispose.dispose();
555
+ this.editorListenerMap.disposeKey(uriString);
378
556
  }
379
557
  });
558
+ this.editorListenerMap.set(uriString, toDispose);
380
559
  return deferred.promise;
381
560
  }
382
561
 
562
+ protected getDiffResult(originalContent: string, appliedResult: string, relativePath: string) {
563
+ const diffResult = createPatch(relativePath, originalContent, appliedResult).split('\n').slice(4).join('\n');
564
+ const rangesFromDiffHunk = diffResult
565
+ .split('\n')
566
+ .map((line) => {
567
+ if (line.startsWith('@@')) {
568
+ const [, , , start, end] = line.match(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/)!;
569
+ return new Range(parseInt(start, 10), 0, parseInt(end, 10), 0);
570
+ }
571
+ return null;
572
+ })
573
+ .filter((range) => range !== null);
574
+ return {
575
+ diff: diffResult,
576
+ rangesFromDiffHunk,
577
+ };
578
+ }
579
+
383
580
  /**
384
581
  * Apply changes of a code block, return stream to render inline diff in stream mode, result to render inline diff directly
385
582
  * range is optional, if not provided, the result will be applied to the the full file