@opensumi/ide-ai-native 3.9.1-next-1748944723.0 → 3.9.1-next-1749007675.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/lib/browser/chat/chat-manager.service.d.ts +1 -0
  2. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  3. package/lib/browser/chat/chat-manager.service.js +8 -3
  4. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  5. package/lib/browser/chat/chat-model.d.ts +3 -1
  6. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  7. package/lib/browser/chat/chat-model.js +48 -17
  8. package/lib/browser/chat/chat-model.js.map +1 -1
  9. package/lib/browser/chat/chat-proxy.service.d.ts +2 -0
  10. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-proxy.service.js +57 -50
  12. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  13. package/lib/browser/chat/chat.feature.registry.d.ts +4 -1
  14. package/lib/browser/chat/chat.feature.registry.d.ts.map +1 -1
  15. package/lib/browser/chat/chat.feature.registry.js +6 -0
  16. package/lib/browser/chat/chat.feature.registry.js.map +1 -1
  17. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  18. package/lib/browser/chat/chat.view.js +29 -12
  19. package/lib/browser/chat/chat.view.js.map +1 -1
  20. package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
  21. package/lib/browser/components/ChatMentionInput.js +30 -141
  22. package/lib/browser/components/ChatMentionInput.js.map +1 -1
  23. package/lib/browser/components/ChatToolRender.module.less +0 -1
  24. package/lib/browser/components/components.module.less +7 -9
  25. package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
  26. package/lib/browser/components/mention-input/mention-input.js +14 -176
  27. package/lib/browser/components/mention-input/mention-input.js.map +1 -1
  28. package/lib/browser/components/mention-input/mention-input.module.less +1 -165
  29. package/lib/browser/components/mention-input/types.d.ts +1 -16
  30. package/lib/browser/components/mention-input/types.d.ts.map +1 -1
  31. package/lib/browser/components/mention-input/types.js +0 -1
  32. package/lib/browser/components/mention-input/types.js.map +1 -1
  33. package/lib/browser/components/utils.d.ts +2 -2
  34. package/lib/browser/context/llm-context.service.d.ts +2 -21
  35. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  36. package/lib/browser/context/llm-context.service.js +20 -162
  37. package/lib/browser/context/llm-context.service.js.map +1 -1
  38. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -1
  39. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -1
  40. package/lib/browser/contrib/intelligent-completions/diff-computer.js +1 -1
  41. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -1
  42. package/lib/browser/contrib/terminal/terminal.feature.registry.js.map +1 -1
  43. package/lib/browser/index.d.ts.map +1 -1
  44. package/lib/browser/index.js +0 -7
  45. package/lib/browser/index.js.map +1 -1
  46. package/lib/browser/mcp/base-apply.service.d.ts +2 -2
  47. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  48. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  49. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  50. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
  51. package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
  52. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  53. package/lib/browser/model/msg-history-manager.d.ts +39 -1
  54. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  55. package/lib/browser/model/msg-history-manager.js +170 -3
  56. package/lib/browser/model/msg-history-manager.js.map +1 -1
  57. package/lib/browser/preferences/schema.d.ts.map +1 -1
  58. package/lib/browser/preferences/schema.js +0 -5
  59. package/lib/browser/preferences/schema.js.map +1 -1
  60. package/lib/browser/types.d.ts +8 -1
  61. package/lib/browser/types.d.ts.map +1 -1
  62. package/lib/browser/types.js.map +1 -1
  63. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  64. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  65. package/lib/common/index.d.ts +0 -2
  66. package/lib/common/index.d.ts.map +1 -1
  67. package/lib/common/index.js +0 -2
  68. package/lib/common/index.js.map +1 -1
  69. package/lib/common/llm-context.d.ts +0 -19
  70. package/lib/common/llm-context.d.ts.map +1 -1
  71. package/lib/common/llm-context.js.map +1 -1
  72. package/lib/common/prompts/context-prompt-provider.d.ts +2 -0
  73. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  74. package/lib/common/prompts/context-prompt-provider.js +29 -35
  75. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  76. package/lib/common/types.d.ts +0 -7
  77. package/lib/common/types.d.ts.map +1 -1
  78. package/lib/node/base-language-model.d.ts.map +1 -1
  79. package/lib/node/base-language-model.js.map +1 -1
  80. package/package.json +24 -25
  81. package/src/browser/chat/chat-manager.service.ts +15 -6
  82. package/src/browser/chat/chat-model.ts +56 -19
  83. package/src/browser/chat/chat-proxy.service.ts +81 -68
  84. package/src/browser/chat/chat.feature.registry.ts +17 -1
  85. package/src/browser/chat/chat.view.tsx +28 -22
  86. package/src/browser/components/ChatMentionInput.tsx +35 -169
  87. package/src/browser/components/ChatToolRender.module.less +0 -1
  88. package/src/browser/components/components.module.less +7 -9
  89. package/src/browser/components/mention-input/mention-input.module.less +1 -165
  90. package/src/browser/components/mention-input/mention-input.tsx +32 -274
  91. package/src/browser/components/mention-input/types.ts +0 -16
  92. package/src/browser/context/llm-context.service.ts +21 -182
  93. package/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts +1 -1
  94. package/src/browser/contrib/intelligent-completions/diff-computer.ts +1 -1
  95. package/src/browser/contrib/terminal/terminal.feature.registry.ts +1 -1
  96. package/src/browser/index.ts +0 -8
  97. package/src/browser/mcp/base-apply.service.ts +1 -0
  98. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
  99. package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
  100. package/src/browser/mcp/tools/handlers/ListDir.ts +1 -1
  101. package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
  102. package/src/browser/model/msg-history-manager.ts +230 -3
  103. package/src/browser/preferences/schema.ts +0 -5
  104. package/src/browser/types.ts +12 -0
  105. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +1 -0
  106. package/src/common/index.ts +0 -3
  107. package/src/common/llm-context.ts +0 -23
  108. package/src/common/prompts/context-prompt-provider.ts +40 -55
  109. package/src/common/types.ts +0 -8
  110. package/src/node/base-language-model.ts +1 -0
  111. package/lib/browser/components/mention-input/mention-select.d.ts +0 -28
  112. package/lib/browser/components/mention-input/mention-select.d.ts.map +0 -1
  113. package/lib/browser/components/mention-input/mention-select.js +0 -136
  114. package/lib/browser/components/mention-input/mention-select.js.map +0 -1
  115. package/lib/browser/components/mention-input/mention-select.module.less +0 -297
  116. package/lib/browser/rules/rules.contribution.d.ts +0 -29
  117. package/lib/browser/rules/rules.contribution.d.ts.map +0 -1
  118. package/lib/browser/rules/rules.contribution.js +0 -94
  119. package/lib/browser/rules/rules.contribution.js.map +0 -1
  120. package/lib/browser/rules/rules.module.less +0 -174
  121. package/lib/browser/rules/rules.service.d.ts +0 -25
  122. package/lib/browser/rules/rules.service.d.ts.map +0 -1
  123. package/lib/browser/rules/rules.service.js +0 -180
  124. package/lib/browser/rules/rules.service.js.map +0 -1
  125. package/lib/browser/rules/rules.view.d.ts +0 -3
  126. package/lib/browser/rules/rules.view.d.ts.map +0 -1
  127. package/lib/browser/rules/rules.view.js +0 -76
  128. package/lib/browser/rules/rules.view.js.map +0 -1
  129. package/lib/common/MDC_PARSER_README.md +0 -171
  130. package/lib/common/mdc-parser.d.ts +0 -60
  131. package/lib/common/mdc-parser.d.ts.map +0 -1
  132. package/lib/common/mdc-parser.js +0 -246
  133. package/lib/common/mdc-parser.js.map +0 -1
  134. package/lib/common/prompts/system-prompt.d.ts +0 -2
  135. package/lib/common/prompts/system-prompt.d.ts.map +0 -1
  136. package/lib/common/prompts/system-prompt.js +0 -5
  137. package/lib/common/prompts/system-prompt.js.map +0 -1
  138. package/src/browser/components/mention-input/mention-select.module.less +0 -297
  139. package/src/browser/components/mention-input/mention-select.tsx +0 -256
  140. package/src/browser/rules/rules.contribution.ts +0 -105
  141. package/src/browser/rules/rules.module.less +0 -174
  142. package/src/browser/rules/rules.service.ts +0 -189
  143. package/src/browser/rules/rules.view.tsx +0 -127
  144. package/src/common/MDC_PARSER_README.md +0 -171
  145. package/src/common/mdc-parser.ts +0 -295
  146. package/src/common/prompts/system-prompt.ts +0 -2
