@xiaozhi-client/endpoint 1.9.7-beta.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 shenjingnan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,612 @@
1
+ # @xiaozhi-client/endpoint
2
+
3
+ 小智接入点 WebSocket 连接管理库,提供独立、易用的小智接入点连接功能。
4
+
5
+ ## 特性
6
+
7
+ - **独立部署** - 无需配置文件、日志系统等外部依赖
8
+ - **简单易用** - 传入端点 URL 即可使用
9
+ - **多端点管理** - 支持同时管理多个小智接入点
10
+ - **MCP 协议** - 完整实现 Model Context Protocol 协议
11
+ - **TypeScript** - 完整的类型定义支持
12
+ - **事件驱动** - 基于 EventEmitter 的状态管理
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install @xiaozhi-client/endpoint
18
+ # 或
19
+ pnpm add @xiaozhi-client/endpoint
20
+ # 或
21
+ yarn add @xiaozhi-client/endpoint
22
+ ```
23
+
24
+ ## 快速开始
25
+
26
+ ### 单个连接(Endpoint)
27
+
28
+ ```typescript
29
+ import { Endpoint } from '@xiaozhi-client/endpoint';
30
+
31
+ const endpoint = new Endpoint("ws://localhost:8080", {
32
+ mcpServers: {
33
+ // 本地 MCP 服务器
34
+ calculator: {
35
+ command: "node",
36
+ args: ["./calculator.js"]
37
+ },
38
+ // SSE MCP 服务器
39
+ "sse-service": {
40
+ type: "sse",
41
+ url: "https://api.example.com/sse"
42
+ }
43
+ },
44
+ reconnectDelay: 2000
45
+ });
46
+
47
+ await endpoint.connect();
48
+
49
+ // 检查状态
50
+ const status = endpoint.getStatus();
51
+ console.log('已连接:', status.connected);
52
+ console.log('可用工具数:', status.availableTools);
53
+
54
+ // 断开连接
55
+ endpoint.disconnect();
56
+ ```
57
+
58
+ ### 多连接管理(EndpointManager)
59
+
60
+ ```typescript
61
+ import { Endpoint, EndpointManager } from '@xiaozhi-client/endpoint';
62
+
63
+ // 创建多个 Endpoint 实例
64
+ const endpoint1 = new Endpoint("ws://localhost:8080", {
65
+ mcpServers: {
66
+ calculator: {
67
+ command: "node",
68
+ args: ["./calculator.js"]
69
+ }
70
+ }
71
+ });
72
+
73
+ const endpoint2 = new Endpoint("ws://localhost:8081", {
74
+ mcpServers: {
75
+ datetime: {
76
+ command: "node",
77
+ args: ["./datetime.js"]
78
+ }
79
+ }
80
+ });
81
+
82
+ // 创建管理器并添加端点
83
+ const manager = new EndpointManager();
84
+ manager.addEndpoint(endpoint1);
85
+ manager.addEndpoint(endpoint2);
86
+
87
+ // 连接所有端点
88
+ await manager.connect();
89
+
90
+ // 检查状态
91
+ const statuses = manager.getConnectionStatus();
92
+ console.log('已连接端点数:', statuses.filter(s => s.connected).length);
93
+
94
+ // 断开所有连接
95
+ await manager.disconnect();
96
+ ```
97
+
98
+ ## API 参考
99
+
100
+ ### Endpoint
101
+
102
+ 单个小智接入点的连接管理类。
103
+
104
+ #### 构造函数
105
+
106
+ ```typescript
107
+ constructor(endpointUrl: string, config: EndpointConfig)
108
+ ```
109
+
110
+ - `endpointUrl`: 小智接入点的 WebSocket URL(必须以 `ws://` 或 `wss://` 开头)
111
+ - `config`: 配置对象
112
+ - `mcpServers`: MCP 服务器配置对象
113
+ - `reconnectDelay`: 重连延迟时间(毫秒),默认 2000
114
+
115
+ #### 方法
116
+
117
+ ##### connect()
118
+
119
+ 连接到小智接入点。
120
+
121
+ ```typescript
122
+ async connect(): Promise<void>
123
+ ```
124
+
125
+ ##### disconnect()
126
+
127
+ 主动断开连接。
128
+
129
+ ```typescript
130
+ disconnect(): void
131
+ ```
132
+
133
+ ##### reconnect()
134
+
135
+ 重连到小智接入点。
136
+
137
+ ```typescript
138
+ async reconnect(): Promise<void>
139
+ ```
140
+
141
+ ##### getStatus()
142
+
143
+ 获取当前连接状态。
144
+
145
+ ```typescript
146
+ getStatus(): EndpointConnectionStatus
147
+ ```
148
+
149
+ 返回类型:
150
+ ```typescript
151
+ interface EndpointConnectionStatus {
152
+ connected: boolean; // 是否已连接
153
+ initialized: boolean; // 是否已完成 MCP 初始化
154
+ url: string; // 端点 URL
155
+ availableTools: number; // 可用工具数量
156
+ connectionState: ConnectionState; // 连接状态枚举
157
+ lastError?: string; // 最后一次错误信息
158
+ }
159
+ ```
160
+
161
+ ##### isConnected()
162
+
163
+ 检查是否已连接。
164
+
165
+ ```typescript
166
+ isConnected(): boolean
167
+ ```
168
+
169
+ ##### getTools()
170
+
171
+ 获取所有可用工具列表。
172
+
173
+ ```typescript
174
+ getTools(): Tool[]
175
+ ```
176
+
177
+ ##### getUrl()
178
+
179
+ 获取端点 URL。
180
+
181
+ ```typescript
182
+ getUrl(): string
183
+ ```
184
+
185
+ ### EndpointManager
186
+
187
+ 多个小智接入点的连接管理类,继承自 EventEmitter。
188
+
189
+ #### 构造函数
190
+
191
+ ```typescript
192
+ constructor(config?: EndpointManagerConfig)
193
+ ```
194
+
195
+ 配置选项:
196
+ ```typescript
197
+ interface EndpointManagerConfig {
198
+ defaultReconnectDelay?: number; // 默认重连延迟(毫秒)
199
+ }
200
+ ```
201
+
202
+ #### 方法
203
+
204
+ ##### addEndpoint()
205
+
206
+ 添加 Endpoint 实例。
207
+
208
+ ```typescript
209
+ addEndpoint(endpoint: Endpoint): void
210
+ ```
211
+
212
+ ##### removeEndpoint()
213
+
214
+ 移除 Endpoint 实例。
215
+
216
+ ```typescript
217
+ removeEndpoint(endpoint: Endpoint): void
218
+ ```
219
+
220
+ ##### connect()
221
+
222
+ 连接所有 Endpoint。
223
+
224
+ ```typescript
225
+ async connect(): Promise<void>
226
+ ```
227
+
228
+ ##### disconnect()
229
+
230
+ 断开所有连接。
231
+
232
+ ```typescript
233
+ async disconnect(): Promise<void>
234
+ ```
235
+
236
+ ##### reconnectAll()
237
+
238
+ 重连所有端点。
239
+
240
+ ```typescript
241
+ async reconnectAll(): Promise<void>
242
+ ```
243
+
244
+ ##### reconnectEndpoint()
245
+
246
+ 重连指定的端点。
247
+
248
+ ```typescript
249
+ async reconnectEndpoint(url: string): Promise<void>
250
+ ```
251
+
252
+ ##### getEndpoints()
253
+
254
+ 获取所有端点列表。
255
+
256
+ ```typescript
257
+ getEndpoints(): string[]
258
+ ```
259
+
260
+ ##### getEndpoint()
261
+
262
+ 获取指定 Endpoint 实例。
263
+
264
+ ```typescript
265
+ getEndpoint(url: string): Endpoint | undefined
266
+ ```
267
+
268
+ ##### getConnectionStatus()
269
+
270
+ 获取所有连接状态。
271
+
272
+ ```typescript
273
+ getConnectionStatus(): SimpleConnectionStatus[]
274
+ ```
275
+
276
+ ##### isAnyConnected()
277
+
278
+ 检查是否有任何连接处于连接状态。
279
+
280
+ ```typescript
281
+ isAnyConnected(): boolean
282
+ ```
283
+
284
+ ##### isEndpointConnected()
285
+
286
+ 检查指定端点是否已连接。
287
+
288
+ ```typescript
289
+ isEndpointConnected(url: string): boolean
290
+ ```
291
+
292
+ ##### getEndpointStatus()
293
+
294
+ 获取指定端点的状态。
295
+
296
+ ```typescript
297
+ getEndpointStatus(url: string): SimpleConnectionStatus | undefined
298
+ ```
299
+
300
+ ##### clearEndpoints()
301
+
302
+ 清除所有端点。
303
+
304
+ ```typescript
305
+ async clearEndpoints(): Promise<void>
306
+ ```
307
+
308
+ ##### cleanup()
309
+
310
+ 清理资源。
311
+
312
+ ```typescript
313
+ async cleanup(): Promise<void>
314
+ ```
315
+
316
+ #### 事件
317
+
318
+ EndpointManager 继承自 EventEmitter,支持以下事件:
319
+
320
+ ```typescript
321
+ // 端点添加事件
322
+ manager.on('endpointAdded', (event) => {
323
+ console.log('端点已添加:', event.endpoint);
324
+ });
325
+
326
+ // 端点移除事件
327
+ manager.on('endpointRemoved', (event) => {
328
+ console.log('端点已移除:', event.endpoint);
329
+ });
330
+ ```
331
+
332
+ ## 类型定义
333
+
334
+ ### EndpointConfig
335
+
336
+ Endpoint 配置接口。
337
+
338
+ ```typescript
339
+ interface EndpointConfig {
340
+ // MCP 服务器配置(必需)
341
+ mcpServers: Record<string, MCPServerConfig>;
342
+ // 重连延迟(可选)
343
+ reconnectDelay?: number;
344
+ // ModelScope API Key(可选)
345
+ modelscopeApiKey?: string;
346
+ }
347
+ ```
348
+
349
+ ### MCPServerConfig
350
+
351
+ MCP 服务器配置类型,支持三种类型:
352
+
353
+ #### 本地 MCP 服务器
354
+
355
+ ```typescript
356
+ interface LocalMCPServerConfig {
357
+ command: string;
358
+ args: string[];
359
+ env?: Record<string, string>;
360
+ }
361
+ ```
362
+
363
+ #### SSE MCP 服务器
364
+
365
+ ```typescript
366
+ interface SSEMCPServerConfig {
367
+ type: "sse";
368
+ url: string;
369
+ headers?: Record<string, string>;
370
+ }
371
+ ```
372
+
373
+ #### Streamable HTTP MCP 服务器
374
+
375
+ ```typescript
376
+ interface StreamableHTTPMCPServerConfig {
377
+ type?: "streamable-http";
378
+ url: string;
379
+ headers?: Record<string, string>;
380
+ }
381
+ ```
382
+
383
+ ### ConnectionState
384
+
385
+ 连接状态枚举。
386
+
387
+ ```typescript
388
+ enum ConnectionState {
389
+ DISCONNECTED = 'DISCONNECTED', // 已断开
390
+ CONNECTING = 'CONNECTING', // 连接中
391
+ CONNECTED = 'CONNECTED' // 已连接
392
+ }
393
+ ```
394
+
395
+ ### ToolCallErrorCode
396
+
397
+ 工具调用错误码。
398
+
399
+ ```typescript
400
+ enum ToolCallErrorCode {
401
+ INVALID_PARAMS = -32602, // 参数无效
402
+ TOOL_NOT_FOUND = -32001, // 工具不存在
403
+ SERVICE_UNAVAILABLE = -32002, // 服务不可用
404
+ TOOL_EXECUTION_ERROR = -32003, // 工具执行错误
405
+ TIMEOUT = -32008 // 超时
406
+ }
407
+ ```
408
+
409
+ ### ToolCallError
410
+
411
+ 工具调用错误类。
412
+
413
+ ```typescript
414
+ class ToolCallError extends Error {
415
+ constructor(
416
+ public code: ToolCallErrorCode,
417
+ message: string,
418
+ public data?: unknown
419
+ )
420
+ }
421
+ ```
422
+
423
+ ## 工具函数
424
+
425
+ ### sliceEndpoint()
426
+
427
+ 截断端点 URL 用于日志显示。
428
+
429
+ ```typescript
430
+ import { sliceEndpoint } from '@xiaozhi-client/endpoint';
431
+
432
+ const short = sliceEndpoint('ws://very-long-endpoint-url-here.example.com/endpoint');
433
+ // 返回: "ws://very-long-endpoint-u...e.com/endpoint"
434
+ ```
435
+
436
+ ### isValidEndpointUrl()
437
+
438
+ 验证端点 URL 格式。
439
+
440
+ ```typescript
441
+ import { isValidEndpointUrl } from '@xiaozhi-client/endpoint';
442
+
443
+ const valid = isValidEndpointUrl('ws://xiaozhi.example.com/endpoint');
444
+ ```
445
+
446
+ ### validateToolCallParams()
447
+
448
+ 验证工具调用参数。
449
+
450
+ ```typescript
451
+ import { validateToolCallParams } from '@xiaozhi-client/endpoint';
452
+
453
+ const params = validateToolCallParams({
454
+ name: 'my_tool',
455
+ arguments: { foo: 'bar' }
456
+ });
457
+ ```
458
+
459
+ ## 完整示例
460
+
461
+ ### 创建简单的小智客户端
462
+
463
+ ```typescript
464
+ import { Endpoint } from '@xiaozhi-client/endpoint';
465
+
466
+ // 使用示例
467
+ async function main() {
468
+ const endpoint = new Endpoint('ws://xiaozhi.example.com/endpoint', {
469
+ mcpServers: {
470
+ calculator: {
471
+ command: "node",
472
+ args: ["./calculator.js"]
473
+ }
474
+ }
475
+ });
476
+
477
+ try {
478
+ await endpoint.connect();
479
+ console.log('连接成功!');
480
+
481
+ const status = endpoint.getStatus();
482
+ console.log('可用工具:', status.availableTools);
483
+
484
+ // 监听连接状态变化...
485
+ } catch (error) {
486
+ console.error('连接失败:', error);
487
+ } finally {
488
+ endpoint.disconnect();
489
+ }
490
+ }
491
+
492
+ main();
493
+ ```
494
+
495
+ ### 多端点负载均衡示例
496
+
497
+ ```typescript
498
+ import { Endpoint, EndpointManager } from '@xiaozhi-client/endpoint';
499
+
500
+ // 创建多个端点
501
+ const endpoint1 = new Endpoint("wss://xiaozhi1.example.com/endpoint", {
502
+ mcpServers: {
503
+ calculator: {
504
+ command: "node",
505
+ args: ["./calculator.js"]
506
+ }
507
+ }
508
+ });
509
+
510
+ const endpoint2 = new Endpoint("wss://xiaozhi2.example.com/endpoint", {
511
+ mcpServers: {
512
+ calculator: {
513
+ command: "node",
514
+ args: ["./calculator.js"]
515
+ }
516
+ }
517
+ });
518
+
519
+ const endpoint3 = new Endpoint("wss://xiaozhi3.example.com/endpoint", {
520
+ mcpServers: {
521
+ calculator: {
522
+ command: "node",
523
+ args: ["./calculator.js"]
524
+ }
525
+ }
526
+ });
527
+
528
+ // 创建管理器
529
+ const manager = new EndpointManager();
530
+
531
+ // 添加所有端点
532
+ manager.addEndpoint(endpoint1);
533
+ manager.addEndpoint(endpoint2);
534
+ manager.addEndpoint(endpoint3);
535
+
536
+ // 连接所有端点
537
+ await manager.connect();
538
+
539
+ // 检查连接状态
540
+ const statuses = manager.getConnectionStatus();
541
+ statuses.forEach(status => {
542
+ console.log(`${status.endpoint}: ${status.connected ? '已连接' : '未连接'}`);
543
+ });
544
+
545
+ // 监听端点添加事件
546
+ manager.on('endpointAdded', (event) => {
547
+ console.log('端点已添加:', event.endpoint);
548
+ });
549
+
550
+ manager.on('endpointRemoved', (event) => {
551
+ console.log('端点已移除:', event.endpoint);
552
+ });
553
+ ```
554
+
555
+ ## 错误处理
556
+
557
+ ```typescript
558
+ import { Endpoint, ToolCallError, ToolCallErrorCode } from '@xiaozhi-client/endpoint';
559
+
560
+ const endpoint = new Endpoint('ws://xiaozhi.example.com/endpoint', {
561
+ mcpServers: {
562
+ calculator: {
563
+ command: "node",
564
+ args: ["./calculator.js"]
565
+ }
566
+ }
567
+ });
568
+
569
+ try {
570
+ await endpoint.connect();
571
+ } catch (error) {
572
+ if (error instanceof ToolCallError) {
573
+ switch (error.code) {
574
+ case ToolCallErrorCode.TIMEOUT:
575
+ console.error('连接超时');
576
+ break;
577
+ case ToolCallErrorCode.SERVICE_UNAVAILABLE:
578
+ console.error('服务不可用');
579
+ break;
580
+ default:
581
+ console.error('未知错误:', error.message);
582
+ }
583
+ }
584
+ }
585
+ ```
586
+
587
+ ## 常见问题
588
+
589
+ ### Q: 如何处理连接断开?
590
+
591
+ A: EndpointManager 不支持自动重连。你需要监听连接状态并手动调用 `reconnect()` 或 `reconnectAll()`。
592
+
593
+ ### Q: 如何自定义工具调用超时时间?
594
+
595
+ A: 目前工具调用超时固定为 30 秒。如需修改,可以在 `Endpoint` 类中调整 `toolCallTimeout` 属性。
596
+
597
+ ### Q: 支持哪些 WebSocket URL 格式?
598
+
599
+ A: 支持 `ws://` 和 `wss://` 协议的 URL。可以使用 `isValidEndpointUrl()` 函数验证 URL 格式。
600
+
601
+ ### Q: 如何监听端点状态变化?
602
+
603
+ A: EndpointManager 继承自 EventEmitter,可以监听 `endpointAdded` 和 `endpointRemoved` 事件。
604
+
605
+ ## 许可证
606
+
607
+ MIT
608
+
609
+ ## 相关链接
610
+
611
+ - [小智客户端](https://github.com/shenjingnan/xiaozhi-client)
612
+ - [MCP 协议规范](https://modelcontextprotocol.io/)