@opensumi/ide-ai-native 3.8.1-next-1740965430.0 → 3.8.1-next-1741071284.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 (83) hide show
  1. package/lib/browser/ai-core.contribution.js +1 -1
  2. package/lib/browser/ai-core.contribution.js.map +1 -1
  3. package/lib/browser/chat/chat-agent.service.d.ts +0 -8
  4. package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
  5. package/lib/browser/chat/chat-agent.service.js +0 -34
  6. package/lib/browser/chat/chat-agent.service.js.map +1 -1
  7. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  8. package/lib/browser/chat/chat-model.js +2 -3
  9. package/lib/browser/chat/chat-model.js.map +1 -1
  10. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-proxy.service.js +1 -1
  12. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  13. package/lib/browser/chat/chat.module.less +2 -1
  14. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  15. package/lib/browser/chat/chat.view.js +60 -9
  16. package/lib/browser/chat/chat.view.js.map +1 -1
  17. package/lib/browser/components/ChatContext/index.js +2 -2
  18. package/lib/browser/components/ChatContext/index.js.map +1 -1
  19. package/lib/browser/components/ChatInput.d.ts.map +1 -1
  20. package/lib/browser/components/ChatInput.js +1 -25
  21. package/lib/browser/components/ChatInput.js.map +1 -1
  22. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  23. package/lib/browser/components/ChatToolRender.js +3 -2
  24. package/lib/browser/components/ChatToolRender.js.map +1 -1
  25. package/lib/browser/components/chat-history.module.less +1 -1
  26. package/lib/browser/components/components.module.less +0 -20
  27. package/lib/browser/context/llm-context.service.d.ts +5 -18
  28. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  29. package/lib/browser/context/llm-context.service.js +47 -80
  30. package/lib/browser/context/llm-context.service.js.map +1 -1
  31. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +1 -1
  32. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
  33. package/lib/browser/contrib/intelligent-completions/view/default.d.ts.map +1 -1
  34. package/lib/browser/contrib/intelligent-completions/view/default.js +6 -0
  35. package/lib/browser/contrib/intelligent-completions/view/default.js.map +1 -1
  36. package/lib/browser/layout/layout.module.less +4 -4
  37. package/lib/browser/mcp/tools/components/index.module.less +0 -1
  38. package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
  39. package/lib/browser/mcp/tools/createNewFileWithText.js +0 -1
  40. package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
  41. package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
  42. package/lib/browser/mcp/tools/getDiagnosticsByPath.js +0 -1
  43. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  44. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
  45. package/lib/browser/mcp/tools/handlers/RunCommand.js +0 -2
  46. package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
  47. package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -1
  48. package/lib/browser/mcp/tools/runTerminalCmd.js +0 -1
  49. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  50. package/lib/browser/preferences/schema.d.ts.map +1 -1
  51. package/lib/browser/preferences/schema.js +1 -0
  52. package/lib/browser/preferences/schema.js.map +1 -1
  53. package/lib/common/llm-context.d.ts +9 -13
  54. package/lib/common/llm-context.d.ts.map +1 -1
  55. package/lib/common/llm-context.js.map +1 -1
  56. package/lib/common/prompts/context-prompt-provider.d.ts +3 -4
  57. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  58. package/lib/common/prompts/context-prompt-provider.js +22 -33
  59. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  60. package/package.json +23 -23
  61. package/src/browser/ai-core.contribution.ts +1 -1
  62. package/src/browser/chat/chat-agent.service.ts +3 -42
  63. package/src/browser/chat/chat-model.ts +6 -11
  64. package/src/browser/chat/chat-proxy.service.ts +1 -2
  65. package/src/browser/chat/chat.module.less +2 -1
  66. package/src/browser/chat/chat.view.tsx +95 -10
  67. package/src/browser/components/ChatContext/index.tsx +2 -2
  68. package/src/browser/components/ChatInput.tsx +3 -67
  69. package/src/browser/components/ChatToolRender.tsx +2 -1
  70. package/src/browser/components/chat-history.module.less +1 -1
  71. package/src/browser/components/components.module.less +0 -20
  72. package/src/browser/context/llm-context.service.ts +54 -93
  73. package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +1 -1
  74. package/src/browser/contrib/intelligent-completions/view/default.ts +7 -0
  75. package/src/browser/layout/layout.module.less +4 -4
  76. package/src/browser/mcp/tools/components/index.module.less +0 -1
  77. package/src/browser/mcp/tools/createNewFileWithText.ts +0 -1
  78. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +0 -1
  79. package/src/browser/mcp/tools/handlers/RunCommand.ts +0 -2
  80. package/src/browser/mcp/tools/runTerminalCmd.ts +0 -1
  81. package/src/browser/preferences/schema.ts +1 -0
  82. package/src/common/llm-context.ts +4 -10
  83. package/src/common/prompts/context-prompt-provider.ts +29 -38
