@opensumi/ide-ai-native 3.9.1-next-1749538805.0 → 3.9.1-next-1749540423.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 (253) hide show
  1. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  2. package/lib/browser/ai-core.contribution.js +4 -9
  3. package/lib/browser/ai-core.contribution.js.map +1 -1
  4. package/lib/browser/chat/apply.service.d.ts +0 -3
  5. package/lib/browser/chat/apply.service.d.ts.map +1 -1
  6. package/lib/browser/chat/apply.service.js +0 -47
  7. package/lib/browser/chat/apply.service.js.map +1 -1
  8. package/lib/browser/chat/chat-manager.service.d.ts +0 -1
  9. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  10. package/lib/browser/chat/chat-manager.service.js +3 -9
  11. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  12. package/lib/browser/chat/chat-model.d.ts +1 -8
  13. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  14. package/lib/browser/chat/chat-model.js +76 -113
  15. package/lib/browser/chat/chat-model.js.map +1 -1
  16. package/lib/browser/chat/chat-proxy.service.d.ts +2 -0
  17. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  18. package/lib/browser/chat/chat-proxy.service.js +57 -50
  19. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  20. package/lib/browser/chat/chat.feature.registry.d.ts +1 -4
  21. package/lib/browser/chat/chat.feature.registry.d.ts.map +1 -1
  22. package/lib/browser/chat/chat.feature.registry.js +0 -6
  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 +10 -50
  26. package/lib/browser/chat/chat.view.js.map +1 -1
  27. package/lib/browser/components/ChatEditor.js +2 -2
  28. package/lib/browser/components/ChatEditor.js.map +1 -1
  29. package/lib/browser/components/ChatHistory.d.ts.map +1 -1
  30. package/lib/browser/components/ChatHistory.js +1 -2
  31. package/lib/browser/components/ChatHistory.js.map +1 -1
  32. package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
  33. package/lib/browser/components/ChatMentionInput.js +30 -148
  34. package/lib/browser/components/ChatMentionInput.js.map +1 -1
  35. package/lib/browser/components/ChatReply.js +2 -2
  36. package/lib/browser/components/ChatReply.js.map +1 -1
  37. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  38. package/lib/browser/components/ChatToolRender.js +2 -7
  39. package/lib/browser/components/ChatToolRender.js.map +1 -1
  40. package/lib/browser/components/ChatToolRender.module.less +0 -25
  41. package/lib/browser/components/components.module.less +8 -37
  42. package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
  43. package/lib/browser/components/mention-input/mention-input.js +14 -150
  44. package/lib/browser/components/mention-input/mention-input.js.map +1 -1
  45. package/lib/browser/components/mention-input/mention-input.module.less +1 -165
  46. package/lib/browser/components/mention-input/types.d.ts +1 -28
  47. package/lib/browser/components/mention-input/types.d.ts.map +1 -1
  48. package/lib/browser/components/mention-input/types.js +0 -1
  49. package/lib/browser/components/mention-input/types.js.map +1 -1
  50. package/lib/browser/components/utils.d.ts +2 -2
  51. package/lib/browser/context/llm-context.service.d.ts +2 -21
  52. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  53. package/lib/browser/context/llm-context.service.js +20 -162
  54. package/lib/browser/context/llm-context.service.js.map +1 -1
  55. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -1
  56. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -1
  57. package/lib/browser/contrib/intelligent-completions/diff-computer.js +1 -1
  58. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -1
  59. package/lib/browser/contrib/terminal/terminal.feature.registry.js.map +1 -1
  60. package/lib/browser/index.d.ts.map +1 -1
  61. package/lib/browser/index.js +0 -7
  62. package/lib/browser/index.js.map +1 -1
  63. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  64. package/lib/browser/layout/ai-layout.js +4 -6
  65. package/lib/browser/layout/ai-layout.js.map +1 -1
  66. package/lib/browser/layout/tabbar.view.d.ts +1 -1
  67. package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
  68. package/lib/browser/layout/tabbar.view.js +12 -5
  69. package/lib/browser/layout/tabbar.view.js.map +1 -1
  70. package/lib/browser/mcp/base-apply.service.d.ts +4 -5
  71. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  72. package/lib/browser/mcp/base-apply.service.js +5 -23
  73. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  74. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +1 -3
  75. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  76. package/lib/browser/mcp/mcp-server-proxy.service.js +0 -4
  77. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  78. package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
  79. package/lib/browser/mcp/mcp-server.feature.registry.js +1 -7
  80. package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
  81. package/lib/browser/mcp/tools/createNewFileWithText.d.ts +3 -1
  82. package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
  83. package/lib/browser/mcp/tools/createNewFileWithText.js +40 -14
  84. package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
  85. package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -1
  86. package/lib/browser/mcp/tools/fileSearch.js +5 -9
  87. package/lib/browser/mcp/tools/fileSearch.js.map +1 -1
  88. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  89. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
  90. package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -1
  91. package/lib/browser/mcp/tools/grepSearch.js +10 -22
  92. package/lib/browser/mcp/tools/grepSearch.js.map +1 -1
  93. package/lib/browser/mcp/tools/handlers/ListDir.js +1 -1
  94. package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
  95. package/lib/browser/mcp/tools/handlers/ReadFile.js +1 -1
  96. package/lib/browser/mcp/tools/handlers/ReadFile.js.map +1 -1
  97. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts +1 -11
  98. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
  99. package/lib/browser/mcp/tools/handlers/RunCommand.js +4 -11
  100. package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
  101. package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
  102. package/lib/browser/mcp/tools/listDir.js +15 -19
  103. package/lib/browser/mcp/tools/listDir.js.map +1 -1
  104. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  105. package/lib/browser/model/msg-history-manager.d.ts +1 -47
  106. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  107. package/lib/browser/model/msg-history-manager.js +2 -127
  108. package/lib/browser/model/msg-history-manager.js.map +1 -1
  109. package/lib/browser/preferences/schema.d.ts.map +1 -1
  110. package/lib/browser/preferences/schema.js +0 -5
  111. package/lib/browser/preferences/schema.js.map +1 -1
  112. package/lib/browser/types.d.ts +1 -12
  113. package/lib/browser/types.d.ts.map +1 -1
  114. package/lib/browser/types.js.map +1 -1
  115. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  116. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  117. package/lib/common/index.d.ts +1 -5
  118. package/lib/common/index.d.ts.map +1 -1
  119. package/lib/common/index.js +0 -2
  120. package/lib/common/index.js.map +1 -1
  121. package/lib/common/llm-context.d.ts +0 -19
  122. package/lib/common/llm-context.d.ts.map +1 -1
  123. package/lib/common/llm-context.js.map +1 -1
  124. package/lib/common/model.d.ts +0 -1
  125. package/lib/common/model.d.ts.map +1 -1
  126. package/lib/common/model.js.map +1 -1
  127. package/lib/common/prompts/context-prompt-provider.d.ts +2 -0
  128. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  129. package/lib/common/prompts/context-prompt-provider.js +29 -35
  130. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  131. package/lib/common/types.d.ts +0 -21
  132. package/lib/common/types.d.ts.map +1 -1
  133. package/lib/common/types.js.map +1 -1
  134. package/lib/common/utils.d.ts +0 -1
  135. package/lib/common/utils.d.ts.map +1 -1
  136. package/lib/common/utils.js +2 -5
  137. package/lib/common/utils.js.map +1 -1
  138. package/lib/node/anthropic/anthropic-language-model.d.ts +1 -1
  139. package/lib/node/base-language-model.d.ts +1 -2
  140. package/lib/node/base-language-model.d.ts.map +1 -1
  141. package/lib/node/base-language-model.js +2 -12
  142. package/lib/node/base-language-model.js.map +1 -1
  143. package/lib/node/deepseek/deepseek-language-model.d.ts +1 -1
  144. package/lib/node/mcp/sumi-mcp-server.d.ts +1 -3
  145. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  146. package/lib/node/mcp/sumi-mcp-server.js +1 -7
  147. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  148. package/lib/node/mcp-server-manager-impl.d.ts +1 -3
  149. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  150. package/lib/node/mcp-server-manager-impl.js +2 -14
  151. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  152. package/lib/node/mcp-server.sse.d.ts +1 -187
  153. package/lib/node/mcp-server.sse.d.ts.map +1 -1
  154. package/lib/node/mcp-server.sse.js +2 -2
  155. package/lib/node/mcp-server.sse.js.map +1 -1
  156. package/lib/node/mcp-server.stdio.d.ts +1 -187
  157. package/lib/node/mcp-server.stdio.d.ts.map +1 -1
  158. package/package.json +26 -27
  159. package/src/browser/ai-core.contribution.ts +4 -14
  160. package/src/browser/chat/apply.service.ts +1 -62
  161. package/src/browser/chat/chat-manager.service.ts +7 -16
  162. package/src/browser/chat/chat-model.ts +73 -130
  163. package/src/browser/chat/chat-proxy.service.ts +81 -68
  164. package/src/browser/chat/chat.feature.registry.ts +1 -17
  165. package/src/browser/chat/chat.view.tsx +12 -73
  166. package/src/browser/components/ChatEditor.tsx +1 -1
  167. package/src/browser/components/ChatHistory.tsx +1 -2
  168. package/src/browser/components/ChatMentionInput.tsx +35 -180
  169. package/src/browser/components/ChatReply.tsx +4 -4
  170. package/src/browser/components/ChatToolRender.module.less +0 -25
  171. package/src/browser/components/ChatToolRender.tsx +2 -10
  172. package/src/browser/components/components.module.less +8 -37
  173. package/src/browser/components/mention-input/mention-input.module.less +1 -165
  174. package/src/browser/components/mention-input/mention-input.tsx +31 -232
  175. package/src/browser/components/mention-input/types.ts +0 -29
  176. package/src/browser/context/llm-context.service.ts +21 -182
  177. package/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts +1 -1
  178. package/src/browser/contrib/intelligent-completions/diff-computer.ts +1 -1
  179. package/src/browser/contrib/terminal/terminal.feature.registry.ts +1 -1
  180. package/src/browser/index.ts +0 -8
  181. package/src/browser/layout/ai-layout.tsx +8 -12
  182. package/src/browser/layout/tabbar.view.tsx +23 -10
  183. package/src/browser/mcp/base-apply.service.ts +10 -30
  184. package/src/browser/mcp/mcp-server-proxy.service.ts +1 -6
  185. package/src/browser/mcp/mcp-server.feature.registry.ts +1 -6
  186. package/src/browser/mcp/tools/createNewFileWithText.ts +46 -17
  187. package/src/browser/mcp/tools/fileSearch.ts +5 -8
  188. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
  189. package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
  190. package/src/browser/mcp/tools/grepSearch.ts +21 -32
  191. package/src/browser/mcp/tools/handlers/ListDir.ts +2 -2
  192. package/src/browser/mcp/tools/handlers/ReadFile.ts +2 -2
  193. package/src/browser/mcp/tools/handlers/RunCommand.ts +14 -21
  194. package/src/browser/mcp/tools/listDir.ts +12 -15
  195. package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
  196. package/src/browser/model/msg-history-manager.ts +2 -181
  197. package/src/browser/preferences/schema.ts +0 -5
  198. package/src/browser/types.ts +0 -18
  199. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +1 -0
  200. package/src/common/index.ts +1 -6
  201. package/src/common/llm-context.ts +0 -23
  202. package/src/common/model.ts +0 -1
  203. package/src/common/prompts/context-prompt-provider.ts +40 -55
  204. package/src/common/types.ts +0 -18
  205. package/src/common/utils.ts +1 -4
  206. package/src/node/base-language-model.ts +14 -11
  207. package/src/node/mcp/sumi-mcp-server.ts +2 -10
  208. package/src/node/mcp-server-manager-impl.ts +2 -17
  209. package/src/node/mcp-server.sse.ts +2 -1
  210. package/lib/browser/components/mention-input/mention-select.d.ts +0 -28
  211. package/lib/browser/components/mention-input/mention-select.d.ts.map +0 -1
  212. package/lib/browser/components/mention-input/mention-select.js +0 -136
  213. package/lib/browser/components/mention-input/mention-select.js.map +0 -1
  214. package/lib/browser/components/mention-input/mention-select.module.less +0 -297
  215. package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.d.ts +0 -15
  216. package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.d.ts.map +0 -1
  217. package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.js +0 -53
  218. package/lib/browser/mcp/tools/handlers/CreateNewFileWithText.js.map +0 -1
  219. package/lib/browser/rules/rules.contribution.d.ts +0 -29
  220. package/lib/browser/rules/rules.contribution.d.ts.map +0 -1
  221. package/lib/browser/rules/rules.contribution.js +0 -94
  222. package/lib/browser/rules/rules.contribution.js.map +0 -1
  223. package/lib/browser/rules/rules.module.less +0 -175
  224. package/lib/browser/rules/rules.service.d.ts +0 -25
  225. package/lib/browser/rules/rules.service.d.ts.map +0 -1
  226. package/lib/browser/rules/rules.service.js +0 -180
  227. package/lib/browser/rules/rules.service.js.map +0 -1
  228. package/lib/browser/rules/rules.view.d.ts +0 -3
  229. package/lib/browser/rules/rules.view.d.ts.map +0 -1
  230. package/lib/browser/rules/rules.view.js +0 -76
  231. package/lib/browser/rules/rules.view.js.map +0 -1
  232. package/lib/common/image-compression.d.ts +0 -25
  233. package/lib/common/image-compression.d.ts.map +0 -1
  234. package/lib/common/image-compression.js +0 -153
  235. package/lib/common/image-compression.js.map +0 -1
  236. package/lib/common/mdc-parser.d.ts +0 -60
  237. package/lib/common/mdc-parser.d.ts.map +0 -1
  238. package/lib/common/mdc-parser.js +0 -246
  239. package/lib/common/mdc-parser.js.map +0 -1
  240. package/lib/common/prompts/system-prompt.d.ts +0 -2
  241. package/lib/common/prompts/system-prompt.d.ts.map +0 -1
  242. package/lib/common/prompts/system-prompt.js +0 -5
  243. package/lib/common/prompts/system-prompt.js.map +0 -1
  244. package/src/browser/components/mention-input/mention-select.module.less +0 -297
  245. package/src/browser/components/mention-input/mention-select.tsx +0 -256
  246. package/src/browser/mcp/tools/handlers/CreateNewFileWithText.ts +0 -49
  247. package/src/browser/rules/rules.contribution.ts +0 -105
  248. package/src/browser/rules/rules.module.less +0 -175
  249. package/src/browser/rules/rules.service.ts +0 -189
  250. package/src/browser/rules/rules.view.tsx +0 -127
  251. package/src/common/image-compression.ts +0 -174
  252. package/src/common/mdc-parser.ts +0 -295
  253. package/src/common/prompts/system-prompt.ts +0 -2