@@ -29,6 +29,7 @@ import { MsgHistoryManager } from '../model/msg-history-manager';
29
29
  import { IChatSlashCommandItem } from '../types';
30
30
 
31
31
  import type { ImagePart, TextPart, ToolCallPart } from 'ai';
32
+ import { ChatFeatureRegistry } from './chat.feature.registry';
32
33
 
33
34
  export type IChatProgressResponseContent =
34
35
  | IChatMarkdownContent
@@ -296,10 +297,13 @@ export class ChatRequestModel implements IChatRequestModel {
296
297
  export class ChatModel extends Disposable implements IChatModel {
297
298
  private requestIdPool = 0;
298
299
 
299
- constructor(initParams?: { sessionId?: string; history?: MsgHistoryManager; modelId?: string }) {
300
+ constructor(
301
+ private chatFeatureRegistry: ChatFeatureRegistry,
302
+ initParams?: { sessionId?: string; history?: MsgHistoryManager; modelId?: string },
303
+ ) {
300
304
  super();
301
305
  this.#sessionId = initParams?.sessionId ?? uuid();
302
- this.history = initParams?.history ?? new MsgHistoryManager();
306
+ this.history = initParams?.history ?? new MsgHistoryManager(this.chatFeatureRegistry);
303
307
  this.#modelId = initParams?.modelId;
304
308
  }
305
309
 
@@ -346,9 +350,9 @@ export class ChatModel extends Disposable implements IChatModel {
346
350
  role: 'user',
347
351
  content: request.message.images?.length
348
352
  ? [
349
- { type: 'text', text: request.message.prompt },
350
- ...request.message.images.map((image) => ({ type: 'image', image: new URL(image) } as ImagePart)),
351
- ]
353
+ { type: 'text', text: request.message.prompt },
354
+ ...request.message.images.map((image) => ({ type: 'image', image: new URL(image) } as ImagePart)),
355
+ ]
352
356
  : request.message.prompt,
353
357
  });
354
358
  for (const part of request.response.responseParts) {
@@ -375,18 +379,58 @@ export class ChatModel extends Disposable implements IChatModel {
375
379
  content: [],
376
380
  });
377
381
  }
