@n0ts123/mcplink-core 0.0.13 → 0.0.14

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/dist/index.d.ts CHANGED
@@ -315,6 +315,15 @@ declare class HttpClient {
315
315
 
316
316
  declare class OpenAIAdapter implements AIAdapter {
317
317
  name: string;
318
+ private pendingToolCall;
319
+ /**
320
+ * 检查 tool_call 参数是否完整(可以解析为 JSON)
321
+ */
322
+ private isToolCallComplete;
323
+ /**
324
+ * 返回并清空 pending tool_call
325
+ */
326
+ private flushPendingToolCall;
318
327
  /**
319
328
  * 构建请求体
320
329
  * 完全开放:除必要字段外,其他参数原封不动传递
package/dist/index.js CHANGED
@@ -403,6 +403,36 @@ var HttpClient = class {
403
403
  // src/adapters/openai.ts
404
404
  var OpenAIAdapter = class {
405
405
  name = "openai";
406
+ // 用于累积 tool_call 参数的状态
407
+ pendingToolCall = null;
408
+ /**
409
+ * 检查 tool_call 参数是否完整(可以解析为 JSON)
410
+ */
411
+ isToolCallComplete(tc) {
412
+ if (!tc.arguments) return false;
413
+ try {
414
+ JSON.parse(tc.arguments);
415
+ return true;
416
+ } catch {
417
+ return false;
418
+ }
419
+ }
420
+ /**
421
+ * 返回并清空 pending tool_call
422
+ */
423
+ flushPendingToolCall() {
424
+ if (!this.pendingToolCall) return null;
425
+ const tc = this.pendingToolCall;
426
+ this.pendingToolCall = null;
427
+ return {
428
+ type: "tool_call",
429
+ toolCall: {
430
+ id: tc.id,
431
+ name: tc.name,
432
+ arguments: tc.arguments ? JSON.parse(tc.arguments) : {}
433
+ }
434
+ };
435
+ }
406
436
  /**
407
437
  * 构建请求体
408
438
  * 完全开放:除必要字段外,其他参数原封不动传递
@@ -475,17 +505,28 @@ var OpenAIAdapter = class {
475
505
  }
476
506
  if (delta?.tool_calls) {
477
507
  const tc = delta.tool_calls[0];
478
- if (tc.id && tc.function?.name) {
479
- return {
480
- type: "tool_call",
481
- toolCall: {
482
- id: tc.id,
483
- name: tc.function.name,
484
- arguments: tc.function.arguments ? JSON.parse(tc.function.arguments) : {}
485
- }
508
+ if (tc.id && tc.function?.name && (!this.pendingToolCall || this.pendingToolCall.id !== tc.id)) {
509
+ const result = this.flushPendingToolCall();
510
+ this.pendingToolCall = {
511
+ id: tc.id,
512
+ name: tc.function.name,
513
+ arguments: tc.function.arguments || ""
486
514
  };
515
+ if (this.isToolCallComplete(this.pendingToolCall)) {
516
+ return this.flushPendingToolCall();
517
+ }
518
+ return result;
519
+ }
520
+ if (this.pendingToolCall && tc.function?.arguments) {
521
+ this.pendingToolCall.arguments += tc.function.arguments;
522
+ if (this.isToolCallComplete(this.pendingToolCall)) {
523
+ return this.flushPendingToolCall();
524
+ }
487
525
  }
488
526
  }
527
+ if (choice?.finish_reason && this.pendingToolCall) {
528
+ return this.flushPendingToolCall();
529
+ }
489
530
  if (choice?.finish_reason) {
490
531
  return { type: "done" };
491
532
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MCPManager.ts","../src/http-client.ts","../src/adapters/openai.ts","../src/MCPLink.ts","../src/standard-stream.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js'\r\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'\r\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\r\nimport type { MCPServerConfig, MCPServerConfigStdio, MCPServerConfigStreamableHTTP, MCPTool, MCPServerStatus } from './types.js'\r\n\r\n/**\r\n * 需要自动重连的错误关键词\r\n * 当工具调用遇到这些错误时,会自动重连服务器并重试一次\r\n */\r\nconst RECONNECT_ERROR_KEYWORDS = [\r\n 'Server not initialized',\r\n 'session not found',\r\n 'Session expired',\r\n 'connection refused',\r\n 'ECONNREFUSED',\r\n 'ECONNRESET',\r\n 'EPIPE',\r\n 'socket hang up',\r\n]\r\n\r\n/**\r\n * MCP 服务器实例\r\n */\r\ninterface MCPServerInstance {\r\n id: string\r\n config: MCPServerConfig\r\n client: Client\r\n transport: StdioClientTransport | StreamableHTTPClientTransport\r\n tools: MCPTool[]\r\n status: 'stopped' | 'starting' | 'running' | 'error'\r\n error?: string\r\n}\r\n\r\n/**\r\n * MCP 管理器\r\n * 负责管理多个 MCP 服务器的连接、工具发现和调用\r\n */\r\nexport class MCPManager {\r\n private servers: Map<string, MCPServerInstance> = new Map()\r\n\r\n /**\r\n * 添加 MCP 服务器配置\r\n */\r\n addServer(id: string, config: MCPServerConfig): void {\r\n if (this.servers.has(id)) {\r\n throw new Error(`MCP server \"${id}\" already exists`)\r\n }\r\n\r\n // 创建 Client\r\n const client = new Client({ name: 'mcplink', version: '0.0.1' }, { capabilities: {} })\r\n\r\n // 创建 Transport\r\n let transport: StdioClientTransport | StreamableHTTPClientTransport\r\n\r\n if (config.type === 'streamable-http') {\r\n const httpConfig = config as MCPServerConfigStreamableHTTP\r\n transport = new StreamableHTTPClientTransport(new URL(httpConfig.url))\r\n } else {\r\n const stdioConfig = config as MCPServerConfigStdio\r\n // 合并当前进程的环境变量和配置的环境变量\r\n // 过滤掉 undefined 值\r\n const processEnv: Record<string, string> = {}\r\n for (const [key, value] of Object.entries(process.env)) {\r\n if (value !== undefined) {\r\n processEnv[key] = value\r\n }\r\n }\r\n const mergedEnv = {\r\n ...processEnv,\r\n ...stdioConfig.env,\r\n }\r\n\r\n // Windows 兼容性处理\r\n // 在 Windows 上,npx/npm 等命令实际上是 .cmd 文件,需要通过 shell 执行\r\n const isWindows = process.platform === 'win32'\r\n let command = stdioConfig.command\r\n let args = stdioConfig.args || []\r\n\r\n if (isWindows) {\r\n // 对于 npx, npm, node 等命令,在 Windows 上需要通过 cmd /c 执行\r\n const windowsCommands = ['npx', 'npm', 'node', 'pnpm', 'yarn', 'bunx']\r\n if (windowsCommands.includes(command.toLowerCase())) {\r\n args = ['/c', command, ...args]\r\n command = 'cmd'\r\n }\r\n }\r\n\r\n transport = new StdioClientTransport({\r\n command,\r\n args,\r\n env: mergedEnv,\r\n })\r\n }\r\n\r\n this.servers.set(id, {\r\n id,\r\n config,\r\n client,\r\n transport,\r\n tools: [],\r\n status: 'stopped',\r\n })\r\n }\r\n\r\n /**\r\n * 启动 MCP 服务器\r\n */\r\n async startServer(id: string): Promise<void> {\r\n const server = this.servers.get(id)\r\n if (!server) {\r\n throw new Error(`MCP server \"${id}\" not found`)\r\n }\r\n\r\n if (server.status === 'running') {\r\n return\r\n }\r\n\r\n server.status = 'starting'\r\n server.error = undefined\r\n\r\n // 打印启动信息\r\n const config = server.config\r\n if (config.type === 'stdio') {\r\n const stdioConfig = config as MCPServerConfigStdio\r\n const isWindows = process.platform === 'win32'\r\n const windowsCommands = ['npx', 'npm', 'node', 'pnpm', 'yarn', 'bunx']\r\n let displayCmd = stdioConfig.command\r\n let displayArgs = stdioConfig.args || []\r\n\r\n if (isWindows && windowsCommands.includes(stdioConfig.command.toLowerCase())) {\r\n displayCmd = 'cmd'\r\n displayArgs = ['/c', stdioConfig.command, ...displayArgs]\r\n }\r\n\r\n console.log(`\\n🔧 [MCP] 正在启动服务器 \"${id}\"...`)\r\n console.log(` 命令: ${displayCmd} ${displayArgs.join(' ')}`)\r\n if (stdioConfig.env && Object.keys(stdioConfig.env).length > 0) {\r\n console.log(` 环境变量: ${Object.keys(stdioConfig.env).join(', ')}`)\r\n }\r\n } else if (config.type === 'streamable-http') {\r\n const httpConfig = config as MCPServerConfigStreamableHTTP\r\n console.log(`\\n🔧 [MCP] 正在连接 Streamable HTTP 服务器 \"${id}\"...`)\r\n console.log(` URL: ${httpConfig.url}`)\r\n }\r\n\r\n try {\r\n // 连接到服务器\r\n await server.client.connect(server.transport)\r\n\r\n // 获取工具列表\r\n const toolsResult = await server.client.listTools()\r\n server.tools = toolsResult.tools.map((tool) => ({\r\n name: tool.name,\r\n description: tool.description || '',\r\n inputSchema: tool.inputSchema as MCPTool['inputSchema'],\r\n }))\r\n\r\n server.status = 'running'\r\n console.log(`✅ [MCP] 服务器 \"${id}\" 启动成功,发现 ${server.tools.length} 个工具`)\r\n if (server.tools.length > 0) {\r\n console.log(` 工具: ${server.tools.map((t) => t.name).join(', ')}`)\r\n }\r\n } catch (error) {\r\n server.status = 'error'\r\n\r\n // 提供更详细的错误信息\r\n let errorMessage = error instanceof Error ? error.message : String(error)\r\n\r\n if (errorMessage.includes('Connection closed')) {\r\n if (config.type === 'stdio') {\r\n const stdioConfig = config as MCPServerConfigStdio\r\n errorMessage =\r\n `MCP 服务器启动失败: 进程立即退出。\\n` +\r\n `命令: ${stdioConfig.command} ${(stdioConfig.args || []).join(' ')}\\n` +\r\n `可能原因:\\n` +\r\n `1. 命令 \"${stdioConfig.command}\" 不存在或不在 PATH 中\\n` +\r\n `2. 如果使用 Docker,请确保 Docker 正在运行\\n` +\r\n `3. 检查环境变量是否正确配置\\n` +\r\n `4. 尝试在终端手动运行命令查看具体错误`\r\n }\r\n }\r\n\r\n // 打印错误到控制台\r\n console.error(`❌ [MCP] 服务器 \"${id}\" 启动失败:`)\r\n console.error(` ${errorMessage.split('\\n').join('\\n ')}`)\r\n\r\n server.error = errorMessage\r\n throw new Error(errorMessage)\r\n }\r\n }\r\n\r\n /**\r\n * 停止 MCP 服务器\r\n */\r\n async stopServer(id: string): Promise<void> {\r\n const server = this.servers.get(id)\r\n if (!server) {\r\n throw new Error(`MCP server \"${id}\" not found`)\r\n }\r\n\r\n if (server.status === 'stopped') {\r\n return\r\n }\r\n\r\n console.log(`🔧 [MCP] 正在停止服务器 \"${id}\"...`)\r\n\r\n try {\r\n await server.client.close()\r\n console.log(`✅ [MCP] 服务器 \"${id}\" 已停止`)\r\n } catch (error) {\r\n console.error(`⚠️ [MCP] 停止服务器 \"${id}\" 时出错:`, error)\r\n } finally {\r\n server.status = 'stopped'\r\n server.tools = []\r\n }\r\n }\r\n\r\n /**\r\n * 启动所有已配置的服务器\r\n */\r\n async startAll(): Promise<void> {\r\n const startPromises = Array.from(this.servers.keys()).map((id) =>\r\n this.startServer(id).catch((error) => {\r\n console.error(`Failed to start MCP server \"${id}\":`, error)\r\n })\r\n )\r\n await Promise.all(startPromises)\r\n }\r\n\r\n /**\r\n * 停止所有服务器\r\n */\r\n async stopAll(): Promise<void> {\r\n const stopPromises = Array.from(this.servers.keys()).map((id) =>\r\n this.stopServer(id).catch((error) => {\r\n console.error(`Failed to stop MCP server \"${id}\":`, error)\r\n })\r\n )\r\n await Promise.all(stopPromises)\r\n }\r\n\r\n /**\r\n * 获取所有可用的工具\r\n */\r\n getAllTools(): MCPTool[] {\r\n const tools: MCPTool[] = []\r\n for (const server of this.servers.values()) {\r\n if (server.status === 'running') {\r\n tools.push(...server.tools)\r\n }\r\n }\r\n return tools\r\n }\r\n\r\n /**\r\n * 检查错误是否需要重连\r\n */\r\n private isReconnectNeeded(error: unknown): boolean {\r\n const errorMessage = error instanceof Error ? error.message : String(error)\r\n return RECONNECT_ERROR_KEYWORDS.some(keyword =>\r\n errorMessage.toLowerCase().includes(keyword.toLowerCase())\r\n )\r\n }\r\n\r\n /**\r\n * 重连指定服务器\r\n */\r\n private async reconnectServer(serverId: string): Promise<boolean> {\r\n const server = this.servers.get(serverId)\r\n if (!server) return false\r\n\r\n console.log(`🔄 [MCP] 正在重连服务器 \"${serverId}\"...`)\r\n\r\n try {\r\n // 先停止\r\n await this.stopServer(serverId)\r\n\r\n // 重新创建 transport(旧的可能已经损坏)\r\n const config = server.config\r\n let transport: StdioClientTransport | StreamableHTTPClientTransport\r\n\r\n if (config.type === 'streamable-http') {\r\n const httpConfig = config as MCPServerConfigStreamableHTTP\r\n transport = new StreamableHTTPClientTransport(new URL(httpConfig.url))\r\n } else {\r\n const stdioConfig = config as MCPServerConfigStdio\r\n const processEnv: Record<string, string> = {}\r\n for (const [key, value] of Object.entries(process.env)) {\r\n if (value !== undefined) {\r\n processEnv[key] = value\r\n }\r\n }\r\n const mergedEnv = {\r\n ...processEnv,\r\n ...stdioConfig.env,\r\n }\r\n\r\n const isWindows = process.platform === 'win32'\r\n let command = stdioConfig.command\r\n let args = stdioConfig.args || []\r\n\r\n if (isWindows) {\r\n const windowsCommands = ['npx', 'npm', 'node', 'pnpm', 'yarn', 'bunx']\r\n if (windowsCommands.includes(command.toLowerCase())) {\r\n args = ['/c', command, ...args]\r\n command = 'cmd'\r\n }\r\n }\r\n\r\n transport = new StdioClientTransport({\r\n command,\r\n args,\r\n env: mergedEnv,\r\n })\r\n }\r\n\r\n // 创建新的 client\r\n const client = new Client({ name: 'mcplink', version: '0.0.1' }, { capabilities: {} })\r\n\r\n // 更新服务器实例\r\n server.client = client\r\n server.transport = transport\r\n\r\n // 重新启动\r\n await this.startServer(serverId)\r\n\r\n console.log(`✅ [MCP] 服务器 \"${serverId}\" 重连成功`)\r\n return true\r\n } catch (error) {\r\n console.error(`❌ [MCP] 服务器 \"${serverId}\" 重连失败:`, error)\r\n return false\r\n }\r\n }\r\n\r\n /**\r\n * 调用工具(带自动重连机制)\r\n */\r\n async callTool(toolName: string, args: Record<string, unknown>): Promise<unknown> {\r\n // 找到提供该工具的服务器\r\n for (const server of this.servers.values()) {\r\n if (server.status !== 'running') continue\r\n\r\n const tool = server.tools.find((t) => t.name === toolName)\r\n if (tool) {\r\n // 尝试调用工具,失败时自动重连并重试一次\r\n const executeCall = async (): Promise<unknown> => {\r\n const result = await server.client.callTool({\r\n name: toolName,\r\n arguments: args,\r\n })\r\n\r\n // 处理结果\r\n if (result.content && Array.isArray(result.content)) {\r\n // 如果是文本内容,拼接返回\r\n const textContents = result.content\r\n .filter((c): c is { type: 'text'; text: string } => c.type === 'text')\r\n .map((c) => c.text)\r\n\r\n if (textContents.length > 0) {\r\n const textResult = textContents.join('\\n')\r\n // 检查是否是错误结果\r\n if (result.isError) {\r\n throw new Error(textResult || '工具执行失败')\r\n }\r\n return textResult\r\n }\r\n }\r\n\r\n // 检查是否是错误结果\r\n if (result.isError) {\r\n const errorContent = result.content\r\n throw new Error(\r\n typeof errorContent === 'string'\r\n ? errorContent\r\n : JSON.stringify(errorContent) || '工具执行失败'\r\n )\r\n }\r\n\r\n return result.content\r\n }\r\n\r\n try {\r\n return await executeCall()\r\n } catch (error) {\r\n // 检查是否需要重连\r\n if (this.isReconnectNeeded(error)) {\r\n console.log(`⚠️ [MCP] 工具调用失败,检测到连接错误,尝试重连: ${error instanceof Error ? error.message : error}`)\r\n\r\n // 尝试重连\r\n const reconnected = await this.reconnectServer(server.id)\r\n\r\n if (reconnected) {\r\n // 重连成功,重试一次\r\n console.log(`🔁 [MCP] 重连成功,正在重试工具调用: ${toolName}`)\r\n return await executeCall()\r\n }\r\n }\r\n\r\n // 重连失败或不需要重连,抛出原始错误\r\n throw error\r\n }\r\n }\r\n }\r\n\r\n throw new Error(`Tool \"${toolName}\" not found in any running MCP server`)\r\n }\r\n\r\n /**\r\n * 获取所有服务器状态\r\n */\r\n getServerStatuses(): MCPServerStatus[] {\r\n return Array.from(this.servers.values()).map((server) => ({\r\n id: server.id,\r\n name: server.id,\r\n config: server.config,\r\n status: server.status,\r\n tools: server.tools,\r\n error: server.error,\r\n }))\r\n }\r\n\r\n /**\r\n * 移除服务器\r\n */\r\n async removeServer(id: string): Promise<void> {\r\n await this.stopServer(id)\r\n this.servers.delete(id)\r\n }\r\n}\r\n","/**\n * HTTP 客户端 - 基于 axios\n * 支持 SSE 流式响应\n */\n\nimport axios, { AxiosInstance, AxiosRequestConfig } from 'axios'\nimport type { AIRequestConfig, AIResponse, AIStreamEvent, Message, ToolDefinition, AIAdapter } from './types.js'\n\nexport class HttpClient {\n private client: AxiosInstance\n\n constructor() {\n this.client = axios.create({\n timeout: 120000,\n })\n }\n\n /**\n * 非流式请求\n */\n async chat(\n aiConfig: AIRequestConfig,\n adapter: AIAdapter,\n messages: Message[],\n tools?: ToolDefinition[]\n ): Promise<AIResponse> {\n const body = adapter.buildRequestBody(aiConfig, messages, tools)\n const headers = { ...adapter.getHeaders(aiConfig), ...aiConfig.headers }\n\n const response = await this.client.post(\n adapter.getEndpoint(aiConfig.baseURL),\n body,\n {\n headers,\n timeout: aiConfig.timeout || 120000,\n }\n )\n\n return adapter.parseResponse(response.data)\n }\n\n /**\n * 流式请求 - SSE\n */\n async *streamChat(\n aiConfig: AIRequestConfig,\n adapter: AIAdapter,\n messages: Message[],\n tools?: ToolDefinition[]\n ): AsyncGenerator<AIStreamEvent> {\n const body = adapter.buildRequestBody(aiConfig, messages, tools)\n // 添加流式标记(适配器处理)\n const streamBody = { ...body as Record<string, unknown>, stream: true }\n const headers = { ...adapter.getHeaders(aiConfig), ...aiConfig.headers }\n\n const response = await this.client.post(\n adapter.getEndpoint(aiConfig.baseURL),\n streamBody,\n {\n headers,\n timeout: aiConfig.timeout || 120000,\n responseType: 'stream',\n }\n )\n\n const stream = response.data as NodeJS.ReadableStream\n\n for await (const event of this.parseSSE(stream)) {\n const parsed = adapter.parseStreamChunk(event)\n if (parsed) {\n yield parsed\n }\n }\n }\n\n /**\n * 解析 SSE 流\n */\n private async *parseSSE(stream: NodeJS.ReadableStream): AsyncGenerator<string> {\n let buffer = ''\n\n for await (const chunk of stream) {\n buffer += chunk.toString()\n\n const lines = buffer.split('\\n')\n buffer = lines.pop() || ''\n\n for (const line of lines) {\n const trimmed = line.trim()\n if (trimmed.startsWith('data: ')) {\n const data = trimmed.slice(6)\n if (data === '[DONE]') {\n return\n }\n if (data) {\n yield data\n }\n }\n }\n }\n\n // 处理剩余内容\n if (buffer.trim().startsWith('data: ')) {\n const data = buffer.trim().slice(6)\n if (data && data !== '[DONE]') {\n yield data\n }\n }\n }\n}\n","/**\n * OpenAI 适配器\n * 支持任意自定义参数(如 enable_thinking)\n */\n\nimport type { AIAdapter, AIRequestConfig, AIResponse, AIStreamEvent, Message, ToolDefinition, ToolCall } from '../types.js'\n\nexport class OpenAIAdapter implements AIAdapter {\n name = 'openai'\n\n /**\n * 构建请求体\n * 完全开放:除必要字段外,其他参数原封不动传递\n */\n buildRequestBody(\n config: AIRequestConfig,\n messages: Message[],\n tools?: ToolDefinition[]\n ): Record<string, unknown> {\n // 提取标准参数\n const { baseURL, apiKey, model, headers, timeout, ...customParams } = config\n\n // 转换消息格式\n const openaiMessages = messages.map(msg => this.convertMessage(msg))\n\n // 转换工具格式\n const openaiTools = tools?.map(tool => ({\n type: 'function' as const,\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n }))\n\n // 构建请求体:标准参数 + 自定义参数(自定义参数可以覆盖标准参数)\n const body: Record<string, unknown> = {\n model,\n messages: openaiMessages,\n // 用户自定义参数(包括 enable_thinking 等)\n ...customParams,\n }\n\n // 如果有工具,添加工具配置\n if (openaiTools && openaiTools.length > 0) {\n body.tools = openaiTools\n }\n\n return body\n }\n\n /**\n * 获取请求头\n */\n getHeaders(config: AIRequestConfig): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n }\n }\n\n /**\n * 获取请求端点\n */\n getEndpoint(baseURL: string): string {\n const normalized = baseURL.replace(/\\/$/, '')\n return `${normalized}/chat/completions`\n }\n\n /**\n * 解析非流式响应\n */\n parseResponse(data: unknown): AIResponse {\n const response = data as {\n choices: Array<{\n message?: {\n content?: string\n tool_calls?: Array<{\n id: string\n function: {\n name: string\n arguments: string\n }\n }>\n }\n }>\n }\n\n const choice = response.choices[0]\n const message = choice?.message\n\n // 解析工具调用\n const toolCalls: ToolCall[] | undefined = message?.tool_calls?.map(tc => ({\n id: tc.id,\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n }))\n\n return {\n content: message?.content || '',\n toolCalls: toolCalls?.length ? toolCalls : undefined,\n }\n }\n\n /**\n * 解析流式数据块\n */\n parseStreamChunk(line: string): AIStreamEvent | null {\n try {\n const data = JSON.parse(line) as {\n choices: Array<{\n delta: {\n content?: string\n tool_calls?: Array<{\n index: number\n id?: string\n function?: {\n name?: string\n arguments?: string\n }\n }>\n }\n finish_reason: string | null\n }>\n }\n\n const choice = data.choices[0]\n const delta = choice?.delta\n\n // 文本内容\n if (delta?.content) {\n return { type: 'text', content: delta.content }\n }\n\n // 工具调用(简化处理,假设一次只返回一个完整 tool_call)\n if (delta?.tool_calls) {\n const tc = delta.tool_calls[0]\n if (tc.id && tc.function?.name) {\n return {\n type: 'tool_call',\n toolCall: {\n id: tc.id,\n name: tc.function.name,\n arguments: tc.function.arguments ? JSON.parse(tc.function.arguments) : {},\n },\n }\n }\n }\n\n // 完成\n if (choice?.finish_reason) {\n return { type: 'done' }\n }\n\n return null\n } catch {\n return null\n }\n }\n\n /**\n * 转换消息格式\n */\n private convertMessage(msg: Message): Record<string, unknown> {\n // 系统/用户/assistant 消息\n if (msg.role !== 'tool') {\n const result: Record<string, unknown> = {\n role: msg.role,\n content: msg.content,\n }\n\n // assistant 消息可能包含 tool_calls\n if (msg.role === 'assistant' && msg.toolCalls) {\n result.tool_calls = msg.toolCalls.map(tc => ({\n id: tc.id,\n type: 'function',\n function: {\n name: tc.name,\n arguments: JSON.stringify(tc.arguments),\n },\n }))\n }\n\n return result\n }\n\n // tool 消息转换为 function 角色\n if (msg.toolResults && msg.toolResults.length > 0) {\n const tr = msg.toolResults[0]\n return {\n role: 'tool',\n tool_call_id: tr.toolCallId,\n content: typeof tr.result === 'string' ? tr.result : JSON.stringify(tr.result),\n }\n }\n\n return {\n role: 'user',\n content: msg.content,\n }\n }\n}\n\n/** OpenAI 适配器实例 */\nexport const openaiAdapter = new OpenAIAdapter()\n","import type { MCPLinkConfig, ChatOptions, ChatResult, MCPServerConfig, MCPServerStatus, MCPTool, AIAdapter, AIStreamEvent, ToolCall, ToolResult, Message, ToolDefinition } from './types.js'\nimport { MCPManager } from './MCPManager.js'\nimport { HttpClient } from './http-client.js'\nimport { openaiAdapter } from './adapters/openai.js'\n\n/**\n * MCPLink - 极简 MCP + AI HTTP 桥接\n *\n * 职责:\n * 1. 管理 MCP 服务器连接\n * 2. 发起 AI HTTP 请求\n * 3. 发现工具调用 → 执行 MCP 工具 → 回调结果\n *\n * 不职责:\n * 1. 不管理消息历史(用户自己维护)\n * 2. 不处理 AI 响应格式(用户通过 onStream 回调处理)\n * 3. 不做复杂的 Agent 循环(用户控制迭代)\n */\nexport class MCPLink {\n private config: MCPLinkConfig\n private mcpManager: MCPManager\n private httpClient: HttpClient\n private adapter: AIAdapter\n private initialized = false\n\n constructor(config: MCPLinkConfig) {\n this.config = config\n this.mcpManager = new MCPManager()\n this.httpClient = new HttpClient()\n\n // 设置适配器\n if (typeof config.adapter === 'string') {\n this.adapter = this.getAdapterByType(config.adapter)\n } else if (config.adapter) {\n this.adapter = config.adapter\n } else {\n this.adapter = openaiAdapter\n }\n\n // 添加 MCP 服务器\n if (config.mcpServers) {\n for (const [id, serverConfig] of Object.entries(config.mcpServers)) {\n this.mcpManager.addServer(id, serverConfig)\n }\n }\n }\n\n /**\n * 初始化 - 连接所有 MCP 服务器\n */\n async initialize(): Promise<void> {\n if (this.initialized) return\n\n await this.mcpManager.startAll()\n this.initialized = true\n }\n\n /**\n * 关闭 - 断开所有 MCP 服务器连接\n */\n async close(): Promise<void> {\n await this.mcpManager.stopAll()\n this.initialized = false\n }\n\n /**\n * 对话 - 极简设计\n *\n * 流程:\n * 1. 发送消息给 AI\n * 2. AI 返回文本/工具调用\n * 3. 如果有工具调用,执行 MCP 工具\n * 4. 返回结果(包括新的消息历史,用户可选择是否继续)\n *\n * 用户需要自己:\n * - 维护 messages 历史\n * - 处理流式响应(通过 onStream)\n * - 决定是否继续迭代(如果返回了 toolCalls)\n */\n async chat(options: ChatOptions): Promise<ChatResult> {\n if (!this.initialized) {\n await this.initialize()\n }\n\n const startTime = Date.now()\n const maxIterations = this.config.maxIterations ?? 10\n let iterations = 0\n let messages = [...options.messages]\n\n // 获取 MCP 工具\n const mcpTools = this.mcpManager.getAllTools()\n const tools: ToolDefinition[] = mcpTools.map(t => ({\n name: t.name,\n description: t.description,\n parameters: t.inputSchema as ToolDefinition['parameters'],\n }))\n\n while (iterations < maxIterations) {\n iterations++\n\n // 调用 AI\n const response = options.stream !== false\n ? await this.streamChat(messages, tools, options.onStream)\n : await this.singleChat(messages, tools)\n\n // 如果没有工具调用,直接返回\n if (!response.toolCalls || response.toolCalls.length === 0) {\n // 添加 assistant 消息到历史\n messages.push({\n role: 'assistant',\n content: response.content,\n })\n\n return {\n content: response.content,\n messages,\n iterations,\n duration: Date.now() - startTime,\n }\n }\n\n // 有工具调用,执行 MCP 工具\n const assistantMessage: Message = {\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n }\n\n const toolResults: ToolResult[] = []\n\n for (const tc of response.toolCalls) {\n let result: unknown\n let isError = false\n\n try {\n result = await this.mcpManager.callTool(tc.name, tc.arguments)\n } catch (error) {\n result = error instanceof Error ? error.message : String(error)\n isError = true\n }\n\n toolResults.push({\n toolCallId: tc.id,\n toolName: tc.name,\n result,\n isError,\n })\n }\n\n // 添加 assistant 和 tool 消息到历史\n messages.push(assistantMessage)\n messages.push({\n role: 'tool',\n content: '',\n toolResults,\n })\n\n // 如果用户提供了 onToolCalls 回调,让用户决定是否继续\n // 否则自动继续(下一轮 AI 调用)\n }\n\n // 达到最大迭代次数\n return {\n content: messages[messages.length - 1]?.content || '',\n messages,\n iterations,\n duration: Date.now() - startTime,\n }\n }\n\n /**\n * 单次 AI 调用(非流式)\n */\n private async singleChat(\n messages: Message[],\n tools?: ToolDefinition[]\n ): Promise<{ content: string; toolCalls?: ToolCall[] }> {\n const response = await this.httpClient.chat(\n this.config.ai,\n this.adapter,\n messages,\n tools\n )\n\n return {\n content: response.content,\n toolCalls: response.toolCalls,\n }\n }\n\n /**\n * 流式 AI 调用\n */\n private async streamChat(\n messages: Message[],\n tools?: ToolDefinition[],\n onStream?: (event: AIStreamEvent) => boolean | void\n ): Promise<{ content: string; toolCalls?: ToolCall[] }> {\n let content = ''\n const toolCalls: ToolCall[] = []\n\n for await (const event of this.httpClient.streamChat(\n this.config.ai,\n this.adapter,\n messages,\n tools\n )) {\n // 调用用户回调\n const shouldContinue = onStream?.(event)\n if (shouldContinue === false) {\n break\n }\n\n switch (event.type) {\n case 'text':\n content += event.content\n break\n case 'tool_call':\n toolCalls.push(event.toolCall)\n break\n case 'error':\n throw event.error\n }\n }\n\n return {\n content,\n toolCalls: toolCalls.length ? toolCalls : undefined,\n }\n }\n\n /**\n * 流式对话 - 公共方法\n * 直接发起流式请求并返回结果\n */\n async chatStream(\n messages: Message[],\n onStream?: (event: AIStreamEvent) => boolean | void\n ): Promise<ChatResult> {\n if (!this.initialized) {\n await this.initialize()\n }\n\n const startTime = Date.now()\n\n // 获取 MCP 工具\n const mcpTools = this.mcpManager.getAllTools()\n const tools: ToolDefinition[] = mcpTools.map(t => ({\n name: t.name,\n description: t.description,\n parameters: t.inputSchema as ToolDefinition['parameters'],\n }))\n\n // 流式调用\n const response = await this.streamChat(messages, tools, onStream)\n\n // 如果有工具调用,执行它们并返回结果\n if (response.toolCalls && response.toolCalls.length > 0) {\n // 执行工具调用\n const toolResults: ToolResult[] = []\n\n for (const tc of response.toolCalls) {\n let result: unknown\n let isError = false\n\n try {\n result = await this.mcpManager.callTool(tc.name, tc.arguments)\n } catch (error) {\n result = error instanceof Error ? error.message : String(error)\n isError = true\n }\n\n toolResults.push({\n toolCallId: tc.id,\n toolName: tc.name,\n result,\n isError,\n })\n }\n\n // 添加 assistant 和 tool 消息到历史\n const assistantMessage: Message = {\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n }\n\n messages.push(assistantMessage)\n messages.push({\n role: 'tool',\n content: '',\n toolResults,\n })\n\n return {\n content: response.content,\n messages,\n iterations: 1,\n duration: Date.now() - startTime,\n }\n }\n\n // 没有工具调用,直接返回\n messages.push({\n role: 'assistant',\n content: response.content,\n })\n\n return {\n content: response.content,\n messages,\n iterations: 1,\n duration: Date.now() - startTime,\n }\n }\n\n /**\n * 根据类型获取适配器\n */\n private getAdapterByType(type: string): AIAdapter {\n switch (type) {\n case 'openai':\n return openaiAdapter\n default:\n throw new Error(`Unknown adapter type: ${type}`)\n }\n }\n\n // ============ MCP 服务器管理 ============\n\n addMCPServer(id: string, config: MCPServerConfig): void {\n this.mcpManager.addServer(id, config)\n }\n\n async removeMCPServer(id: string): Promise<void> {\n await this.mcpManager.removeServer(id)\n }\n\n async startMCPServer(id: string): Promise<void> {\n await this.mcpManager.startServer(id)\n }\n\n async stopMCPServer(id: string): Promise<void> {\n await this.mcpManager.stopServer(id)\n }\n\n getMCPServerStatuses(): MCPServerStatus[] {\n return this.mcpManager.getServerStatuses()\n }\n\n getTools(): MCPTool[] {\n return this.mcpManager.getAllTools()\n }\n\n async callTool(toolName: string, args: Record<string, unknown>): Promise<unknown> {\n return this.mcpManager.callTool(toolName, args)\n }\n}\n","/**\n * 标准事件流转换器\n * 将底层 AI 事件转换为完整的标准事件流\n * 用户可选择使用底层事件或标准事件\n */\n\nimport type { AIStreamEvent, ToolCall } from './types.js'\n\n/** 标准流式事件类型 */\nexport type StandardStreamEvent =\n | { type: 'text_start' }\n | { type: 'text_delta'; content: string }\n | { type: 'text_end' }\n | { type: 'thinking_start' }\n | { type: 'thinking_delta'; content: string }\n | { type: 'thinking_end' }\n | { type: 'tool_call_start'; toolCallId: string; toolName: string; toolArgs: Record<string, unknown> }\n | { type: 'tool_call_delta'; toolCallId: string; argsTextDelta: string }\n | { type: 'tool_call_end'; toolCallId: string }\n | { type: 'tool_executing'; toolCallId: string; toolName: string }\n | { type: 'tool_result'; toolCallId: string; toolName: string; toolResult: unknown; duration: number; isError?: boolean }\n | { type: 'iteration_start'; iteration: number; maxIterations: number }\n | { type: 'iteration_end'; iteration: number }\n | { type: 'complete'; totalIterations: number; totalDuration: number }\n | { type: 'error'; error: Error }\n\n/**\n * 标准事件流生成器选项\n */\nexport interface StandardStreamOptions {\n /** 最大迭代次数 */\n maxIterations?: number\n /** 工具执行函数 */\n executeTool: (name: string, args: Record<string, unknown>) => Promise<unknown>\n /** 底层事件回调(可选,用于自定义处理) */\n onRawEvent?: (event: AIStreamEvent) => boolean | void\n}\n\n/**\n * 将底层事件流转换为标准事件流\n */\nexport async function* toStandardStream(\n rawStream: AsyncGenerator<AIStreamEvent>,\n options: StandardStreamOptions\n): AsyncGenerator<StandardStreamEvent> {\n let iteration = 0\n const maxIterations = options.maxIterations ?? 10\n const startTime = Date.now()\n let hasTextStarted = false\n\n // 跟踪工具调用状态\n const pendingToolCalls = new Map<string, ToolCall & { argsBuffer: string }>()\n\n for await (const event of rawStream) {\n // 调用原始事件回调\n const shouldContinue = options.onRawEvent?.(event)\n if (shouldContinue === false) break\n\n switch (event.type) {\n case 'text':\n if (!hasTextStarted) {\n hasTextStarted = true\n yield { type: 'text_start' }\n }\n if (event.content) {\n yield { type: 'text_delta', content: event.content }\n }\n break\n\n case 'tool_call': {\n // 发送 text_end(如果有文本)\n if (hasTextStarted) {\n hasTextStarted = false\n yield { type: 'text_end' }\n }\n\n const tc = event.toolCall\n pendingToolCalls.set(tc.id, { ...tc, argsBuffer: '' })\n\n yield {\n type: 'tool_call_start',\n toolCallId: tc.id,\n toolName: tc.name,\n toolArgs: tc.arguments,\n }\n\n yield {\n type: 'tool_executing',\n toolCallId: tc.id,\n toolName: tc.name,\n }\n\n // 执行工具\n const toolStartTime = Date.now()\n let result: unknown\n let isError = false\n\n try {\n result = await options.executeTool(tc.name, tc.arguments)\n } catch (error) {\n result = error instanceof Error ? error.message : String(error)\n isError = true\n }\n\n const duration = Date.now() - toolStartTime\n\n yield {\n type: 'tool_result',\n toolCallId: tc.id,\n toolName: tc.name,\n toolResult: result,\n duration,\n isError,\n }\n\n pendingToolCalls.delete(tc.id)\n break\n }\n\n case 'done':\n // 发送 text_end(如果有文本)\n if (hasTextStarted) {\n hasTextStarted = false\n yield { type: 'text_end' }\n }\n break\n\n case 'error':\n yield { type: 'error', error: event.error }\n return\n }\n }\n\n // 确保发送 text_end\n if (hasTextStarted) {\n yield { type: 'text_end' }\n }\n\n // 发送完成事件\n yield {\n type: 'complete',\n totalIterations: iteration,\n totalDuration: Date.now() - startTime,\n }\n}\n\n/**\n * 标准响应处理器 - 非流式\n * 收集完整响应内容\n */\nexport interface StandardResponse {\n content: string\n toolCalls: Array<{\n id: string\n name: string\n arguments: Record<string, unknown>\n result?: unknown\n duration?: number\n isError?: boolean\n }>\n iterations: number\n duration: number\n}\n\n/**\n * 从标准事件流收集完整响应\n */\nexport async function collectStandardResponse(\n stream: AsyncGenerator<StandardStreamEvent>\n): Promise<StandardResponse> {\n const response: StandardResponse = {\n content: '',\n toolCalls: [],\n iterations: 0,\n duration: 0,\n }\n\n const toolCallMap = new Map<string, StandardResponse['toolCalls'][0]>()\n\n for await (const event of stream) {\n switch (event.type) {\n case 'text_delta':\n response.content += event.content\n break\n\n case 'tool_call_start': {\n const tc = {\n id: event.toolCallId,\n name: event.toolName,\n arguments: event.toolArgs,\n }\n response.toolCalls.push(tc)\n toolCallMap.set(event.toolCallId, tc)\n break\n }\n\n case 'tool_result': {\n const tc = toolCallMap.get(event.toolCallId)\n if (tc) {\n tc.result = event.toolResult\n tc.duration = event.duration\n tc.isError = event.isError\n }\n break\n }\n\n case 'complete':\n response.iterations = event.totalIterations\n response.duration = event.totalDuration\n break\n }\n }\n\n return response\n}\n"]}
1
+ {"version":3,"sources":["../src/MCPManager.ts","../src/http-client.ts","../src/adapters/openai.ts","../src/MCPLink.ts","../src/standard-stream.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js'\r\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'\r\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\r\nimport type { MCPServerConfig, MCPServerConfigStdio, MCPServerConfigStreamableHTTP, MCPTool, MCPServerStatus } from './types.js'\r\n\r\n/**\r\n * 需要自动重连的错误关键词\r\n * 当工具调用遇到这些错误时,会自动重连服务器并重试一次\r\n */\r\nconst RECONNECT_ERROR_KEYWORDS = [\r\n 'Server not initialized',\r\n 'session not found',\r\n 'Session expired',\r\n 'connection refused',\r\n 'ECONNREFUSED',\r\n 'ECONNRESET',\r\n 'EPIPE',\r\n 'socket hang up',\r\n]\r\n\r\n/**\r\n * MCP 服务器实例\r\n */\r\ninterface MCPServerInstance {\r\n id: string\r\n config: MCPServerConfig\r\n client: Client\r\n transport: StdioClientTransport | StreamableHTTPClientTransport\r\n tools: MCPTool[]\r\n status: 'stopped' | 'starting' | 'running' | 'error'\r\n error?: string\r\n}\r\n\r\n/**\r\n * MCP 管理器\r\n * 负责管理多个 MCP 服务器的连接、工具发现和调用\r\n */\r\nexport class MCPManager {\r\n private servers: Map<string, MCPServerInstance> = new Map()\r\n\r\n /**\r\n * 添加 MCP 服务器配置\r\n */\r\n addServer(id: string, config: MCPServerConfig): void {\r\n if (this.servers.has(id)) {\r\n throw new Error(`MCP server \"${id}\" already exists`)\r\n }\r\n\r\n // 创建 Client\r\n const client = new Client({ name: 'mcplink', version: '0.0.1' }, { capabilities: {} })\r\n\r\n // 创建 Transport\r\n let transport: StdioClientTransport | StreamableHTTPClientTransport\r\n\r\n if (config.type === 'streamable-http') {\r\n const httpConfig = config as MCPServerConfigStreamableHTTP\r\n transport = new StreamableHTTPClientTransport(new URL(httpConfig.url))\r\n } else {\r\n const stdioConfig = config as MCPServerConfigStdio\r\n // 合并当前进程的环境变量和配置的环境变量\r\n // 过滤掉 undefined 值\r\n const processEnv: Record<string, string> = {}\r\n for (const [key, value] of Object.entries(process.env)) {\r\n if (value !== undefined) {\r\n processEnv[key] = value\r\n }\r\n }\r\n const mergedEnv = {\r\n ...processEnv,\r\n ...stdioConfig.env,\r\n }\r\n\r\n // Windows 兼容性处理\r\n // 在 Windows 上,npx/npm 等命令实际上是 .cmd 文件,需要通过 shell 执行\r\n const isWindows = process.platform === 'win32'\r\n let command = stdioConfig.command\r\n let args = stdioConfig.args || []\r\n\r\n if (isWindows) {\r\n // 对于 npx, npm, node 等命令,在 Windows 上需要通过 cmd /c 执行\r\n const windowsCommands = ['npx', 'npm', 'node', 'pnpm', 'yarn', 'bunx']\r\n if (windowsCommands.includes(command.toLowerCase())) {\r\n args = ['/c', command, ...args]\r\n command = 'cmd'\r\n }\r\n }\r\n\r\n transport = new StdioClientTransport({\r\n command,\r\n args,\r\n env: mergedEnv,\r\n })\r\n }\r\n\r\n this.servers.set(id, {\r\n id,\r\n config,\r\n client,\r\n transport,\r\n tools: [],\r\n status: 'stopped',\r\n })\r\n }\r\n\r\n /**\r\n * 启动 MCP 服务器\r\n */\r\n async startServer(id: string): Promise<void> {\r\n const server = this.servers.get(id)\r\n if (!server) {\r\n throw new Error(`MCP server \"${id}\" not found`)\r\n }\r\n\r\n if (server.status === 'running') {\r\n return\r\n }\r\n\r\n server.status = 'starting'\r\n server.error = undefined\r\n\r\n // 打印启动信息\r\n const config = server.config\r\n if (config.type === 'stdio') {\r\n const stdioConfig = config as MCPServerConfigStdio\r\n const isWindows = process.platform === 'win32'\r\n const windowsCommands = ['npx', 'npm', 'node', 'pnpm', 'yarn', 'bunx']\r\n let displayCmd = stdioConfig.command\r\n let displayArgs = stdioConfig.args || []\r\n\r\n if (isWindows && windowsCommands.includes(stdioConfig.command.toLowerCase())) {\r\n displayCmd = 'cmd'\r\n displayArgs = ['/c', stdioConfig.command, ...displayArgs]\r\n }\r\n\r\n console.log(`\\n🔧 [MCP] 正在启动服务器 \"${id}\"...`)\r\n console.log(` 命令: ${displayCmd} ${displayArgs.join(' ')}`)\r\n if (stdioConfig.env && Object.keys(stdioConfig.env).length > 0) {\r\n console.log(` 环境变量: ${Object.keys(stdioConfig.env).join(', ')}`)\r\n }\r\n } else if (config.type === 'streamable-http') {\r\n const httpConfig = config as MCPServerConfigStreamableHTTP\r\n console.log(`\\n🔧 [MCP] 正在连接 Streamable HTTP 服务器 \"${id}\"...`)\r\n console.log(` URL: ${httpConfig.url}`)\r\n }\r\n\r\n try {\r\n // 连接到服务器\r\n await server.client.connect(server.transport)\r\n\r\n // 获取工具列表\r\n const toolsResult = await server.client.listTools()\r\n server.tools = toolsResult.tools.map((tool) => ({\r\n name: tool.name,\r\n description: tool.description || '',\r\n inputSchema: tool.inputSchema as MCPTool['inputSchema'],\r\n }))\r\n\r\n server.status = 'running'\r\n console.log(`✅ [MCP] 服务器 \"${id}\" 启动成功,发现 ${server.tools.length} 个工具`)\r\n if (server.tools.length > 0) {\r\n console.log(` 工具: ${server.tools.map((t) => t.name).join(', ')}`)\r\n }\r\n } catch (error) {\r\n server.status = 'error'\r\n\r\n // 提供更详细的错误信息\r\n let errorMessage = error instanceof Error ? error.message : String(error)\r\n\r\n if (errorMessage.includes('Connection closed')) {\r\n if (config.type === 'stdio') {\r\n const stdioConfig = config as MCPServerConfigStdio\r\n errorMessage =\r\n `MCP 服务器启动失败: 进程立即退出。\\n` +\r\n `命令: ${stdioConfig.command} ${(stdioConfig.args || []).join(' ')}\\n` +\r\n `可能原因:\\n` +\r\n `1. 命令 \"${stdioConfig.command}\" 不存在或不在 PATH 中\\n` +\r\n `2. 如果使用 Docker,请确保 Docker 正在运行\\n` +\r\n `3. 检查环境变量是否正确配置\\n` +\r\n `4. 尝试在终端手动运行命令查看具体错误`\r\n }\r\n }\r\n\r\n // 打印错误到控制台\r\n console.error(`❌ [MCP] 服务器 \"${id}\" 启动失败:`)\r\n console.error(` ${errorMessage.split('\\n').join('\\n ')}`)\r\n\r\n server.error = errorMessage\r\n throw new Error(errorMessage)\r\n }\r\n }\r\n\r\n /**\r\n * 停止 MCP 服务器\r\n */\r\n async stopServer(id: string): Promise<void> {\r\n const server = this.servers.get(id)\r\n if (!server) {\r\n throw new Error(`MCP server \"${id}\" not found`)\r\n }\r\n\r\n if (server.status === 'stopped') {\r\n return\r\n }\r\n\r\n console.log(`🔧 [MCP] 正在停止服务器 \"${id}\"...`)\r\n\r\n try {\r\n await server.client.close()\r\n console.log(`✅ [MCP] 服务器 \"${id}\" 已停止`)\r\n } catch (error) {\r\n console.error(`⚠️ [MCP] 停止服务器 \"${id}\" 时出错:`, error)\r\n } finally {\r\n server.status = 'stopped'\r\n server.tools = []\r\n }\r\n }\r\n\r\n /**\r\n * 启动所有已配置的服务器\r\n */\r\n async startAll(): Promise<void> {\r\n const startPromises = Array.from(this.servers.keys()).map((id) =>\r\n this.startServer(id).catch((error) => {\r\n console.error(`Failed to start MCP server \"${id}\":`, error)\r\n })\r\n )\r\n await Promise.all(startPromises)\r\n }\r\n\r\n /**\r\n * 停止所有服务器\r\n */\r\n async stopAll(): Promise<void> {\r\n const stopPromises = Array.from(this.servers.keys()).map((id) =>\r\n this.stopServer(id).catch((error) => {\r\n console.error(`Failed to stop MCP server \"${id}\":`, error)\r\n })\r\n )\r\n await Promise.all(stopPromises)\r\n }\r\n\r\n /**\r\n * 获取所有可用的工具\r\n */\r\n getAllTools(): MCPTool[] {\r\n const tools: MCPTool[] = []\r\n for (const server of this.servers.values()) {\r\n if (server.status === 'running') {\r\n tools.push(...server.tools)\r\n }\r\n }\r\n return tools\r\n }\r\n\r\n /**\r\n * 检查错误是否需要重连\r\n */\r\n private isReconnectNeeded(error: unknown): boolean {\r\n const errorMessage = error instanceof Error ? error.message : String(error)\r\n return RECONNECT_ERROR_KEYWORDS.some(keyword =>\r\n errorMessage.toLowerCase().includes(keyword.toLowerCase())\r\n )\r\n }\r\n\r\n /**\r\n * 重连指定服务器\r\n */\r\n private async reconnectServer(serverId: string): Promise<boolean> {\r\n const server = this.servers.get(serverId)\r\n if (!server) return false\r\n\r\n console.log(`🔄 [MCP] 正在重连服务器 \"${serverId}\"...`)\r\n\r\n try {\r\n // 先停止\r\n await this.stopServer(serverId)\r\n\r\n // 重新创建 transport(旧的可能已经损坏)\r\n const config = server.config\r\n let transport: StdioClientTransport | StreamableHTTPClientTransport\r\n\r\n if (config.type === 'streamable-http') {\r\n const httpConfig = config as MCPServerConfigStreamableHTTP\r\n transport = new StreamableHTTPClientTransport(new URL(httpConfig.url))\r\n } else {\r\n const stdioConfig = config as MCPServerConfigStdio\r\n const processEnv: Record<string, string> = {}\r\n for (const [key, value] of Object.entries(process.env)) {\r\n if (value !== undefined) {\r\n processEnv[key] = value\r\n }\r\n }\r\n const mergedEnv = {\r\n ...processEnv,\r\n ...stdioConfig.env,\r\n }\r\n\r\n const isWindows = process.platform === 'win32'\r\n let command = stdioConfig.command\r\n let args = stdioConfig.args || []\r\n\r\n if (isWindows) {\r\n const windowsCommands = ['npx', 'npm', 'node', 'pnpm', 'yarn', 'bunx']\r\n if (windowsCommands.includes(command.toLowerCase())) {\r\n args = ['/c', command, ...args]\r\n command = 'cmd'\r\n }\r\n }\r\n\r\n transport = new StdioClientTransport({\r\n command,\r\n args,\r\n env: mergedEnv,\r\n })\r\n }\r\n\r\n // 创建新的 client\r\n const client = new Client({ name: 'mcplink', version: '0.0.1' }, { capabilities: {} })\r\n\r\n // 更新服务器实例\r\n server.client = client\r\n server.transport = transport\r\n\r\n // 重新启动\r\n await this.startServer(serverId)\r\n\r\n console.log(`✅ [MCP] 服务器 \"${serverId}\" 重连成功`)\r\n return true\r\n } catch (error) {\r\n console.error(`❌ [MCP] 服务器 \"${serverId}\" 重连失败:`, error)\r\n return false\r\n }\r\n }\r\n\r\n /**\r\n * 调用工具(带自动重连机制)\r\n */\r\n async callTool(toolName: string, args: Record<string, unknown>): Promise<unknown> {\r\n // 找到提供该工具的服务器\r\n for (const server of this.servers.values()) {\r\n if (server.status !== 'running') continue\r\n\r\n const tool = server.tools.find((t) => t.name === toolName)\r\n if (tool) {\r\n // 尝试调用工具,失败时自动重连并重试一次\r\n const executeCall = async (): Promise<unknown> => {\r\n const result = await server.client.callTool({\r\n name: toolName,\r\n arguments: args,\r\n })\r\n\r\n // 处理结果\r\n if (result.content && Array.isArray(result.content)) {\r\n // 如果是文本内容,拼接返回\r\n const textContents = result.content\r\n .filter((c): c is { type: 'text'; text: string } => c.type === 'text')\r\n .map((c) => c.text)\r\n\r\n if (textContents.length > 0) {\r\n const textResult = textContents.join('\\n')\r\n // 检查是否是错误结果\r\n if (result.isError) {\r\n throw new Error(textResult || '工具执行失败')\r\n }\r\n return textResult\r\n }\r\n }\r\n\r\n // 检查是否是错误结果\r\n if (result.isError) {\r\n const errorContent = result.content\r\n throw new Error(\r\n typeof errorContent === 'string'\r\n ? errorContent\r\n : JSON.stringify(errorContent) || '工具执行失败'\r\n )\r\n }\r\n\r\n return result.content\r\n }\r\n\r\n try {\r\n return await executeCall()\r\n } catch (error) {\r\n // 检查是否需要重连\r\n if (this.isReconnectNeeded(error)) {\r\n console.log(`⚠️ [MCP] 工具调用失败,检测到连接错误,尝试重连: ${error instanceof Error ? error.message : error}`)\r\n\r\n // 尝试重连\r\n const reconnected = await this.reconnectServer(server.id)\r\n\r\n if (reconnected) {\r\n // 重连成功,重试一次\r\n console.log(`🔁 [MCP] 重连成功,正在重试工具调用: ${toolName}`)\r\n return await executeCall()\r\n }\r\n }\r\n\r\n // 重连失败或不需要重连,抛出原始错误\r\n throw error\r\n }\r\n }\r\n }\r\n\r\n throw new Error(`Tool \"${toolName}\" not found in any running MCP server`)\r\n }\r\n\r\n /**\r\n * 获取所有服务器状态\r\n */\r\n getServerStatuses(): MCPServerStatus[] {\r\n return Array.from(this.servers.values()).map((server) => ({\r\n id: server.id,\r\n name: server.id,\r\n config: server.config,\r\n status: server.status,\r\n tools: server.tools,\r\n error: server.error,\r\n }))\r\n }\r\n\r\n /**\r\n * 移除服务器\r\n */\r\n async removeServer(id: string): Promise<void> {\r\n await this.stopServer(id)\r\n this.servers.delete(id)\r\n }\r\n}\r\n","/**\r\n * HTTP 客户端 - 基于 axios\r\n * 支持 SSE 流式响应\r\n */\r\n\r\nimport axios, { AxiosInstance, AxiosRequestConfig } from 'axios'\r\nimport type { AIRequestConfig, AIResponse, AIStreamEvent, Message, ToolDefinition, AIAdapter } from './types.js'\r\n\r\nexport class HttpClient {\r\n private client: AxiosInstance\r\n\r\n constructor() {\r\n this.client = axios.create({\r\n timeout: 120000,\r\n })\r\n }\r\n\r\n /**\r\n * 非流式请求\r\n */\r\n async chat(\r\n aiConfig: AIRequestConfig,\r\n adapter: AIAdapter,\r\n messages: Message[],\r\n tools?: ToolDefinition[]\r\n ): Promise<AIResponse> {\r\n const body = adapter.buildRequestBody(aiConfig, messages, tools)\r\n const headers = { ...adapter.getHeaders(aiConfig), ...aiConfig.headers }\r\n\r\n const response = await this.client.post(\r\n adapter.getEndpoint(aiConfig.baseURL),\r\n body,\r\n {\r\n headers,\r\n timeout: aiConfig.timeout || 120000,\r\n }\r\n )\r\n\r\n return adapter.parseResponse(response.data)\r\n }\r\n\r\n /**\r\n * 流式请求 - SSE\r\n */\r\n async *streamChat(\r\n aiConfig: AIRequestConfig,\r\n adapter: AIAdapter,\r\n messages: Message[],\r\n tools?: ToolDefinition[]\r\n ): AsyncGenerator<AIStreamEvent> {\r\n const body = adapter.buildRequestBody(aiConfig, messages, tools)\r\n // 添加流式标记(适配器处理)\r\n const streamBody = { ...body as Record<string, unknown>, stream: true }\r\n const headers = { ...adapter.getHeaders(aiConfig), ...aiConfig.headers }\r\n\r\n const response = await this.client.post(\r\n adapter.getEndpoint(aiConfig.baseURL),\r\n streamBody,\r\n {\r\n headers,\r\n timeout: aiConfig.timeout || 120000,\r\n responseType: 'stream',\r\n }\r\n )\r\n\r\n const stream = response.data as NodeJS.ReadableStream\r\n\r\n for await (const event of this.parseSSE(stream)) {\r\n const parsed = adapter.parseStreamChunk(event)\r\n if (parsed) {\r\n yield parsed\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 解析 SSE 流\r\n */\r\n private async *parseSSE(stream: NodeJS.ReadableStream): AsyncGenerator<string> {\r\n let buffer = ''\r\n\r\n for await (const chunk of stream) {\r\n buffer += chunk.toString()\r\n\r\n const lines = buffer.split('\\n')\r\n buffer = lines.pop() || ''\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim()\r\n if (trimmed.startsWith('data: ')) {\r\n const data = trimmed.slice(6)\r\n if (data === '[DONE]') {\r\n return\r\n }\r\n if (data) {\r\n yield data\r\n }\r\n }\r\n }\r\n }\r\n\r\n // 处理剩余内容\r\n if (buffer.trim().startsWith('data: ')) {\r\n const data = buffer.trim().slice(6)\r\n if (data && data !== '[DONE]') {\r\n yield data\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * OpenAI 适配器\r\n * 支持任意自定义参数(如 enable_thinking)\r\n */\r\n\r\nimport type { AIAdapter, AIRequestConfig, AIResponse, AIStreamEvent, Message, ToolDefinition, ToolCall } from '../types.js'\r\n\r\nexport class OpenAIAdapter implements AIAdapter {\r\n name = 'openai'\r\n\r\n // 用于累积 tool_call 参数的状态\r\n private pendingToolCall: { id: string; name: string; arguments: string } | null = null\r\n\r\n /**\r\n * 检查 tool_call 参数是否完整(可以解析为 JSON)\r\n */\r\n private isToolCallComplete(tc: { arguments: string }): boolean {\r\n if (!tc.arguments) return false\r\n try {\r\n JSON.parse(tc.arguments)\r\n return true\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n /**\r\n * 返回并清空 pending tool_call\r\n */\r\n private flushPendingToolCall(): AIStreamEvent | null {\r\n if (!this.pendingToolCall) return null\r\n const tc = this.pendingToolCall\r\n this.pendingToolCall = null\r\n return {\r\n type: 'tool_call',\r\n toolCall: {\r\n id: tc.id,\r\n name: tc.name,\r\n arguments: tc.arguments ? JSON.parse(tc.arguments) : {},\r\n },\r\n }\r\n }\r\n\r\n /**\r\n * 构建请求体\r\n * 完全开放:除必要字段外,其他参数原封不动传递\r\n */\r\n buildRequestBody(\r\n config: AIRequestConfig,\r\n messages: Message[],\r\n tools?: ToolDefinition[]\r\n ): Record<string, unknown> {\r\n // 提取标准参数\r\n const { baseURL, apiKey, model, headers, timeout, ...customParams } = config\r\n\r\n // 转换消息格式\r\n const openaiMessages = messages.map(msg => this.convertMessage(msg))\r\n\r\n // 转换工具格式\r\n const openaiTools = tools?.map(tool => ({\r\n type: 'function' as const,\r\n function: {\r\n name: tool.name,\r\n description: tool.description,\r\n parameters: tool.parameters,\r\n },\r\n }))\r\n\r\n // 构建请求体:标准参数 + 自定义参数(自定义参数可以覆盖标准参数)\r\n const body: Record<string, unknown> = {\r\n model,\r\n messages: openaiMessages,\r\n // 用户自定义参数(包括 enable_thinking 等)\r\n ...customParams,\r\n }\r\n\r\n // 如果有工具,添加工具配置\r\n if (openaiTools && openaiTools.length > 0) {\r\n body.tools = openaiTools\r\n }\r\n\r\n return body\r\n }\r\n\r\n /**\r\n * 获取请求头\r\n */\r\n getHeaders(config: AIRequestConfig): Record<string, string> {\r\n return {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${config.apiKey}`,\r\n }\r\n }\r\n\r\n /**\r\n * 获取请求端点\r\n */\r\n getEndpoint(baseURL: string): string {\r\n const normalized = baseURL.replace(/\\/$/, '')\r\n return `${normalized}/chat/completions`\r\n }\r\n\r\n /**\r\n * 解析非流式响应\r\n */\r\n parseResponse(data: unknown): AIResponse {\r\n const response = data as {\r\n choices: Array<{\r\n message?: {\r\n content?: string\r\n tool_calls?: Array<{\r\n id: string\r\n function: {\r\n name: string\r\n arguments: string\r\n }\r\n }>\r\n }\r\n }>\r\n }\r\n\r\n const choice = response.choices[0]\r\n const message = choice?.message\r\n\r\n // 解析工具调用\r\n const toolCalls: ToolCall[] | undefined = message?.tool_calls?.map(tc => ({\r\n id: tc.id,\r\n name: tc.function.name,\r\n arguments: JSON.parse(tc.function.arguments),\r\n }))\r\n\r\n return {\r\n content: message?.content || '',\r\n toolCalls: toolCalls?.length ? toolCalls : undefined,\r\n }\r\n }\r\n\r\n /**\r\n * 解析流式数据块\r\n */\r\n parseStreamChunk(line: string): AIStreamEvent | null {\r\n try {\r\n const data = JSON.parse(line) as {\r\n choices: Array<{\r\n delta: {\r\n content?: string\r\n tool_calls?: Array<{\r\n index: number\r\n id?: string\r\n function?: {\r\n name?: string\r\n arguments?: string\r\n }\r\n }>\r\n }\r\n finish_reason: string | null\r\n }>\r\n }\r\n\r\n const choice = data.choices[0]\r\n const delta = choice?.delta\r\n\r\n // 文本内容\r\n if (delta?.content) {\r\n return { type: 'text', content: delta.content }\r\n }\r\n\r\n // 工具调用(支持参数累积,处理分片的 tool_call)\r\n if (delta?.tool_calls) {\r\n const tc = delta.tool_calls[0]\r\n // 新的 tool_call(没有 pending 或 id 不同)\r\n if (tc.id && tc.function?.name && (!this.pendingToolCall || this.pendingToolCall.id !== tc.id)) {\r\n const result = this.flushPendingToolCall()\r\n this.pendingToolCall = {\r\n id: tc.id,\r\n name: tc.function.name,\r\n arguments: tc.function.arguments || ''\r\n }\r\n if (this.isToolCallComplete(this.pendingToolCall)) {\r\n return this.flushPendingToolCall()\r\n }\r\n return result\r\n }\r\n // 累积参数(同一个 tool_call 的后续 delta)\r\n if (this.pendingToolCall && tc.function?.arguments) {\r\n this.pendingToolCall.arguments += tc.function.arguments\r\n if (this.isToolCallComplete(this.pendingToolCall)) {\r\n return this.flushPendingToolCall()\r\n }\r\n }\r\n }\r\n // finish_reason 且有 pendingToolCall,强制完成\r\n if (choice?.finish_reason && this.pendingToolCall) {\r\n return this.flushPendingToolCall()\r\n }\r\n\r\n // 完成\r\n if (choice?.finish_reason) {\r\n return { type: 'done' }\r\n }\r\n\r\n return null\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n /**\r\n * 转换消息格式\r\n */\r\n private convertMessage(msg: Message): Record<string, unknown> {\r\n // 系统/用户/assistant 消息\r\n if (msg.role !== 'tool') {\r\n const result: Record<string, unknown> = {\r\n role: msg.role,\r\n content: msg.content,\r\n }\r\n\r\n // assistant 消息可能包含 tool_calls\r\n if (msg.role === 'assistant' && msg.toolCalls) {\r\n result.tool_calls = msg.toolCalls.map(tc => ({\r\n id: tc.id,\r\n type: 'function',\r\n function: {\r\n name: tc.name,\r\n arguments: JSON.stringify(tc.arguments),\r\n },\r\n }))\r\n }\r\n\r\n return result\r\n }\r\n\r\n // tool 消息转换为 function 角色\r\n if (msg.toolResults && msg.toolResults.length > 0) {\r\n const tr = msg.toolResults[0]\r\n return {\r\n role: 'tool',\r\n tool_call_id: tr.toolCallId,\r\n content: typeof tr.result === 'string' ? tr.result : JSON.stringify(tr.result),\r\n }\r\n }\r\n\r\n return {\r\n role: 'user',\r\n content: msg.content,\r\n }\r\n }\r\n}\r\n\r\n/** OpenAI 适配器实例 */\r\nexport const openaiAdapter = new OpenAIAdapter()\r\n","import type { MCPLinkConfig, ChatOptions, ChatResult, MCPServerConfig, MCPServerStatus, MCPTool, AIAdapter, AIStreamEvent, ToolCall, ToolResult, Message, ToolDefinition } from './types.js'\nimport { MCPManager } from './MCPManager.js'\nimport { HttpClient } from './http-client.js'\nimport { openaiAdapter } from './adapters/openai.js'\n\n/**\n * MCPLink - 极简 MCP + AI HTTP 桥接\n *\n * 职责:\n * 1. 管理 MCP 服务器连接\n * 2. 发起 AI HTTP 请求\n * 3. 发现工具调用 → 执行 MCP 工具 → 回调结果\n *\n * 不职责:\n * 1. 不管理消息历史(用户自己维护)\n * 2. 不处理 AI 响应格式(用户通过 onStream 回调处理)\n * 3. 不做复杂的 Agent 循环(用户控制迭代)\n */\nexport class MCPLink {\n private config: MCPLinkConfig\n private mcpManager: MCPManager\n private httpClient: HttpClient\n private adapter: AIAdapter\n private initialized = false\n\n constructor(config: MCPLinkConfig) {\n this.config = config\n this.mcpManager = new MCPManager()\n this.httpClient = new HttpClient()\n\n // 设置适配器\n if (typeof config.adapter === 'string') {\n this.adapter = this.getAdapterByType(config.adapter)\n } else if (config.adapter) {\n this.adapter = config.adapter\n } else {\n this.adapter = openaiAdapter\n }\n\n // 添加 MCP 服务器\n if (config.mcpServers) {\n for (const [id, serverConfig] of Object.entries(config.mcpServers)) {\n this.mcpManager.addServer(id, serverConfig)\n }\n }\n }\n\n /**\n * 初始化 - 连接所有 MCP 服务器\n */\n async initialize(): Promise<void> {\n if (this.initialized) return\n\n await this.mcpManager.startAll()\n this.initialized = true\n }\n\n /**\n * 关闭 - 断开所有 MCP 服务器连接\n */\n async close(): Promise<void> {\n await this.mcpManager.stopAll()\n this.initialized = false\n }\n\n /**\n * 对话 - 极简设计\n *\n * 流程:\n * 1. 发送消息给 AI\n * 2. AI 返回文本/工具调用\n * 3. 如果有工具调用,执行 MCP 工具\n * 4. 返回结果(包括新的消息历史,用户可选择是否继续)\n *\n * 用户需要自己:\n * - 维护 messages 历史\n * - 处理流式响应(通过 onStream)\n * - 决定是否继续迭代(如果返回了 toolCalls)\n */\n async chat(options: ChatOptions): Promise<ChatResult> {\n if (!this.initialized) {\n await this.initialize()\n }\n\n const startTime = Date.now()\n const maxIterations = this.config.maxIterations ?? 10\n let iterations = 0\n let messages = [...options.messages]\n\n // 获取 MCP 工具\n const mcpTools = this.mcpManager.getAllTools()\n const tools: ToolDefinition[] = mcpTools.map(t => ({\n name: t.name,\n description: t.description,\n parameters: t.inputSchema as ToolDefinition['parameters'],\n }))\n\n while (iterations < maxIterations) {\n iterations++\n\n // 调用 AI\n const response = options.stream !== false\n ? await this.streamChat(messages, tools, options.onStream)\n : await this.singleChat(messages, tools)\n\n // 如果没有工具调用,直接返回\n if (!response.toolCalls || response.toolCalls.length === 0) {\n // 添加 assistant 消息到历史\n messages.push({\n role: 'assistant',\n content: response.content,\n })\n\n return {\n content: response.content,\n messages,\n iterations,\n duration: Date.now() - startTime,\n }\n }\n\n // 有工具调用,执行 MCP 工具\n const assistantMessage: Message = {\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n }\n\n const toolResults: ToolResult[] = []\n\n for (const tc of response.toolCalls) {\n let result: unknown\n let isError = false\n\n try {\n result = await this.mcpManager.callTool(tc.name, tc.arguments)\n } catch (error) {\n result = error instanceof Error ? error.message : String(error)\n isError = true\n }\n\n toolResults.push({\n toolCallId: tc.id,\n toolName: tc.name,\n result,\n isError,\n })\n }\n\n // 添加 assistant 和 tool 消息到历史\n messages.push(assistantMessage)\n messages.push({\n role: 'tool',\n content: '',\n toolResults,\n })\n\n // 如果用户提供了 onToolCalls 回调,让用户决定是否继续\n // 否则自动继续(下一轮 AI 调用)\n }\n\n // 达到最大迭代次数\n return {\n content: messages[messages.length - 1]?.content || '',\n messages,\n iterations,\n duration: Date.now() - startTime,\n }\n }\n\n /**\n * 单次 AI 调用(非流式)\n */\n private async singleChat(\n messages: Message[],\n tools?: ToolDefinition[]\n ): Promise<{ content: string; toolCalls?: ToolCall[] }> {\n const response = await this.httpClient.chat(\n this.config.ai,\n this.adapter,\n messages,\n tools\n )\n\n return {\n content: response.content,\n toolCalls: response.toolCalls,\n }\n }\n\n /**\n * 流式 AI 调用\n */\n private async streamChat(\n messages: Message[],\n tools?: ToolDefinition[],\n onStream?: (event: AIStreamEvent) => boolean | void\n ): Promise<{ content: string; toolCalls?: ToolCall[] }> {\n let content = ''\n const toolCalls: ToolCall[] = []\n\n for await (const event of this.httpClient.streamChat(\n this.config.ai,\n this.adapter,\n messages,\n tools\n )) {\n // 调用用户回调\n const shouldContinue = onStream?.(event)\n if (shouldContinue === false) {\n break\n }\n\n switch (event.type) {\n case 'text':\n content += event.content\n break\n case 'tool_call':\n toolCalls.push(event.toolCall)\n break\n case 'error':\n throw event.error\n }\n }\n\n return {\n content,\n toolCalls: toolCalls.length ? toolCalls : undefined,\n }\n }\n\n /**\n * 流式对话 - 公共方法\n * 直接发起流式请求并返回结果\n */\n async chatStream(\n messages: Message[],\n onStream?: (event: AIStreamEvent) => boolean | void\n ): Promise<ChatResult> {\n if (!this.initialized) {\n await this.initialize()\n }\n\n const startTime = Date.now()\n\n // 获取 MCP 工具\n const mcpTools = this.mcpManager.getAllTools()\n const tools: ToolDefinition[] = mcpTools.map(t => ({\n name: t.name,\n description: t.description,\n parameters: t.inputSchema as ToolDefinition['parameters'],\n }))\n\n // 流式调用\n const response = await this.streamChat(messages, tools, onStream)\n\n // 如果有工具调用,执行它们并返回结果\n if (response.toolCalls && response.toolCalls.length > 0) {\n // 执行工具调用\n const toolResults: ToolResult[] = []\n\n for (const tc of response.toolCalls) {\n let result: unknown\n let isError = false\n\n try {\n result = await this.mcpManager.callTool(tc.name, tc.arguments)\n } catch (error) {\n result = error instanceof Error ? error.message : String(error)\n isError = true\n }\n\n toolResults.push({\n toolCallId: tc.id,\n toolName: tc.name,\n result,\n isError,\n })\n }\n\n // 添加 assistant 和 tool 消息到历史\n const assistantMessage: Message = {\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n }\n\n messages.push(assistantMessage)\n messages.push({\n role: 'tool',\n content: '',\n toolResults,\n })\n\n return {\n content: response.content,\n messages,\n iterations: 1,\n duration: Date.now() - startTime,\n }\n }\n\n // 没有工具调用,直接返回\n messages.push({\n role: 'assistant',\n content: response.content,\n })\n\n return {\n content: response.content,\n messages,\n iterations: 1,\n duration: Date.now() - startTime,\n }\n }\n\n /**\n * 根据类型获取适配器\n */\n private getAdapterByType(type: string): AIAdapter {\n switch (type) {\n case 'openai':\n return openaiAdapter\n default:\n throw new Error(`Unknown adapter type: ${type}`)\n }\n }\n\n // ============ MCP 服务器管理 ============\n\n addMCPServer(id: string, config: MCPServerConfig): void {\n this.mcpManager.addServer(id, config)\n }\n\n async removeMCPServer(id: string): Promise<void> {\n await this.mcpManager.removeServer(id)\n }\n\n async startMCPServer(id: string): Promise<void> {\n await this.mcpManager.startServer(id)\n }\n\n async stopMCPServer(id: string): Promise<void> {\n await this.mcpManager.stopServer(id)\n }\n\n getMCPServerStatuses(): MCPServerStatus[] {\n return this.mcpManager.getServerStatuses()\n }\n\n getTools(): MCPTool[] {\n return this.mcpManager.getAllTools()\n }\n\n async callTool(toolName: string, args: Record<string, unknown>): Promise<unknown> {\n return this.mcpManager.callTool(toolName, args)\n }\n}\n","/**\n * 标准事件流转换器\n * 将底层 AI 事件转换为完整的标准事件流\n * 用户可选择使用底层事件或标准事件\n */\n\nimport type { AIStreamEvent, ToolCall } from './types.js'\n\n/** 标准流式事件类型 */\nexport type StandardStreamEvent =\n | { type: 'text_start' }\n | { type: 'text_delta'; content: string }\n | { type: 'text_end' }\n | { type: 'thinking_start' }\n | { type: 'thinking_delta'; content: string }\n | { type: 'thinking_end' }\n | { type: 'tool_call_start'; toolCallId: string; toolName: string; toolArgs: Record<string, unknown> }\n | { type: 'tool_call_delta'; toolCallId: string; argsTextDelta: string }\n | { type: 'tool_call_end'; toolCallId: string }\n | { type: 'tool_executing'; toolCallId: string; toolName: string }\n | { type: 'tool_result'; toolCallId: string; toolName: string; toolResult: unknown; duration: number; isError?: boolean }\n | { type: 'iteration_start'; iteration: number; maxIterations: number }\n | { type: 'iteration_end'; iteration: number }\n | { type: 'complete'; totalIterations: number; totalDuration: number }\n | { type: 'error'; error: Error }\n\n/**\n * 标准事件流生成器选项\n */\nexport interface StandardStreamOptions {\n /** 最大迭代次数 */\n maxIterations?: number\n /** 工具执行函数 */\n executeTool: (name: string, args: Record<string, unknown>) => Promise<unknown>\n /** 底层事件回调(可选,用于自定义处理) */\n onRawEvent?: (event: AIStreamEvent) => boolean | void\n}\n\n/**\n * 将底层事件流转换为标准事件流\n */\nexport async function* toStandardStream(\n rawStream: AsyncGenerator<AIStreamEvent>,\n options: StandardStreamOptions\n): AsyncGenerator<StandardStreamEvent> {\n let iteration = 0\n const maxIterations = options.maxIterations ?? 10\n const startTime = Date.now()\n let hasTextStarted = false\n\n // 跟踪工具调用状态\n const pendingToolCalls = new Map<string, ToolCall & { argsBuffer: string }>()\n\n for await (const event of rawStream) {\n // 调用原始事件回调\n const shouldContinue = options.onRawEvent?.(event)\n if (shouldContinue === false) break\n\n switch (event.type) {\n case 'text':\n if (!hasTextStarted) {\n hasTextStarted = true\n yield { type: 'text_start' }\n }\n if (event.content) {\n yield { type: 'text_delta', content: event.content }\n }\n break\n\n case 'tool_call': {\n // 发送 text_end(如果有文本)\n if (hasTextStarted) {\n hasTextStarted = false\n yield { type: 'text_end' }\n }\n\n const tc = event.toolCall\n pendingToolCalls.set(tc.id, { ...tc, argsBuffer: '' })\n\n yield {\n type: 'tool_call_start',\n toolCallId: tc.id,\n toolName: tc.name,\n toolArgs: tc.arguments,\n }\n\n yield {\n type: 'tool_executing',\n toolCallId: tc.id,\n toolName: tc.name,\n }\n\n // 执行工具\n const toolStartTime = Date.now()\n let result: unknown\n let isError = false\n\n try {\n result = await options.executeTool(tc.name, tc.arguments)\n } catch (error) {\n result = error instanceof Error ? error.message : String(error)\n isError = true\n }\n\n const duration = Date.now() - toolStartTime\n\n yield {\n type: 'tool_result',\n toolCallId: tc.id,\n toolName: tc.name,\n toolResult: result,\n duration,\n isError,\n }\n\n pendingToolCalls.delete(tc.id)\n break\n }\n\n case 'done':\n // 发送 text_end(如果有文本)\n if (hasTextStarted) {\n hasTextStarted = false\n yield { type: 'text_end' }\n }\n break\n\n case 'error':\n yield { type: 'error', error: event.error }\n return\n }\n }\n\n // 确保发送 text_end\n if (hasTextStarted) {\n yield { type: 'text_end' }\n }\n\n // 发送完成事件\n yield {\n type: 'complete',\n totalIterations: iteration,\n totalDuration: Date.now() - startTime,\n }\n}\n\n/**\n * 标准响应处理器 - 非流式\n * 收集完整响应内容\n */\nexport interface StandardResponse {\n content: string\n toolCalls: Array<{\n id: string\n name: string\n arguments: Record<string, unknown>\n result?: unknown\n duration?: number\n isError?: boolean\n }>\n iterations: number\n duration: number\n}\n\n/**\n * 从标准事件流收集完整响应\n */\nexport async function collectStandardResponse(\n stream: AsyncGenerator<StandardStreamEvent>\n): Promise<StandardResponse> {\n const response: StandardResponse = {\n content: '',\n toolCalls: [],\n iterations: 0,\n duration: 0,\n }\n\n const toolCallMap = new Map<string, StandardResponse['toolCalls'][0]>()\n\n for await (const event of stream) {\n switch (event.type) {\n case 'text_delta':\n response.content += event.content\n break\n\n case 'tool_call_start': {\n const tc = {\n id: event.toolCallId,\n name: event.toolName,\n arguments: event.toolArgs,\n }\n response.toolCalls.push(tc)\n toolCallMap.set(event.toolCallId, tc)\n break\n }\n\n case 'tool_result': {\n const tc = toolCallMap.get(event.toolCallId)\n if (tc) {\n tc.result = event.toolResult\n tc.duration = event.duration\n tc.isError = event.isError\n }\n break\n }\n\n case 'complete':\n response.iterations = event.totalIterations\n response.duration = event.totalDuration\n break\n }\n }\n\n return response\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n0ts123/mcplink-core",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "description": "MCPLink 核心 SDK - AI Agent 工具调用框架",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",