@opensumi/ide-ai-native 3.9.1-next-1749175927.0 → 3.9.1-next-1749196667.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 (197) 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 -51
  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 +28 -124
  34. package/lib/browser/components/ChatMentionInput.js.map +1 -1
  35. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  36. package/lib/browser/components/ChatToolRender.js +2 -7
  37. package/lib/browser/components/ChatToolRender.js.map +1 -1
  38. package/lib/browser/components/ChatToolRender.module.less +0 -25
  39. package/lib/browser/components/components.module.less +0 -7
  40. package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
  41. package/lib/browser/components/mention-input/mention-input.js +13 -155
  42. package/lib/browser/components/mention-input/mention-input.js.map +1 -1
  43. package/lib/browser/components/mention-input/mention-input.module.less +0 -165
  44. package/lib/browser/components/mention-input/types.d.ts +1 -15
  45. package/lib/browser/components/mention-input/types.d.ts.map +1 -1
  46. package/lib/browser/components/mention-input/types.js +0 -1
  47. package/lib/browser/components/mention-input/types.js.map +1 -1
  48. package/lib/browser/components/utils.d.ts +2 -2
  49. package/lib/browser/context/llm-context.service.d.ts +2 -21
  50. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  51. package/lib/browser/context/llm-context.service.js +20 -162
  52. package/lib/browser/context/llm-context.service.js.map +1 -1
  53. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -1
  54. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -1
  55. package/lib/browser/contrib/intelligent-completions/diff-computer.js +1 -1
  56. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -1
  57. package/lib/browser/contrib/terminal/terminal.feature.registry.js.map +1 -1
  58. package/lib/browser/index.d.ts.map +1 -1
  59. package/lib/browser/index.js +0 -7
  60. package/lib/browser/index.js.map +1 -1
  61. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  62. package/lib/browser/layout/ai-layout.js +4 -6
  63. package/lib/browser/layout/ai-layout.js.map +1 -1
  64. package/lib/browser/layout/tabbar.view.d.ts +1 -1
  65. package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
  66. package/lib/browser/layout/tabbar.view.js +12 -5
  67. package/lib/browser/layout/tabbar.view.js.map +1 -1
  68. package/lib/browser/mcp/base-apply.service.d.ts +4 -5
  69. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  70. package/lib/browser/mcp/base-apply.service.js +5 -23
  71. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  72. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +1 -3
  73. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  74. package/lib/browser/mcp/mcp-server-proxy.service.js +0 -4
  75. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  76. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  77. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
  78. package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
  79. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  80. package/lib/browser/model/msg-history-manager.d.ts +1 -47
  81. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  82. package/lib/browser/model/msg-history-manager.js +2 -127
  83. package/lib/browser/model/msg-history-manager.js.map +1 -1
  84. package/lib/browser/preferences/schema.d.ts.map +1 -1
  85. package/lib/browser/preferences/schema.js +0 -5
  86. package/lib/browser/preferences/schema.js.map +1 -1
  87. package/lib/browser/types.d.ts +1 -12
  88. package/lib/browser/types.d.ts.map +1 -1
  89. package/lib/browser/types.js.map +1 -1
  90. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  91. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  92. package/lib/common/index.d.ts +1 -5
  93. package/lib/common/index.d.ts.map +1 -1
  94. package/lib/common/index.js +0 -2
  95. package/lib/common/index.js.map +1 -1
  96. package/lib/common/llm-context.d.ts +0 -19
  97. package/lib/common/llm-context.d.ts.map +1 -1
  98. package/lib/common/llm-context.js.map +1 -1
  99. package/lib/common/prompts/context-prompt-provider.d.ts +2 -0
  100. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  101. package/lib/common/prompts/context-prompt-provider.js +29 -35
  102. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  103. package/lib/common/types.d.ts +0 -21
  104. package/lib/common/types.d.ts.map +1 -1
  105. package/lib/common/types.js.map +1 -1
  106. package/lib/common/utils.d.ts +0 -1
  107. package/lib/common/utils.d.ts.map +1 -1
  108. package/lib/common/utils.js +2 -5
  109. package/lib/common/utils.js.map +1 -1
  110. package/lib/node/base-language-model.d.ts +1 -2
  111. package/lib/node/base-language-model.d.ts.map +1 -1
  112. package/lib/node/base-language-model.js +1 -10
  113. package/lib/node/base-language-model.js.map +1 -1
  114. package/lib/node/mcp/sumi-mcp-server.d.ts +1 -3
  115. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  116. package/lib/node/mcp/sumi-mcp-server.js +1 -7
  117. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  118. package/lib/node/mcp-server-manager-impl.d.ts +1 -3
  119. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  120. package/lib/node/mcp-server-manager-impl.js +2 -14
  121. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  122. package/package.json +24 -25
  123. package/src/browser/ai-core.contribution.ts +4 -14
  124. package/src/browser/chat/apply.service.ts +1 -62
  125. package/src/browser/chat/chat-manager.service.ts +7 -16
  126. package/src/browser/chat/chat-model.ts +73 -130
  127. package/src/browser/chat/chat-proxy.service.ts +81 -68
  128. package/src/browser/chat/chat.feature.registry.ts +1 -17
  129. package/src/browser/chat/chat.view.tsx +12 -74
  130. package/src/browser/components/ChatEditor.tsx +1 -1
  131. package/src/browser/components/ChatHistory.tsx +1 -2
  132. package/src/browser/components/ChatMentionInput.tsx +32 -144
  133. package/src/browser/components/ChatToolRender.module.less +0 -25
  134. package/src/browser/components/ChatToolRender.tsx +2 -10
  135. package/src/browser/components/components.module.less +0 -7
  136. package/src/browser/components/mention-input/mention-input.module.less +0 -165
  137. package/src/browser/components/mention-input/mention-input.tsx +29 -244
  138. package/src/browser/components/mention-input/types.ts +0 -15
  139. package/src/browser/context/llm-context.service.ts +21 -182
  140. package/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts +1 -1
  141. package/src/browser/contrib/intelligent-completions/diff-computer.ts +1 -1
  142. package/src/browser/contrib/terminal/terminal.feature.registry.ts +1 -1
  143. package/src/browser/index.ts +0 -8
  144. package/src/browser/layout/ai-layout.tsx +8 -12
  145. package/src/browser/layout/tabbar.view.tsx +23 -10
  146. package/src/browser/mcp/base-apply.service.ts +10 -30
  147. package/src/browser/mcp/mcp-server-proxy.service.ts +1 -6
  148. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
  149. package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
  150. package/src/browser/mcp/tools/handlers/ListDir.ts +1 -1
  151. package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
  152. package/src/browser/model/msg-history-manager.ts +2 -181
  153. package/src/browser/preferences/schema.ts +0 -5
  154. package/src/browser/types.ts +0 -18
  155. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +1 -0
  156. package/src/common/index.ts +1 -6
  157. package/src/common/llm-context.ts +0 -23
  158. package/src/common/prompts/context-prompt-provider.ts +40 -55
  159. package/src/common/types.ts +0 -18
  160. package/src/common/utils.ts +1 -4
  161. package/src/node/base-language-model.ts +13 -10
  162. package/src/node/mcp/sumi-mcp-server.ts +2 -10
  163. package/src/node/mcp-server-manager-impl.ts +2 -17
  164. package/lib/browser/rules/rules.contribution.d.ts +0 -29
  165. package/lib/browser/rules/rules.contribution.d.ts.map +0 -1
  166. package/lib/browser/rules/rules.contribution.js +0 -94
  167. package/lib/browser/rules/rules.contribution.js.map +0 -1
  168. package/lib/browser/rules/rules.module.less +0 -174
  169. package/lib/browser/rules/rules.service.d.ts +0 -25
  170. package/lib/browser/rules/rules.service.d.ts.map +0 -1
  171. package/lib/browser/rules/rules.service.js +0 -180
  172. package/lib/browser/rules/rules.service.js.map +0 -1
  173. package/lib/browser/rules/rules.view.d.ts +0 -3
  174. package/lib/browser/rules/rules.view.d.ts.map +0 -1
  175. package/lib/browser/rules/rules.view.js +0 -76
  176. package/lib/browser/rules/rules.view.js.map +0 -1
  177. package/lib/common/MDC_PARSER_README.md +0 -171
  178. package/lib/common/image-compression.d.ts +0 -25
  179. package/lib/common/image-compression.d.ts.map +0 -1
  180. package/lib/common/image-compression.js +0 -153
  181. package/lib/common/image-compression.js.map +0 -1
  182. package/lib/common/mdc-parser.d.ts +0 -60
  183. package/lib/common/mdc-parser.d.ts.map +0 -1
  184. package/lib/common/mdc-parser.js +0 -246
  185. package/lib/common/mdc-parser.js.map +0 -1
  186. package/lib/common/prompts/system-prompt.d.ts +0 -2
  187. package/lib/common/prompts/system-prompt.d.ts.map +0 -1
  188. package/lib/common/prompts/system-prompt.js +0 -5
  189. package/lib/common/prompts/system-prompt.js.map +0 -1
  190. package/src/browser/rules/rules.contribution.ts +0 -105
  191. package/src/browser/rules/rules.module.less +0 -174
  192. package/src/browser/rules/rules.service.ts +0 -189
  193. package/src/browser/rules/rules.view.tsx +0 -127
  194. package/src/common/MDC_PARSER_README.md +0 -171
  195. package/src/common/image-compression.ts +0 -174
  196. package/src/common/mdc-parser.ts +0 -295
  197. package/src/common/prompts/system-prompt.ts +0 -2
