@opensumi/ide-ai-native 3.8.1-next-1740452912.0 → 3.8.1-next-1740463566.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 (122) hide show
  1. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  2. package/lib/browser/ai-core.contribution.js +10 -3
  3. package/lib/browser/ai-core.contribution.js.map +1 -1
  4. package/lib/browser/chat/chat-manager.service.d.ts +5 -0
  5. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  6. package/lib/browser/chat/chat-manager.service.js +18 -1
  7. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  8. package/lib/browser/chat/chat-model.d.ts +2 -0
  9. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  10. package/lib/browser/chat/chat-model.js +8 -2
  11. package/lib/browser/chat/chat-model.js.map +1 -1
  12. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  13. package/lib/browser/chat/chat.view.js +31 -8
  14. package/lib/browser/chat/chat.view.js.map +1 -1
  15. package/lib/browser/components/ChatContext/index.js +2 -2
  16. package/lib/browser/components/ChatContext/index.js.map +1 -1
  17. package/lib/browser/context/llm-context.service.d.ts +16 -5
  18. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  19. package/lib/browser/context/llm-context.service.js +78 -47
  20. package/lib/browser/context/llm-context.service.js.map +1 -1
  21. package/lib/browser/index.d.ts.map +1 -1
  22. package/lib/browser/index.js +4 -0
  23. package/lib/browser/index.js.map +1 -1
  24. package/lib/browser/mcp/config/components/mcp-config.module.less +178 -0
  25. package/lib/browser/mcp/config/components/mcp-config.view.d.ts +3 -0
  26. package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -0
  27. package/lib/browser/mcp/config/components/mcp-config.view.js +150 -0
  28. package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -0
  29. package/lib/browser/mcp/config/components/mcp-server-form.d.ts +16 -0
  30. package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +1 -0
  31. package/lib/browser/mcp/config/components/mcp-server-form.js +84 -0
  32. package/lib/browser/mcp/config/components/mcp-server-form.js.map +1 -0
  33. package/lib/browser/mcp/config/components/mcp-server-form.module.less +78 -0
  34. package/lib/browser/mcp/config/mcp-config.commands.d.ts +10 -0
  35. package/lib/browser/mcp/config/mcp-config.commands.d.ts.map +1 -0
  36. package/lib/browser/mcp/config/mcp-config.commands.js +35 -0
  37. package/lib/browser/mcp/config/mcp-config.commands.js.map +1 -0
  38. package/lib/browser/mcp/config/mcp-config.contribution.d.ts +16 -0
  39. package/lib/browser/mcp/config/mcp-config.contribution.d.ts.map +1 -0
  40. package/lib/browser/mcp/config/mcp-config.contribution.js +62 -0
  41. package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -0
  42. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +6 -0
  43. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  44. package/lib/browser/mcp/mcp-server-proxy.service.js +10 -1
  45. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  46. package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
  47. package/lib/browser/mcp/mcp-server.feature.registry.js +3 -2
  48. package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
  49. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
  50. package/lib/browser/mcp/tools/handlers/RunCommand.js +2 -0
  51. package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
  52. package/lib/browser/preferences/schema.d.ts.map +1 -1
  53. package/lib/browser/preferences/schema.js +16 -0
  54. package/lib/browser/preferences/schema.js.map +1 -1
  55. package/lib/common/index.d.ts +8 -1
  56. package/lib/common/index.d.ts.map +1 -1
  57. package/lib/common/index.js +3 -1
  58. package/lib/common/index.js.map +1 -1
  59. package/lib/common/llm-context.d.ts +12 -9
  60. package/lib/common/llm-context.d.ts.map +1 -1
  61. package/lib/common/llm-context.js.map +1 -1
  62. package/lib/common/mcp-server-manager.d.ts +17 -1
  63. package/lib/common/mcp-server-manager.d.ts.map +1 -1
  64. package/lib/common/mcp-server-manager.js.map +1 -1
  65. package/lib/common/prompts/context-prompt-provider.d.ts +2 -3
  66. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  67. package/lib/common/prompts/context-prompt-provider.js +21 -22
  68. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  69. package/lib/common/tool-invocation-registry.d.ts +2 -2
  70. package/lib/common/tool-invocation-registry.d.ts.map +1 -1
  71. package/lib/common/tool-invocation-registry.js +1 -1
  72. package/lib/common/tool-invocation-registry.js.map +1 -1
  73. package/lib/common/types.d.ts +6 -0
  74. package/lib/common/types.d.ts.map +1 -1
  75. package/lib/common/utils.d.ts.map +1 -1
  76. package/lib/common/utils.js +2 -1
  77. package/lib/common/utils.js.map +1 -1
  78. package/lib/node/mcp/sumi-mcp-server.d.ts +17 -3
  79. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  80. package/lib/node/mcp/sumi-mcp-server.js +59 -6
  81. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  82. package/lib/node/mcp-server-manager-impl.d.ts +4 -3
  83. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  84. package/lib/node/mcp-server-manager-impl.js +26 -6
  85. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  86. package/lib/node/mcp-server.d.ts +5 -16
  87. package/lib/node/mcp-server.d.ts.map +1 -1
  88. package/lib/node/mcp-server.js +12 -6
  89. package/lib/node/mcp-server.js.map +1 -1
  90. package/lib/node/openai/openai-language-model.d.ts +4 -3
  91. package/lib/node/openai/openai-language-model.d.ts.map +1 -1
  92. package/lib/node/openai/openai-language-model.js +3 -2
  93. package/lib/node/openai/openai-language-model.js.map +1 -1
  94. package/package.json +27 -27
  95. package/src/browser/ai-core.contribution.ts +13 -4
  96. package/src/browser/chat/chat-manager.service.ts +17 -1
  97. package/src/browser/chat/chat-model.ts +18 -3
  98. package/src/browser/chat/chat.view.tsx +48 -8
  99. package/src/browser/components/ChatContext/index.tsx +2 -2
  100. package/src/browser/context/llm-context.service.ts +90 -54
  101. package/src/browser/index.ts +4 -0
  102. package/src/browser/mcp/config/components/mcp-config.module.less +178 -0
  103. package/src/browser/mcp/config/components/mcp-config.view.tsx +215 -0
  104. package/src/browser/mcp/config/components/mcp-server-form.module.less +78 -0
  105. package/src/browser/mcp/config/components/mcp-server-form.tsx +144 -0
  106. package/src/browser/mcp/config/mcp-config.commands.ts +29 -0
  107. package/src/browser/mcp/config/mcp-config.contribution.ts +65 -0
  108. package/src/browser/mcp/mcp-server-proxy.service.ts +14 -2
  109. package/src/browser/mcp/mcp-server.feature.registry.ts +3 -2
  110. package/src/browser/mcp/tools/handlers/RunCommand.ts +2 -0
  111. package/src/browser/preferences/schema.ts +16 -0
  112. package/src/common/index.ts +7 -1
  113. package/src/common/llm-context.ts +10 -4
  114. package/src/common/mcp-server-manager.ts +17 -1
  115. package/src/common/prompts/context-prompt-provider.ts +26 -28
  116. package/src/common/tool-invocation-registry.ts +2 -2
  117. package/src/common/types.ts +6 -0
  118. package/src/common/utils.ts +3 -1
  119. package/src/node/mcp/sumi-mcp-server.ts +67 -9
  120. package/src/node/mcp-server-manager-impl.ts +30 -9
  121. package/src/node/mcp-server.ts +11 -14
  122. package/src/node/openai/openai-language-model.ts +7 -4
