@opensumi/ide-ai-native 3.8.1-next-1740556231.0 → 3.8.1-next-1740625266.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.
- package/lib/browser/ai-core.contextkeys.d.ts +1 -1
- package/lib/browser/ai-core.contextkeys.d.ts.map +1 -1
- package/lib/browser/ai-core.contextkeys.js +1 -1
- package/lib/browser/ai-core.contextkeys.js.map +1 -1
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +10 -3
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +30 -1
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/contrib/inline-completions/inline-completions.controller.js +1 -1
- package/lib/browser/contrib/inline-completions/inline-completions.controller.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/index.d.ts +2 -1
- package/lib/browser/contrib/intelligent-completions/index.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/index.js +4 -1
- package/lib/browser/contrib/intelligent-completions/index.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +2 -2
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +5 -4
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js +4 -2
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/default.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/default.js +17 -11
- package/lib/browser/contrib/intelligent-completions/view/default.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +4 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.module.less +178 -0
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts +3 -0
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -0
- package/lib/browser/mcp/config/components/mcp-config.view.js +150 -0
- package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.d.ts +16 -0
- package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.js +84 -0
- package/lib/browser/mcp/config/components/mcp-server-form.js.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.module.less +78 -0
- package/lib/browser/mcp/config/mcp-config.commands.d.ts +10 -0
- package/lib/browser/mcp/config/mcp-config.commands.d.ts.map +1 -0
- package/lib/browser/mcp/config/mcp-config.commands.js +35 -0
- package/lib/browser/mcp/config/mcp-config.commands.js.map +1 -0
- package/lib/browser/mcp/config/mcp-config.contribution.d.ts +16 -0
- package/lib/browser/mcp/config/mcp-config.contribution.d.ts.map +1 -0
- package/lib/browser/mcp/config/mcp-config.contribution.js +62 -0
- package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts +6 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js +10 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js +3 -2
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +16 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/common/index.d.ts +8 -1
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +3 -1
- package/lib/common/index.js.map +1 -1
- package/lib/common/mcp-server-manager.d.ts +17 -1
- package/lib/common/mcp-server-manager.d.ts.map +1 -1
- package/lib/common/mcp-server-manager.js.map +1 -1
- package/lib/common/tool-invocation-registry.d.ts +2 -2
- package/lib/common/tool-invocation-registry.d.ts.map +1 -1
- package/lib/common/tool-invocation-registry.js +1 -1
- package/lib/common/tool-invocation-registry.js.map +1 -1
- package/lib/common/types.d.ts +6 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +2 -1
- package/lib/common/utils.js.map +1 -1
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js +5 -4
- package/lib/node/base-language-model.js.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.d.ts +17 -3
- package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.js +59 -6
- package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
- package/lib/node/mcp-server-manager-impl.d.ts +4 -3
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
- package/lib/node/mcp-server-manager-impl.js +26 -6
- package/lib/node/mcp-server-manager-impl.js.map +1 -1
- package/lib/node/mcp-server.d.ts +5 -16
- package/lib/node/mcp-server.d.ts.map +1 -1
- package/lib/node/mcp-server.js +12 -6
- package/lib/node/mcp-server.js.map +1 -1
- package/lib/node/openai/openai-language-model.d.ts +4 -3
- package/lib/node/openai/openai-language-model.d.ts.map +1 -1
- package/lib/node/openai/openai-language-model.js +3 -2
- package/lib/node/openai/openai-language-model.js.map +1 -1
- package/package.json +27 -27
- package/src/browser/ai-core.contextkeys.ts +3 -3
- package/src/browser/ai-core.contribution.ts +13 -4
- package/src/browser/chat/chat.view.tsx +47 -0
- package/src/browser/contrib/inline-completions/inline-completions.controller.ts +1 -1
- package/src/browser/contrib/intelligent-completions/index.ts +5 -1
- package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +3 -3
- package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +6 -5
- package/src/browser/contrib/intelligent-completions/view/code-edits-previewer.ts +4 -2
- package/src/browser/contrib/intelligent-completions/view/default.ts +27 -19
- package/src/browser/index.ts +4 -0
- package/src/browser/mcp/config/components/mcp-config.module.less +178 -0
- package/src/browser/mcp/config/components/mcp-config.view.tsx +215 -0
- package/src/browser/mcp/config/components/mcp-server-form.module.less +78 -0
- package/src/browser/mcp/config/components/mcp-server-form.tsx +144 -0
- package/src/browser/mcp/config/mcp-config.commands.ts +29 -0
- package/src/browser/mcp/config/mcp-config.contribution.ts +65 -0
- package/src/browser/mcp/mcp-server-proxy.service.ts +14 -2
- package/src/browser/mcp/mcp-server.feature.registry.ts +3 -2
- package/src/browser/preferences/schema.ts +16 -0
- package/src/common/index.ts +7 -1
- package/src/common/mcp-server-manager.ts +17 -1
- package/src/common/tool-invocation-registry.ts +2 -2
- package/src/common/types.ts +6 -0
- package/src/common/utils.ts +3 -1
- package/src/node/base-language-model.ts +7 -4
- package/src/node/mcp/sumi-mcp-server.ts +67 -9
- package/src/node/mcp-server-manager-impl.ts +30 -9
- package/src/node/mcp-server.ts +11 -14
- package/src/node/openai/openai-language-model.ts +7 -4
|
@@ -72,7 +72,7 @@ export interface ToolInvocationRegistry {
|
|
|
72
72
|
*
|
|
73
73
|
* @param providerName - 要移除其工具的工具提供者名称(在 `ToolRequest` 中指定)
|
|
74
74
|
*/
|
|
75
|
-
|
|
75
|
+
unregisterProviderTools(providerName: string): void;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export const ToolProvider = Symbol('ToolProvider');
|
|
@@ -83,7 +83,7 @@ export interface ToolProvider {
|
|
|
83
83
|
export class ToolInvocationRegistryImpl implements ToolInvocationRegistry {
|
|
84
84
|
private tools: Map<string, ToolRequest> = new Map<string, ToolRequest>();
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
unregisterProviderTools(providerName: string): void {
|
|
87
87
|
const toolsToRemove: string[] = [];
|
|
88
88
|
for (const [id, tool] of this.tools.entries()) {
|
|
89
89
|
if (tool.providerName === providerName) {
|
package/src/common/types.ts
CHANGED
|
@@ -34,6 +34,12 @@ export interface IMCPServerProxyService {
|
|
|
34
34
|
$getMCPTools(): Promise<MCPTool[]>;
|
|
35
35
|
// 通知前端 MCP 服务注册表发生了变化
|
|
36
36
|
$updateMCPServers(): Promise<void>;
|
|
37
|
+
// 获取所有 MCP 服务器列表
|
|
38
|
+
$getServers(): Promise<Array<{ name: string; isStarted: boolean }>>;
|
|
39
|
+
// 启动指定的 MCP 服务器
|
|
40
|
+
$startServer(serverName: string): Promise<void>;
|
|
41
|
+
// 停止指定的 MCP 服务器
|
|
42
|
+
$stopServer(serverName: string): Promise<void>;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
export interface MCPTool {
|
package/src/common/utils.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { IEditorDocumentModel } from '@opensumi/ide-editor';
|
|
2
2
|
|
|
3
|
+
import { BUILTIN_MCP_SERVER_NAME } from './index';
|
|
4
|
+
|
|
3
5
|
const BACK_QUOTE_3_SYMBOL = '```';
|
|
4
6
|
const MIN_PROMPT_CHARS = 10;
|
|
5
7
|
|
|
@@ -49,4 +51,4 @@ export const extractCodeBlocks = (content: string): string => {
|
|
|
49
51
|
return newContents.join('\n');
|
|
50
52
|
};
|
|
51
53
|
|
|
52
|
-
export const getToolName = (toolName: string, serverName =
|
|
54
|
+
export const getToolName = (toolName: string, serverName = BUILTIN_MCP_SERVER_NAME) => `mcp_${serverName}_${toolName}`;
|
|
@@ -41,11 +41,14 @@ export abstract class BaseLanguageModel {
|
|
|
41
41
|
): Promise<any> {
|
|
42
42
|
const provider = this.initializeProvider(options);
|
|
43
43
|
const clientId = options.clientId;
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
|
|
45
|
+
let allFunctions: ToolRequest[] = [];
|
|
46
|
+
// 如果没有传入 clientId,则不使用工具
|
|
47
|
+
if (clientId) {
|
|
48
|
+
const registry = this.toolInvocationRegistryManager.getRegistry(clientId);
|
|
49
|
+
allFunctions = options.noTool ? [] : registry.getAllFunctions();
|
|
46
50
|
}
|
|
47
|
-
|
|
48
|
-
const allFunctions = options.noTool ? [] : registry.getAllFunctions();
|
|
51
|
+
|
|
49
52
|
return this.handleStreamingRequest(
|
|
50
53
|
provider,
|
|
51
54
|
request,
|
|
@@ -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 {
|
|
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 {
|
|
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 =
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
145
|
+
// enabled 为 true 时,会自动启动内置服务器, 并注册工具
|
|
146
|
+
async initBuiltinServer(builtinMCPServer: BuiltinMCPServer, enabled: boolean = true): Promise<void> {
|
|
135
147
|
this.addOrUpdateServerDirectly(builtinMCPServer);
|
|
136
|
-
|
|
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
|
}
|
package/src/node/mcp-server.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
9
|
+
export class StdioMCPServerImpl implements IMCPServer {
|
|
18
10
|
private name: string;
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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 {
|
|
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):
|
|
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
|
|
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:
|
|
25
|
+
protected getModelIdentifier(provider: OpenAICompatibleProvider, modelId?: string): LanguageModelV1 {
|
|
23
26
|
return provider(modelId || 'qwen-max');
|
|
24
27
|
}
|
|
25
28
|
}
|