378
- (history[history.length - 1].content as Array<TextPart | ToolCallPart>).push({
379
- type: 'tool-call',
380
- toolCallId: part.content.id,
381
- toolName: part.content.function.name,
382
+ const toolCallId = part.content.id;
383
+ console.log('[ChatModel] Processing toolCall', {
384
+ toolCallId,
385
+ functionName: part.content.function.name,
386
+ hasArguments: !!part.content.function.arguments,
387
+ hasResult: !!part.content.result,
388
+ });
389
+
390
+ const toolCallInfo = {
391
+ id: toolCallId,
392
+ name: part.content.function.name,
382
393
  args: (() => {
383
394
  try {
384
- return JSON.parse(part.content.function.arguments || '{}');
395
+ const args = JSON.parse(part.content.function.arguments || '{}');
396
+ console.log('[ChatModel] Parsed toolCall arguments', {
397
+ toolCallId,
398
+ args,
399
+ });
400
+ return args;
401
+ } catch (e) {
402
+ console.error('[ChatModel] Failed to parse tool call arguments:', e);
403
+ return {};
404
+ }
405
+ })(),
406
+ result: (() => {
407
+ try {
408
+ const result = JSON.parse(part.content.result || '{}');
409
+ console.log('[ChatModel] Parsed toolCall result', {
410
+ toolCallId,
411
+ resultSize: JSON.stringify(result).length,
412
+ });
413
+ return result;
385
414
  } catch (e) {
386
- console.error('Failed to parse tool call arguments:', e);
415
+ console.error('[ChatModel] Failed to parse tool result:', e);
387
416
  return {};
388
417
  }
389
418
  })(),
419
+ };
420
+
421
+ // 保存 toolCall 信息到 history manager
422
+ console.log('[ChatModel] Saving toolCall to history manager', {
423
+ toolCallId,
424
+ requestId: request.requestId,
425
+ });
426
+ this.history.addToolCall(toolCallInfo);
427
+ this.history.setMessageAdditional(request.requestId, { toolCallId });
428
+
429
+ (history[history.length - 1].content as Array<TextPart | ToolCallPart>).push({
430
+ type: 'tool-call',
431
+ toolCallId: part.content.id,
432
+ toolName: part.content.function.name,
433
+ args: toolCallInfo.args,
390
434
  });
391
435
  history.push({
392
436
  role: 'tool',
@@ -395,14 +439,7 @@ export class ChatModel extends Disposable implements IChatModel {
395
439
  type: 'tool-result',
396
440
  toolCallId: part.content.id,
397
441
  toolName: part.content.function.name,
398
- result: (() => {
399
- try {
400
- return JSON.parse(part.content.result || '{}');
401
- } catch (e) {
402
- console.error('Failed to parse tool result:', e);
403
- return {};
404
- }
405
- })(),
442
+ result: toolCallInfo.result,
406
443
  },
407
444
  ],
408
445
  });
@@ -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,7 +2,13 @@ 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 { IChatFeatureRegistry, IChatSlashCommandHandler, IChatSlashCommandItem, IImageUploadProvider } from '../types';
5
+ import {
6
+ IChatFeatureRegistry,
7
+ IChatSlashCommandHandler,
8
+ IChatSlashCommandItem,
9
+ IImageUploadProvider,
10
+ IMessageSummaryProvider,
11
+ } from '../types';
6
12
 
7
13
  import { ChatSlashCommandItemModel, ChatWelcomeMessageModel } from './chat-model';
8
14
  import { ChatProxyService } from './chat-proxy.service';
@@ -14,6 +20,8 @@ export class ChatFeatureRegistry extends Disposable implements IChatFeatureRegis
14
20
  private slashCommandsHandlerMap: Map<string, IChatSlashCommandHandler> = new Map();
15
21
  private imageUploadProvider: IImageUploadProvider | undefined;
16
22
 
23
+ private messageSummaryProvider?: IMessageSummaryProvider;
24
+
17
25
  public registerImageUploadProvider(provider: IImageUploadProvider): void {
18
26
  this.imageUploadProvider = provider;
19
27
  }
@@ -22,6 +30,14 @@ export class ChatFeatureRegistry extends Disposable implements IChatFeatureRegis
22
30
  return this.imageUploadProvider;
23
31
  }