@@ -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>();
@@ -9,7 +9,6 @@ import {
9
9
  useInjectable,
10
10
  useUpdateOnEvent,
11
11
  } from '@opensumi/ide-core-browser';
12
- import debounce from 'lodash/debounce';
13
12
  import { Popover, PopoverPosition } from '@opensumi/ide-core-browser/lib/components';
14
13
  import { EnhanceIcon } from '@opensumi/ide-core-browser/lib/components/ai-native';
15
14
  import {
@@ -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,61 +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
- console.error('[ChatView] Failed to get message summary:', error);
974
- return currentTitle;
975
- }
976
- },
977
- 1000,
978
- { leading: false, trailing: true },
979
- ),
980
- [chatFeatureRegistry, aiChatService.sessionModel.sessionId],
981
- );
982
-
983
- // 使用 ref 来跟踪最新的请求
984
- const latestSummaryRequestRef = React.useRef<number>(0);
985
-
986
946
  React.useEffect(() => {
987
- const getHistoryList = async () => {
947
+ const getHistoryList = () => {
988
948
  const currentMessages = aiChatService.sessionModel.history.getMessages();
989
- const latestUserMessage = [...currentMessages].find((m) => m.role === ChatMessageRole.User);
990
- const currentTitle = latestUserMessage
991
- ? cleanAttachedTextWrapper(latestUserMessage.content).slice(0, MAX_TITLE_LENGTH)
992
- : '';
993
-
994
- // 设置初始标题
995
- setCurrentTitle(currentTitle);
996
-
997
- const messages = currentMessages.map((msg) => ({
998
- role: msg.role,
999
- content: msg.content,
1000
- }));
1001
-
1002
- // 只有当消息数量超过阈值时才生成摘要
1003
- if (messages.length > 2) {
1004
- const requestId = Date.now();
1005
- latestSummaryRequestRef.current = requestId;
1006
-
1007
- const summary = await debouncedGetSummary(messages, currentTitle);
1008
-
1009
- // 检查是否是最新请求
1010
- if (requestId === latestSummaryRequestRef.current && summary) {
1011
- setCurrentTitle(summary);
1012
- }
1013
- }
1014
-
949
+ const latestUserMessage = currentMessages.findLast((m) => m.role === ChatMessageRole.User);
950
+ setCurrentTitle(
951
+ latestUserMessage ? cleanAttachedTextWrapper(latestUserMessage.content).slice(0, MAX_TITLE_LENGTH) : '',
952
+ );
1015
953
  setHistoryList(
1016
954
  aiChatService.getSessions().map((session) => {
1017
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);
@@ -10,13 +10,7 @@ import {
10
10
  useInjectable,
11
11
  } from '@opensumi/ide-core-browser';
12
12
  import { Icon, getIcon } from '@opensumi/ide-core-browser/lib/components';
13
- import {
14
- AINativeSettingSectionsId,
15
- ChatFeatureRegistryToken,
16
- RulesServiceToken,
17
- URI,
18
- localize,
19
- } from '@opensumi/ide-core-common';
13
+ import { AINativeSettingSectionsId, ChatFeatureRegistryToken, URI, localize } from '@opensumi/ide-core-common';
20
14
  import { CommandService } from '@opensumi/ide-core-common/lib/command';
21
15
  import { defaultFilesWatcherExcludes } from '@opensumi/ide-core-common/lib/preferences/file-watch';
22
16
  import { WorkbenchEditorService } from '@opensumi/ide-editor';
@@ -31,8 +25,6 @@ import { LLMContextService } from '../../common/llm-context';
31
25
  import { ChatFeatureRegistry } from '../chat/chat.feature.registry';
32
26
  import { ChatInternalService } from '../chat/chat.internal.service';
33
27
  import { MCPConfigCommands } from '../mcp/config/mcp-config.commands';
34
- import { RulesCommands } from '../rules/rules.contribution';
35
- import { RulesService } from '../rules/rules.service';
36
28
 
37
29
  import styles from './components.module.less';
38
30
  import { MentionInput } from './mention-input/mention-input';
@@ -85,15 +77,10 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
85
77
  const outlineTreeService = useInjectable<OutlineTreeService>(OutlineTreeService);
86
78
  const prevOutlineItems = useRef<MentionItem[]>([]);
87
79
  const preferenceService = useInjectable<PreferenceService>(PreferenceService);
88
- const rulesService = useInjectable<RulesService>(RulesServiceToken);
89
80
  const handleShowMCPConfig = React.useCallback(() => {
90
81
  commandService.executeCommand(MCPConfigCommands.OPEN_MCP_CONFIG.id);
91
82
  }, [commandService]);
92
83
 
93
- const handleShowRules = React.useCallback(() => {
94
- commandService.executeCommand(RulesCommands.OPEN_RULES_FILE.id);
95
- }, [commandService]);
96
-
97
84
  useEffect(() => {
98
85
  if (props.value !== value) {
99
86
  setValue(props.value || '');
@@ -120,55 +107,6 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
120
107
  [outlineTreeService],
121
108
  );
122
109
 
123
- // 拆分目录路径为多个层级的辅助函数
124
- const expandFolderPaths = async (folderPaths: string[], workspaceRootPath: string): Promise<MentionItem[]> => {
125
- const expandedPaths = new Set<string>();
126
- const workspaceUri = new URI(workspaceRootPath);
127
-
128
- // 将所有路径展开为多层级
129
- for (const folderPath of folderPaths) {
130
- const uri = new URI(folderPath);
131
- const relativePath = await workspaceService.asRelativePath(uri);
132
-
133
- if (relativePath?.path) {
134
- const pathSegments = relativePath.path.split('/').filter(Boolean);
135
-
136
- // 为每个层级创建路径
137
- for (let i = 0; i < pathSegments.length; i++) {
138
- const segmentPath = pathSegments.slice(0, i + 1).join('/');
139
- const fullPath = workspaceUri.resolve(segmentPath).codeUri.fsPath;
140
-
141
- // 避免添加工作区本身或其上级目录
142
- if (fullPath !== workspaceRootPath && !workspaceRootPath.startsWith(fullPath)) {
143
- expandedPaths.add(fullPath);
144
- }
145
- }
146
- } else {
147
- // 如果无法获取相对路径,直接添加(但仍要过滤工作区路径)
148
- if (folderPath !== workspaceRootPath && !workspaceRootPath.startsWith(folderPath)) {
149
- expandedPaths.add(folderPath);
150
- }
151
- }
152
- }
153
-
154
- // 转换为 MentionItem 格式
155
- return Promise.all(
156
- Array.from(expandedPaths).map(async (folderPath) => {
157
- const uri = new URI(folderPath);
158
- const relativePath = await workspaceService.asRelativePath(uri);
159
- return {
160
- id: uri.codeUri.fsPath,
161
- type: MentionType.FOLDER,
162
- text: uri.displayName,
163
- value: uri.codeUri.fsPath,
164
- description: relativePath?.root ? relativePath.path : '',
165
- contextId: uri.codeUri.fsPath,
166
- icon: getIcon('folder'),
167
- };
168
- }),
169
- );
170
- };
171
-
172
110
  // 默认菜单项
173
111
  const defaultMenuItems: MentionItem[] = [
174
112
  {
@@ -276,7 +214,21 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
276
214
  .filter((folder) => folder !== workspaceService.workspace?.uri.toString() && folder !== '/'),
277
215
  ),
278
216
  );
279
- folders = await expandFolderPaths(recentFolder, workspaceService.workspace?.uri.toString() || '');
217
+ folders = await Promise.all(
218
+ recentFolder.map(async (folder) => {
219
+ const uri = new URI(folder);
220
+ const relativePath = await workspaceService.asRelativePath(uri);
221
+ return {
222
+ id: uri.codeUri.fsPath,
223
+ type: MentionType.FOLDER,
224
+ text: uri.displayName,
225
+ value: uri.codeUri.fsPath,
226
+ description: relativePath?.root ? relativePath.path : '',
227
+ contextId: uri.codeUri.fsPath,
228
+ icon: getIcon('folder'),
229
+ };
230
+ }),
231
+ );
280
232
  } else {
281
233
  const rootUris = (await workspaceService.roots).map((root) => new URI(root.uri).codeUri.fsPath.toString());
282
234
  const files = await searchService.find(searchText, {
@@ -294,11 +246,22 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
294
246
  .filter((folder) => folder !== workspaceService.workspace?.uri.toString()),
295
247
  ),
296
248
  );
297
- return await expandFolderPaths(folders, workspaceService.workspace?.uri.toString() || '');
249
+ return Promise.all(
250
+ folders.map(async (folder) => {
251
+ const uri = new URI(folder);
252
+ return {
253
+ id: uri.codeUri.fsPath,
254
+ type: MentionType.FOLDER,
255
+ text: uri.displayName,
256
+ value: uri.codeUri.fsPath,
257
+ description: (await workspaceService.asRelativePath(uri.parent))?.path || '',
258
+ contextId: uri.codeUri.fsPath,
259
+ icon: getIcon('folder'),
260
+ };
261
+ }),
262
+ );
298
263
  }
299
- return folders
300
- .filter(Boolean)
301
- .filter((folder) => folder.id !== new URI(workspaceService.workspace?.uri).codeUri.fsPath);
264
+ return folders.filter((folder) => folder.id !== new URI(workspaceService.workspace?.uri).codeUri.fsPath);
302
265
  },
303
266
  },
304
267
  {
@@ -349,80 +312,12 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
349
312
  }
350
313
  },
351
314
  },
352
- {
353
- id: MentionType.RULE,
354
- type: MentionType.RULE,
355
- text: 'Rule',
356
- icon: getIcon('rules'),
357
- getHighestLevelItems: () => [],
358
- getItems: async (searchText: string) => {
359
- const rules = await rulesService.projectRules;
360
- const mappedRules = rules.map((rule) => {
361
- const uri = new URI(rule.path);
362
- return {
363
- id: uri.codeUri.fsPath,
364
- type: MentionType.RULE,
365
- text: uri.displayName,
366
- value: uri.codeUri.fsPath,
367
- contextId: uri.codeUri.fsPath,
368
- description: rule.description,
369
- icon: getIcon('rules'),
370
- };
371
- });
372
-
373
- if (!searchText) {
374
- return mappedRules.slice(0, 10);
375
- }
376
-
377
- const lowerSearchText = searchText.toLocaleLowerCase();
378
- return mappedRules
379
- .filter((rule) => rule.text.toLocaleLowerCase().includes(lowerSearchText))
380
- .sort((a, b) => {
381
- const aTextLower = a.text.toLocaleLowerCase();
382
- const bTextLower = b.text.toLocaleLowerCase();
383
- const aDescLower = a.description?.toLocaleLowerCase() || '';
384
- const bDescLower = b.description?.toLocaleLowerCase() || '';
385
-
386
- // 优先级:文件名包含搜索文本 > 描述包含搜索文本
387
- const aTextMatch = aTextLower.includes(lowerSearchText);
388
- const bTextMatch = bTextLower.includes(lowerSearchText);
389
- const aDescMatch = aDescLower.includes(lowerSearchText);
390
- const bDescMatch = bDescLower.includes(lowerSearchText);
391
-
392
- if (aTextMatch && bTextMatch) {
393
- // 如果都匹配文件名,按文件名字母序排序
394
- return aTextLower.localeCompare(bTextLower);
395
- }
396
- if (aTextMatch && !bTextMatch) {
397
- return -1;
398
- }
399
- if (!aTextMatch && bTextMatch) {
400
- return 1;
401
- }
402
-
403
- // 如果文件名都不匹配,比较描述
404
- if (aDescMatch && bDescMatch) {
405
- return aTextLower.localeCompare(bTextLower);
406
- }
407
- if (aDescMatch && !bDescMatch) {
408
- return -1;
409
- }
410
- if (!aDescMatch && bDescMatch) {
411
- return 1;
412
- }
413
-
414
- // 如果都不匹配,按文件名字母序排序
415
- return aTextLower.localeCompare(bTextLower);
416
- })
417
- .slice(0, 10);
418
- },
419
- },
420
315
  ];
421
316
 
422
317
  const defaultMentionInputFooterOptions: FooterConfig = useMemo(
423
318
  () => ({
424
319
  modelOptions: [
425
- { label: 'Claude 4 Sonnet', value: 'claude_sonnet4' },
320
+ { label: 'QWQ 32B', value: 'qwq-32b' },
426
321
  { label: 'DeepSeek R1', value: 'deepseek-r1' },
427
322
  ],
428
323
  defaultModel:
@@ -435,13 +330,6 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
435
330
  onClick: handleShowMCPConfig,
436
331
  position: FooterButtonPosition.LEFT,
437
332
  },
438
- {
439
- id: 'rules',
440
- icon: 'rules',
441
- title: 'Rules',
442
- onClick: handleShowRules,
443
- position: FooterButtonPosition.LEFT,
444
- },
445
333
  {
446
334
  id: 'upload-image',
447
335
  icon: 'image',
@@ -23,7 +23,6 @@
23
23
  display: flex;
24
24
  align-items: center;
25
25
  font-weight: 500;
26
- width: calc(100% - 20px);
27
26
  color: var(--design-text-foreground);
28
27
  }
29
28
 
@@ -35,30 +34,6 @@
35
34
  margin-left: 5px;
36
35
  font-size: 11px;
37
36
  color: var(--descriptionForeground);
38
- width: calc(100% - 36px);
39
- display: flex;
40
- align-items: center;
41
- justify-content: flex-start;
42
-
43
- .tool_prefix {
44
- color: var(--design-text-placeholderForeground);
45
- margin-right: 10px;
46
- flex-shrink: 0;
47
- }
48
-
49
- .tool_name {
50
- opacity: 0.8;
51
- font-size: 9px;
52
- flex: 1;
53
- text-overflow: ellipsis;
54
- direction: rtl;
55
- unicode-bidi: plaintext;
56
- overflow: hidden;
57
- white-space: nowrap;
58
- display: inline-block;
59
- margin-right: 10px;
60
- text-align: left;
61
- }
62
37
  }
63
38
 
64
39
  .expand_icon {