@@ -4,15 +4,16 @@ import { Autowired, Injectable } from '@opensumi/di';
4
4
  import {
5
5
  CancellationToken,
6
6
  ChatFeatureRegistryToken,
7
- ChatMessageRole,
8
7
  ChatServiceToken,
9
8
  Disposable,
10
9
  Emitter,
10
+ IChatContent,
11
11
  IChatProgress,
12
12
  IDisposable,
13
13
  ILogger,
14
- toDisposable
14
+ toDisposable,
15
15
  } from '@opensumi/ide-core-common';
16
+ import { ChatMessageRole } from '@opensumi/ide-core-common';
16
17
  import { IChatMessage } from '@opensumi/ide-core-common/lib/types/ai-native';
17
18
 
18
19
  import {
@@ -25,8 +26,6 @@ import {
25
26
  IChatFollowup,
26
27
  IChatMessageStructure,
27
28
  } from '../../common';
28
- import { LLMContextService, LLMContextServiceToken } from '../../common/llm-context';
29
- import { ChatAgentPromptProvider } from '../../common/prompts/context-prompt-provider';
30
29
  import { IChatFeatureRegistry } from '../types';
31
30
 
32
31
  import { ChatService } from './chat.api.service';
@@ -37,12 +36,6 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
37
36
 
38
37
  private defaultAgentId: string | undefined;
39
38
 
40
- private initialUserMessageMap: Map<string, string> = new Map();
41
-
42
- private shouldUpdateContext = false;
43
-
44
- private contextVersion: number;
45
-
46
39
  private readonly _onDidChangeAgents = new Emitter<void>();
47
40
  readonly onDidChangeAgents = this._onDidChangeAgents.event;
48
41
 
@@ -52,12 +45,6 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
52
45
  @Autowired(ILogger)
53
46
  logger: ILogger;
54
47
 
55
- @Autowired(LLMContextServiceToken)
56
- protected readonly contextService: LLMContextService;
57
-
58
- @Autowired(ChatAgentPromptProvider)
59
- protected readonly promptProvider: ChatAgentPromptProvider;
60
-
61
48
  @Autowired(ChatServiceToken)
62
49
  private aiChatService: ChatService;
63
50
 
@@ -67,12 +54,6 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
67
54
  constructor() {
68
55
  super();
69
56
  this.addDispose(this._onDidChangeAgents);
70
- this.addDispose(this.contextService.onDidContextFilesChangeEvent((event) => {
71
- if (event.version !== this.contextVersion) {
72
- this.contextVersion = event.version;
73
- this.shouldUpdateContext = true;
74
- }
75
- }));
76
57
  }
77
58
 
78
59
  registerAgent(agent: IChatAgent): IDisposable {
@@ -139,8 +120,6 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
139
120
  if (!data) {
140
121
  throw new Error(`No agent with id ${id}`);
141
122
  }
142
-
143
- // system
144
123
  if (data.agent.metadata.systemPrompt) {
145
124
  history.unshift({
146
125
  role: ChatMessageRole.System,
@@ -148,28 +127,10 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
148
127
  });
149
128
  }
150
129
 
151
- // 发送第一条消息时携带初始 context
152
- if (!this.initialUserMessageMap.has(id)) {
153
- this.initialUserMessageMap.set(id, request.message);
154
- const rawMessage = request.message;
155
- request.message = this.provideContextMessage(rawMessage);
156
- }
157
-
158
- if (this.shouldUpdateContext) {
159
- request.message = this.provideContextMessage(request.message);
160
- this.shouldUpdateContext = false;
161
- }
162
-
163
130
  const result = await data.agent.invoke(request, progress, history, token);
164
131
  return result;
165
132
  }
166
133
 
167
- private provideContextMessage(message: string) {
168
- const context = this.contextService.serialize();
169
- const fullMessage = this.promptProvider.provideContextPrompt(context, message);
170
- return fullMessage;
171
- }
172
-
173
134
  populateChatInput(id: string, message: IChatMessageStructure) {
174
135
  this.aiChatService.sendMessage({
175
136
  ...message,
@@ -1,4 +1,4 @@
1
- import { Injectable } from '@opensumi/di';
1
+ import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
2
2
  import {
3
3
  Disposable,
4
4
  Emitter,
@@ -8,6 +8,8 @@ import {
8
8
  IChatProgress,
9
9
  IChatToolContent,
10
10
  IChatTreeData,
11
+ ILogger,
12
+ memoize,
11
13
  uuid,
12
14
  } from '@opensumi/ide-core-common';
13
15
  import { MarkdownString, isMarkdownString } from '@opensumi/monaco-editor-core/esm/vs/base/common/htmlContent';
@@ -272,18 +274,13 @@ export class ChatRequestModel implements IChatRequestModel {
272
274
  export class ChatModel extends Disposable implements IChatModel {
273
275
  private static requestIdPool = 0;
274
276
 
275
- constructor(initParams?: {
276
- sessionId?: string;
277
- history?: MsgHistoryManager;
278
- requests?: ChatRequestModel[];
279
- }) {
277
+ constructor(initParams?: { sessionId?: string; history?: MsgHistoryManager; requests?: ChatRequestModel[] }) {
280
278
  super();
281
279
  this.#sessionId = initParams?.sessionId ?? uuid();
282
280
  this.history = initParams?.history ?? new MsgHistoryManager();
283
281
  if (initParams?.requests) {
284
282
  this.#requests = new Map(initParams.requests.map((r) => [r.requestId, r]));
285
283
  }
286
-
287
284
  }
288
285
 
289
286
  #sessionId: string;
@@ -303,11 +300,9 @@ export class ChatModel extends Disposable implements IChatModel {
303
300
  readonly history: MsgHistoryManager;
304
301
 
305
302
  addRequest(message: IChatRequestMessage): ChatRequestModel {
306
- const msg = message;
307
-
308
303
  const requestId = `${this.sessionId}_request_${ChatModel.requestIdPool++}`;
309
- const response = new ChatResponseModel(requestId, this, msg.agentId);
310
- const request = new ChatRequestModel(requestId, this, msg, response);
304
+ const response = new ChatResponseModel(requestId, this, message.agentId);
305
+ const request = new ChatRequestModel(requestId, this, message, response);
311
306
 
312
307
  this.#requests.set(requestId, request);
313
308
  return request;
@@ -8,7 +8,6 @@ import {
8
8
  ChatServiceToken,
9
9
  Deferred,
10
10
  Disposable,
11
- getOperatingSystemName,
12
11
  IAIBackService,
13
12
  IAIReporter,
14
13
  IApplicationService,
@@ -93,7 +92,7 @@ export class ChatProxyService extends Disposable {
93
92
  AINativeSettingSectionsId.SystemPrompt,
94
93
  '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.',
95
94
  ) +
96
- `\n\n<user_info>\nThe user's OS is ${getOperatingSystemName()}. The absolute path of the user's workspace is ${this.appConfig.workspaceDir}.\n</user_info>`,
95
+ `\n\n<user_info>\nThe user's OS version is ${this.applicationService.frontendOS}. The absolute path of the user's workspace is ${this.appConfig.workspaceDir}.\n</user_info>`,
97
96
  },
98
97
  invoke: async (
99
98
  request: IChatAgentRequest,
@@ -279,6 +279,7 @@
279
279
  }
280
280
  }
281
281
 
282
+
282
283
  .chat_tips_container {
283
284
  display: flex;
284
285
  align-items: center;
@@ -289,6 +290,6 @@
289
290
  }
290
291
 
291
292
  .chat_history {
292
- width: calc(100% - 40px);
293
+ width: calc(100% - 60px);
293
294
  color: var(--design-text-foreground);
294
295
  }
@@ -5,6 +5,7 @@ import {
5
5
  AINativeConfigService,
6
6
  CommandService,
7
7
  getIcon,
8
+ useEventEffect,
8
9
  useInjectable,
9
10
  useUpdateOnEvent,
10
11
  } from '@opensumi/ide-core-browser';
@@ -41,6 +42,8 @@ import {
41
42
  IChatMessageStructure,
42
43
  TokenMCPServerProxyService,
43
44
  } from '../../common';
45
+ import { LLMContextService, LLMContextServiceToken } from '../../common/llm-context';
46
+ import { ChatAgentPromptProvider } from '../../common/prompts/context-prompt-provider';
44
47
  import { ChatContext } from '../components/ChatContext';
45
48
  import { CodeBlockWrapperInput } from '../components/ChatEditor';
46
49
  import ChatHistory, { IChatHistoryItem } from '../components/ChatHistory';
@@ -79,11 +82,18 @@ export const AIChatView = () => {
79
82
  const chatAgentService = useInjectable<IChatAgentService>(IChatAgentService);
80
83
  const chatFeatureRegistry = useInjectable<ChatFeatureRegistry>(ChatFeatureRegistryToken);
81
84
  const chatRenderRegistry = useInjectable<ChatRenderRegistry>(ChatRenderRegistryToken);
85
+ const contextService = useInjectable<LLMContextService>(LLMContextServiceToken);
86
+ const promptProvider = useInjectable<ChatAgentPromptProvider>(ChatAgentPromptProvider);
87
+ const mcpServerProxyService = useInjectable<MCPServerProxyService>(TokenMCPServerProxyService);
82
88
 
83
89
  const layoutService = useInjectable<IMainLayoutService>(IMainLayoutService);
84
90
  const msgHistoryManager = aiChatService.sessionModel.history;
85
91
  const containerRef = React.useRef<HTMLDivElement>(null);
92
+ const autoScroll = React.useRef<boolean>(true);
86
93
  const chatInputRef = React.useRef<{ setInputValue: (v: string) => void } | null>(null);
94
+ const dialogService = useInjectable<IDialogService>(IDialogService);
95
+ const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
96
+ const commandService = useInjectable<CommandService>(CommandService);
87
97
 
88
98
  const [shortcutCommands, setShortcutCommands] = React.useState<ChatSlashCommandItemModel[]>([]);
89
99
 
@@ -105,6 +115,8 @@ export const AIChatView = () => {
105
115
  const [defaultAgentId, setDefaultAgentId] = React.useState<string>('');
106
116
  const [command, setCommand] = React.useState('');
107
117
  const [theme, setTheme] = React.useState<string | null>(null);
118
+ const [mcpToolsCount, setMcpToolsCount] = React.useState<number>(0);
119
+ const [mcpServersCount, setMcpServersCount] = React.useState<number>(0);
108
120
 
109
121
  React.useEffect(() => {
110
122
  const featureSlashCommands = chatFeatureRegistry.getAllShortcutSlashCommand();
@@ -154,8 +166,29 @@ export const AIChatView = () => {
154
166
  [],
155
167
  );
156
168
 
169
+ const onDidWheel = React.useCallback(
170
+ (e: WheelEvent) => {
171
+ // 向上滚动
172
+ if (e.deltaY < 0) {
173
+ autoScroll.current = false;
174
+ } else {
175
+ autoScroll.current = true;
176
+ }
177
+ },
178
+ [autoScroll],
179
+ );
180
+
181
+ React.useEffect(() => {
182
+ if (containerRef.current) {
183
+ containerRef.current.addEventListener('wheel', onDidWheel);
184
+ return () => {
185
+ containerRef.current?.removeEventListener('wheel', onDidWheel);
186
+ };
187
+ }
188
+ }, [autoScroll]);
189
+
157
190
  const scrollToBottom = React.useCallback(() => {
158
- if (containerRef && containerRef.current) {
191
+ if (containerRef && containerRef.current && autoScroll.current) {
159
192
  const lastElement = containerRef.current.lastElementChild;
160
193
  if (lastElement) {
161
194
  lastElement.scrollIntoView({ behavior: 'smooth', block: 'end' });
@@ -165,7 +198,7 @@ export const AIChatView = () => {
165
198
  containerRef.current.classList.add(SCROLL_CLASSNAME);
166
199
  }
167
200
  }
168
- }, [containerRef]);
201
+ }, [containerRef, autoScroll]);
169
202
 
170
203
  const handleDispatchMessage = React.useCallback(
171
204
  (dispatch: TDispatchAction) => {
@@ -187,7 +220,7 @@ export const AIChatView = () => {
187
220
  disposer.addDispose(
188
221
  chatApiService.onScrollToBottom(() => {
189
222
  requestAnimationFrame(() => {
190
- scrollToBottom();
223
+ // scrollToBottom();
191
224
  });
192
225
  }),
193
226
  );
@@ -504,7 +537,10 @@ export const AIChatView = () => {
504
537
  const { message, agentId, command, reportExtra } = value;
505
538
  const { actionType, actionSource } = reportExtra || {};
506
539
 
507
- const request = aiChatService.createRequest(message, agentId!, command);
540
+ const context = contextService.serialize();
541
+ const fullMessage = await promptProvider.provideContextPrompt(context, message);
542
+
543
+ const request = aiChatService.createRequest(fullMessage, agentId!, command);
508
544
  if (!request) {
509
545
  return;
510
546
  }
@@ -653,6 +689,32 @@ export const AIChatView = () => {
653
689
  };
654
690
  }, [aiChatService.sessionModel]);
655
691
 
692
+ useEventEffect(
693
+ mcpServerProxyService.onChangeMCPServers,
694
+ () => {
695
+ mcpServerProxyService.getAllMCPTools().then((tools) => {
696
+ setMcpToolsCount(tools.length);
697
+ });
698
+ mcpServerProxyService.$getServers().then((servers) => {
699
+ setMcpServersCount(servers.length);
700
+ });
701
+ },
702
+ [mcpServerProxyService],
703
+ );
704
+
705
+ const handleShowMCPTools = React.useCallback(async () => {
706
+ const tools = await mcpServerProxyService.getAllMCPTools();
707
+ dialogService.open({
708
+ message: <MCPToolsDialog tools={tools} />,
709
+ type: MessageType.Empty,
710
+ buttons: ['关闭'],
711
+ });
712
+ }, [mcpServerProxyService, dialogService]);
713
+
714
+ const handleShowMCPConfig = React.useCallback(() => {
715
+ commandService.executeCommand(OPEN_MCP_CONFIG_COMMAND.id);
716
+ }, [commandService]);
717
+
656
718
  return (
657
719
  <div id={styles.ai_chat_view}>
658
720
  <div className={styles.header_container}>
@@ -692,6 +754,18 @@ export const AIChatView = () => {
692
754
  </Popover>
693
755
  ))}
694
756
  </div>
757
+ <div className={styles.header_operate_right}>
758
+ {aiNativeConfigService.capabilities.supportsMCP && (
759
+ <>
760
+ <div className={styles.tag} onClick={handleShowMCPConfig}>
761
+ {`MCP Servers: ${mcpServersCount}`}
762
+ </div>
763
+ <div className={styles.tag} onClick={handleShowMCPTools}>
764
+ {`MCP Tools: ${mcpToolsCount}`}
765
+ </div>
766
+ </>
767
+ )}
768
+ </div>
695
769
  </div>
696
770
  <ChatInputWrapperRender
697
771
  onSend={(value, agentId, command) =>
@@ -734,8 +808,6 @@ export function DefaultChatViewHeader({
734
808
  const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
735
809
  const mcpServerProxyService = useInjectable<MCPServerProxyService>(TokenMCPServerProxyService);
736
810
  const aiChatService = useInjectable<ChatInternalService>(IChatInternalService);
737
- const commandService = useInjectable<CommandService>(CommandService);
738
-
739
811
  const [historyList, setHistoryList] = React.useState<IChatHistoryItem[]>([]);
740
812
  const [currentTitle, setCurrentTitle] = React.useState<string>('');
741
813
  const handleNewChat = React.useCallback(() => {
@@ -756,10 +828,6 @@ export function DefaultChatViewHeader({
756
828
  [aiChatService],
757
829
  );
758
830
 
759
- const handleShowMCPConfig = React.useCallback(() => {
760
- commandService.executeCommand(OPEN_MCP_CONFIG_COMMAND.id);
761
- }, [commandService]);
762
-
763
831
  const handleShowMCPTools = React.useCallback(async () => {
764
832
  const tools = await mcpServerProxyService.getAllMCPTools();
765
833
  dialogService.open({
@@ -848,6 +916,23 @@ export function DefaultChatViewHeader({
848
916
  ariaLabel={localize('aiNative.operate.clear.title')}
849
917
  />
850
918
  </Popover>
919
+ {aiNativeConfigService.capabilities.supportsMCP && (
920
+ <Popover
921
+ overlayClassName={styles.popover_icon}
922
+ id={'ai-chat-header-tools'}
923
+ position={PopoverPosition.left}
924
+ title={localize('aiNative.operate.tools.title')}
925
+ >
926
+ <EnhanceIcon
927
+ wrapperClassName={styles.action_btn}
928
+ className={getIcon('menubar-tool')}
929
+ onClick={handleShowMCPTools}
930
+ tabIndex={0}
931
+ role='button'
932
+ ariaLabel={localize('aiNative.operate.tools.title')}
933
+ />
934
+ </Popover>
935
+ )}
851
936
  <Popover
852
937
  overlayClassName={styles.popover_icon}
853
938
  id={'ai-chat-header-close'}
@@ -39,7 +39,7 @@ export const ChatContext = memo(() => {
39
39
  50,
40
40
  )((files) => {
41
41
  if (files) {
42
- updateAddedFiles([...files.attached]);
42
+ updateAddedFiles(files);
43
43
  }
44
44
  }, contextService);
45
45
 
@@ -57,7 +57,7 @@ export const ChatContext = memo(() => {
57
57
  }, []);
58
58
 
59
59
  const onDidDeselect = useCallback((uri: URI) => {
60
- contextService.removeFileFromContext(uri, true);
60
+ contextService.removeFileFromContext(uri);
61
61
  }, []);
62
62
 
63
63
  const onDidClickFile = useCallback((uri: URI) => {
@@ -1,29 +1,18 @@
1
1
  import cls from 'classnames';
2
2
  import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
3
3
 
4
- import { AINativeConfigService, useInjectable, useLatest } from '@opensumi/ide-core-browser';
4
+ import { useInjectable, useLatest } from '@opensumi/ide-core-browser';
5
5
  import { Icon, Popover, PopoverPosition, getIcon } from '@opensumi/ide-core-browser/lib/components';
6
6
  import { EnhanceIcon } from '@opensumi/ide-core-browser/lib/components/ai-native';
7
7
  import { InteractiveInput } from '@opensumi/ide-core-browser/lib/components/ai-native/interactive-input/index';
8
- import {
9
- ChatAgentViewServiceToken,
10
- ChatFeatureRegistryToken,
11
- MessageType,
12
- localize,
13
- runWhenIdle,
14
- } from '@opensumi/ide-core-common';
15
- import { CommandService } from '@opensumi/ide-core-common/lib/command';
8
+ import { ChatAgentViewServiceToken, ChatFeatureRegistryToken, localize, runWhenIdle } from '@opensumi/ide-core-common';
16
9
  import { MonacoCommandRegistry } from '@opensumi/ide-editor/lib/browser/monaco-contrib/command/command.service';
17
- import { IDialogService } from '@opensumi/ide-overlay';
18
10
 
19
- import { AT_SIGN_SYMBOL, IChatAgentService, SLASH_SYMBOL, TokenMCPServerProxyService } from '../../common';
11
+ import { AT_SIGN_SYMBOL, IChatAgentService, SLASH_SYMBOL } from '../../common';
20
12
  import { ChatAgentViewService } from '../chat/chat-agent.view.service';
21
13
  import { ChatSlashCommandItemModel } from '../chat/chat-model';
22
14
  import { ChatProxyService } from '../chat/chat-proxy.service';
23
15
  import { ChatFeatureRegistry } from '../chat/chat.feature.registry';
24
- import { OPEN_MCP_CONFIG_COMMAND } from '../mcp/config/mcp-config.commands';
25
- import { MCPServerProxyService } from '../mcp/mcp-server-proxy.service';
26
- import { MCPToolsDialog } from '../mcp/mcp-tools-dialog.view';
27
16
  import { IChatSlashCommandItem } from '../types';
28
17
 
29
18
  import styles from './components.module.less';
@@ -205,29 +194,12 @@ export const ChatInput = React.forwardRef((props: IChatInputProps, ref) => {
205
194
  const [isExpand, setIsExpand] = useState(false);
206
195
  const [placeholder, setPlaceHolder] = useState(localize('aiNative.chat.input.placeholder.default'));
207
196
 
208
- const dialogService = useInjectable<IDialogService>(IDialogService);
209
- const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
210
- const mcpServerProxyService = useInjectable<MCPServerProxyService>(TokenMCPServerProxyService);
211
197
  const monacoCommandRegistry = useInjectable<MonacoCommandRegistry>(MonacoCommandRegistry);
212
198
  const chatAgentService = useInjectable<IChatAgentService>(IChatAgentService);
213
199
  const chatFeatureRegistry = useInjectable<ChatFeatureRegistry>(ChatFeatureRegistryToken);
214
- const commandService = useInjectable<CommandService>(CommandService);
215
200
 
216
201
  const currentAgentIdRef = useLatest(agentId);
217
202
 
218
- const handleShowMCPConfig = React.useCallback(() => {
219
- commandService.executeCommand(OPEN_MCP_CONFIG_COMMAND.id);
220
- }, [commandService]);
221
-
222
- const handleShowMCPTools = React.useCallback(async () => {
223
- const tools = await mcpServerProxyService.getAllMCPTools();
224
- dialogService.open({
225
- message: <MCPToolsDialog tools={tools} />,
226
- type: MessageType.Empty,
227
- buttons: ['关闭'],
228
- });
229
- }, [mcpServerProxyService, dialogService]);
230
-
231
203
  useImperativeHandle(ref, () => ({
232
204
  setInputValue: (v: string) => {
233
205
  setValue(v);
@@ -489,42 +461,6 @@ export const ChatInput = React.forwardRef((props: IChatInputProps, ref) => {
489
461
  height={inputHeight}
490
462
  popoverPosition={PopoverPosition.left}
491
463
  />
492
- <div className={styles.chat_input_footer}>
493
- {aiNativeConfigService.capabilities.supportsMCP && (
494
- <div className={styles.mcp_desc}>
495
- <Popover
496
- overlayClassName={styles.popover_icon}
497
- id={'ai-chat-header-mcp-server'}
498
- position={PopoverPosition.left}
499
- title={'MCP Server'}
500
- >
501
- <EnhanceIcon
502
- wrapperClassName={styles.action_btn}
503
- className={'codicon codicon-server'}
504
- onClick={handleShowMCPConfig}
505
- tabIndex={0}
506
- role='button'
507
- ariaLabel={'MCP Server'}
508
- />
509
- </Popover>
510
- <Popover
511
- overlayClassName={styles.popover_icon}
512
- id={'ai-chat-header-tools'}
513
- position={PopoverPosition.left}
514
- title={localize('aiNative.operate.tools.title')}
515
- >
516
- <EnhanceIcon
517
- wrapperClassName={styles.action_btn}
518
- className={getIcon('menubar-tool')}
519
- onClick={handleShowMCPTools}
520
- tabIndex={0}
521
- role='button'
522
- ariaLabel={localize('aiNative.operate.tools.title')}
523
- />
524
- </Popover>
525
- </div>
526
- )}
527
- </div>
528
464
  </div>
529
465
  );
530
466
  });
@@ -67,12 +67,13 @@ export const ChatToolRender = (props: { value: IChatToolContent['content']; mess
67
67
  <div className={styles['chat-tool-render']}>
68
68
  <div className={styles['tool-header']} onClick={toggleExpand}>
69
69
  <div className={styles['tool-name']}>
70
- <Icon iconClass={`codicon codicon-triangle-${isExpanded ? 'down' : 'right'}`} />
70
+ <span className={cls(styles['expand-icon'], { [styles.expanded]: isExpanded })}>▶</span>
71
71
  {label}
72
72
  </div>
73
73
  {value.state && (
74
74
  <div className={styles['tool-state']}>
75
75
  <span className={styles['state-icon']}>{stateInfo.icon}</span>
76
+ <span className={styles['state-label']}>{stateInfo.label}</span>
76
77
  </div>
77
78
  )}
78
79
  </div>
@@ -3,7 +3,7 @@
3
3
  align-items: center;
4
4
  justify-content: space-between;
5
5
  font-size: 13px;
6
- padding: 0 0 0 12px;
6
+ padding: 0 4px 0 12px;
7
7
  color: var(--editor-foreground);
8
8
  text-overflow: ellipsis;
9
9
  white-space: nowrap;
@@ -96,7 +96,6 @@
96
96
  .chat_input_container {
97
97
  position: relative;
98
98
  border-radius: 9px;
99
- padding: 10px 0px 0px 0px;
100
99
  border: 1px solid var(--kt-input-border);
101
100
  background-color: var(--design-chatInput-background);
102
101
  &.active {
@@ -506,22 +505,3 @@
506
505
  }
507
506
  }
508
507
  }
509
-
510
- .chat_input_footer {
511
- padding: 0px 10px;
512
- display: flex;
513
- align-items: center;
514
- font-size: 12px;
515
-
516
- .model_selector {
517
- display: flex;
518
- font-size: 11px;
519
- align-items: center;
520
- }
521
-
522
- .mcp_desc {
523
- padding: 5px 0px;
524
- display: flex;
525
- align-items: center;
526
- }
527
- }