@xiaozhi-client/endpoint 1.9.7-beta.7 → 1.9.7-beta.9

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
@@ -490,6 +490,15 @@ declare function isValidEndpointUrl(endpoint: string): boolean;
490
490
  * @param target - 目标对象
491
491
  * @param sources - 源对象
492
492
  * @returns 合并后的对象
493
+ *
494
+ * @example
495
+ * ```typescript
496
+ * const result = deepMerge(
497
+ * { a: 1, b: { x: 1 } },
498
+ * { b: { y: 2 }, c: 3 }
499
+ * );
500
+ * // 返回: { a: 1, b: { x: 1, y: 2 }, c: 3 }
501
+ * ```
493
502
  */
494
503
  declare function deepMerge<T>(target: Partial<T>, ...sources: Array<Partial<T>>): T;
495
504
  /**
package/dist/index.js CHANGED
@@ -84,6 +84,14 @@ function isValidEndpointUrl(endpoint) {
84
84
  }
85
85
  }
86
86
  __name(isValidEndpointUrl, "isValidEndpointUrl");
87
+ function isSafeKey(key) {
88
+ const dangerousKeys = ["__proto__", "constructor", "prototype"];
89
+ if (dangerousKeys.includes(key)) {
90
+ return false;
91
+ }
92
+ return typeof key === "string" && key.length > 0;
93
+ }
94
+ __name(isSafeKey, "isSafeKey");
87
95
  function deepMerge(target, ...sources) {
88
96
  if (sources.length === 0) {
89
97
  return target;
@@ -92,14 +100,20 @@ function deepMerge(target, ...sources) {
92
100
  if (source === void 0) {
93
101
  return target;
94
102
  }
95
- for (const key in source) {
96
- if (typeof source[key] === "object" && source[key] !== null && !Array.isArray(source[key]) && typeof target[key] === "object" && target[key] !== null && !Array.isArray(target[key])) {
103
+ const keys = Object.keys(source);
104
+ for (const key of keys) {
105
+ if (!isSafeKey(key)) {
106
+ continue;
107
+ }
108
+ const sourceValue = source[key];
109
+ const targetValue = target[key];
110
+ if (typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
97
111
  target[key] = deepMerge(
98
- target[key],
99
- source[key]
112
+ targetValue,
113
+ sourceValue
100
114
  );
101
115
  } else {
102
- target[key] = source[key];
116
+ target[key] = sourceValue;
103
117
  }
104
118
  }
105
119
  return deepMerge(target, ...sources);
@@ -122,7 +136,7 @@ __name(formatErrorMessage, "formatErrorMessage");
122
136
 
123
137
  // src/internal-mcp-manager.ts
124
138
  import { MCPManager } from "@xiaozhi-client/mcp-core";
125
- import { MCPTransportType } from "@xiaozhi-client/mcp-core";
139
+ import { convertLegacyToNew } from "@xiaozhi-client/config";
126
140
  var InternalMCPManagerAdapter = class {
127
141
  constructor(config) {
128
142
  this.config = config;
@@ -134,12 +148,8 @@ var InternalMCPManagerAdapter = class {
134
148
  this.mcpManager.addServer(serviceName, mcpConfig);
135
149
  }
136
150
  this.mcpManager.on("connected", (data) => {
137
- console.info(
138
- `MCP \u670D\u52A1 ${data.serverName} \u5DF2\u8FDE\u63A5\uFF0C\u5DE5\u5177\u6570: ${data.tools.length}`
139
- );
140
151
  });
141
152
  this.mcpManager.on("error", (data) => {
142
- console.error(`MCP \u670D\u52A1 ${data.serverName} \u51FA\u9519:`, data.error);
143
153
  });
144
154
  }
145
155
  static {
@@ -214,31 +224,12 @@ var InternalMCPManagerAdapter = class {
214
224
  }
215
225
  /**
216
226
  * 将 MCPServerConfig 转换为 MCPServiceConfig
227
+ * 使用统一的配置适配器,确保路径解析逻辑一致
217
228
  */
218
229
  convertToMCPServiceConfig(serviceName, config) {
219
- if ("command" in config) {
220
- return {
221
- type: MCPTransportType.STDIO,
222
- command: config.command,
223
- args: config.args,
224
- env: config.env
225
- };
226
- }
227
- if ("type" in config && config.type === "sse") {
228
- return {
229
- type: MCPTransportType.SSE,
230
- url: config.url,
231
- headers: config.headers
232
- };
233
- }
234
- if ("url" in config) {
235
- return {
236
- type: MCPTransportType.STREAMABLE_HTTP,
237
- url: config.url,
238
- headers: config.headers
239
- };
240
- }
241
- throw new Error(`\u4E0D\u652F\u6301\u7684 MCP \u670D\u52A1\u5668\u914D\u7F6E: ${serviceName}`);
230
+ const converted = convertLegacyToNew(serviceName, config);
231
+ const { name, ...rest } = converted;
232
+ return rest;
242
233
  }
243
234
  };
244
235
 
@@ -291,9 +282,6 @@ var Endpoint = class {
291
282
  inputSchema: ensureToolJSONSchema(toolInfo.inputSchema)
292
283
  }));
293
284
  } catch (error) {
294
- console.error(
295
- `\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`
296
- );
297
285
  return [];
298
286
  }
299
287
  }