@@ -10,11 +10,11 @@ import { RPCService } from '@opensumi/ide-connection';
10
10
  import { ILogger } from '@opensumi/ide-core-common';
11
11
  import { INodeLogger } from '@opensumi/ide-core-node';
12
12
 
13
- import { ISumiMCPServerBackend } from '../../common';
14
- import { MCPServerDescription, MCPServerManager } from '../../common/mcp-server-manager';
13
+ import { BUILTIN_MCP_SERVER_NAME, ISumiMCPServerBackend } from '../../common';
14
+ import { IMCPServer, MCPServerDescription } from '../../common/mcp-server-manager';
15
15
  import { IToolInvocationRegistryManager, ToolInvocationRegistryManager } from '../../common/tool-invocation-registry';
16
16
  import { IMCPServerProxyService, MCPTool } from '../../common/types';
17
- import { IMCPServer } from '../mcp-server';
17
+ import { StdioMCPServerImpl } from '../mcp-server';
18
18
  import { MCPServerManagerImpl } from '../mcp-server-manager-impl';
19
19
 
20
20
  // 每个 BrowserTab 都对应了一个 SumiMCPServerBackend 实例
@@ -55,7 +55,6 @@ export class SumiMCPServerBackend extends RPCService<IMCPServerProxyService> imp
55
55
  }
56
56
  // 获取 MCP 工具
57
57
  const tools = await this.client.$getMCPTools();