@@ -28,7 +28,7 @@ import {
28
28
  import { MsgHistoryManager } from '../model/msg-history-manager';
29
29
  import { IChatSlashCommandItem } from '../types';
30
30
 
31
- import { ChatFeatureRegistry } from './chat.feature.registry';
31
+ import type { ImagePart, TextPart, ToolCallPart } from 'ai';
32
32
 
33
33
  export type IChatProgressResponseContent =
34
34
  | IChatMarkdownContent
@@ -296,13 +296,10 @@ export class ChatRequestModel implements IChatRequestModel {
296
296
  export class ChatModel extends Disposable implements IChatModel {
297
297
  private requestIdPool = 0;
298
298
 
299
- constructor(
300
- private chatFeatureRegistry: ChatFeatureRegistry,
301
- initParams?: { sessionId?: string; history?: MsgHistoryManager; modelId?: string },
302
- ) {
299
+ constructor(initParams?: { sessionId?: string; history?: MsgHistoryManager; modelId?: string }) {
303
300
  super();
304
301
  this.#sessionId = initParams?.sessionId ?? uuid();
305
- this.history = initParams?.history ?? new MsgHistoryManager(this.chatFeatureRegistry);
302
+ this.history = initParams?.history ?? new MsgHistoryManager();
306
303
  this.#modelId = initParams?.modelId;
307
304
  }
308
305
 
@@ -339,142 +336,88 @@ export class ChatModel extends Disposable implements IChatModel {
339
336
  this.#modelId = modelId;
340
337
  }
341
338
 
342
- private processMemorySummaries(): CoreMessage[] {
343
- const memorySummaries = this.history.getMemorySummaries();
344
- if (memorySummaries.length === 0) {
345
- return [];
346
- }
347
-
348
- const processedSummaries = memorySummaries
349
- .map((summary) => {
350
- try {
351
- const parsed = JSON.parse(summary.content);
352
- return parsed.memory || parsed.content || summary.content;
353
- } catch {
354
- return summary.content;
355
- }
356
- })
357
- .filter((content) => content && content !== 'no_memory_needed')
358
- .filter((content, index, self) => self.indexOf(content) === index);
359
-
360
- return processedSummaries.length > 0
361
- ? [
362
- {
363
- role: 'system',
364
- content: '以下是之前对话的总结:\n' + processedSummaries.join('\n\n'),
365
- },
366
- ]
367
- : [];
368
- }
369
-
370
- private processToolCall(part: IChatToolContent, history: CoreMessage[]): void {
371
- if (history[history.length - 1].role !== 'assistant') {
372
- history.push({
373
- role: 'assistant',
374
- content: [],
375
- });
376
- }
377
-
378
- const toolCallId = part.content.id;
379
- const toolCallInfo = {
380
- id: toolCallId,
381
- name: part.content.function.name,
382
- args: this.parseJsonSafely(part.content.function.arguments || '{}', 'tool call arguments'),
383
- result: this.parseJsonSafely(part.content.result || '{}', 'tool result'),
384
- };
385
-
386
- this.history.addToolCall(toolCallInfo);
387
- this.history.setMessageAdditional(part.content.id, { toolCallId });
388
-
389
- const lastMessage = history[history.length - 1];
390
- lastMessage.content = [
391
- {
392
- type: 'tool-call',
393
- toolCallId: part.content.id,
394
- toolName: part.content.function.name,
395
- args: toolCallInfo.args,
396
- },
397
- ];
398
-
399
- history.push({
400
- role: 'tool',
401
- content: [
402
- {
403
- type: 'tool-result',
404
- toolCallId: part.content.id,
405
- toolName: part.content.function.name,
406
- result: toolCallInfo.result,
407
- },
408
- ],
409
- });
410
- }
411
-
412
- private parseJsonSafely(jsonString: string, context: string): any {
413
- try {
414
- return JSON.parse(jsonString);
415
- } catch (e) {
416
- console.error(`[ChatModel] Failed to parse ${context}:`, e);
417
- return {};
418
- }
419
- }
420
-
421
- private processRecentMessages(): CoreMessage[] {
339
+ getMessageHistory(contextWindow?: number) {
422
340
  const history: CoreMessage[] = [];
423
- // MsgHistoryManager 获取消息,并过滤掉已总结的消息
424
- const recentMessages = this.history
425
- .getMessages()
426
- .filter((msg) => !msg.isSummarized)
427
- .slice(-this.history.memoryConfig.shortTermSize);
428
-
429
- for (const message of recentMessages) {
341
+ for (const request of this.requests) {
342
+ if (!request.response.isComplete) {
343
+ continue;
344
+ }
430
345
  history.push({
431
346
  role: 'user',
432
- content: message.content,
347
+ content: request.message.images?.length
348
+ ? [
349
+ { type: 'text', text: request.message.prompt },
350
+ ...request.message.images.map((image) => ({ type: 'image', image: new URL(image) } as ImagePart)),
351
+ ]
352
+ : request.message.prompt,
433
353
  });
434
-
435
- // 如果有响应内容,添加响应
436
- const additional = this.history.getMessageAdditional(message.id);
437
- if (additional?.response) {
438
- const response = additional.response;
439
- if (response.kind === 'toolCall') {
440
- this.processToolCall(response, history);
441
- } else {
354
+ for (const part of request.response.responseParts) {
355
+ if (part.kind === 'treeData' || part.kind === 'component') {
356
+ continue;
357
+ }
358
+ if (part.kind !== 'toolCall') {
442
359
  history.push({
443
360
  role: 'assistant',
444
- content: response.kind === 'markdownContent' ? response.content.value : response.content,
361
+ content: [
362
+ {
363
+ type: 'text',
364
+ text: part.kind === 'markdownContent' ? part.content.value : part.content,
365
+ },
366
+ ],
367
+ });
368
+ } else {
369
+ // 直接开始toolCall场景
370
+ if (history[history.length - 1].role !== 'assistant') {
371
+ history.push({
372
+ role: 'assistant',
373
+ content: [],
374
+ });
375
+ }
376
+ (history[history.length - 1].content as Array<TextPart | ToolCallPart>).push({
377
+ type: 'tool-call',
378
+ toolCallId: part.content.id,
379
+ toolName: part.content.function.name,
380
+ args: (() => {
381
+ try {
382
+ return JSON.parse(part.content.function.arguments || '{}');
383
+ } catch (e) {
384
+ console.error('Failed to parse tool call arguments:', e);
385
+ return {};
386
+ }
387
+ })(),
388
+ });
389
+ history.push({
390
+ role: 'tool',
391
+ content: [
392
+ {
393
+ type: 'tool-result',
394
+ toolCallId: part.content.id,
395
+ toolName: part.content.function.name,
396
+ result: (() => {
397
+ try {
398
+ return JSON.parse(part.content.result || '{}');
399
+ } catch (e) {
400
+ console.error('Failed to parse tool result:', e);
401
+ return {};
402
+ }
403
+ })(),
404
+ },
405
+ ],
445
406
  });
446
407
  }
447
408
  }
448
409
  }
449
-
450
- return history;
451
- }
452
-
453
- private limitTokens(history: CoreMessage[], contextWindow?: number): CoreMessage[] {
454
- if (!contextWindow) {
455
- return history;
456
- }
457
-
458
- let currentHistory = history;
459
- let tokenCount = JSON.stringify(currentHistory).length / 3;
460
-
461
- while (tokenCount > contextWindow && currentHistory.length > 1) {
462
- if (currentHistory[0].role === 'system' && currentHistory.length > 2) {
463
- currentHistory = [currentHistory[0], ...currentHistory.slice(2)];
464
- } else {
465
- currentHistory = currentHistory.slice(1);
410
+ if (contextWindow) {
411
+ while (this.#slicedMessageCount < history.length) {
412
+ // 简单的使用 JSON.stringify 计算 token 数量
413
+ const tokenCount = JSON.stringify(history.slice(this.#slicedMessageCount)).length / 3;
414
+ if (tokenCount <= contextWindow) {
415
+ break;
416
+ }
417
+ this.#slicedMessageCount++;
466
418
  }
467
- tokenCount = JSON.stringify(currentHistory).length / 3;
468
419
  }
469
-
470
- return currentHistory;
471
- }
472
-
473
- getMessageHistory(contextWindow?: number): CoreMessage[] {
474
- const memorySummaries = this.processMemorySummaries();
475
- const recentMessages = this.processRecentMessages();
476
- const history = [...memorySummaries, ...recentMessages];
477
- return this.limitTokens(history, contextWindow);
420
+ return history.slice(this.#slicedMessageCount);
478
421
  }
479
422
 
480
423
  addRequest(message: IChatRequestMessage): ChatRequestModel {
@@ -1,16 +1,18 @@
1
1
  import { Autowired, Injectable } from '@opensumi/di';
2
- import { PreferenceService } from '@opensumi/ide-core-browser';
2
+ import { AppConfig, PreferenceService } from '@opensumi/ide-core-browser';
3
3
  import {
4
4
  AIBackSerivcePath,
5
5
  CancellationToken,
6
6
  ChatAgentViewServiceToken,
7
7
  ChatFeatureRegistryToken,
8
+ ChatServiceToken,
8
9
  Deferred,
9
10
  Disposable,
10
11
  IAIBackService,
11
12
  IAIReporter,
12
13
  IApplicationService,
13
14
  IChatProgress,
15
+ getOperatingSystemName,
14
16
  } from '@opensumi/ide-core-common';
15
17
  import { AINativeSettingSectionsId } from '@opensumi/ide-core-common/lib/settings/ai-native';
16
18
  import { MonacoCommandRegistry } from '@opensumi/ide-editor/lib/browser/monaco-contrib/command/command.service';
@@ -25,10 +27,10 @@ import {
25
27
  IChatAgentService,
26
28
  IChatAgentWelcomeMessage,
27
29
  } from '../../common';
28
- import { DEFAULT_SYSTEM_PROMPT } from '../../common/prompts/system-prompt';
29
30
  import { ChatToolRender } from '../components/ChatToolRender';
30
31
  import { IChatAgentViewService } from '../types';
31
32
 
33
+ import { ChatService } from './chat.api.service';
32
34
  import { ChatFeatureRegistry } from './chat.feature.registry';
33
35
 
34
36
  /**
@@ -51,6 +53,9 @@ export class ChatProxyService extends Disposable {
51
53
  @Autowired(MonacoCommandRegistry)
52
54
  private readonly monacoCommandRegistry: MonacoCommandRegistry;
53
55
 
56
+ @Autowired(ChatServiceToken)
57
+ private aiChatService: ChatService;
58
+
54
59
  @Autowired(IAIReporter)
55
60
  private readonly aiReporter: IAIReporter;
56
61
 
@@ -66,6 +71,9 @@ export class ChatProxyService extends Disposable {
66
71
  @Autowired(IMessageService)
67
72
  private readonly messageService: IMessageService;
68
73
 
74
+ @Autowired(AppConfig)
75
+ private readonly appConfig: AppConfig;
76
+
69
77
  private chatDeferred: Deferred<void> = new Deferred<void>();
70
78
 
71
79
  public getRequestOptions() {
@@ -104,74 +112,79 @@ export class ChatProxyService extends Disposable {
104
112
  initialProps: {},
105
113
  });
106
114
 
107
- this.applicationService.getBackendOS().then(() => {
108
- this.addDispose(
109
- this.chatAgentService.registerAgent({
110
- id: ChatProxyService.AGENT_ID,
111
- metadata: {
112
- systemPrompt: this.preferenceService.get<string>(
115
+ this.addDispose(
116
+ this.chatAgentService.registerAgent({
117
+ id: ChatProxyService.AGENT_ID,
118
+ metadata: {
119
+ systemPrompt:
120
+ this.preferenceService.get<string>(
113
121
  AINativeSettingSectionsId.SystemPrompt,
114
- DEFAULT_SYSTEM_PROMPT,
115
- ),
116
- },
117
- invoke: async (
118
- request: IChatAgentRequest,
119
- progress: (part: IChatProgress) => void,
120
- history: CoreMessage[],
121
- token: CancellationToken,
122
- ): Promise<IChatAgentResult> => {
123
- this.chatDeferred = new Deferred<void>();
124
- const { message, command } = request;
125
- let prompt: string = message;
126
- if (command) {
127
- const commandHandler = this.chatFeatureRegistry.getSlashCommandHandler(command);
128
- if (commandHandler && commandHandler.providerPrompt) {
129
- const editor = this.monacoCommandRegistry.getActiveCodeEditor();
130
- const slashCommandPrompt = await commandHandler.providerPrompt(message, editor);
131
- prompt = slashCommandPrompt;
132
- }
122
+ 'You are a powerful AI coding assistant working in OpenSumi, a top IDE framework. You collaborate with a USER to solve coding tasks, which may involve creating, modifying, or debugging code, or answering questions. When the USER sends a message, relevant context (e.g., open files, cursor position, edit history, linter errors) may be attached. Use this information as needed.\n\n<tool_calling>\nYou have access to tools to assist with tasks. Follow these rules:\n1. Always adhere to the tool call schema and provide all required parameters.\n2. Only use tools explicitly provided; ignore unavailable ones.\n3. Avoid mentioning tool names to the USER (e.g., say "I will edit your file" instead of "I need to use the edit_file tool").\n4. Only call tools when necessary; respond directly if the task is general or you already know the answer.\n5. Explain to the USER why you’re using a tool before calling it.\n</tool_calling>\n\n<making_code_changes>\nWhen modifying code:\n1. Use code edit tools instead of outputting code unless explicitly requested.\n2. Limit tool calls to one per turn.\n3. Ensure generated code is immediately executable by including necessary imports, dependencies, and endpoints.\n4. For new projects, create a dependency management file (e.g., requirements.txt) and a README.\n5. For web apps, design a modern, user-friendly UI.\n6. Avoid generating non-textual or excessively long code.\n7. Read file contents before editing, unless appending a small change or creating a new file.\n8. Fix introduced linter errors if possible, but stop after 3 attempts and ask the USER for guidance.\n9. Reapply reasonable code edits if they weren’t followed initially.\n</making_code_changes>\n\nUse the appropriate tools to fulfill the USER’s request, ensuring all required parameters are provided or inferred from context.',
123
+ ) +
124
+ `\n\n<user_info>\nThe user's OS is ${getOperatingSystemName()}. The absolute path of the user's workspace is ${
125
+ this.appConfig.workspaceDir
126
+ }.\n</user_info>`,
127
+ },
128
+ invoke: async (
129
+ request: IChatAgentRequest,
130
+ progress: (part: IChatProgress) => void,
131
+ history: CoreMessage[],
132
+ token: CancellationToken,
133
+ ): Promise<IChatAgentResult> => {
134
+ this.chatDeferred = new Deferred<void>();
135
+
136
+ const { message, command } = request;
137
+ let prompt: string = message;
138
+
139
+ if (command) {
140
+ const commandHandler = this.chatFeatureRegistry.getSlashCommandHandler(command);
141
+ if (commandHandler && commandHandler.providerPrompt) {
142
+ const editor = this.monacoCommandRegistry.getActiveCodeEditor();
143
+ const slashCommandPrompt = await commandHandler.providerPrompt(message, editor);
144
+ prompt = slashCommandPrompt;
133
145
  }
134
-
135
- const stream = await this.aiBackService.requestStream(
136
- prompt,
137
- {
138
- requestId: request.requestId,
139
- sessionId: request.sessionId,
140
- history,
141
- images: request.images,
142
- ...this.getRequestOptions(),
143
- },
144
- token,
145
- );
146
-
147
- listenReadable<IChatProgress>(stream, {
148
- onData: (data) => {
149
- progress(data);
150
- },
151
- onEnd: () => {
152
- this.chatDeferred.resolve();
153
- },
154
- onError: (error) => {
155
- this.messageService.error(error.message);
156
- this.aiReporter.end(request.sessionId + '_' + request.requestId, {
157
- message: error.message,
158
- success: false,
159
- command,
160
- });
161
- },
162
- });
163
-
164
- await this.chatDeferred.promise;
165
- return {};
166
- },
167
- provideSlashCommands: async (): Promise<IChatAgentCommand[]> =>
168
- this.chatFeatureRegistry
169
- .getAllSlashCommand()
170
- .map((s) => ({ ...s, name: s.name, description: s.description || '' })),
171
- provideChatWelcomeMessage: async (): Promise<IChatAgentWelcomeMessage | undefined> => undefined,
172
- }),
173
- );
174
- });
146
+ }
147
+
148
+ const stream = await this.aiBackService.requestStream(
149
+ prompt,
150
+ {
151
+ requestId: request.requestId,
152
+ sessionId: request.sessionId,
153
+ history,
154
+ images: request.images,
155
+ ...this.getRequestOptions(),
156
+ },
157
+ token,
158
+ );
159
+
160
+ listenReadable<IChatProgress>(stream, {
161
+ onData: (data) => {
162
+ progress(data);
163
+ },
164
+ onEnd: () => {
165
+ this.chatDeferred.resolve();
166
+ },
167
+ onError: (error) => {
168
+ this.messageService.error(error.message);
169
+ this.aiReporter.end(request.sessionId + '_' + request.requestId, {
170
+ message: error.message,
171
+ success: false,
172
+ command,
173
+ });
174
+ },
175
+ });
176
+
177
+ await this.chatDeferred.promise;
178
+ return {};
179
+ },
180
+ provideSlashCommands: async (token: CancellationToken): Promise<IChatAgentCommand[]> =>
181
+ this.chatFeatureRegistry
182
+ .getAllSlashCommand()
183
+ .map((s) => ({ ...s, name: s.name, description: s.description || '' })),
184
+ provideChatWelcomeMessage: async (token: CancellationToken): Promise<IChatAgentWelcomeMessage | undefined> =>
185
+ undefined,
186
+ }),
187
+ );
175
188
 
176
189
  queueMicrotask(() => {
177
190
  this.chatAgentService.updateAgent(ChatProxyService.AGENT_ID, {});
@@ -2,13 +2,7 @@ import { Injectable } from '@opensumi/di';
2
2
  import { Disposable, Emitter, Event, getDebugLogger } from '@opensumi/ide-core-common';
3
3
 
4
4
  import { IChatWelcomeMessageContent, ISampleQuestions, SLASH_SYMBOL } from '../../common';
5
- import {
6
- IChatFeatureRegistry,
7
- IChatSlashCommandHandler,
8
- IChatSlashCommandItem,
9
- IImageUploadProvider,
10
- IMessageSummaryProvider,
11
- } from '../types';
5
+ import { IChatFeatureRegistry, IChatSlashCommandHandler, IChatSlashCommandItem, IImageUploadProvider } from '../types';
12
6
 
13
7
  import { ChatSlashCommandItemModel, ChatWelcomeMessageModel } from './chat-model';
14
8
  import { ChatProxyService } from './chat-proxy.service';
@@ -20,8 +14,6 @@ export class ChatFeatureRegistry extends Disposable implements IChatFeatureRegis
20
14
  private slashCommandsHandlerMap: Map<string, IChatSlashCommandHandler> = new Map();
21
15
  private imageUploadProvider: IImageUploadProvider | undefined;
22
16
 
23
- private messageSummaryProvider?: IMessageSummaryProvider;
24
-
25
17
  public registerImageUploadProvider(provider: IImageUploadProvider): void {
26
18
  this.imageUploadProvider = provider;
27
19
  }
@@ -30,14 +22,6 @@ export class ChatFeatureRegistry extends Disposable implements IChatFeatureRegis
30
22
  return this.imageUploadProvider;
31
23
  }
32
24
 
33
- public registerMessageSummaryProvider(provider: IMessageSummaryProvider): void {
34
- this.messageSummaryProvider = provider;
35
- }
36
-
37
- public getMessageSummaryProvider(): IMessageSummaryProvider | undefined {
38
- return this.messageSummaryProvider;
39
- }
40
-
41
25
  public chatWelcomeMessageModel?: ChatWelcomeMessageModel;
42
26
 
43
27
  private _onDidWelcomeMessageChange: Emitter<void> = new Emitter<void>();
@@ -1,4 +1,3 @@
1
- import debounce from 'lodash/debounce';
2
1
  import * as React from 'react';
3
2
  import { MessageList } from 'react-chat-elements';
4
3
 
@@ -618,12 +617,7 @@ export const AIChatView = () => {
618
617
  const { message, images, agentId, command, reportExtra } = value;
619
618
  const { actionType, actionSource } = reportExtra || {};
620
619
 
621
- const request = aiChatService.createRequest(
622
- message.replaceAll(LLM_CONTEXT_KEY_REGEX, ''),
623
- agentId!,
624
- images,
625
- command,
626
- );
620
+ const request = aiChatService.createRequest(message, agentId!, images, command);
627
621
  if (!request) {
628
622
  return;
629
623
  }
@@ -647,7 +641,7 @@ export const AIChatView = () => {
647
641
  600 * 1000,
648
642
  );
649
643
  msgHistoryManager.addUserMessage({
650
- content: message,
644
+ content: message.replaceAll(LLM_CONTEXT_KEY_REGEX, ''),
651
645
  images: images || [],
652
646
  agentId: agentId!,
653
647
  agentCommand: command!,
@@ -701,9 +695,14 @@ export const AIChatView = () => {
701
695
  let processedContent = message;
702
696
  const filePattern = /\{\{@file:(.*?)\}\}/g;
703
697
  const fileMatches = message.match(filePattern);
698
+ let isCleanContext = false;
704
699
  if (fileMatches) {
705
700
  for (const match of fileMatches) {
706
701
  const filePath = match.replace(/\{\{@file:(.*?)\}\}/, '$1');
702
+ if (filePath && !isCleanContext) {
703
+ isCleanContext = true;
704
+ llmContextService.cleanFileContext();
705
+ }
707
706
  const fileUri = new URI(filePath);
708
707
  const relativePath = (await workspaceService.asRelativePath(fileUri))?.path || fileUri.displayName;
709
708
  processedContent = processedContent.replace(match, `\`${LLM_CONTEXT_KEY.AttachedFile}${relativePath}\``);
@@ -739,18 +738,6 @@ export const AIChatView = () => {
739
738
  );
740
739
  }
741
740
  }
742
- const rulePattern = /\{\{@rule:(.*?)\}\}/g;
743
- const ruleMatches = processedContent.match(rulePattern);
744
- if (ruleMatches) {
745
- for (const match of ruleMatches) {
746
- const ruleName = match.replace(/\{\{@rule:(.*?)\}\}/, '$1');
747
- const ruleUri = new URI(ruleName);
748
- processedContent = processedContent.replace(
749
- match,
750
- `\`${LLM_CONTEXT_KEY.AttachedFile}${ruleUri.displayName}\``,
751
- );
752
- }
753
- }
754
741
  return handleAgentReply({ message: processedContent, images, agentId, command, reportExtra });
755
742
  },
756
743
  [handleAgentReply],
@@ -931,7 +918,6 @@ export function DefaultChatViewHeader({
931
918
  }) {
932
919
  const aiChatService = useInjectable<ChatInternalService>(IChatInternalService);
933
920
  const messageService = useInjectable<IMessageService>(IMessageService);
934
- const chatFeatureRegistry = useInjectable<ChatFeatureRegistry>(ChatFeatureRegistryToken);
935
921
 
936
922
  const [historyList, setHistoryList] = React.useState<IChatHistoryItem[]>([]);
937
923
  const [currentTitle, setCurrentTitle] = React.useState<string>('');
@@ -957,60 +943,13 @@ export function DefaultChatViewHeader({
957
943
  [aiChatService],
958
944
  );
959
945
 
960
- // 防抖函数,避免频繁触发摘要生成
961
- const debouncedGetSummary = React.useCallback(
962
- debounce(
963
- async (messages: { role: ChatMessageRole; content: string }[], currentTitle: string): Promise<string> => {
964
- const summaryProvider = chatFeatureRegistry.getMessageSummaryProvider();
965
- if (!summaryProvider || !aiChatService.sessionModel.sessionId) {
966
- return currentTitle;
967
- }
968
-
969
- try {
970
- const summary = await summaryProvider.getMessageSummary(messages);
971
- return summary ? summary.slice(0, MAX_TITLE_LENGTH) : currentTitle;
972
- } catch (error) {
973
- return currentTitle;
974
- }
975
- },
976
- 1000,
977
- { leading: false, trailing: true },
978
- ),
979
- [chatFeatureRegistry, aiChatService.sessionModel.sessionId],
980
- );
981
-
982
- // 使用 ref 来跟踪最新的请求
983
- const latestSummaryRequestRef = React.useRef<number>(0);
984
-
985
946
  React.useEffect(() => {
986
- const getHistoryList = async () => {
947
+ const getHistoryList = () => {
987
948
  const currentMessages = aiChatService.sessionModel.history.getMessages();
988
- const latestUserMessage = [...currentMessages].find((m) => m.role === ChatMessageRole.User);
989
- const currentTitle = latestUserMessage
990
- ? cleanAttachedTextWrapper(latestUserMessage.content).slice(0, MAX_TITLE_LENGTH)
991
- : '';
992
-
993
- // 设置初始标题
994
- setCurrentTitle(currentTitle);
995
-
996
- const messages = currentMessages.map((msg) => ({
997
- role: msg.role,
998
- content: msg.content,
999
- }));
1000
-
1001
- // 只有当消息数量超过阈值时才生成摘要
1002
- if (messages.length > 2) {
1003
- const requestId = Date.now();
1004
- latestSummaryRequestRef.current = requestId;
1005
-
1006
- const summary = await debouncedGetSummary(messages, currentTitle);
1007
-
1008
- // 检查是否是最新请求
1009
- if (requestId === latestSummaryRequestRef.current && summary) {
1010
- setCurrentTitle(summary);
1011
- }
1012
- }
1013
-
949
+ const latestUserMessage = currentMessages.findLast((m) => m.role === ChatMessageRole.User);
950
+ setCurrentTitle(
951
+ latestUserMessage ? cleanAttachedTextWrapper(latestUserMessage.content).slice(0, MAX_TITLE_LENGTH) : '',
952
+ );
1014
953
  setHistoryList(
1015
954
  aiChatService.getSessions().map((session) => {
1016
955
  const history = session.history;
@@ -25,7 +25,7 @@ import {
25
25
  localize,
26
26
  runWhenIdle,
27
27
  } from '@opensumi/ide-core-common';
28
- import { insertSnippetWithMonacoEditor } from '@opensumi/ide-editor/lib/browser/editor-collection.service';
28
+ import { insertSnippetWithMonacoEditor } from '@opensumi/ide-editor/lib/browser/base-editor-wrapper';
29
29
  import { MonacoCommandRegistry } from '@opensumi/ide-editor/lib/browser/monaco-contrib/command/command.service';
30
30
  import { ITheme, IThemeService } from '@opensumi/ide-theme';
31
31
  import { WorkbenchThemeService } from '@opensumi/ide-theme/lib/browser/workbench.theme.service';
@@ -216,8 +216,7 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
216
216
  // 渲染历史记录列表
217
217
  const renderHistory = useCallback(() => {
218
218
  const filteredList = historyList
219
- .slice(-MAX_HISTORY_LIST)
220
- .reverse()
219
+ .slice(0, MAX_HISTORY_LIST)
221
220
  .filter((item) => item.title && item.title.includes(searchValue));
222
221
 
223
222
  const groupedHistoryList = formatHistory(filteredList);