@@ -313,7 +301,6 @@ var Endpoint = class {
313
301
  */
314
302
  async attemptConnection() {
315
303
  this.connectionState = "connecting" /* CONNECTING */;
316
- console.debug(`\u6B63\u5728\u8FDE\u63A5\u5C0F\u667A\u63A5\u5165\u70B9: ${sliceEndpoint(this.endpointUrl)}`);
317
304
  return new Promise((resolve, reject) => {
318
305
  this.connectionTimeout = setTimeout(() => {
319
306
  const error = new Error("\u8FDE\u63A5\u8D85\u65F6 (10000ms)");
@@ -330,7 +317,6 @@ var Endpoint = class {
330
317
  const message = JSON.parse(data.toString());
331
318
  this.handleMessage(message);
332
319
  } catch (error) {
333
- console.error("MCP \u6D88\u606F\u89E3\u6790\u9519\u8BEF:", error);
334
320
  }
335
321
  });
336
322
  this.ws.on("close", (code, reason) => {
@@ -352,7 +338,6 @@ var Endpoint = class {
352
338
  }
353
339
  this.connectionStatus = true;
354
340
  this.connectionState = "connected" /* CONNECTED */;
355
- console.debug("MCP WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB");
356
341
  }
357
342
  /**
358
343
  * 处理连接错误
@@ -363,7 +348,6 @@ var Endpoint = class {
363
348
  clearTimeout(this.connectionTimeout);
364
349
  this.connectionTimeout = null;
365
350
  }
366
- console.error("MCP WebSocket \u9519\u8BEF:", error.message);
367
351
  this.cleanupConnection();
368
352
  }
369
353
  /**
@@ -373,7 +357,6 @@ var Endpoint = class {
373
357
  this.connectionStatus = false;
374
358
  this.serverInitialized = false;
375
359
  this.connectionState = "disconnected" /* DISCONNECTED */;
376
- console.info(`\u5C0F\u667A\u8FDE\u63A5\u5DF2\u5173\u95ED (\u4EE3\u7801: ${code}, \u539F\u56E0: ${reason})`);
377
360
  }
378
361
  /**
379
362
  * 清理连接资源
@@ -388,7 +371,6 @@ var Endpoint = class {
388
371
  this.ws.terminate();
389
372
  }
390
373
  } catch (error) {
391
- console.debug("WebSocket \u5173\u95ED\u65F6\u51FA\u73B0\u9519\u8BEF\uFF08\u5DF2\u5FFD\u7565\uFF09:", error);
392
374
  }
393
375
  this.ws = null;
394
376
  }
@@ -404,9 +386,7 @@ var Endpoint = class {
404
386
  * 处理 MCP 消息
405
387
  */
406
388
  handleMessage(message) {
407
- console.debug("\u6536\u5230 MCP \u6D88\u606F:", JSON.stringify(message, null, 2));
408
389
  if (!message.method) {
409
- console.debug("\u6536\u5230\u6CA1\u6709 method \u5B57\u6BB5\u7684\u6D88\u606F\uFF0C\u5FFD\u7565");
410
390
  return;
411
391
  }
412
392
  switch (message.method) {
@@ -424,35 +404,27 @@ var Endpoint = class {
424
404
  }
425
405
  });
426
406
  this.serverInitialized = true;
427
- console.debug("MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210");
428
407
  break;
429
408
  case "tools/list": {
430
409
  const toolsList = this.getTools();
431
410
  this.sendResponse(message.id, { tools: toolsList });
432
- console.debug(`MCP \u5DE5\u5177\u5217\u8868\u5DF2\u53D1\u9001 (${toolsList.length}\u4E2A\u5DE5\u5177)`);
433
411
  break;
434
412
  }
435
413
  case "tools/call": {
436
414
  this.handleToolCall(message).catch((error) => {
437
- console.error("\u5904\u7406\u5DE5\u5177\u8C03\u7528\u65F6\u53D1\u751F\u672A\u6355\u83B7\u9519\u8BEF:", error);
438
415
  });
439
416
  break;
440
417
  }
441
418
  case "ping":
442
419
  this.sendResponse(message.id, {});
443
- console.debug("\u56DE\u5E94 MCP ping \u6D88\u606F");
444
420
  break;
445
421
  default:
446
- console.warn(`\u672A\u77E5\u7684 MCP \u8BF7\u6C42: ${message.method}`);
447
422
  }
448
423
  }
449
424
  /**
450
425
  * 发送响应消息
451
426
  */
452
427
  sendResponse(id, result) {
453
- console.debug(
454
- `\u5C1D\u8BD5\u53D1\u9001\u54CD\u5E94: id=${id}, isConnected=${this.connectionStatus}, wsReadyState=${this.ws?.readyState}`
455
- );
456
428
  if (this.connectionStatus && this.ws?.readyState === WebSocket.OPEN) {
457
429
  const response = {
458
430
  jsonrpc: "2.0",
@@ -461,22 +433,9 @@ var Endpoint = class {
461
433
  };
462
434
  try {
463
435
  this.ws.send(JSON.stringify(response));
464
- console.debug("\u54CD\u5E94\u5DF2\u53D1\u9001", {
465
- id,
466
- responseSize: JSON.stringify(response).length
467
- });
468
436
  } catch (error) {
469
- console.error("\u53D1\u9001\u54CD\u5E94\u5931\u8D25", {
470
- id,
471
- error
472
- });
473
437
  }
474
438
  } else {
475
- console.error("\u65E0\u6CD5\u53D1\u9001\u54CD\u5E94", {
476
- id,
477
- isConnected: this.connectionStatus,
478
- wsReadyState: this.ws?.readyState
479
- });
480
439
  }
481
440
  }
482
441
  /**
@@ -503,7 +462,6 @@ var Endpoint = class {
503
462
  * 主动断开小智连接
504
463
  */
505
464
  async disconnect() {
506
- console.info("\u4E3B\u52A8\u65AD\u5F00\u5C0F\u667A\u8FDE\u63A5");
507
465
  await this.mcpAdapter.cleanup();
508
466
  this.cleanupConnection();
509
467
  }
@@ -511,7 +469,6 @@ var Endpoint = class {
511
469
  * 重连小智接入点
512
470
  */
513
471
  async reconnect() {
514
- console.info(`\u91CD\u8FDE\u5C0F\u667A\u63A5\u5165\u70B9: ${sliceEndpoint(this.endpointUrl)}`);
515
472
  this.disconnect();
516
473
  await new Promise((resolve) => setTimeout(resolve, this.reconnectDelay));
517
474
  await this.connect();
@@ -530,11 +487,6 @@ var Endpoint = class {
530
487
  const startTime = Date.now();
531
488
  try {
532
489
  const params = validateToolCallParams(request.params);
533
- console.info("\u5F00\u59CB\u5904\u7406\u5DE5\u5177\u8C03\u7528", {
534
- requestId,
535
- toolName: params.name,
536
- hasArguments: !!params.arguments
537
- });
538
490
  const result = await this.executeToolWithTimeout(
539
491
  params.name,
540
492
  params.arguments || {},
@@ -546,11 +498,6 @@ var Endpoint = class {
546
498
  ],
547
499
  isError: result.isError || false
548
500
  });
549
- console.info("\u5DE5\u5177\u8C03\u7528\u6210\u529F", {
550
- requestId,
551
- toolName: params.name,
552
- duration: `${Date.now() - startTime}ms`
553
- });
554
501
  } catch (error) {
555
502
  this.handleToolCallError(error, requestId, Date.now() - startTime);
556
503
  }
@@ -612,11 +559,6 @@ var Endpoint = class {
612
559
  };
613
560
  }
614
561
  this.sendErrorResponse(requestId, errorResponse);
615
- console.error("\u5DE5\u5177\u8C03\u7528\u5931\u8D25", {
616
- requestId,
617
- duration: `${duration}ms`,
618
- error: errorResponse
619
- });
620
562
  }
621
563
  /**
622
564
  * 发送错误响应
@@ -629,7 +571,6 @@ var Endpoint = class {
629
571
  error
630
572
  };
631
573
  this.ws.send(JSON.stringify(response));
632
- console.debug("\u5DF2\u53D1\u9001\u9519\u8BEF\u54CD\u5E94:", response);
633
574
  }
634
575
  }
635
576
  };
@@ -645,7 +586,6 @@ var EndpointManager = class extends EventEmitter {
645
586
  constructor(config) {
646
587
  super();
647
588
  this.config = config;
648
- console.debug("[EndpointManager] \u5B9E\u4F8B\u5DF2\u521B\u5EFA\uFF08\u65B0 API\uFF09");
649
589
  }
650
590
  static {
651
591
  __name(this, "EndpointManager");
@@ -660,12 +600,8 @@ var EndpointManager = class extends EventEmitter {
660
600
  addEndpoint(endpoint) {
661
601
  const url = endpoint.getUrl();
662
602
  if (this.endpoints.has(url)) {
663
- console.debug(
664
- `[EndpointManager] \u63A5\u5165\u70B9 ${sliceEndpoint(url)} \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u6DFB\u52A0`
665
- );
666
603
  return;
667
604
  }
668
- console.debug(`[EndpointManager] \u6DFB\u52A0\u63A5\u5165\u70B9: ${sliceEndpoint(url)}`);
669
605
  this.endpoints.set(url, endpoint);
670
606
  this.connectionStates.set(url, {
671
607
  endpoint: url,
@@ -682,12 +618,8 @@ var EndpointManager = class extends EventEmitter {
682
618
  removeEndpoint(endpoint) {
683
619
  const url = endpoint.getUrl();
684
620
  if (!this.endpoints.has(url)) {
685
- console.debug(
686
- `[EndpointManager] \u63A5\u5165\u70B9 ${sliceEndpoint(url)} \u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u79FB\u9664`
687
- );
688
621
  return;
689
622
  }
690
- console.debug(`[EndpointManager] \u79FB\u9664\u63A5\u5165\u70B9: ${sliceEndpoint(url)}`);
691
623
  endpoint.disconnect();
692
624
  this.endpoints.delete(url);
693
625
  this.connectionStates.delete(url);
@@ -697,12 +629,10 @@ var EndpointManager = class extends EventEmitter {
697
629
  * 连接所有 Endpoint
698
630
  */
699
631
  async connect() {
700
- console.debug(`[EndpointManager] \u5F00\u59CB\u8FDE\u63A5\u6240\u6709\u63A5\u5165\u70B9\uFF0C\u603B\u6570: ${this.endpoints.size}`);
701
632
  const promises = [];
702
633
  for (const [url, endpoint] of this.endpoints) {
703
634
  promises.push(
704
635
  this.connectSingleEndpoint(url, endpoint).catch((error) => {
705
- console.error(`[EndpointManager] \u8FDE\u63A5\u5931\u8D25: ${sliceEndpoint(url)}`, error);
706
636
  const status = this.connectionStates.get(url);
707
637
  if (status) {
708
638
  status.connected = false;
@@ -716,13 +646,11 @@ var EndpointManager = class extends EventEmitter {
716
646
  const connectedCount = Array.from(this.connectionStates.values()).filter(
717
647
  (s) => s.connected
718
648
  ).length;
719
- console.info(`[EndpointManager] \u8FDE\u63A5\u5B8C\u6210: \u6210\u529F ${connectedCount}/${this.endpoints.size}`);
720
649
  }
721
650
  /**
722
651
  * 断开所有连接
723
652
  */
724
653
  async disconnect() {
725
- console.debug("[EndpointManager] \u5F00\u59CB\u65AD\u5F00\u6240\u6709\u8FDE\u63A5");
726
654
  const promises = [];
727
655
  for (const endpoint of this.endpoints.values()) {
728
656
  promises.push(
@@ -736,7 +664,6 @@ var EndpointManager = class extends EventEmitter {
736
664
  status.connected = false;
737
665
  status.initialized = false;
738
666
  }
739
- console.debug("[EndpointManager] \u6240\u6709\u63A5\u5165\u70B9\u5DF2\u65AD\u5F00\u8FDE\u63A5");
740
667
  }
741
668
  /**
742
669
  * 获取所有 Endpoint URL
@@ -790,12 +717,10 @@ var EndpointManager = class extends EventEmitter {
790
717
  * 重连所有端点
791
718
  */
792
719
  async reconnectAll() {
793
- console.info("[EndpointManager] \u5F00\u59CB\u91CD\u8FDE\u6240\u6709\u63A5\u5165\u70B9");
794
720
  const promises = [];
795
721
  for (const [url, endpoint] of this.endpoints) {
796
722
  promises.push(
797
723
  this.reconnectSingleEndpoint(url, endpoint).catch((error) => {
798
- console.error(`[EndpointManager] \u91CD\u8FDE\u5931\u8D25: ${sliceEndpoint(url)}`, error);
799
724
  })
800
725
  );
801
726
  }
@@ -817,19 +742,15 @@ var EndpointManager = class extends EventEmitter {
817
742
  * 清除所有端点
818
743
  */
819
744
  async clearEndpoints() {
820
- console.debug("[EndpointManager] \u6E05\u9664\u6240\u6709\u63A5\u5165\u70B9");
821
745
  await this.disconnect();
822
746
  this.endpoints.clear();
823
747
  this.connectionStates.clear();
824
- console.info("[EndpointManager] \u6240\u6709\u63A5\u5165\u70B9\u5DF2\u6E05\u9664");
825
748
  }
826
749
  /**
827
750
  * 清理资源
828
751
  */
829
752
  async cleanup() {
830
- console.debug("[EndpointManager] \u5F00\u59CB\u6E05\u7406\u8D44\u6E90");
831
753
  await this.clearEndpoints();
832
- console.debug("[EndpointManager] \u8D44\u6E90\u6E05\u7406\u5B8C\u6210");
833
754
  }
834
755
  // ==================== 私有方法 ====================
835
756
  /**
@@ -840,7 +761,6 @@ var EndpointManager = class extends EventEmitter {
840
761
  if (!status) {
841
762
  throw new Error(`\u7AEF\u70B9\u72B6\u6001\u4E0D\u5B58\u5728: ${sliceEndpoint(url)}`);
842
763
  }
843
- console.debug(`[EndpointManager] \u8FDE\u63A5\u7AEF\u70B9: ${sliceEndpoint(url)}`);
844
764
  status.connected = false;
845
765
  status.initialized = false;
846
766
  await endpoint.connect();
@@ -848,7 +768,6 @@ var EndpointManager = class extends EventEmitter {
848
768
  status.initialized = true;
849
769
  status.lastConnected = /* @__PURE__ */ new Date();
850
770
  status.lastError = void 0;
851
- console.info(`[EndpointManager] \u7AEF\u70B9\u8FDE\u63A5\u6210\u529F: ${sliceEndpoint(url)}`);
852
771
  }
853
772
  /**
854
773
  * 重连单个端点
@@ -858,13 +777,11 @@ var EndpointManager = class extends EventEmitter {
858
777
  if (!status) {
859
778
  throw new Error(`\u7AEF\u70B9\u72B6\u6001\u4E0D\u5B58\u5728: ${sliceEndpoint(url)}`);
860
779
  }
861
- console.debug(`[EndpointManager] \u91CD\u8FDE\u7AEF\u70B9: ${sliceEndpoint(url)}`);
862
780
  await endpoint.reconnect();
863
781
  status.connected = true;
864
782
  status.initialized = true;
865
783
  status.lastConnected = /* @__PURE__ */ new Date();
866
784
  status.lastError = void 0;
867
- console.info(`[EndpointManager] \u7AEF\u70B9\u91CD\u8FDE\u6210\u529F: ${sliceEndpoint(url)}`);
868
785
  }
869
786
  };
870
787
  export {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/endpoint.ts","../src/types.ts","../src/utils.ts","../src/internal-mcp-manager.ts","../src/manager.ts"],"sourcesContent":["/**\n * Endpoint 类(新 API)\n * 管理单个小智接入点的 WebSocket 连接\n * 实现 MCP (Model Context Protocol) 协议通信\n *\n * 与 EndpointConnection 的区别:\n * - 构造函数直接传入 mcpServers 配置,不需要单独调用 setServiceManager()\n * - 配置更简洁直观\n */\n\nimport type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport WebSocket from \"ws\";\nimport type { ExtendedMCPMessage, MCPMessage } from \"./mcp.js\";\nimport type {\n EndpointConfig,\n EndpointConnectionStatus,\n ToolCallResult,\n} from \"./types.js\";\nimport {\n ConnectionState,\n ToolCallError as ToolCallErrorClass,\n ToolCallErrorCode as ToolCallErrorCodeEnum,\n ensureToolJSONSchema as ensureToolJSONSchemaFn,\n} from \"./types.js\";\nimport { validateToolCallParams } from \"./utils.js\";\nimport { sliceEndpoint } from \"./utils.js\";\nimport { InternalMCPManagerAdapter } from \"./internal-mcp-manager.js\";\n\n// 导出错误类型供外部使用\nexport {\n ToolCallErrorCodeEnum as ToolCallErrorCode,\n ToolCallErrorClass as ToolCallError,\n};\n\n/**\n * Endpoint 类\n * 负责管理单个小智接入点的 WebSocket 连接\n * 使用新的配置方式:直接在构造函数中传入 mcpServers 配置\n */\nexport class Endpoint {\n private endpointUrl: string;\n private ws: WebSocket | null = null;\n private connectionStatus = false;\n private serverInitialized = false;\n private mcpAdapter: InternalMCPManagerAdapter;\n\n // 连接状态管理\n private connectionState: ConnectionState = ConnectionState.DISCONNECTED;\n\n // 最后一次错误信息\n private lastError: string | null = null;\n\n // 连接超时定时器\n private connectionTimeout: NodeJS.Timeout | null = null;\n\n // 工具调用超时配置\n private toolCallTimeout = 30000;\n private reconnectDelay: number; // 重连延迟(毫秒)\n\n /**\n * 构造函数\n *\n * @param endpointUrl - 小智接入点 URL\n * @param config - Endpoint 配置(包含 mcpServers)\n */\n constructor(endpointUrl: string, config: EndpointConfig) {\n this.endpointUrl = endpointUrl;\n this.reconnectDelay = config.reconnectDelay ?? 2000;\n\n // 创建内部 MCP 适配器\n this.mcpAdapter = new InternalMCPManagerAdapter(config);\n }\n\n /**\n * 获取 Endpoint URL\n */\n getUrl(): string {\n return this.endpointUrl;\n }\n\n /**\n * 获取当前所有工具列表\n */\n getTools(): Tool[] {\n try {\n const allTools = this.mcpAdapter.getAllTools();\n\n return allTools.map((toolInfo) => ({\n name: toolInfo.name,\n description: toolInfo.description,\n inputSchema: ensureToolJSONSchemaFn(toolInfo.inputSchema),\n }));\n } catch (error) {\n console.error(\n `获取工具列表失败: ${error instanceof Error ? error.message : String(error)}`\n );\n return [];\n }\n }\n\n /**\n * 连接小智接入点\n */\n public async connect(): Promise<void> {\n // 初始化 MCP 适配器\n await this.mcpAdapter.initialize();\n\n // 如果正在连接中,等待当前连接完成\n if (this.connectionState === ConnectionState.CONNECTING) {\n throw new Error(\"连接正在进行中,请等待连接完成\");\n }\n\n // 清理之前的连接\n this.cleanupConnection();\n\n return this.attemptConnection();\n }\n\n /**\n * 尝试建立连接\n */\n private async attemptConnection(): Promise<void> {\n this.connectionState = ConnectionState.CONNECTING;\n console.debug(`正在连接小智接入点: ${sliceEndpoint(this.endpointUrl)}`);\n\n return new Promise((resolve, reject) => {\n // 设置连接超时\n this.connectionTimeout = setTimeout(() => {\n const error = new Error(\"连接超时 (10000ms)\");\n this.handleConnectionError(error);\n reject(error);\n }, 10000);\n\n this.ws = new WebSocket(this.endpointUrl);\n\n this.ws.on(\"open\", () => {\n this.handleConnectionSuccess();\n resolve();\n });\n\n this.ws.on(\"message\", (data) => {\n try {\n const message: MCPMessage = JSON.parse(data.toString());\n this.handleMessage(message);\n } catch (error) {\n console.error(\"MCP 消息解析错误:\", error);\n }\n });\n\n this.ws.on(\"close\", (code, reason) => {\n this.handleConnectionClose(code, reason.toString());\n });\n\n this.ws.on(\"error\", (error) => {\n this.handleConnectionError(error);\n reject(error);\n });\n });\n }\n\n /**\n * 处理连接成功\n */\n private handleConnectionSuccess(): void {\n // 清理连接超时定时器\n if (this.connectionTimeout) {\n clearTimeout(this.connectionTimeout);\n this.connectionTimeout = null;\n }\n\n this.connectionStatus = true;\n this.connectionState = ConnectionState.CONNECTED;\n\n console.debug(\"MCP WebSocket 连接已建立\");\n }\n\n /**\n * 处理连接错误\n */\n private handleConnectionError(error: Error): void {\n // 记录最后一次错误信息\n this.lastError = error.message;\n\n // 清理连接超时定时器\n if (this.connectionTimeout) {\n clearTimeout(this.connectionTimeout);\n this.connectionTimeout = null;\n }\n\n console.error(\"MCP WebSocket 错误:\", error.message);\n\n // 清理当前连接\n this.cleanupConnection();\n }\n\n /**\n * 处理连接关闭\n */\n private handleConnectionClose(code: number, reason: string): void {\n this.connectionStatus = false;\n this.serverInitialized = false;\n this.connectionState = ConnectionState.DISCONNECTED;\n console.info(`小智连接已关闭 (代码: ${code}, 原因: ${reason})`);\n }\n\n /**\n * 清理连接资源\n */\n private cleanupConnection(): void {\n // 清理 WebSocket\n if (this.ws) {\n this.ws.removeAllListeners();\n\n try {\n if (this.ws.readyState === WebSocket.OPEN) {\n this.ws.close(1000, \"Cleaning up connection\");\n } else if (this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.terminate();\n }\n } catch (error) {\n console.debug(\"WebSocket 关闭时出现错误(已忽略):\", error);\n }\n\n this.ws = null;\n }\n\n // 清理连接超时定时器\n if (this.connectionTimeout) {\n clearTimeout(this.connectionTimeout);\n this.connectionTimeout = null;\n }\n\n // 重置连接状态\n this.connectionStatus = false;\n this.serverInitialized = false;\n\n // 重置连接状态为已断开\n this.connectionState = ConnectionState.DISCONNECTED;\n }\n\n /**\n * 处理 MCP 消息\n */\n private handleMessage(message: MCPMessage): void {\n console.debug(\"收到 MCP 消息:\", JSON.stringify(message, null, 2));\n\n if (!message.method) {\n console.debug(\"收到没有 method 字段的消息,忽略\");\n return;\n }\n\n switch (message.method) {\n case \"initialize\":\n case \"notifications/initialized\":\n this.sendResponse(message.id, {\n protocolVersion: \"2024-11-05\",\n capabilities: {\n tools: { listChanged: true },\n logging: {},\n },\n serverInfo: {\n name: \"xiaozhi-mcp-server\",\n version: \"1.0.0\",\n },\n });\n this.serverInitialized = true;\n console.debug(\"MCP 服务器初始化完成\");\n break;\n\n case \"tools/list\": {\n const toolsList = this.getTools();\n this.sendResponse(message.id, { tools: toolsList });\n console.debug(`MCP 工具列表已发送 (${toolsList.length}个工具)`);\n break;\n }\n\n case \"tools/call\": {\n this.handleToolCall(message).catch((error) => {\n console.error(\"处理工具调用时发生未捕获错误:\", error);\n });\n break;\n }\n\n case \"ping\":\n this.sendResponse(message.id, {});\n console.debug(\"回应 MCP ping 消息\");\n break;\n\n default:\n console.warn(`未知的 MCP 请求: ${message.method}`);\n }\n }\n\n /**\n * 发送响应消息\n */\n private sendResponse(id: number | string, result: unknown): void {\n console.debug(\n `尝试发送响应: id=${id}, isConnected=${this.connectionStatus}, wsReadyState=${this.ws?.readyState}`\n );\n\n if (this.connectionStatus && this.ws?.readyState === WebSocket.OPEN) {\n const response: ExtendedMCPMessage = {\n jsonrpc: \"2.0\",\n id,\n result,\n };\n\n try {\n this.ws.send(JSON.stringify(response));\n console.debug(\"响应已发送\", {\n id,\n responseSize: JSON.stringify(response).length,\n });\n } catch (error) {\n console.error(\"发送响应失败\", {\n id,\n error,\n });\n }\n } else {\n console.error(\"无法发送响应\", {\n id,\n isConnected: this.connectionStatus,\n wsReadyState: this.ws?.readyState,\n });\n }\n }\n\n /**\n * 获取服务器状态\n */\n public getStatus(): EndpointConnectionStatus {\n const availableTools = this.mcpAdapter.getAllTools().length;\n\n return {\n connected: this.connectionStatus,\n initialized: this.serverInitialized,\n url: this.endpointUrl,\n availableTools,\n connectionState: this.connectionState,\n lastError: this.lastError,\n };\n }\n\n /**\n * 检查连接状态\n */\n public isConnected(): boolean {\n return this.connectionStatus;\n }\n\n /**\n * 主动断开小智连接\n */\n public async disconnect(): Promise<void> {\n console.info(\"主动断开小智连接\");\n\n // 清理 MCP 适配器\n await this.mcpAdapter.cleanup();\n\n // 清理 WebSocket 连接\n this.cleanupConnection();\n }\n\n /**\n * 重连小智接入点\n */\n public async reconnect(): Promise<void> {\n console.info(`重连小智接入点: ${sliceEndpoint(this.endpointUrl)}`);\n\n // 先断开连接\n this.disconnect();\n\n // 等待可配置的时间确保连接完全断开\n await new Promise((resolve) => setTimeout(resolve, this.reconnectDelay));\n\n // 重新连接\n await this.connect();\n }\n\n /**\n * 处理工具调用请求\n */\n private async handleToolCall(request: MCPMessage): Promise<void> {\n if (request.id === undefined || request.id === null) {\n throw new ToolCallErrorClass(\n ToolCallErrorCodeEnum.INVALID_PARAMS,\n \"请求 ID 不能为空\"\n );\n }\n\n const requestId = request.id;\n const startTime = Date.now();\n\n try {\n const params = validateToolCallParams(request.params);\n\n console.info(\"开始处理工具调用\", {\n requestId,\n toolName: params.name,\n hasArguments: !!params.arguments,\n });\n\n const result = await this.executeToolWithTimeout(\n params.name,\n params.arguments || {},\n this.toolCallTimeout\n );\n\n this.sendResponse(requestId, {\n content: result.content || [\n { type: \"text\", text: JSON.stringify(result) },\n ],\n isError: result.isError || false,\n });\n\n console.info(\"工具调用成功\", {\n requestId,\n toolName: params.name,\n duration: `${Date.now() - startTime}ms`,\n });\n } catch (error) {\n this.handleToolCallError(error, requestId, Date.now() - startTime);\n }\n }\n\n /**\n * 带超时控制的工具执行\n */\n private async executeToolWithTimeout(\n toolName: string,\n arguments_: Record<string, unknown>,\n timeoutMs = 30000\n ): Promise<ToolCallResult> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(\n new ToolCallErrorClass(\n ToolCallErrorCodeEnum.TIMEOUT,\n `工具调用超时 (${timeoutMs}ms): ${toolName}`\n )\n );\n }, timeoutMs);\n\n this.mcpAdapter\n .callTool(toolName, arguments_)\n .then((result: ToolCallResult) => {\n clearTimeout(timeoutId);\n resolve(result);\n })\n .catch((error: unknown) => {\n clearTimeout(timeoutId);\n\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n\n if (errorMessage.includes(\"未找到工具\")) {\n reject(\n new ToolCallErrorClass(\n ToolCallErrorCodeEnum.TOOL_NOT_FOUND,\n `工具不存在: ${toolName}`\n )\n );\n } else {\n reject(\n new ToolCallErrorClass(\n ToolCallErrorCodeEnum.TOOL_EXECUTION_ERROR,\n `工具执行失败: ${errorMessage}`\n )\n );\n }\n });\n });\n }\n\n /**\n * 处理工具调用错误\n */\n private handleToolCallError(\n error: unknown,\n requestId: string | number | undefined,\n duration: number\n ): void {\n let errorResponse: {\n code: number;\n message: string;\n data?: unknown;\n };\n\n if (error instanceof ToolCallErrorClass) {\n errorResponse = {\n code: error.code,\n message: error.message,\n data: error.data,\n };\n } else {\n const errorMessage = error instanceof Error ? error.message : \"未知错误\";\n errorResponse = {\n code: ToolCallErrorCodeEnum.TOOL_EXECUTION_ERROR,\n message: errorMessage,\n data: { originalError: String(error) || \"null\" },\n };\n }\n\n this.sendErrorResponse(requestId, errorResponse);\n\n console.error(\"工具调用失败\", {\n requestId,\n duration: `${duration}ms`,\n error: errorResponse,\n });\n }\n\n /**\n * 发送错误响应\n */\n private sendErrorResponse(\n id: string | number | undefined,\n error: { code: number; message: string; data?: unknown }\n ): void {\n if (this.connectionStatus && this.ws?.readyState === WebSocket.OPEN) {\n const response = {\n jsonrpc: \"2.0\",\n id,\n error,\n };\n this.ws.send(JSON.stringify(response));\n console.debug(\"已发送错误响应:\", response);\n }\n }\n}\n","// =========================\n// 1. 工具调用相关类型\n// =========================\n\n/**\n * 工具调用结果接口\n */\nexport interface ToolCallResult {\n content: Array<{\n type: string;\n text: string;\n }>;\n isError?: boolean;\n}\n\n/**\n * 工具调用参数接口\n */\nexport interface ToolCallParams {\n name: string;\n arguments?: Record<string, unknown>;\n}\n\n/**\n * 验证后的工具调用参数\n */\nexport interface ValidatedToolCallParams {\n name: string;\n arguments?: Record<string, unknown>;\n}\n\n/**\n * 工具调用错误码枚举\n */\nexport enum ToolCallErrorCode {\n /** 无效参数 */\n INVALID_PARAMS = -32602,\n /** 工具不存在 */\n TOOL_NOT_FOUND = -32601,\n /** 服务不可用 */\n SERVICE_UNAVAILABLE = -32001,\n /** 调用超时 */\n TIMEOUT = -32002,\n /** 工具执行错误 */\n TOOL_EXECUTION_ERROR = -32000,\n}\n\n/**\n * 工具调用错误类\n */\nexport class ToolCallError extends Error {\n constructor(\n public code: ToolCallErrorCode,\n message: string,\n public data?: unknown\n ) {\n super(message);\n this.name = \"ToolCallError\";\n }\n}\n\n// =========================\n// 2. JSON Schema 类型\n// =========================\n\n/**\n * JSON Schema 类型定义\n * 兼容 MCP SDK 的 JSON Schema 格式\n */\nexport type JSONSchema =\n | (Record<string, unknown> & {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n })\n | Record<string, unknown>;\n\n/**\n * 确保对象符合 MCP Tool JSON Schema 格式\n * 返回类型兼容 MCP SDK 的 Tool 类型\n */\nexport function ensureToolJSONSchema(schema: JSONSchema): {\n type: \"object\";\n properties?: Record<string, object>;\n required?: string[];\n additionalProperties?: boolean;\n} {\n if (\n typeof schema === \"object\" &&\n schema !== null &&\n \"type\" in schema &&\n schema.type === \"object\"\n ) {\n return schema as {\n type: \"object\";\n properties?: Record<string, object>;\n required?: string[];\n additionalProperties?: boolean;\n };\n }\n\n // 如果不符合标准格式,返回默认的空对象 schema\n return {\n type: \"object\",\n properties: {},\n required: [],\n additionalProperties: true,\n };\n}\n\n// =========================\n// 3. 工具信息类型\n// =========================\n\n/**\n * 增强的工具信息接口\n * 包含工具的启用状态和使用统计信息\n */\nexport interface EnhancedToolInfo {\n /** 工具唯一标识符,格式为 \"{serviceName}__{originalName}\" */\n name: string;\n\n /** 工具描述信息 */\n description: string;\n\n /** 工具输入参数的 JSON Schema 定义 */\n inputSchema: JSONSchema;\n\n /** 工具所属的 MCP 服务名称 */\n serviceName: string;\n\n /** 工具在 MCP 服务中的原始名称 */\n originalName: string;\n\n /** 工具是否启用 */\n enabled: boolean;\n\n /** 工具使用次数统计 */\n usageCount: number;\n\n /** 工具最后使用时间 (ISO 8601 格式字符串) */\n lastUsedTime: string;\n}\n\n/**\n * MCP 服务管理器接口\n * 用于工具调用,避免循环依赖\n */\nexport interface IMCPServiceManager {\n /** 获取所有工具列表 */\n getAllTools(): EnhancedToolInfo[];\n\n /** 调用工具 */\n callTool(\n toolName: string,\n arguments_: Record<string, unknown>\n ): Promise<ToolCallResult>;\n}\n\n// =========================\n// 4. 连接状态类型\n// =========================\n\n/**\n * 连接状态枚举\n */\nexport enum ConnectionState {\n DISCONNECTED = \"disconnected\",\n CONNECTING = \"connecting\",\n CONNECTED = \"connected\",\n FAILED = \"failed\",\n}\n\n/**\n * 连接选项接口\n */\nexport interface ConnectionOptions {\n /** 连接超时时间(毫秒),默认 10000 */\n connectionTimeout?: number;\n /** 重连延迟时间(毫秒),默认 2000 */\n reconnectDelay?: number;\n}\n\n// =========================\n// 5. EndpointConnection 状态类型\n// =========================\n\n/**\n * EndpointConnection 状态接口\n */\nexport interface EndpointConnectionStatus {\n /** 是否已连接 */\n connected: boolean;\n /** 是否已初始化 */\n initialized: boolean;\n /** 接入点 URL */\n url: string;\n /** 可用工具数量 */\n availableTools: number;\n /** 连接状态 */\n connectionState: ConnectionState;\n /** 最后一次错误信息 */\n lastError: string | null;\n}\n\n// =========================\n// 6. EndpointManager 状态类型\n// =========================\n\n/**\n * 简单连接状态接口\n */\nexport interface SimpleConnectionStatus {\n /** 接入点地址 */\n endpoint: string;\n /** 是否已连接 */\n connected: boolean;\n /** 是否已初始化 */\n initialized: boolean;\n /** 最后连接时间 */\n lastConnected?: Date;\n /** 最后错误信息 */\n lastError?: string;\n}\n\n/**\n * 完整连接状态接口(扩展 SimpleConnectionStatus)\n */\nexport interface ConnectionStatus extends SimpleConnectionStatus {\n // 扩展字段可以在这里添加\n}\n\n/**\n * 配置变更事件类型\n */\nexport interface ConfigChangeEvent {\n type:\n | \"endpoints_added\"\n | \"endpoints_removed\"\n | \"endpoints_updated\"\n | \"options_updated\";\n data: {\n added?: string[];\n removed?: string[];\n updated?: string[];\n oldOptions?: Partial<ConnectionOptions>;\n newOptions?: Partial<ConnectionOptions>;\n };\n timestamp: Date;\n}\n\n/**\n * 重连结果接口\n */\nexport interface ReconnectResult {\n successCount: number;\n failureCount: number;\n results: Array<{\n endpoint: string;\n success: boolean;\n error?: string;\n }>;\n}\n\n// =========================\n// 7. 新 API 配置类型\n// =========================\n\n/**\n * MCP 服务器配置类型\n * 支持三种配置方式:\n * 1. 本地命令 (stdio): { command: string; args: string[]; env?: Record<string, string> }\n * 2. SSE: { type: \"sse\"; url: string; headers?: Record<string, string> }\n * 3. Streamable HTTP: { type?: \"streamable-http\"; url: string; headers?: Record<string, string> }\n */\nexport type MCPServerConfig =\n | LocalMCPServerConfig\n | SSEMCPServerConfig\n | StreamableHTTPMCPServerConfig;\n\n/**\n * 本地 MCP 服务器配置\n */\nexport interface LocalMCPServerConfig {\n command: string;\n args: string[];\n env?: Record<string, string>;\n}\n\n/**\n * SSE MCP 服务器配置\n */\nexport interface SSEMCPServerConfig {\n type: \"sse\";\n url: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Streamable HTTP MCP 服务器配置\n */\nexport interface StreamableHTTPMCPServerConfig {\n type?: \"streamable-http\"; // 可选,默认就是 streamable-http\n url: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Endpoint 配置接口\n * 用于新 API:直接在构造函数中传入 MCP 服务器配置\n */\nexport interface EndpointConfig {\n /** MCP 服务器配置(声明式) */\n mcpServers: Record<string, MCPServerConfig>;\n /** 可选:重连延迟(毫秒),默认 2000 */\n reconnectDelay?: number;\n /** 可选:ModelScope API Key(全局) */\n modelscopeApiKey?: string;\n}\n\n/**\n * EndpointManager 配置接口(新 API 简化版)\n */\nexport interface EndpointManagerConfig {\n /** 可选:默认重连延迟(毫秒) */\n defaultReconnectDelay?: number;\n}\n","/**\n * 工具函数模块\n *\n * 内联的必要工具函数,确保包的独立性\n */\n\nimport type { ValidatedToolCallParams } from \"./types.js\";\n\n/**\n * 截断端点 URL 用于日志显示\n *\n * @param endpoint - 完整的端点 URL\n * @returns 截断后的 URL\n *\n * @example\n * ```typescript\n * sliceEndpoint(\"ws://very-long-endpoint-url-here.example.com/endpoint\")\n * // 返回: \"ws://very-long-endpoint-u...e.com/endpoint\"\n * ```\n */\nexport function sliceEndpoint(endpoint: string): string {\n return `${endpoint.slice(0, 30)}...${endpoint.slice(-10)}`;\n}\n\n/**\n * 验证工具调用参数\n *\n * @param params - 待验证的参数\n * @returns 验证后的参数\n * @throws {Error} 如果参数无效\n *\n * @example\n * ```typescript\n * const params = validateToolCallParams({\n * name: \"test_tool\",\n * arguments: { foo: \"bar\" }\n * });\n * ```\n */\nexport function validateToolCallParams(\n params: unknown\n): ValidatedToolCallParams {\n // 基础类型检查\n if (!params || typeof params !== \"object\") {\n throw new Error(\"工具调用参数必须是对象\");\n }\n\n const p = params as Record<string, unknown>;\n\n // 验证工具名称\n if (!p.name || typeof p.name !== \"string\") {\n throw new Error(\"工具名称必须是字符串\");\n }\n\n // 构建验证后的参数\n const validated: ValidatedToolCallParams = {\n name: p.name,\n };\n\n // 验证参数(可选)\n if (p.arguments !== undefined) {\n if (typeof p.arguments !== \"object\" || p.arguments === null) {\n throw new Error(\"工具参数必须是对象\");\n }\n validated.arguments = p.arguments as Record<string, unknown>;\n }\n\n return validated;\n}\n\n/**\n * 验证端点 URL 格式\n *\n * @param endpoint - 待验证的端点 URL\n * @returns 是否为有效的 WebSocket URL\n */\nexport function isValidEndpointUrl(endpoint: string): boolean {\n if (!endpoint || typeof endpoint !== \"string\") {\n return false;\n }\n\n if (!endpoint.startsWith(\"ws://\") && !endpoint.startsWith(\"wss://\")) {\n return false;\n }\n\n try {\n new URL(endpoint);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * 深度合并对象\n *\n * @param target - 目标对象\n * @param sources - 源对象\n * @returns 合并后的对象\n */\nexport function deepMerge<T>(\n target: Partial<T>,\n ...sources: Array<Partial<T>>\n): T {\n if (sources.length === 0) {\n return target as T;\n }\n\n const source = sources.shift();\n\n if (source === undefined) {\n return target as T;\n }\n\n for (const key in source) {\n if (\n typeof source[key] === \"object\" &&\n source[key] !== null &&\n !Array.isArray(source[key]) &&\n typeof target[key] === \"object\" &&\n target[key] !== null &&\n !Array.isArray(target[key])\n ) {\n (target as Record<string, unknown>)[key] = deepMerge(\n target[key] as Record<string, unknown>,\n source[key] as Record<string, unknown>\n );\n } else {\n (target as Record<string, unknown>)[key] = source[key];\n }\n }\n\n return deepMerge(target, ...sources);\n}\n\n/**\n * 延迟执行\n *\n * @param ms - 延迟时间(毫秒)\n * @returns Promise\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * 格式化错误消息\n *\n * @param error - 错误对象\n * @returns 格式化后的错误消息\n */\nexport function formatErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n return String(error);\n}\n","/**\n * 内部 MCP 服务管理器适配器\n * 将 mcpServers 配置转换为 IMCPServiceManager 接口\n * 使用 @xiaozhi-client/mcp-core 的 MCPManager 实现真实的 MCP 功能\n */\n\nimport { MCPManager } from \"@xiaozhi-client/mcp-core\";\nimport type { MCPServiceConfig } from \"@xiaozhi-client/mcp-core\";\nimport { MCPTransportType } from \"@xiaozhi-client/mcp-core\";\nimport type { EnhancedToolInfo, ToolCallResult } from \"./types.js\";\nimport type { IMCPServiceManager } from \"./types.js\";\nimport type { EndpointConfig, MCPServerConfig } from \"./types.js\";\n\n/**\n * 内部 MCP 服务管理器适配器\n * 实现 IMCPServiceManager 接口,使用真正的 MCPManager\n */\nexport class InternalMCPManagerAdapter implements IMCPServiceManager {\n private mcpManager: MCPManager;\n private tools: Map<string, EnhancedToolInfo> = new Map();\n private isInitialized = false;\n\n constructor(private config: EndpointConfig) {\n this.mcpManager = new MCPManager();\n\n // 转换配置并添加到 MCPManager\n for (const [serviceName, serverConfig] of Object.entries(\n config.mcpServers\n )) {\n const mcpConfig = this.convertToMCPServiceConfig(serviceName, serverConfig);\n this.mcpManager.addServer(serviceName, mcpConfig);\n }\n\n // 设置事件监听\n this.mcpManager.on(\"connected\", (data) => {\n console.info(\n `MCP 服务 ${data.serverName} 已连接,工具数: ${data.tools.length}`\n );\n });\n\n this.mcpManager.on(\"error\", (data) => {\n console.error(`MCP 服务 ${data.serverName} 出错:`, data.error);\n });\n }\n\n /**\n * 初始化并启动所有 MCP 服务\n */\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n return;\n }\n\n // 连接所有 MCP 服务\n await this.mcpManager.connect();\n\n // 刷新工具列表\n await this.refreshTools();\n\n this.isInitialized = true;\n }\n\n /**\n * 获取所有工具列表\n */\n getAllTools(): EnhancedToolInfo[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * 调用工具(真实实现)\n */\n async callTool(\n toolName: string,\n arguments_: Record<string, unknown>\n ): Promise<ToolCallResult> {\n // 解析工具名称:serviceName__toolName\n const [serviceName, actualToolName] = this.parseToolName(toolName);\n\n // 调用真实的 MCP 工具\n return this.mcpManager.callTool(serviceName, actualToolName, arguments_);\n }\n\n /**\n * 清理资源\n */\n async cleanup(): Promise<void> {\n await this.mcpManager.disconnect();\n this.tools.clear();\n this.isInitialized = false;\n }\n\n /**\n * 刷新工具列表\n */\n private async refreshTools(): Promise<void> {\n this.tools.clear();\n\n const mcpTools = this.mcpManager.listTools();\n\n for (const mcpTool of mcpTools) {\n const enhancedTool: EnhancedToolInfo = {\n name: `${mcpTool.serverName}__${mcpTool.name}`,\n description: mcpTool.description,\n inputSchema: mcpTool.inputSchema as any,\n serviceName: mcpTool.serverName,\n originalName: mcpTool.name,\n enabled: true,\n usageCount: 0,\n lastUsedTime: new Date().toISOString(),\n };\n this.tools.set(enhancedTool.name, enhancedTool);\n }\n }\n\n /**\n * 解析工具名称\n */\n private parseToolName(toolName: string): [string, string] {\n const parts = toolName.split(\"__\");\n if (parts.length < 2) {\n throw new Error(`无效的工具名称格式: ${toolName}`);\n }\n const serviceName = parts[0];\n const actualToolName = parts.slice(1).join(\"__\"); // 支持工具名中包含 __\n return [serviceName, actualToolName];\n }\n\n /**\n * 将 MCPServerConfig 转换为 MCPServiceConfig\n */\n private convertToMCPServiceConfig(\n serviceName: string,\n config: MCPServerConfig\n ): Omit<MCPServiceConfig, \"name\"> {\n // 本地命令配置\n if (\"command\" in config) {\n return {\n type: MCPTransportType.STDIO,\n command: config.command,\n args: config.args,\n env: config.env,\n };\n }\n\n // SSE 配置\n if (\"type\" in config && config.type === \"sse\") {\n return {\n type: MCPTransportType.SSE,\n url: config.url,\n headers: config.headers,\n };\n }\n\n // Streamable HTTP 配置(默认)\n if (\"url\" in config) {\n return {\n type: MCPTransportType.STREAMABLE_HTTP,\n url: config.url,\n headers: config.headers,\n };\n }\n\n throw new Error(`不支持的 MCP 服务器配置: ${serviceName}`);\n }\n}\n","/**\n * EndpointManager(新 API)\n * 管理多个小智接入点的连接,每个小智接入点独立运行\n *\n * 与旧 EndpointManager 的区别:\n * - 使用 addEndpoint(endpoint) 添加 Endpoint 实例\n * - 不需要 initialize() 和 setServiceManager()\n * - 配置更简洁直观\n */\n\nimport { EventEmitter } from \"node:events\";\nimport type { Endpoint } from \"./endpoint.js\";\nimport type { EndpointManagerConfig, SimpleConnectionStatus } from \"./types.js\";\nimport { sliceEndpoint } from \"./utils.js\";\n\n/**\n * 小智接入点管理器(新 API)\n * 负责管理多个小智接入点的连接\n */\nexport class EndpointManager extends EventEmitter {\n private endpoints: Map<string, Endpoint> = new Map();\n private connectionStates: Map<string, SimpleConnectionStatus> = new Map();\n\n /**\n * 构造函数\n *\n * @param config - 可选的配置\n */\n constructor(private config?: EndpointManagerConfig) {\n super();\n console.debug(\"[EndpointManager] 实例已创建(新 API)\");\n }\n\n /**\n * 添加 Endpoint 实例\n *\n * @param endpoint - Endpoint 实例\n */\n addEndpoint(endpoint: Endpoint): void {\n const url = endpoint.getUrl();\n\n if (this.endpoints.has(url)) {\n console.debug(\n `[EndpointManager] 接入点 ${sliceEndpoint(url)} 已存在,跳过添加`\n );\n return;\n }\n\n console.debug(`[EndpointManager] 添加接入点: ${sliceEndpoint(url)}`);\n\n this.endpoints.set(url, endpoint);\n this.connectionStates.set(url, {\n endpoint: url,\n connected: false,\n initialized: false,\n });\n\n // 发射事件\n this.emit(\"endpointAdded\", { endpoint: url });\n }\n\n /**\n * 移除 Endpoint 实例\n *\n * @param endpoint - Endpoint 实例\n */\n removeEndpoint(endpoint: Endpoint): void {\n const url = endpoint.getUrl();\n\n if (!this.endpoints.has(url)) {\n console.debug(\n `[EndpointManager] 接入点 ${sliceEndpoint(url)} 不存在,跳过移除`\n );\n return;\n }\n\n console.debug(`[EndpointManager] 移除接入点: ${sliceEndpoint(url)}`);\n\n // 断开连接\n endpoint.disconnect();\n\n // 清理状态\n this.endpoints.delete(url);\n this.connectionStates.delete(url);\n\n // 发射事件\n this.emit(\"endpointRemoved\", { endpoint: url });\n }\n\n /**\n * 连接所有 Endpoint\n */\n async connect(): Promise<void> {\n console.debug(`[EndpointManager] 开始连接所有接入点,总数: ${this.endpoints.size}`);\n\n const promises: Promise<void>[] = [];\n\n for (const [url, endpoint] of this.endpoints) {\n promises.push(\n this.connectSingleEndpoint(url, endpoint).catch((error) => {\n console.error(`[EndpointManager] 连接失败: ${sliceEndpoint(url)}`, error);\n // 更新失败状态\n const status = this.connectionStates.get(url);\n if (status) {\n status.connected = false;\n status.initialized = false;\n status.lastError = error instanceof Error ? error.message : String(error);\n }\n })\n );\n }\n\n await Promise.allSettled(promises);\n\n // 统计连接结果\n const connectedCount = Array.from(this.connectionStates.values()).filter(\n (s) => s.connected\n ).length;\n\n console.info(`[EndpointManager] 连接完成: 成功 ${connectedCount}/${this.endpoints.size}`);\n }\n\n /**\n * 断开所有连接\n */\n async disconnect(): Promise<void> {\n console.debug(\"[EndpointManager] 开始断开所有连接\");\n\n const promises: Promise<void>[] = [];\n\n for (const endpoint of this.endpoints.values()) {\n promises.push(\n Promise.resolve().then(() => {\n endpoint.disconnect();\n })\n );\n }\n\n await Promise.allSettled(promises);\n\n // 重置所有状态\n for (const status of this.connectionStates.values()) {\n status.connected = false;\n status.initialized = false;\n }\n\n console.debug(\"[EndpointManager] 所有接入点已断开连接\");\n }\n\n /**\n * 获取所有 Endpoint URL\n */\n getEndpoints(): string[] {\n return Array.from(this.endpoints.keys());\n }\n\n /**\n * 获取指定 Endpoint 实例\n *\n * @param url - Endpoint URL\n */\n getEndpoint(url: string): Endpoint | undefined {\n return this.endpoints.get(url);\n }\n\n /**\n * 获取所有连接状态\n */\n getConnectionStatus(): SimpleConnectionStatus[] {\n return Array.from(this.connectionStates.values());\n }\n\n /**\n * 检查是否有任何连接处于连接状态\n */\n isAnyConnected(): boolean {\n for (const status of this.connectionStates.values()) {\n if (status.connected) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * 检查指定端点是否已连接\n *\n * @param url - 端点 URL\n */\n isEndpointConnected(url: string): boolean {\n const status = this.connectionStates.get(url);\n return status?.connected ?? false;\n }\n\n /**\n * 获取指定端点的状态\n *\n * @param url - 端点 URL\n */\n getEndpointStatus(url: string): SimpleConnectionStatus | undefined {\n return this.connectionStates.get(url);\n }\n\n /**\n * 重连所有端点\n */\n async reconnectAll(): Promise<void> {\n console.info(\"[EndpointManager] 开始重连所有接入点\");\n\n const promises: Promise<void>[] = [];\n\n for (const [url, endpoint] of this.endpoints) {\n promises.push(\n this.reconnectSingleEndpoint(url, endpoint).catch((error) => {\n console.error(`[EndpointManager] 重连失败: ${sliceEndpoint(url)}`, error);\n })\n );\n }\n\n await Promise.allSettled(promises);\n }\n\n /**\n * 重连指定的端点\n *\n * @param url - 要重连的端点 URL\n */\n async reconnectEndpoint(url: string): Promise<void> {\n const endpoint = this.endpoints.get(url);\n if (!endpoint) {\n throw new Error(`接入点不存在: ${sliceEndpoint(url)}`);\n }\n\n await this.reconnectSingleEndpoint(url, endpoint);\n }\n\n /**\n * 清除所有端点\n */\n async clearEndpoints(): Promise<void> {\n console.debug(\"[EndpointManager] 清除所有接入点\");\n\n await this.disconnect();\n\n this.endpoints.clear();\n this.connectionStates.clear();\n\n console.info(\"[EndpointManager] 所有接入点已清除\");\n }\n\n /**\n * 清理资源\n */\n async cleanup(): Promise<void> {\n console.debug(\"[EndpointManager] 开始清理资源\");\n\n await this.clearEndpoints();\n\n console.debug(\"[EndpointManager] 资源清理完成\");\n }\n\n // ==================== 私有方法 ====================\n\n /**\n * 连接单个端点\n */\n private async connectSingleEndpoint(\n url: string,\n endpoint: Endpoint\n ): Promise<void> {\n const status = this.connectionStates.get(url);\n if (!status) {\n throw new Error(`端点状态不存在: ${sliceEndpoint(url)}`);\n }\n\n console.debug(`[EndpointManager] 连接端点: ${sliceEndpoint(url)}`);\n\n // 更新状态为连接中\n status.connected = false;\n status.initialized = false;\n\n // 执行连接\n await endpoint.connect();\n\n // 更新连接成功状态\n status.connected = true;\n status.initialized = true;\n status.lastConnected = new Date();\n status.lastError = undefined;\n\n console.info(`[EndpointManager] 端点连接成功: ${sliceEndpoint(url)}`);\n }\n\n /**\n * 重连单个端点\n */\n private async reconnectSingleEndpoint(\n url: string,\n endpoint: Endpoint\n ): Promise<void> {\n const status = this.connectionStates.get(url);\n if (!status) {\n throw new Error(`端点状态不存在: ${sliceEndpoint(url)}`);\n }\n\n console.debug(`[EndpointManager] 重连端点: ${sliceEndpoint(url)}`);\n\n // 执行重连\n await endpoint.reconnect();\n\n // 更新连接成功状态\n status.connected = true;\n status.initialized = true;\n status.lastConnected = new Date();\n status.lastError = undefined;\n\n console.info(`[EndpointManager] 端点重连成功: ${sliceEndpoint(url)}`);\n }\n}\n"],"mappings":"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","names":["ToolCallErrorCode","ConnectionState"]}
1
+ {"version":3,"sources":["../src/endpoint.ts","../src/types.ts","../src/utils.ts","../src/internal-mcp-manager.ts","../src/manager.ts"],"sourcesContent":["/**\n * Endpoint 类(新 API)\n * 管理单个小智接入点的 WebSocket 连接\n * 实现 MCP (Model Context Protocol) 协议通信\n *\n * 与 EndpointConnection 的区别:\n * - 构造函数直接传入 mcpServers 配置,不需要单独调用 setServiceManager()\n * - 配置更简洁直观\n */\n\nimport type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport WebSocket from \"ws\";\nimport type { ExtendedMCPMessage, MCPMessage } from \"./mcp.js\";\nimport type {\n EndpointConfig,\n EndpointConnectionStatus,\n ToolCallResult,\n} from \"./types.js\";\nimport {\n ConnectionState,\n ToolCallError as ToolCallErrorClass,\n ToolCallErrorCode as ToolCallErrorCodeEnum,\n ensureToolJSONSchema as ensureToolJSONSchemaFn,\n} from \"./types.js\";\nimport { validateToolCallParams } from \"./utils.js\";\nimport { sliceEndpoint } from \"./utils.js\";\nimport { InternalMCPManagerAdapter } from \"./internal-mcp-manager.js\";\n\n// 导出错误类型供外部使用\nexport {\n ToolCallErrorCodeEnum as ToolCallErrorCode,\n ToolCallErrorClass as ToolCallError,\n};\n\n/**\n * Endpoint 类\n * 负责管理单个小智接入点的 WebSocket 连接\n * 使用新的配置方式:直接在构造函数中传入 mcpServers 配置\n */\nexport class Endpoint {\n private endpointUrl: string;\n private ws: WebSocket | null = null;\n private connectionStatus = false;\n private serverInitialized = false;\n private mcpAdapter: InternalMCPManagerAdapter;\n\n // 连接状态管理\n private connectionState: ConnectionState = ConnectionState.DISCONNECTED;\n\n // 最后一次错误信息\n private lastError: string | null = null;\n\n // 连接超时定时器\n private connectionTimeout: NodeJS.Timeout | null = null;\n\n // 工具调用超时配置\n private toolCallTimeout = 30000;\n private reconnectDelay: number; // 重连延迟(毫秒)\n\n /**\n * 构造函数\n *\n * @param endpointUrl - 小智接入点 URL\n * @param config - Endpoint 配置(包含 mcpServers)\n */\n constructor(endpointUrl: string, config: EndpointConfig) {\n this.endpointUrl = endpointUrl;\n this.reconnectDelay = config.reconnectDelay ?? 2000;\n\n // 创建内部 MCP 适配器\n this.mcpAdapter = new InternalMCPManagerAdapter(config);\n }\n\n /**\n * 获取 Endpoint URL\n */\n getUrl(): string {\n return this.endpointUrl;\n }\n\n /**\n * 获取当前所有工具列表\n */\n getTools(): Tool[] {\n try {\n const allTools = this.mcpAdapter.getAllTools();\n\n return allTools.map((toolInfo) => ({\n name: toolInfo.name,\n description: toolInfo.description,\n inputSchema: ensureToolJSONSchemaFn(toolInfo.inputSchema),\n }));\n } catch (error) {\n console.error(\n `获取工具列表失败: ${error instanceof Error ? error.message : String(error)}`\n );\n return [];\n }\n }\n\n /**\n * 连接小智接入点\n */\n public async connect(): Promise<void> {\n // 初始化 MCP 适配器\n await this.mcpAdapter.initialize();\n\n // 如果正在连接中,等待当前连接完成\n if (this.connectionState === ConnectionState.CONNECTING) {\n throw new Error(\"连接正在进行中,请等待连接完成\");\n }\n\n // 清理之前的连接\n this.cleanupConnection();\n\n return this.attemptConnection();\n }\n\n /**\n * 尝试建立连接\n */\n private async attemptConnection(): Promise<void> {\n this.connectionState = ConnectionState.CONNECTING;\n console.debug(`正在连接小智接入点: ${sliceEndpoint(this.endpointUrl)}`);\n\n return new Promise((resolve, reject) => {\n // 设置连接超时\n this.connectionTimeout = setTimeout(() => {\n const error = new Error(\"连接超时 (10000ms)\");\n this.handleConnectionError(error);\n reject(error);\n }, 10000);\n\n this.ws = new WebSocket(this.endpointUrl);\n\n this.ws.on(\"open\", () => {\n this.handleConnectionSuccess();\n resolve();\n });\n\n this.ws.on(\"message\", (data) => {\n try {\n const message: MCPMessage = JSON.parse(data.toString());\n this.handleMessage(message);\n } catch (error) {\n console.error(\"MCP 消息解析错误:\", error);\n }\n });\n\n this.ws.on(\"close\", (code, reason) => {\n this.handleConnectionClose(code, reason.toString());\n });\n\n this.ws.on(\"error\", (error) => {\n this.handleConnectionError(error);\n reject(error);\n });\n });\n }\n\n /**\n * 处理连接成功\n */\n private handleConnectionSuccess(): void {\n // 清理连接超时定时器\n if (this.connectionTimeout) {\n clearTimeout(this.connectionTimeout);\n this.connectionTimeout = null;\n }\n\n this.connectionStatus = true;\n this.connectionState = ConnectionState.CONNECTED;\n\n console.debug(\"MCP WebSocket 连接已建立\");\n }\n\n /**\n * 处理连接错误\n */\n private handleConnectionError(error: Error): void {\n // 记录最后一次错误信息\n this.lastError = error.message;\n\n // 清理连接超时定时器\n if (this.connectionTimeout) {\n clearTimeout(this.connectionTimeout);\n this.connectionTimeout = null;\n }\n\n console.error(\"MCP WebSocket 错误:\", error.message);\n\n // 清理当前连接\n this.cleanupConnection();\n }\n\n /**\n * 处理连接关闭\n */\n private handleConnectionClose(code: number, reason: string): void {\n this.connectionStatus = false;\n this.serverInitialized = false;\n this.connectionState = ConnectionState.DISCONNECTED;\n console.info(`小智连接已关闭 (代码: ${code}, 原因: ${reason})`);\n }\n\n /**\n * 清理连接资源\n */\n private cleanupConnection(): void {\n // 清理 WebSocket\n if (this.ws) {\n this.ws.removeAllListeners();\n\n try {\n if (this.ws.readyState === WebSocket.OPEN) {\n this.ws.close(1000, \"Cleaning up connection\");\n } else if (this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.terminate();\n }\n } catch (error) {\n console.debug(\"WebSocket 关闭时出现错误(已忽略):\", error);\n }\n\n this.ws = null;\n }\n\n // 清理连接超时定时器\n if (this.connectionTimeout) {\n clearTimeout(this.connectionTimeout);\n this.connectionTimeout = null;\n }\n\n // 重置连接状态\n this.connectionStatus = false;\n this.serverInitialized = false;\n\n // 重置连接状态为已断开\n this.connectionState = ConnectionState.DISCONNECTED;\n }\n\n /**\n * 处理 MCP 消息\n */\n private handleMessage(message: MCPMessage): void {\n console.debug(\"收到 MCP 消息:\", JSON.stringify(message, null, 2));\n\n if (!message.method) {\n console.debug(\"收到没有 method 字段的消息,忽略\");\n return;\n }\n\n switch (message.method) {\n case \"initialize\":\n case \"notifications/initialized\":\n this.sendResponse(message.id, {\n protocolVersion: \"2024-11-05\",\n capabilities: {\n tools: { listChanged: true },\n logging: {},\n },\n serverInfo: {\n name: \"xiaozhi-mcp-server\",\n version: \"1.0.0\",\n },\n });\n this.serverInitialized = true;\n console.debug(\"MCP 服务器初始化完成\");\n break;\n\n case \"tools/list\": {\n const toolsList = this.getTools();\n this.sendResponse(message.id, { tools: toolsList });\n console.debug(`MCP 工具列表已发送 (${toolsList.length}个工具)`);\n break;\n }\n\n case \"tools/call\": {\n this.handleToolCall(message).catch((error) => {\n console.error(\"处理工具调用时发生未捕获错误:\", error);\n });\n break;\n }\n\n case \"ping\":\n this.sendResponse(message.id, {});\n console.debug(\"回应 MCP ping 消息\");\n break;\n\n default:\n console.warn(`未知的 MCP 请求: ${message.method}`);\n }\n }\n\n /**\n * 发送响应消息\n */\n private sendResponse(id: number | string, result: unknown): void {\n console.debug(\n `尝试发送响应: id=${id}, isConnected=${this.connectionStatus}, wsReadyState=${this.ws?.readyState}`\n );\n\n if (this.connectionStatus && this.ws?.readyState === WebSocket.OPEN) {\n const response: ExtendedMCPMessage = {\n jsonrpc: \"2.0\",\n id,\n result,\n };\n\n try {\n this.ws.send(JSON.stringify(response));\n console.debug(\"响应已发送\", {\n id,\n responseSize: JSON.stringify(response).length,\n });\n } catch (error) {\n console.error(\"发送响应失败\", {\n id,\n error,\n });\n }\n } else {\n console.error(\"无法发送响应\", {\n id,\n isConnected: this.connectionStatus,\n wsReadyState: this.ws?.readyState,\n });\n }\n }\n\n /**\n * 获取服务器状态\n */\n public getStatus(): EndpointConnectionStatus {\n const availableTools = this.mcpAdapter.getAllTools().length;\n\n return {\n connected: this.connectionStatus,\n initialized: this.serverInitialized,\n url: this.endpointUrl,\n availableTools,\n connectionState: this.connectionState,\n lastError: this.lastError,\n };\n }\n\n /**\n * 检查连接状态\n */\n public isConnected(): boolean {\n return this.connectionStatus;\n }\n\n /**\n * 主动断开小智连接\n */\n public async disconnect(): Promise<void> {\n console.info(\"主动断开小智连接\");\n\n // 清理 MCP 适配器\n await this.mcpAdapter.cleanup();\n\n // 清理 WebSocket 连接\n this.cleanupConnection();\n }\n\n /**\n * 重连小智接入点\n */\n public async reconnect(): Promise<void> {\n console.info(`重连小智接入点: ${sliceEndpoint(this.endpointUrl)}`);\n\n // 先断开连接\n this.disconnect();\n\n // 等待可配置的时间确保连接完全断开\n await new Promise((resolve) => setTimeout(resolve, this.reconnectDelay));\n\n // 重新连接\n await this.connect();\n }\n\n /**\n * 处理工具调用请求\n */\n private async handleToolCall(request: MCPMessage): Promise<void> {\n if (request.id === undefined || request.id === null) {\n throw new ToolCallErrorClass(\n ToolCallErrorCodeEnum.INVALID_PARAMS,\n \"请求 ID 不能为空\"\n );\n }\n\n const requestId = request.id;\n const startTime = Date.now();\n\n try {\n const params = validateToolCallParams(request.params);\n\n console.info(\"开始处理工具调用\", {\n requestId,\n toolName: params.name,\n hasArguments: !!params.arguments,\n });\n\n const result = await this.executeToolWithTimeout(\n params.name,\n params.arguments || {},\n this.toolCallTimeout\n );\n\n this.sendResponse(requestId, {\n content: result.content || [\n { type: \"text\", text: JSON.stringify(result) },\n ],\n isError: result.isError || false,\n });\n\n console.info(\"工具调用成功\", {\n requestId,\n toolName: params.name,\n duration: `${Date.now() - startTime}ms`,\n });\n } catch (error) {\n this.handleToolCallError(error, requestId, Date.now() - startTime);\n }\n }\n\n /**\n * 带超时控制的工具执行\n */\n private async executeToolWithTimeout(\n toolName: string,\n arguments_: Record<string, unknown>,\n timeoutMs = 30000\n ): Promise<ToolCallResult> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(\n new ToolCallErrorClass(\n ToolCallErrorCodeEnum.TIMEOUT,\n `工具调用超时 (${timeoutMs}ms): ${toolName}`\n )\n );\n }, timeoutMs);\n\n this.mcpAdapter\n .callTool(toolName, arguments_)\n .then((result: ToolCallResult) => {\n clearTimeout(timeoutId);\n resolve(result);\n })\n .catch((error: unknown) => {\n clearTimeout(timeoutId);\n\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n\n if (errorMessage.includes(\"未找到工具\")) {\n reject(\n new ToolCallErrorClass(\n ToolCallErrorCodeEnum.TOOL_NOT_FOUND,\n `工具不存在: ${toolName}`\n )\n );\n } else {\n reject(\n new ToolCallErrorClass(\n ToolCallErrorCodeEnum.TOOL_EXECUTION_ERROR,\n `工具执行失败: ${errorMessage}`\n )\n );\n }\n });\n });\n }\n\n /**\n * 处理工具调用错误\n */\n private handleToolCallError(\n error: unknown,\n requestId: string | number | undefined,\n duration: number\n ): void {\n let errorResponse: {\n code: number;\n message: string;\n data?: unknown;\n };\n\n if (error instanceof ToolCallErrorClass) {\n errorResponse = {\n code: error.code,\n message: error.message,\n data: error.data,\n };\n } else {\n const errorMessage = error instanceof Error ? error.message : \"未知错误\";\n errorResponse = {\n code: ToolCallErrorCodeEnum.TOOL_EXECUTION_ERROR,\n message: errorMessage,\n data: { originalError: String(error) || \"null\" },\n };\n }\n\n this.sendErrorResponse(requestId, errorResponse);\n\n console.error(\"工具调用失败\", {\n requestId,\n duration: `${duration}ms`,\n error: errorResponse,\n });\n }\n\n /**\n * 发送错误响应\n */\n private sendErrorResponse(\n id: string | number | undefined,\n error: { code: number; message: string; data?: unknown }\n ): void {\n if (this.connectionStatus && this.ws?.readyState === WebSocket.OPEN) {\n const response = {\n jsonrpc: \"2.0\",\n id,\n error,\n };\n this.ws.send(JSON.stringify(response));\n console.debug(\"已发送错误响应:\", response);\n }\n }\n}\n","// =========================\n// 1. 工具调用相关类型\n// =========================\n\n/**\n * 工具调用结果接口\n */\nexport interface ToolCallResult {\n content: Array<{\n type: string;\n text: string;\n }>;\n isError?: boolean;\n}\n\n/**\n * 工具调用参数接口\n */\nexport interface ToolCallParams {\n name: string;\n arguments?: Record<string, unknown>;\n}\n\n/**\n * 验证后的工具调用参数\n */\nexport interface ValidatedToolCallParams {\n name: string;\n arguments?: Record<string, unknown>;\n}\n\n/**\n * 工具调用错误码枚举\n */\nexport enum ToolCallErrorCode {\n /** 无效参数 */\n INVALID_PARAMS = -32602,\n /** 工具不存在 */\n TOOL_NOT_FOUND = -32601,\n /** 服务不可用 */\n SERVICE_UNAVAILABLE = -32001,\n /** 调用超时 */\n TIMEOUT = -32002,\n /** 工具执行错误 */\n TOOL_EXECUTION_ERROR = -32000,\n}\n\n/**\n * 工具调用错误类\n */\nexport class ToolCallError extends Error {\n constructor(\n public code: ToolCallErrorCode,\n message: string,\n public data?: unknown\n ) {\n super(message);\n this.name = \"ToolCallError\";\n }\n}\n\n// =========================\n// 2. JSON Schema 类型\n// =========================\n\n/**\n * JSON Schema 类型定义\n * 兼容 MCP SDK 的 JSON Schema 格式\n */\nexport type JSONSchema =\n | (Record<string, unknown> & {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n })\n | Record<string, unknown>;\n\n/**\n * 确保对象符合 MCP Tool JSON Schema 格式\n * 返回类型兼容 MCP SDK 的 Tool 类型\n */\nexport function ensureToolJSONSchema(schema: JSONSchema): {\n type: \"object\";\n properties?: Record<string, object>;\n required?: string[];\n additionalProperties?: boolean;\n} {\n if (\n typeof schema === \"object\" &&\n schema !== null &&\n \"type\" in schema &&\n schema.type === \"object\"\n ) {\n return schema as {\n type: \"object\";\n properties?: Record<string, object>;\n required?: string[];\n additionalProperties?: boolean;\n };\n }\n\n // 如果不符合标准格式,返回默认的空对象 schema\n return {\n type: \"object\",\n properties: {},\n required: [],\n additionalProperties: true,\n };\n}\n\n// =========================\n// 3. 工具信息类型\n// =========================\n\n/**\n * 增强的工具信息接口\n * 包含工具的启用状态和使用统计信息\n */\nexport interface EnhancedToolInfo {\n /** 工具唯一标识符,格式为 \"{serviceName}__{originalName}\" */\n name: string;\n\n /** 工具描述信息 */\n description: string;\n\n /** 工具输入参数的 JSON Schema 定义 */\n inputSchema: JSONSchema;\n\n /** 工具所属的 MCP 服务名称 */\n serviceName: string;\n\n /** 工具在 MCP 服务中的原始名称 */\n originalName: string;\n\n /** 工具是否启用 */\n enabled: boolean;\n\n /** 工具使用次数统计 */\n usageCount: number;\n\n /** 工具最后使用时间 (ISO 8601 格式字符串) */\n lastUsedTime: string;\n}\n\n/**\n * MCP 服务管理器接口\n * 用于工具调用,避免循环依赖\n */\nexport interface IMCPServiceManager {\n /** 获取所有工具列表 */\n getAllTools(): EnhancedToolInfo[];\n\n /** 调用工具 */\n callTool(\n toolName: string,\n arguments_: Record<string, unknown>\n ): Promise<ToolCallResult>;\n}\n\n// =========================\n// 4. 连接状态类型\n// =========================\n\n/**\n * 连接状态枚举\n */\nexport enum ConnectionState {\n DISCONNECTED = \"disconnected\",\n CONNECTING = \"connecting\",\n CONNECTED = \"connected\",\n FAILED = \"failed\",\n}\n\n/**\n * 连接选项接口\n */\nexport interface ConnectionOptions {\n /** 连接超时时间(毫秒),默认 10000 */\n connectionTimeout?: number;\n /** 重连延迟时间(毫秒),默认 2000 */\n reconnectDelay?: number;\n}\n\n// =========================\n// 5. EndpointConnection 状态类型\n// =========================\n\n/**\n * EndpointConnection 状态接口\n */\nexport interface EndpointConnectionStatus {\n /** 是否已连接 */\n connected: boolean;\n /** 是否已初始化 */\n initialized: boolean;\n /** 接入点 URL */\n url: string;\n /** 可用工具数量 */\n availableTools: number;\n /** 连接状态 */\n connectionState: ConnectionState;\n /** 最后一次错误信息 */\n lastError: string | null;\n}\n\n// =========================\n// 6. EndpointManager 状态类型\n// =========================\n\n/**\n * 简单连接状态接口\n */\nexport interface SimpleConnectionStatus {\n /** 接入点地址 */\n endpoint: string;\n /** 是否已连接 */\n connected: boolean;\n /** 是否已初始化 */\n initialized: boolean;\n /** 最后连接时间 */\n lastConnected?: Date;\n /** 最后错误信息 */\n lastError?: string;\n}\n\n/**\n * 完整连接状态接口(扩展 SimpleConnectionStatus)\n */\nexport interface ConnectionStatus extends SimpleConnectionStatus {\n // 扩展字段可以在这里添加\n}\n\n/**\n * 配置变更事件类型\n */\nexport interface ConfigChangeEvent {\n type:\n | \"endpoints_added\"\n | \"endpoints_removed\"\n | \"endpoints_updated\"\n | \"options_updated\";\n data: {\n added?: string[];\n removed?: string[];\n updated?: string[];\n oldOptions?: Partial<ConnectionOptions>;\n newOptions?: Partial<ConnectionOptions>;\n };\n timestamp: Date;\n}\n\n/**\n * 重连结果接口\n */\nexport interface ReconnectResult {\n successCount: number;\n failureCount: number;\n results: Array<{\n endpoint: string;\n success: boolean;\n error?: string;\n }>;\n}\n\n// =========================\n// 7. 新 API 配置类型\n// =========================\n\n/**\n * MCP 服务器配置类型\n * 支持三种配置方式:\n * 1. 本地命令 (stdio): { command: string; args: string[]; env?: Record<string, string> }\n * 2. SSE: { type: \"sse\"; url: string; headers?: Record<string, string> }\n * 3. Streamable HTTP: { type?: \"streamable-http\"; url: string; headers?: Record<string, string> }\n */\nexport type MCPServerConfig =\n | LocalMCPServerConfig\n | SSEMCPServerConfig\n | StreamableHTTPMCPServerConfig;\n\n/**\n * 本地 MCP 服务器配置\n */\nexport interface LocalMCPServerConfig {\n command: string;\n args: string[];\n env?: Record<string, string>;\n}\n\n/**\n * SSE MCP 服务器配置\n */\nexport interface SSEMCPServerConfig {\n type: \"sse\";\n url: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Streamable HTTP MCP 服务器配置\n */\nexport interface StreamableHTTPMCPServerConfig {\n type?: \"streamable-http\"; // 可选,默认就是 streamable-http\n url: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Endpoint 配置接口\n * 用于新 API:直接在构造函数中传入 MCP 服务器配置\n */\nexport interface EndpointConfig {\n /** MCP 服务器配置(声明式) */\n mcpServers: Record<string, MCPServerConfig>;\n /** 可选:重连延迟(毫秒),默认 2000 */\n reconnectDelay?: number;\n /** 可选:ModelScope API Key(全局) */\n modelscopeApiKey?: string;\n}\n\n/**\n * EndpointManager 配置接口(新 API 简化版)\n */\nexport interface EndpointManagerConfig {\n /** 可选:默认重连延迟(毫秒) */\n defaultReconnectDelay?: number;\n}\n","/**\n * 工具函数模块\n *\n * 内联的必要工具函数,确保包的独立性\n */\n\nimport type { ValidatedToolCallParams } from \"./types.js\";\n\n/**\n * 截断端点 URL 用于日志显示\n *\n * @param endpoint - 完整的端点 URL\n * @returns 截断后的 URL\n *\n * @example\n * ```typescript\n * sliceEndpoint(\"ws://very-long-endpoint-url-here.example.com/endpoint\")\n * // 返回: \"ws://very-long-endpoint-u...e.com/endpoint\"\n * ```\n */\nexport function sliceEndpoint(endpoint: string): string {\n return `${endpoint.slice(0, 30)}...${endpoint.slice(-10)}`;\n}\n\n/**\n * 验证工具调用参数\n *\n * @param params - 待验证的参数\n * @returns 验证后的参数\n * @throws {Error} 如果参数无效\n *\n * @example\n * ```typescript\n * const params = validateToolCallParams({\n * name: \"test_tool\",\n * arguments: { foo: \"bar\" }\n * });\n * ```\n */\nexport function validateToolCallParams(\n params: unknown\n): ValidatedToolCallParams {\n // 基础类型检查\n if (!params || typeof params !== \"object\") {\n throw new Error(\"工具调用参数必须是对象\");\n }\n\n const p = params as Record<string, unknown>;\n\n // 验证工具名称\n if (!p.name || typeof p.name !== \"string\") {\n throw new Error(\"工具名称必须是字符串\");\n }\n\n // 构建验证后的参数\n const validated: ValidatedToolCallParams = {\n name: p.name,\n };\n\n // 验证参数(可选)\n if (p.arguments !== undefined) {\n if (typeof p.arguments !== \"object\" || p.arguments === null) {\n throw new Error(\"工具参数必须是对象\");\n }\n validated.arguments = p.arguments as Record<string, unknown>;\n }\n\n return validated;\n}\n\n/**\n * 验证端点 URL 格式\n *\n * @param endpoint - 待验证的端点 URL\n * @returns 是否为有效的 WebSocket URL\n */\nexport function isValidEndpointUrl(endpoint: string): boolean {\n if (!endpoint || typeof endpoint !== \"string\") {\n return false;\n }\n\n if (!endpoint.startsWith(\"ws://\") && !endpoint.startsWith(\"wss://\")) {\n return false;\n }\n\n try {\n new URL(endpoint);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * 检查属性名是否安全,防止原型污染攻击\n *\n * @param key - 待检查的属性名\n * @returns 是否为安全的属性名\n *\n * @example\n * ```typescript\n * isSafeKey(\"name\") // true\n * isSafeKey(\"__proto__\") // false\n * isSafeKey(\"constructor\") // false\n * ```\n */\nfunction isSafeKey(key: string): boolean {\n // 拒绝已知的危险属性名\n const dangerousKeys = [\"__proto__\", \"constructor\", \"prototype\"];\n if (dangerousKeys.includes(key)) {\n return false;\n }\n\n // 确保属性名是普通的字符串(不是 Symbol 等)\n return typeof key === \"string\" && key.length > 0;\n}\n\n/**\n * 深度合并对象\n *\n * @param target - 目标对象\n * @param sources - 源对象\n * @returns 合并后的对象\n *\n * @example\n * ```typescript\n * const result = deepMerge(\n * { a: 1, b: { x: 1 } },\n * { b: { y: 2 }, c: 3 }\n * );\n * // 返回: { a: 1, b: { x: 1, y: 2 }, c: 3 }\n * ```\n */\nexport function deepMerge<T>(\n target: Partial<T>,\n ...sources: Array<Partial<T>>\n): T {\n if (sources.length === 0) {\n return target as T;\n }\n\n const source = sources.shift();\n\n if (source === undefined) {\n return target as T;\n }\n\n // 使用 Object.keys() 替代 for...in,只遍历对象自身的可枚举属性\n const keys = Object.keys(source as Record<string, unknown>);\n\n for (const key of keys) {\n // 跳过不安全的 key,防止原型污染攻击\n if (!isSafeKey(key)) {\n continue;\n }\n\n const sourceValue = (source as Record<string, unknown>)[key];\n const targetValue = (target as Record<string, unknown>)[key];\n\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === \"object\" &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n (target as Record<string, unknown>)[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n );\n } else {\n (target as Record<string, unknown>)[key] = sourceValue;\n }\n }\n\n return deepMerge(target, ...sources);\n}\n\n/**\n * 延迟执行\n *\n * @param ms - 延迟时间(毫秒)\n * @returns Promise\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * 格式化错误消息\n *\n * @param error - 错误对象\n * @returns 格式化后的错误消息\n */\nexport function formatErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n return String(error);\n}\n","/**\n * 内部 MCP 服务管理器适配器\n * 将 mcpServers 配置转换为 IMCPServiceManager 接口\n * 使用 @xiaozhi-client/mcp-core 的 MCPManager 实现真实的 MCP 功能\n */\n\nimport { MCPManager } from \"@xiaozhi-client/mcp-core\";\nimport type { MCPServiceConfig } from \"@xiaozhi-client/mcp-core\";\nimport type { EnhancedToolInfo, ToolCallResult } from \"./types.js\";\nimport type { IMCPServiceManager } from \"./types.js\";\nimport type { EndpointConfig, MCPServerConfig } from \"./types.js\";\nimport { convertLegacyToNew } from \"@xiaozhi-client/config\";\n\n/**\n * 内部 MCP 服务管理器适配器\n * 实现 IMCPServiceManager 接口,使用真正的 MCPManager\n */\nexport class InternalMCPManagerAdapter implements IMCPServiceManager {\n private mcpManager: MCPManager;\n private tools: Map<string, EnhancedToolInfo> = new Map();\n private isInitialized = false;\n\n constructor(private config: EndpointConfig) {\n this.mcpManager = new MCPManager();\n\n // 转换配置并添加到 MCPManager\n for (const [serviceName, serverConfig] of Object.entries(\n config.mcpServers\n )) {\n const mcpConfig = this.convertToMCPServiceConfig(serviceName, serverConfig);\n this.mcpManager.addServer(serviceName, mcpConfig);\n }\n\n // 设置事件监听\n this.mcpManager.on(\"connected\", (data) => {\n console.info(\n `MCP 服务 ${data.serverName} 已连接,工具数: ${data.tools.length}`\n );\n });\n\n this.mcpManager.on(\"error\", (data) => {\n console.error(`MCP 服务 ${data.serverName} 出错:`, data.error);\n });\n }\n\n /**\n * 初始化并启动所有 MCP 服务\n */\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n return;\n }\n\n // 连接所有 MCP 服务\n await this.mcpManager.connect();\n\n // 刷新工具列表\n await this.refreshTools();\n\n this.isInitialized = true;\n }\n\n /**\n * 获取所有工具列表\n */\n getAllTools(): EnhancedToolInfo[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * 调用工具(真实实现)\n */\n async callTool(\n toolName: string,\n arguments_: Record<string, unknown>\n ): Promise<ToolCallResult> {\n // 解析工具名称:serviceName__toolName\n const [serviceName, actualToolName] = this.parseToolName(toolName);\n\n // 调用真实的 MCP 工具\n return this.mcpManager.callTool(serviceName, actualToolName, arguments_);\n }\n\n /**\n * 清理资源\n */\n async cleanup(): Promise<void> {\n await this.mcpManager.disconnect();\n this.tools.clear();\n this.isInitialized = false;\n }\n\n /**\n * 刷新工具列表\n */\n private async refreshTools(): Promise<void> {\n this.tools.clear();\n\n const mcpTools = this.mcpManager.listTools();\n\n for (const mcpTool of mcpTools) {\n const enhancedTool: EnhancedToolInfo = {\n name: `${mcpTool.serverName}__${mcpTool.name}`,\n description: mcpTool.description,\n inputSchema: mcpTool.inputSchema as any,\n serviceName: mcpTool.serverName,\n originalName: mcpTool.name,\n enabled: true,\n usageCount: 0,\n lastUsedTime: new Date().toISOString(),\n };\n this.tools.set(enhancedTool.name, enhancedTool);\n }\n }\n\n /**\n * 解析工具名称\n */\n private parseToolName(toolName: string): [string, string] {\n const parts = toolName.split(\"__\");\n if (parts.length < 2) {\n throw new Error(`无效的工具名称格式: ${toolName}`);\n }\n const serviceName = parts[0];\n const actualToolName = parts.slice(1).join(\"__\"); // 支持工具名中包含 __\n return [serviceName, actualToolName];\n }\n\n /**\n * 将 MCPServerConfig 转换为 MCPServiceConfig\n * 使用统一的配置适配器,确保路径解析逻辑一致\n */\n private convertToMCPServiceConfig(\n serviceName: string,\n config: MCPServerConfig\n ): Omit<MCPServiceConfig, \"name\"> {\n // 使用统一的转换函数,自动处理相对路径解析\n // convertLegacyToNew 会:\n // 1. 解析 command 中的相对路径(相对于配置文件目录)\n // 2. 解析 args 中的相对路径\n // 3. 返回带有 name 字段的完整配置\n const converted = convertLegacyToNew(serviceName, config);\n\n // 移除 name 字段(因为 InternalMCPManagerAdapter 不需要)\n const { name, ...rest } = converted;\n\n return rest;\n }\n}\n","/**\n * EndpointManager(新 API)\n * 管理多个小智接入点的连接,每个小智接入点独立运行\n *\n * 与旧 EndpointManager 的区别:\n * - 使用 addEndpoint(endpoint) 添加 Endpoint 实例\n * - 不需要 initialize() 和 setServiceManager()\n * - 配置更简洁直观\n */\n\nimport { EventEmitter } from \"node:events\";\nimport type { Endpoint } from \"./endpoint.js\";\nimport type { EndpointManagerConfig, SimpleConnectionStatus } from \"./types.js\";\nimport { sliceEndpoint } from \"./utils.js\";\n\n/**\n * 小智接入点管理器(新 API)\n * 负责管理多个小智接入点的连接\n */\nexport class EndpointManager extends EventEmitter {\n private endpoints: Map<string, Endpoint> = new Map();\n private connectionStates: Map<string, SimpleConnectionStatus> = new Map();\n\n /**\n * 构造函数\n *\n * @param config - 可选的配置\n */\n constructor(private config?: EndpointManagerConfig) {\n super();\n console.debug(\"[EndpointManager] 实例已创建(新 API)\");\n }\n\n /**\n * 添加 Endpoint 实例\n *\n * @param endpoint - Endpoint 实例\n */\n addEndpoint(endpoint: Endpoint): void {\n const url = endpoint.getUrl();\n\n if (this.endpoints.has(url)) {\n console.debug(\n `[EndpointManager] 接入点 ${sliceEndpoint(url)} 已存在,跳过添加`\n );\n return;\n }\n\n console.debug(`[EndpointManager] 添加接入点: ${sliceEndpoint(url)}`);\n\n this.endpoints.set(url, endpoint);\n this.connectionStates.set(url, {\n endpoint: url,\n connected: false,\n initialized: false,\n });\n\n // 发射事件\n this.emit(\"endpointAdded\", { endpoint: url });\n }\n\n /**\n * 移除 Endpoint 实例\n *\n * @param endpoint - Endpoint 实例\n */\n removeEndpoint(endpoint: Endpoint): void {\n const url = endpoint.getUrl();\n\n if (!this.endpoints.has(url)) {\n console.debug(\n `[EndpointManager] 接入点 ${sliceEndpoint(url)} 不存在,跳过移除`\n );\n return;\n }\n\n console.debug(`[EndpointManager] 移除接入点: ${sliceEndpoint(url)}`);\n\n // 断开连接\n endpoint.disconnect();\n\n // 清理状态\n this.endpoints.delete(url);\n this.connectionStates.delete(url);\n\n // 发射事件\n this.emit(\"endpointRemoved\", { endpoint: url });\n }\n\n /**\n * 连接所有 Endpoint\n */\n async connect(): Promise<void> {\n console.debug(`[EndpointManager] 开始连接所有接入点,总数: ${this.endpoints.size}`);\n\n const promises: Promise<void>[] = [];\n\n for (const [url, endpoint] of this.endpoints) {\n promises.push(\n this.connectSingleEndpoint(url, endpoint).catch((error) => {\n console.error(`[EndpointManager] 连接失败: ${sliceEndpoint(url)}`, error);\n // 更新失败状态\n const status = this.connectionStates.get(url);\n if (status) {\n status.connected = false;\n status.initialized = false;\n status.lastError = error instanceof Error ? error.message : String(error);\n }\n })\n );\n }\n\n await Promise.allSettled(promises);\n\n // 统计连接结果\n const connectedCount = Array.from(this.connectionStates.values()).filter(\n (s) => s.connected\n ).length;\n\n console.info(`[EndpointManager] 连接完成: 成功 ${connectedCount}/${this.endpoints.size}`);\n }\n\n /**\n * 断开所有连接\n */\n async disconnect(): Promise<void> {\n console.debug(\"[EndpointManager] 开始断开所有连接\");\n\n const promises: Promise<void>[] = [];\n\n for (const endpoint of this.endpoints.values()) {\n promises.push(\n Promise.resolve().then(() => {\n endpoint.disconnect();\n })\n );\n }\n\n await Promise.allSettled(promises);\n\n // 重置所有状态\n for (const status of this.connectionStates.values()) {\n status.connected = false;\n status.initialized = false;\n }\n\n console.debug(\"[EndpointManager] 所有接入点已断开连接\");\n }\n\n /**\n * 获取所有 Endpoint URL\n */\n getEndpoints(): string[] {\n return Array.from(this.endpoints.keys());\n }\n\n /**\n * 获取指定 Endpoint 实例\n *\n * @param url - Endpoint URL\n */\n getEndpoint(url: string): Endpoint | undefined {\n return this.endpoints.get(url);\n }\n\n /**\n * 获取所有连接状态\n */\n getConnectionStatus(): SimpleConnectionStatus[] {\n return Array.from(this.connectionStates.values());\n }\n\n /**\n * 检查是否有任何连接处于连接状态\n */\n isAnyConnected(): boolean {\n for (const status of this.connectionStates.values()) {\n if (status.connected) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * 检查指定端点是否已连接\n *\n * @param url - 端点 URL\n */\n isEndpointConnected(url: string): boolean {\n const status = this.connectionStates.get(url);\n return status?.connected ?? false;\n }\n\n /**\n * 获取指定端点的状态\n *\n * @param url - 端点 URL\n */\n getEndpointStatus(url: string): SimpleConnectionStatus | undefined {\n return this.connectionStates.get(url);\n }\n\n /**\n * 重连所有端点\n */\n async reconnectAll(): Promise<void> {\n console.info(\"[EndpointManager] 开始重连所有接入点\");\n\n const promises: Promise<void>[] = [];\n\n for (const [url, endpoint] of this.endpoints) {\n promises.push(\n this.reconnectSingleEndpoint(url, endpoint).catch((error) => {\n console.error(`[EndpointManager] 重连失败: ${sliceEndpoint(url)}`, error);\n })\n );\n }\n\n await Promise.allSettled(promises);\n }\n\n /**\n * 重连指定的端点\n *\n * @param url - 要重连的端点 URL\n */\n async reconnectEndpoint(url: string): Promise<void> {\n const endpoint = this.endpoints.get(url);\n if (!endpoint) {\n throw new Error(`接入点不存在: ${sliceEndpoint(url)}`);\n }\n\n await this.reconnectSingleEndpoint(url, endpoint);\n }\n\n /**\n * 清除所有端点\n */\n async clearEndpoints(): Promise<void> {\n console.debug(\"[EndpointManager] 清除所有接入点\");\n\n await this.disconnect();\n\n this.endpoints.clear();\n this.connectionStates.clear();\n\n console.info(\"[EndpointManager] 所有接入点已清除\");\n }\n\n /**\n * 清理资源\n */\n async cleanup(): Promise<void> {\n console.debug(\"[EndpointManager] 开始清理资源\");\n\n await this.clearEndpoints();\n\n console.debug(\"[EndpointManager] 资源清理完成\");\n }\n\n // ==================== 私有方法 ====================\n\n /**\n * 连接单个端点\n */\n private async connectSingleEndpoint(\n url: string,\n endpoint: Endpoint\n ): Promise<void> {\n const status = this.connectionStates.get(url);\n if (!status) {\n throw new Error(`端点状态不存在: ${sliceEndpoint(url)}`);\n }\n\n console.debug(`[EndpointManager] 连接端点: ${sliceEndpoint(url)}`);\n\n // 更新状态为连接中\n status.connected = false;\n status.initialized = false;\n\n // 执行连接\n await endpoint.connect();\n\n // 更新连接成功状态\n status.connected = true;\n status.initialized = true;\n status.lastConnected = new Date();\n status.lastError = undefined;\n\n console.info(`[EndpointManager] 端点连接成功: ${sliceEndpoint(url)}`);\n }\n\n /**\n * 重连单个端点\n */\n private async reconnectSingleEndpoint(\n url: string,\n endpoint: Endpoint\n ): Promise<void> {\n const status = this.connectionStates.get(url);\n if (!status) {\n throw new Error(`端点状态不存在: ${sliceEndpoint(url)}`);\n }\n\n console.debug(`[EndpointManager] 重连端点: ${sliceEndpoint(url)}`);\n\n // 执行重连\n await endpoint.reconnect();\n\n // 更新连接成功状态\n status.connected = true;\n status.initialized = true;\n status.lastConnected = new Date();\n status.lastError = undefined;\n\n console.info(`[EndpointManager] 端点重连成功: ${sliceEndpoint(url)}`);\n }\n}\n"],"mappings":"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","names":["ToolCallErrorCode","ConnectionState"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiaozhi-client/endpoint",
3
- "version": "1.9.7-beta.7",
3
+ "version": "1.9.7-beta.9",
4
4
  "description": "小智接入点 WebSocket 连接管理库",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,7 +21,8 @@
21
21
  ],
22
22
  "dependencies": {
23
23
  "ws": "^8.14.2",
24
- "@xiaozhi-client/mcp-core": "1.9.7-beta.7"
24
+ "@xiaozhi-client/mcp-core": "1.9.7-beta.9",
25
+ "@xiaozhi-client/config": "1.9.7-beta.9"
25
26
  },
26
27
  "peerDependencies": {
27
28
  "@modelcontextprotocol/sdk": "^1.24.0"