58
- this.logger.log('[Node backend] SUMI MCP tools', tools);
59
58
  return tools;
60
59
  }
61
60
 
@@ -81,10 +80,10 @@ export class SumiMCPServerBackend extends RPCService<IMCPServerProxyService> imp
81
80
  }));
82
81
  }
83
82
 
84
- public async initBuiltinMCPServer() {
83
+ public async initBuiltinMCPServer(enabled: boolean) {
85
84
  const builtinMCPServer = new BuiltinMCPServer(this, this.logger);
86
85
  this.mcpServerManager.setClientId(this.clientId);
87
- await this.mcpServerManager.initBuiltinServer(builtinMCPServer);
86
+ await this.mcpServerManager.initBuiltinServer(builtinMCPServer, enabled);
88
87
  this.client?.$updateMCPServers();
89
88
  }
90
89
 
@@ -130,12 +129,72 @@ export class SumiMCPServerBackend extends RPCService<IMCPServerProxyService> imp
130
129
 
131
130
  return this.server;
132
131
  }
132
+
133
+ async getServers() {
134
+ const servers = Array.from(this.mcpServerManager.getServers().entries());
135
+ const serverInfos = await Promise.all(
136
+ servers.map(async ([serverName, server]) => {
137
+ let toolNames: string[] = [];
138
+ if (server.isStarted()) {
139
+ // 只获取正在运行的 MCP Server 的工具列表
140
+ const toolsResponse = await server.getTools();
141
+ toolNames = toolsResponse.tools.map((tool) => tool.name);
142
+ }
143
+
144
+ // OpenSumi 内置的 MCP Server
145
+ if (serverName === BUILTIN_MCP_SERVER_NAME) {
146
+ return {
147
+ name: server.getServerName(),
148
+ isStarted: server.isStarted(),
149
+ type: 'builtin rpc',
150
+ tools: toolNames,
151
+ };
152
+ }
153
+
154
+ // 第三方 Stdio 类型的 MCP Server
155
+ if (server instanceof StdioMCPServerImpl) {
156
+ return {
157
+ name: server.getServerName(),
158
+ isStarted: server.isStarted(),
159
+ type: 'stdio',
160
+ command: server.command + ' ' + (server.args?.join(' ') || ''),
161
+ tools: toolNames,
162
+ };
163
+ }
164
+
165
+ // TODO SSE 类型的 MCP Server
166
+
167
+ return {
168
+ name: server.getServerName(),
169
+ isStarted: server.isStarted(),
170
+ type: '[MOCK] stdio',
171
+ command: '[MOCK] npx sumi-ide-mcp-server',
172
+ tools: toolNames,
173
+ };
174
+ }),
175
+ );
176
+
177
+ // 将 builtin server 放在第一位
178
+ const builtinServer = serverInfos.find((server) => server.name === BUILTIN_MCP_SERVER_NAME);
179
+ const otherServers = serverInfos.filter((server) => server.name !== BUILTIN_MCP_SERVER_NAME);
180
+ return builtinServer ? [builtinServer, ...otherServers] : otherServers;
181
+ }
182
+
183
+ async startServer(serverName: string) {
184
+ await this.mcpServerManager.startServer(serverName);
185
+ this.client?.$updateMCPServers();
186
+ }
187
+
188
+ async stopServer(serverName: string) {
189
+ await this.mcpServerManager.stopServer(serverName);
190
+ this.client?.$updateMCPServers();
191
+ }
133
192
  }
134
193
 
135
194
  export const TokenBuiltinMCPServer = Symbol('TokenBuiltinMCPServer');
136
195
 