24
32
 
33
+ public registerMessageSummaryProvider(provider: IMessageSummaryProvider): void {
34
+ this.messageSummaryProvider = provider;
35
+ }
36
+
37
+ public getMessageSummaryProvider(): IMessageSummaryProvider | undefined {
38
+ return this.messageSummaryProvider;
39
+ }
40
+
25
41
  public chatWelcomeMessageModel?: ChatWelcomeMessageModel;
26
42
 
27
43
  private _onDidWelcomeMessageChange: Emitter<void> = new Emitter<void>();
@@ -617,12 +617,7 @@ export const AIChatView = () => {
617
617
  const { message, images, agentId, command, reportExtra } = value;
618
618
  const { actionType, actionSource } = reportExtra || {};
619
619
 
620
- const request = aiChatService.createRequest(
621
- message.replaceAll(LLM_CONTEXT_KEY_REGEX, ''),
622
- agentId!,
623
- images,
624
- command,
625
- );
620
+ const request = aiChatService.createRequest(message, agentId!, images, command);
626
621
  if (!request) {
627
622
  return;
628
623
  }
@@ -646,7 +641,7 @@ export const AIChatView = () => {
646
641
  600 * 1000,
647
642
  );
648
643
  msgHistoryManager.addUserMessage({
649
- content: message,
644
+ content: message.replaceAll(LLM_CONTEXT_KEY_REGEX, ''),
650
645
  images: images || [],
651
646
  agentId: agentId!,
652
647
  agentCommand: command!,
@@ -700,9 +695,14 @@ export const AIChatView = () => {
700
695
  let processedContent = message;
701
696
  const filePattern = /\{\{@file:(.*?)\}\}/g;
702
697
  const fileMatches = message.match(filePattern);
698
+ let isCleanContext = false;
703
699
  if (fileMatches) {
704
700
  for (const match of fileMatches) {
705
701
  const filePath = match.replace(/\{\{@file:(.*?)\}\}/, '$1');
702
+ if (filePath && !isCleanContext) {
703
+ isCleanContext = true;
704
+ llmContextService.cleanFileContext();
705
+ }
706
706
  const fileUri = new URI(filePath);
707
707
  const relativePath = (await workspaceService.asRelativePath(fileUri))?.path || fileUri.displayName;
708
708
  processedContent = processedContent.replace(match, `\`${LLM_CONTEXT_KEY.AttachedFile}${relativePath}\``);
@@ -738,18 +738,6 @@ export const AIChatView = () => {
738
738
  );
739
739
  }
740
740
  }
741
- const rulePattern = /\{\{@rule:(.*?)\}\}/g;
742
- const ruleMatches = processedContent.match(rulePattern);
743
- if (ruleMatches) {
744
- for (const match of ruleMatches) {
745
- const ruleName = match.replace(/\{\{@rule:(.*?)\}\}/, '$1');
746
- const ruleUri = new URI(ruleName);
747
- processedContent = processedContent.replace(
748
- match,
749
- `\`${LLM_CONTEXT_KEY.AttachedFile}${ruleUri.displayName}\``,
750
- );
751
- }
752
- }
753
741
  return handleAgentReply({ message: processedContent, images, agentId, command, reportExtra });
754
742
  },
755
743
  [handleAgentReply],
@@ -930,6 +918,7 @@ export function DefaultChatViewHeader({
930
918
  }) {
931
919
  const aiChatService = useInjectable<ChatInternalService>(IChatInternalService);
932
920
  const messageService = useInjectable<IMessageService>(IMessageService);
921
+ const chatFeatureRegistry = useInjectable<ChatFeatureRegistry>(ChatFeatureRegistryToken);
933
922
 
934
923
  const [historyList, setHistoryList] = React.useState<IChatHistoryItem[]>([]);
935
924
  const [currentTitle, setCurrentTitle] = React.useState<string>('');
@@ -959,9 +948,26 @@ export function DefaultChatViewHeader({
959
948
  const getHistoryList = () => {
960
949
  const currentMessages = aiChatService.sessionModel.history.getMessages();
961
950
  const latestUserMessage = currentMessages.findLast((m) => m.role === ChatMessageRole.User);
962
- setCurrentTitle(
963
- latestUserMessage ? cleanAttachedTextWrapper(latestUserMessage.content).slice(0, MAX_TITLE_LENGTH) : '',
964
- );
951
+ const summaryProvider = chatFeatureRegistry.getMessageSummaryProvider();
952
+ const currentTitle = latestUserMessage
953
+ ? cleanAttachedTextWrapper(latestUserMessage.content).slice(0, MAX_TITLE_LENGTH)
954
+ : '';
955
+ const messages = aiChatService.sessionModel.history.getMessages().map((msg) => ({
956
+ role: msg.role,
957
+ content: msg.content,
958
+ }));
959
+ if (messages.length > 2 && summaryProvider && aiChatService.sessionModel.sessionId) {
960
+ summaryProvider.getMessageSummary(messages).then((summary) => {
961
+ if (summary) {
962
+ setCurrentTitle(summary.slice(0, MAX_TITLE_LENGTH));
963
+ } else {
964
+ setCurrentTitle(currentTitle);
965
+ }
966
+ });
967
+ } else {
968
+ setCurrentTitle(currentTitle);
969
+ }
970
+
965
971
  setHistoryList(
966
972
  aiChatService.getSessions().map((session) => {
967
973
  const history = session.history;