@xiaozhi-client/endpoint 1.9.7-beta.10
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 +21 -0
- package/README.md +612 -0
- package/dist/index.d.ts +551 -0
- package/dist/index.js +801 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
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/)
|