137
196
  export class BuiltinMCPServer implements IMCPServer {
138
- private started: boolean = true;
197
+ private started: boolean = false;
139
198
 
140
199
  constructor(private readonly sumiMCPServer: SumiMCPServerBackend, private readonly logger: ILogger) {}
141
200
 
@@ -144,7 +203,7 @@ export class BuiltinMCPServer implements IMCPServer {
144
203
  }
145
204
 
146
205
  getServerName(): string {
147
- return 'sumi-builtin';
206
+ return BUILTIN_MCP_SERVER_NAME;
148
207
  }
149
208
 
150
209
  async start(): Promise<void> {
@@ -182,7 +241,6 @@ export class BuiltinMCPServer implements IMCPServer {
182
241
  throw new Error('MCP Server not started');
183
242
  }
184
243
  const tools = await this.sumiMCPServer.getMCPTools();
185
- this.logger.debug('[BuiltinMCPServer] getTools', tools);
186
244
  return { tools } as any;
187
245
  }
188
246
 
@@ -2,13 +2,12 @@ import { ToolExecutionOptions } from 'ai';
2
2
 
3
3
  import { ILogger } from '@opensumi/ide-core-common';
4
4
 
5
- import { MCPServerDescription, MCPServerManager, MCPTool } from '../common/mcp-server-manager';
5
+ import { IMCPServer, MCPServerDescription, MCPServerManager, MCPTool } from '../common/mcp-server-manager';
6
6
  import { IToolInvocationRegistryManager, ToolRequest } from '../common/tool-invocation-registry';
7
7
  import { getToolName } from '../common/utils';
8
8
 
9
9
  import { BuiltinMCPServer } from './mcp/sumi-mcp-server';
10
- import { IMCPServer, MCPServerImpl } from './mcp-server';
11
-
10
+ import { StdioMCPServerImpl } from './mcp-server';
12
11
  // 这应该是 Browser Tab 维度的,每个 Tab 对应一个 MCPServerManagerImpl
13
12
  export class MCPServerManagerImpl implements MCPServerManager {
14
13
  protected servers: Map<string, IMCPServer> = new Map();
@@ -16,6 +15,10 @@ export class MCPServerManagerImpl implements MCPServerManager {
16
15
  // 当前实例对应的 clientId
17
16
  private clientId: string;
18
17
 
18
+ getServers(): Map<string, IMCPServer> {
19
+ return this.servers;
20
+ }
21
+
19
22
  constructor(
20
23
  private readonly toolInvocationRegistryManager: IToolInvocationRegistryManager,
21
24
  private readonly logger: ILogger,
@@ -25,13 +28,20 @@ export class MCPServerManagerImpl implements MCPServerManager {
25
28
  this.clientId = clientId;
26
29
  }
27
30
 
31
+ private unregisterServerTools(serverName: string) {
32
+ const registry = this.toolInvocationRegistryManager.getRegistry(this.clientId);
33
+ registry.unregisterProviderTools(serverName);
34
+ }
35
+
28
36
  async stopServer(serverName: string): Promise<void> {
29
37
  const server = this.servers.get(serverName);
30
38
  if (!server) {
31
39
  throw new Error(`MCP server "${serverName}" not found.`);
32
40
  }
33
- server.stop();
34
- this.logger.log(`MCP server "${serverName}" stopped.`);
41
+ await server.stop();
42
+ // 停止服务器后,需要从注册表中移除该服务器的所有工具
43
+ this.unregisterServerTools(serverName);
44
+ this.logger.log(`MCP server "${serverName}" stopped and tools unregistered.`);
35
45
  }
36
46
 
37
47
  async getStartedServers(): Promise<string[]> {
@@ -63,6 +73,7 @@ export class MCPServerManagerImpl implements MCPServerManager {
63
73
  throw new Error(`MCP server "${serverName}" not found.`);
64
74
  }
65
75
  await server.start();
76
+ await this.registerTools(serverName);
66
77
  }
67
78
 
68
79
  async getServerNames(): Promise<string[]> {
@@ -122,7 +133,7 @@ export class MCPServerManagerImpl implements MCPServerManager {
122
133
  if (existingServer) {
123
134
  existingServer.update(command, args, env);
124
135
  } else {
125
- const newServer = new MCPServerImpl(name, command, args, env, this.logger);
136
+ const newServer = new StdioMCPServerImpl(name, command, args, env, this.logger);
126
137
  this.servers.set(name, newServer);
127
138
  }
128
139
  }
@@ -131,16 +142,23 @@ export class MCPServerManagerImpl implements MCPServerManager {
131
142
  this.servers.set(server.getServerName(), server);
132
143
  }
133
144
 
134
- async initBuiltinServer(builtinMCPServer: BuiltinMCPServer): Promise<void> {
145
+ // enabled true 时,会自动启动内置服务器, 并注册工具
146
+ async initBuiltinServer(builtinMCPServer: BuiltinMCPServer, enabled: boolean = true): Promise<void> {
135
147
  this.addOrUpdateServerDirectly(builtinMCPServer);
136
- await this.registerTools(builtinMCPServer.getServerName());
148
+ if (enabled) {
149
+ await builtinMCPServer.start();
150
+ await this.registerTools(builtinMCPServer.getServerName());
151
+ }
137
152
  }
138
153
 
139
154
  async addExternalMCPServers(servers: MCPServerDescription[]): Promise<void> {
140
155
  for (const server of servers) {
141
156
  this.addOrUpdateServer(server);
157
+ if (!server.enabled) {
158
+ // 如果是 enabled 为 false 的 server,则不进行启动
159
+ continue;
160
+ }
142
161
  await this.startServer(server.name);
143
- await this.registerTools(server.name);
144
162
  }
145
163
  }
146
164
 
@@ -148,7 +166,10 @@ export class MCPServerManagerImpl implements MCPServerManager {
148
166
  const server = this.servers.get(name);
149
167
  if (server) {
150
168
  server.stop();
169
+ // 移除服务器时,也需要从注册表中移除该服务器的所有工具
170
+ this.unregisterServerTools(name);
151
171
  this.servers.delete(name);
172
+ this.logger.log(`MCP server "${name}" removed and tools unregistered.`);
152
173
  } else {
153
174
  this.logger.warn(`MCP server "${name}" not found.`);
154
175
  }
@@ -4,20 +4,12 @@ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
4
4
 
5
5
  import { ILogger } from '@opensumi/ide-core-common';
6
6
 
7
- export interface IMCPServer {
8
- isStarted(): boolean;
9
- start(): Promise<void>;
10
- getServerName(): string;
11
- callTool(toolName: string, toolCallId: string, arg_string: string): ReturnType<Client['callTool']>;
12
- getTools(): ReturnType<Client['listTools']>;
13
- update(command: string, args?: string[], env?: { [key: string]: string }): void;
14
- stop(): void;
15
- }
7
+ import { IMCPServer } from '../common/mcp-server-manager';
16
8
 
17
- export class MCPServerImpl implements IMCPServer {
9
+ export class StdioMCPServerImpl implements IMCPServer {
18
10
  private name: string;
19
- private command: string;
20
- private args?: string[];
11
+ public command: string;
12
+ public args?: string[];
21
13
  private client: Client;
22
14
  private env?: { [key: string]: string };
23
15
  private started: boolean = false;
@@ -116,12 +108,17 @@ export class MCPServerImpl implements IMCPServer {
116
108
  this.env = env;
117
109
  }
118
110
 
119
- stop(): void {
111
+ async stop(): Promise<void> {
120
112
  if (!this.started || !this.client) {
121
113
  return;
122
114
  }
123
115
  this.logger?.log(`Stopping MCP server "${this.name}"`);
124
- this.client.close();
116
+ try {
117
+ await this.client.close();
118
+ } catch (error) {
119
+ this.logger?.error(`Failed to stop MCP server "${this.name}":`, error);
120
+ }
121
+ this.logger?.log(`MCP server "${this.name}" stopped`);
125
122
  this.started = false;
126
123
  }
127
124
  }
@@ -1,25 +1,28 @@
1
- import { OpenAIProvider, createOpenAI } from '@ai-sdk/openai';
1
+ import { OpenAICompatibleProvider, createOpenAICompatible } from '@ai-sdk/openai-compatible';
2
+ import { LanguageModelV1 } from 'ai';
2
3
 
3
4
  import { Injectable } from '@opensumi/di';
4
5
  import { AINativeSettingSectionsId, IAIBackServiceOption } from '@opensumi/ide-core-common';
5
6
 
6
7
  import { BaseLanguageModel } from '../base-language-model';
8
+
7
9
  export const DeepSeekModelIdentifier = Symbol('DeepSeekModelIdentifier');
8
10
 
9
11
  @Injectable()
10
12
  export class OpenAIModel extends BaseLanguageModel {
11
- protected initializeProvider(options: IAIBackServiceOption): OpenAIProvider {
13
+ protected initializeProvider(options: IAIBackServiceOption): OpenAICompatibleProvider {
12
14
  const apiKey = options.apiKey;
13
15
  if (!apiKey) {
14
16
  throw new Error(`Please provide OpenAI API Key in preferences (${AINativeSettingSectionsId.OpenaiApiKey})`);
15
17
  }
16
- return createOpenAI({
18
+ return createOpenAICompatible({
17
19
  apiKey,
18
20
  baseURL: options.baseURL || 'https://dashscope.aliyuncs.com/compatible-mode/v1',
21
+ name: 'openai',
19
22
  });
20
23
  }
21
24
 
22
- protected getModelIdentifier(provider: OpenAIProvider, modelId?: string) {
25
+ protected getModelIdentifier(provider: OpenAICompatibleProvider, modelId?: string): LanguageModelV1 {
23
26
  return provider(modelId || 'qwen-max');
24
27
  }
25
28
  }