@kadi.build/core 0.0.1-alpha.1 → 0.0.1-alpha.11
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/README.md +361 -230
- package/dist/abilities/AbilityCache.d.ts +242 -0
- package/dist/abilities/AbilityCache.d.ts.map +1 -0
- package/dist/abilities/AbilityCache.js +285 -0
- package/dist/abilities/AbilityCache.js.map +1 -0
- package/dist/abilities/AbilityContext.d.ts +215 -0
- package/dist/abilities/AbilityContext.d.ts.map +1 -0
- package/dist/abilities/AbilityContext.js +36 -0
- package/dist/abilities/AbilityContext.js.map +1 -0
- package/dist/abilities/AbilityLoader.d.ts +203 -0
- package/dist/abilities/AbilityLoader.d.ts.map +1 -0
- package/dist/abilities/AbilityLoader.js +343 -0
- package/dist/abilities/AbilityLoader.js.map +1 -0
- package/dist/abilities/AbilityProxy.d.ts +496 -0
- package/dist/abilities/AbilityProxy.d.ts.map +1 -0
- package/dist/abilities/AbilityProxy.js +551 -0
- package/dist/abilities/AbilityProxy.js.map +1 -0
- package/dist/abilities/AbilityValidator.d.ts +172 -0
- package/dist/abilities/AbilityValidator.d.ts.map +1 -0
- package/dist/abilities/AbilityValidator.js +253 -0
- package/dist/abilities/AbilityValidator.js.map +1 -0
- package/dist/abilities/index.d.ts +26 -0
- package/dist/abilities/index.d.ts.map +1 -0
- package/dist/abilities/index.js +23 -0
- package/dist/abilities/index.js.map +1 -0
- package/dist/abilities/types.d.ts +223 -0
- package/dist/abilities/types.d.ts.map +1 -0
- package/dist/abilities/types.js +10 -0
- package/dist/abilities/types.js.map +1 -0
- package/dist/api/index.d.ts +92 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +124 -0
- package/dist/api/index.js.map +1 -0
- package/dist/broker/BrokerConnection.d.ts +253 -0
- package/dist/broker/BrokerConnection.d.ts.map +1 -0
- package/dist/broker/BrokerConnection.js +434 -0
- package/dist/broker/BrokerConnection.js.map +1 -0
- package/dist/broker/BrokerConnectionManager.d.ts +216 -0
- package/dist/broker/BrokerConnectionManager.d.ts.map +1 -0
- package/dist/broker/BrokerConnectionManager.js +305 -0
- package/dist/broker/BrokerConnectionManager.js.map +1 -0
- package/dist/broker/BrokerProtocol.d.ts +280 -0
- package/dist/broker/BrokerProtocol.d.ts.map +1 -0
- package/dist/broker/BrokerProtocol.js +466 -0
- package/dist/broker/BrokerProtocol.js.map +1 -0
- package/dist/broker/index.d.ts +9 -0
- package/dist/broker/index.d.ts.map +1 -0
- package/dist/broker/index.js +9 -0
- package/dist/broker/index.js.map +1 -0
- package/dist/client/KadiClient.d.ts +459 -0
- package/dist/client/KadiClient.d.ts.map +1 -0
- package/dist/client/KadiClient.js +902 -0
- package/dist/client/KadiClient.js.map +1 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +138 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +226 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/config/ConfigResolver.d.ts +135 -0
- package/dist/config/ConfigResolver.d.ts.map +1 -0
- package/dist/config/ConfigResolver.js +282 -0
- package/dist/config/ConfigResolver.js.map +1 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/index.js.map +1 -0
- package/dist/errors/index.d.ts +9 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +8 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/events/EventHub.d.ts +172 -0
- package/dist/events/EventHub.d.ts.map +1 -0
- package/dist/events/EventHub.js +333 -0
- package/dist/events/EventHub.js.map +1 -0
- package/dist/events/index.d.ts +7 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +7 -0
- package/dist/events/index.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/messages/index.d.ts +33 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +33 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/schemas/index.d.ts +22 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +27 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/kadi-extensions.d.ts +231 -0
- package/dist/schemas/kadi-extensions.d.ts.map +1 -0
- package/dist/schemas/kadi-extensions.js +14 -0
- package/dist/schemas/kadi-extensions.js.map +1 -0
- package/dist/schemas/mcp/schema.d.ts +1399 -0
- package/dist/schemas/mcp/schema.d.ts.map +1 -0
- package/dist/schemas/mcp/schema.js +53 -0
- package/dist/schemas/mcp/schema.js.map +1 -0
- package/dist/schemas/mcp/version.d.ts +37 -0
- package/dist/schemas/mcp/version.d.ts.map +1 -0
- package/dist/schemas/mcp/version.js +39 -0
- package/dist/schemas/mcp/version.js.map +1 -0
- package/dist/schemas/schema-builders.d.ts +178 -0
- package/dist/schemas/schema-builders.d.ts.map +1 -0
- package/dist/schemas/schema-builders.js +258 -0
- package/dist/schemas/schema-builders.js.map +1 -0
- package/dist/schemas/zod-helpers.d.ts +129 -0
- package/dist/schemas/zod-helpers.d.ts.map +1 -0
- package/dist/schemas/zod-helpers.js +225 -0
- package/dist/schemas/zod-helpers.js.map +1 -0
- package/dist/schemas/zod-to-json-schema.d.ts +159 -0
- package/dist/schemas/zod-to-json-schema.d.ts.map +1 -0
- package/dist/schemas/zod-to-json-schema.js +154 -0
- package/dist/schemas/zod-to-json-schema.js.map +1 -0
- package/dist/tools/ToolRegistry.d.ts +256 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/tools/ToolRegistry.js +340 -0
- package/dist/tools/ToolRegistry.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/transports/BrokerTransport.d.ts +151 -0
- package/dist/transports/BrokerTransport.d.ts.map +1 -0
- package/dist/transports/BrokerTransport.js +261 -0
- package/dist/transports/BrokerTransport.js.map +1 -0
- package/dist/transports/NativeTransport.d.ts +178 -0
- package/dist/transports/NativeTransport.d.ts.map +1 -0
- package/dist/transports/NativeTransport.js +397 -0
- package/dist/transports/NativeTransport.js.map +1 -0
- package/dist/transports/StdioTransport.d.ts +250 -0
- package/dist/transports/StdioTransport.d.ts.map +1 -0
- package/dist/transports/StdioTransport.js +487 -0
- package/dist/transports/StdioTransport.js.map +1 -0
- package/dist/transports/index.d.ts +10 -0
- package/dist/transports/index.d.ts.map +1 -0
- package/dist/transports/index.js +9 -0
- package/dist/transports/index.js.map +1 -0
- package/dist/types/broker.d.ts +279 -0
- package/dist/types/broker.d.ts.map +1 -0
- package/dist/types/broker.js +19 -0
- package/dist/types/broker.js.map +1 -0
- package/dist/types/config.d.ts +325 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +17 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/errors.d.ts +178 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +165 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/events.d.ts +210 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +8 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +34 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/protocol.d.ts +48 -0
- package/dist/types/protocol.d.ts.map +1 -0
- package/dist/types/protocol.js +11 -0
- package/dist/types/protocol.js.map +1 -0
- package/dist/types/tools.d.ts +67 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +16 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/transport.d.ts +250 -0
- package/dist/types/transport.d.ts.map +1 -0
- package/dist/types/transport.js +18 -0
- package/dist/types/transport.js.map +1 -0
- package/dist/types/zod-tools.d.ts +198 -0
- package/dist/types/zod-tools.d.ts.map +1 -0
- package/dist/types/zod-tools.js +14 -0
- package/dist/types/zod-tools.js.map +1 -0
- package/dist/utils/StdioMessageReader.d.ts +122 -0
- package/dist/utils/StdioMessageReader.d.ts.map +1 -0
- package/dist/utils/StdioMessageReader.js +209 -0
- package/dist/utils/StdioMessageReader.js.map +1 -0
- package/dist/utils/StdioMessageWriter.d.ts +104 -0
- package/dist/utils/StdioMessageWriter.d.ts.map +1 -0
- package/dist/utils/StdioMessageWriter.js +162 -0
- package/dist/utils/StdioMessageWriter.js.map +1 -0
- package/dist/validation/SchemaValidator.d.ts +208 -0
- package/dist/validation/SchemaValidator.d.ts.map +1 -0
- package/dist/validation/SchemaValidator.js +411 -0
- package/dist/validation/SchemaValidator.js.map +1 -0
- package/dist/validation/index.d.ts +11 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +10 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +70 -5
- package/agent.json +0 -18
- package/broker.js +0 -214
- package/index.js +0 -370
- package/ipc.js +0 -220
- package/ipcInterfaces/pythonAbilityIPC.py +0 -177
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Broker Connection
|
|
3
|
+
*
|
|
4
|
+
* Wraps a single WebSocket connection to a KADI broker.
|
|
5
|
+
* Handles connection lifecycle, message sending/receiving, and state management.
|
|
6
|
+
*
|
|
7
|
+
* @module broker/BrokerConnection
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from 'events';
|
|
10
|
+
import type { BrokerConfig, JsonRpcRequest, JsonRpcResponse, JsonRpcNotification } from '../types/index.js';
|
|
11
|
+
import { ConnectionState } from '../types/index.js';
|
|
12
|
+
/**
|
|
13
|
+
* Broker Connection Events
|
|
14
|
+
*/
|
|
15
|
+
export interface BrokerConnectionEvents {
|
|
16
|
+
/**
|
|
17
|
+
* Emitted when connection is established
|
|
18
|
+
*/
|
|
19
|
+
connected: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Emitted when connection is closed
|
|
22
|
+
*/
|
|
23
|
+
disconnected: (code: number, reason: string) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Emitted when an error occurs
|
|
26
|
+
*/
|
|
27
|
+
error: (error: Error) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Emitted when a message is received
|
|
30
|
+
*/
|
|
31
|
+
message: (message: JsonRpcResponse | JsonRpcNotification) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Emitted when connection state changes
|
|
34
|
+
*/
|
|
35
|
+
stateChange: (oldState: ConnectionState, newState: ConnectionState) => void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Broker Connection
|
|
39
|
+
*
|
|
40
|
+
* Manages a single WebSocket connection to a broker.
|
|
41
|
+
* Handles low-level connection lifecycle and message framing.
|
|
42
|
+
*
|
|
43
|
+
* Does NOT handle:
|
|
44
|
+
* - Protocol logic (handshake, auth) - that's BrokerProtocol's job
|
|
45
|
+
* - Multiple connections - that's BrokerConnectionManager's job
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const connection = new BrokerConnection({
|
|
50
|
+
* url: 'ws://localhost:8080',
|
|
51
|
+
* name: 'local',
|
|
52
|
+
* connectionTimeout: 10000
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* connection.on('connected', () => {
|
|
56
|
+
* console.log('Connected to broker');
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* connection.on('message', (message) => {
|
|
60
|
+
* console.log('Received:', message);
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* await connection.connect();
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare class BrokerConnection extends EventEmitter {
|
|
67
|
+
/**
|
|
68
|
+
* Broker configuration
|
|
69
|
+
*/
|
|
70
|
+
private readonly config;
|
|
71
|
+
/**
|
|
72
|
+
* WebSocket instance
|
|
73
|
+
*/
|
|
74
|
+
private ws;
|
|
75
|
+
/**
|
|
76
|
+
* Current connection state
|
|
77
|
+
*/
|
|
78
|
+
private _state;
|
|
79
|
+
/**
|
|
80
|
+
* Assigned agent ID (set after handshake)
|
|
81
|
+
*/
|
|
82
|
+
private _agentId;
|
|
83
|
+
/**
|
|
84
|
+
* Heartbeat timer
|
|
85
|
+
*/
|
|
86
|
+
private heartbeatTimer;
|
|
87
|
+
/**
|
|
88
|
+
* Connection timestamp
|
|
89
|
+
*/
|
|
90
|
+
private _connectedAt;
|
|
91
|
+
/**
|
|
92
|
+
* Last heartbeat timestamp
|
|
93
|
+
*/
|
|
94
|
+
private _lastHeartbeat;
|
|
95
|
+
/**
|
|
96
|
+
* Pending requests (for matching responses)
|
|
97
|
+
*/
|
|
98
|
+
private pendingRequests;
|
|
99
|
+
/**
|
|
100
|
+
* Request ID counter
|
|
101
|
+
*/
|
|
102
|
+
private requestIdCounter;
|
|
103
|
+
/**
|
|
104
|
+
* Create a new BrokerConnection
|
|
105
|
+
*
|
|
106
|
+
* @param config - Broker configuration
|
|
107
|
+
*/
|
|
108
|
+
constructor(config: BrokerConfig);
|
|
109
|
+
/**
|
|
110
|
+
* Connect to the broker
|
|
111
|
+
*
|
|
112
|
+
* @throws {KadiError} If connection fails
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* await connection.connect();
|
|
117
|
+
* console.log('Connected!');
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
connect(): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Disconnect from the broker
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* await connection.disconnect();
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
disconnect(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Send a JSON-RPC request and wait for response
|
|
132
|
+
*
|
|
133
|
+
* @template T - Response result type
|
|
134
|
+
* @param request - JSON-RPC request
|
|
135
|
+
* @returns Promise resolving to the response result
|
|
136
|
+
*
|
|
137
|
+
* @throws {KadiError} If request fails or times out
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const result = await connection.sendRequest({
|
|
142
|
+
* jsonrpc: '2.0',
|
|
143
|
+
* method: 'kadi.handshake',
|
|
144
|
+
* params: { name: 'my-agent' },
|
|
145
|
+
* id: 1
|
|
146
|
+
* });
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
sendRequest<T = unknown>(request: JsonRpcRequest): Promise<T>;
|
|
150
|
+
/**
|
|
151
|
+
* Send a JSON-RPC notification (no response expected)
|
|
152
|
+
*
|
|
153
|
+
* @param notification - JSON-RPC notification
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* connection.sendNotification({
|
|
158
|
+
* jsonrpc: '2.0',
|
|
159
|
+
* method: 'kadi.heartbeat',
|
|
160
|
+
* params: { timestamp: Date.now() }
|
|
161
|
+
* });
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
sendNotification(notification: JsonRpcNotification): void;
|
|
165
|
+
/**
|
|
166
|
+
* Send a tool result back to broker as JSON-RPC response
|
|
167
|
+
*
|
|
168
|
+
* Used when this client acts as a tool provider and needs to respond to invocations.
|
|
169
|
+
* The requestId must match the incoming request's id field for proper routing.
|
|
170
|
+
*
|
|
171
|
+
* @param requestId - Request ID to respond to (CRITICAL: must match incoming request id)
|
|
172
|
+
* @param result - Result data to send back
|
|
173
|
+
*/
|
|
174
|
+
sendResponse(requestId: string | number | undefined, result: unknown): void;
|
|
175
|
+
/**
|
|
176
|
+
* Send a tool error back to broker as JSON-RPC error response
|
|
177
|
+
*
|
|
178
|
+
* Used when tool execution fails and we need to report the error back.
|
|
179
|
+
* The requestId must match the incoming request's id field for proper routing.
|
|
180
|
+
*
|
|
181
|
+
* @param requestId - Request ID to respond to (CRITICAL: must match incoming request id)
|
|
182
|
+
* @param code - Error code (e.g., ErrorCode.TOOL_NOT_FOUND)
|
|
183
|
+
* @param message - Human-readable error message
|
|
184
|
+
* @param data - Optional additional error context
|
|
185
|
+
*/
|
|
186
|
+
sendError(requestId: string | number | undefined, code: string, message: string, data?: Record<string, unknown>): void;
|
|
187
|
+
/**
|
|
188
|
+
* Send raw data to broker
|
|
189
|
+
*
|
|
190
|
+
* @param data - Data to send (request, response, or notification)
|
|
191
|
+
*/
|
|
192
|
+
private send;
|
|
193
|
+
/**
|
|
194
|
+
* Handle incoming WebSocket message
|
|
195
|
+
*
|
|
196
|
+
* @param data - Raw message data
|
|
197
|
+
*/
|
|
198
|
+
private handleMessage;
|
|
199
|
+
/**
|
|
200
|
+
* Handle WebSocket close event
|
|
201
|
+
*
|
|
202
|
+
* @param code - Close code
|
|
203
|
+
* @param reason - Close reason
|
|
204
|
+
*/
|
|
205
|
+
private handleClose;
|
|
206
|
+
/**
|
|
207
|
+
* Setup heartbeat timer
|
|
208
|
+
*/
|
|
209
|
+
private setupHeartbeat;
|
|
210
|
+
/**
|
|
211
|
+
* Cleanup connection resources
|
|
212
|
+
*/
|
|
213
|
+
private cleanup;
|
|
214
|
+
/**
|
|
215
|
+
* Set connection state and emit event
|
|
216
|
+
*
|
|
217
|
+
* @param newState - New state
|
|
218
|
+
*/
|
|
219
|
+
private setState;
|
|
220
|
+
/**
|
|
221
|
+
* Get broker name
|
|
222
|
+
*/
|
|
223
|
+
get name(): string;
|
|
224
|
+
/**
|
|
225
|
+
* Get broker URL
|
|
226
|
+
*/
|
|
227
|
+
get url(): string;
|
|
228
|
+
/**
|
|
229
|
+
* Get current connection state
|
|
230
|
+
*/
|
|
231
|
+
get state(): ConnectionState;
|
|
232
|
+
/**
|
|
233
|
+
* Check if connected
|
|
234
|
+
*/
|
|
235
|
+
get isConnected(): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Get assigned agent ID
|
|
238
|
+
*/
|
|
239
|
+
get agentId(): string | null;
|
|
240
|
+
/**
|
|
241
|
+
* Set agent ID (called after handshake)
|
|
242
|
+
*/
|
|
243
|
+
set agentId(id: string | null);
|
|
244
|
+
/**
|
|
245
|
+
* Get connection timestamp
|
|
246
|
+
*/
|
|
247
|
+
get connectedAt(): number | null;
|
|
248
|
+
/**
|
|
249
|
+
* Get last heartbeat timestamp
|
|
250
|
+
*/
|
|
251
|
+
get lastHeartbeat(): number | null;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=BrokerConnection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrokerConnection.d.ts","sourceRoot":"","sources":["../../src/broker/BrokerConnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Broker Connection
|
|
3
|
+
*
|
|
4
|
+
* Wraps a single WebSocket connection to a KADI broker.
|
|
5
|
+
* Handles connection lifecycle, message sending/receiving, and state management.
|
|
6
|
+
*
|
|
7
|
+
* @module broker/BrokerConnection
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from 'events';
|
|
10
|
+
import WebSocket from 'ws';
|
|
11
|
+
import { ConnectionState } from '../types/index.js';
|
|
12
|
+
import { KadiError, ErrorCode } from '../types/index.js';
|
|
13
|
+
/**
|
|
14
|
+
* Broker Connection
|
|
15
|
+
*
|
|
16
|
+
* Manages a single WebSocket connection to a broker.
|
|
17
|
+
* Handles low-level connection lifecycle and message framing.
|
|
18
|
+
*
|
|
19
|
+
* Does NOT handle:
|
|
20
|
+
* - Protocol logic (handshake, auth) - that's BrokerProtocol's job
|
|
21
|
+
* - Multiple connections - that's BrokerConnectionManager's job
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const connection = new BrokerConnection({
|
|
26
|
+
* url: 'ws://localhost:8080',
|
|
27
|
+
* name: 'local',
|
|
28
|
+
* connectionTimeout: 10000
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* connection.on('connected', () => {
|
|
32
|
+
* console.log('Connected to broker');
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* connection.on('message', (message) => {
|
|
36
|
+
* console.log('Received:', message);
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* await connection.connect();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export class BrokerConnection extends EventEmitter {
|
|
43
|
+
/**
|
|
44
|
+
* Broker configuration
|
|
45
|
+
*/
|
|
46
|
+
config;
|
|
47
|
+
/**
|
|
48
|
+
* WebSocket instance
|
|
49
|
+
*/
|
|
50
|
+
ws = null;
|
|
51
|
+
/**
|
|
52
|
+
* Current connection state
|
|
53
|
+
*/
|
|
54
|
+
_state = ConnectionState.DISCONNECTED;
|
|
55
|
+
/**
|
|
56
|
+
* Assigned agent ID (set after handshake)
|
|
57
|
+
*/
|
|
58
|
+
_agentId = null;
|
|
59
|
+
/**
|
|
60
|
+
* Heartbeat timer
|
|
61
|
+
*/
|
|
62
|
+
heartbeatTimer = null;
|
|
63
|
+
/**
|
|
64
|
+
* Connection timestamp
|
|
65
|
+
*/
|
|
66
|
+
_connectedAt = null;
|
|
67
|
+
/**
|
|
68
|
+
* Last heartbeat timestamp
|
|
69
|
+
*/
|
|
70
|
+
_lastHeartbeat = null;
|
|
71
|
+
/**
|
|
72
|
+
* Pending requests (for matching responses)
|
|
73
|
+
*/
|
|
74
|
+
pendingRequests = new Map();
|
|
75
|
+
/**
|
|
76
|
+
* Request ID counter
|
|
77
|
+
*/
|
|
78
|
+
requestIdCounter = 0;
|
|
79
|
+
/**
|
|
80
|
+
* Create a new BrokerConnection
|
|
81
|
+
*
|
|
82
|
+
* @param config - Broker configuration
|
|
83
|
+
*/
|
|
84
|
+
constructor(config) {
|
|
85
|
+
super();
|
|
86
|
+
this.config = {
|
|
87
|
+
...config,
|
|
88
|
+
connectionTimeout: config.connectionTimeout ?? 10000,
|
|
89
|
+
requestTimeout: config.requestTimeout ?? 30000,
|
|
90
|
+
heartbeatInterval: config.heartbeatInterval ?? 30000,
|
|
91
|
+
autoReconnect: config.autoReconnect ?? true,
|
|
92
|
+
maxReconnectAttempts: config.maxReconnectAttempts ?? 5
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Connect to the broker
|
|
97
|
+
*
|
|
98
|
+
* @throws {KadiError} If connection fails
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* await connection.connect();
|
|
103
|
+
* console.log('Connected!');
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
async connect() {
|
|
107
|
+
if (this._state !== ConnectionState.DISCONNECTED) {
|
|
108
|
+
throw new KadiError('Connection already in progress or established', ErrorCode.CONNECTION_FAILED, 400, { currentState: this._state, broker: this.config.name });
|
|
109
|
+
}
|
|
110
|
+
this.setState(ConnectionState.CONNECTING);
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
const timeout = setTimeout(() => {
|
|
113
|
+
this.cleanup();
|
|
114
|
+
reject(new KadiError(`Connection timeout after ${this.config.connectionTimeout}ms`, ErrorCode.CONNECTION_TIMEOUT, 408, { broker: this.config.name, url: this.config.url }));
|
|
115
|
+
}, this.config.connectionTimeout);
|
|
116
|
+
try {
|
|
117
|
+
this.ws = new WebSocket(this.config.url);
|
|
118
|
+
this.ws.on('open', () => {
|
|
119
|
+
clearTimeout(timeout);
|
|
120
|
+
this._connectedAt = Date.now();
|
|
121
|
+
this.setState(ConnectionState.CONNECTED);
|
|
122
|
+
this.setupHeartbeat();
|
|
123
|
+
this.emit('connected');
|
|
124
|
+
resolve();
|
|
125
|
+
});
|
|
126
|
+
this.ws.on('error', (error) => {
|
|
127
|
+
clearTimeout(timeout);
|
|
128
|
+
this.emit('error', error);
|
|
129
|
+
reject(new KadiError(`WebSocket error: ${error.message}`, ErrorCode.CONNECTION_FAILED, 500, { broker: this.config.name, url: this.config.url, originalError: error.message }));
|
|
130
|
+
});
|
|
131
|
+
this.ws.on('close', (code, reason) => {
|
|
132
|
+
clearTimeout(timeout);
|
|
133
|
+
this.handleClose(code, reason.toString());
|
|
134
|
+
});
|
|
135
|
+
this.ws.on('message', (data) => {
|
|
136
|
+
this.handleMessage(data);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
clearTimeout(timeout);
|
|
141
|
+
this.cleanup();
|
|
142
|
+
reject(KadiError.from(error, ErrorCode.CONNECTION_FAILED));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Disconnect from the broker
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* await connection.disconnect();
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
async disconnect() {
|
|
155
|
+
this.cleanup();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Send a JSON-RPC request and wait for response
|
|
159
|
+
*
|
|
160
|
+
* @template T - Response result type
|
|
161
|
+
* @param request - JSON-RPC request
|
|
162
|
+
* @returns Promise resolving to the response result
|
|
163
|
+
*
|
|
164
|
+
* @throws {KadiError} If request fails or times out
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* const result = await connection.sendRequest({
|
|
169
|
+
* jsonrpc: '2.0',
|
|
170
|
+
* method: 'kadi.handshake',
|
|
171
|
+
* params: { name: 'my-agent' },
|
|
172
|
+
* id: 1
|
|
173
|
+
* });
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
async sendRequest(request) {
|
|
177
|
+
if (!this.isConnected) {
|
|
178
|
+
throw new KadiError('Not connected to broker', ErrorCode.BROKER_NOT_CONNECTED, 503, { broker: this.config.name });
|
|
179
|
+
}
|
|
180
|
+
// Generate ID if not provided
|
|
181
|
+
if (request.id === undefined) {
|
|
182
|
+
request.id = ++this.requestIdCounter;
|
|
183
|
+
}
|
|
184
|
+
return new Promise((resolve, reject) => {
|
|
185
|
+
const timeout = setTimeout(() => {
|
|
186
|
+
this.pendingRequests.delete(request.id);
|
|
187
|
+
reject(new KadiError(`Request timeout after ${this.config.requestTimeout}ms`, ErrorCode.BROKER_TIMEOUT, 408, { broker: this.config.name, method: request.method, requestId: request.id }));
|
|
188
|
+
}, this.config.requestTimeout);
|
|
189
|
+
this.pendingRequests.set(request.id, {
|
|
190
|
+
id: request.id,
|
|
191
|
+
resolve: resolve,
|
|
192
|
+
reject,
|
|
193
|
+
timeout,
|
|
194
|
+
timestamp: Date.now()
|
|
195
|
+
});
|
|
196
|
+
this.send(request);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Send a JSON-RPC notification (no response expected)
|
|
201
|
+
*
|
|
202
|
+
* @param notification - JSON-RPC notification
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* connection.sendNotification({
|
|
207
|
+
* jsonrpc: '2.0',
|
|
208
|
+
* method: 'kadi.heartbeat',
|
|
209
|
+
* params: { timestamp: Date.now() }
|
|
210
|
+
* });
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
sendNotification(notification) {
|
|
214
|
+
if (!this.isConnected) {
|
|
215
|
+
throw new KadiError('Not connected to broker', ErrorCode.BROKER_NOT_CONNECTED, 503, { broker: this.config.name });
|
|
216
|
+
}
|
|
217
|
+
this.send(notification);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Send a tool result back to broker as JSON-RPC response
|
|
221
|
+
*
|
|
222
|
+
* Used when this client acts as a tool provider and needs to respond to invocations.
|
|
223
|
+
* The requestId must match the incoming request's id field for proper routing.
|
|
224
|
+
*
|
|
225
|
+
* @param requestId - Request ID to respond to (CRITICAL: must match incoming request id)
|
|
226
|
+
* @param result - Result data to send back
|
|
227
|
+
*/
|
|
228
|
+
sendResponse(requestId, result) {
|
|
229
|
+
if (!requestId) {
|
|
230
|
+
// No ID = broker can't route response, so silently drop
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (!this.isConnected) {
|
|
234
|
+
throw new KadiError('Not connected to broker', ErrorCode.BROKER_NOT_CONNECTED, 503, { broker: this.config.name });
|
|
235
|
+
}
|
|
236
|
+
// Send proper JSON-RPC response with matching id
|
|
237
|
+
const response = {
|
|
238
|
+
jsonrpc: '2.0',
|
|
239
|
+
result,
|
|
240
|
+
id: requestId
|
|
241
|
+
};
|
|
242
|
+
this.send(response);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Send a tool error back to broker as JSON-RPC error response
|
|
246
|
+
*
|
|
247
|
+
* Used when tool execution fails and we need to report the error back.
|
|
248
|
+
* The requestId must match the incoming request's id field for proper routing.
|
|
249
|
+
*
|
|
250
|
+
* @param requestId - Request ID to respond to (CRITICAL: must match incoming request id)
|
|
251
|
+
* @param code - Error code (e.g., ErrorCode.TOOL_NOT_FOUND)
|
|
252
|
+
* @param message - Human-readable error message
|
|
253
|
+
* @param data - Optional additional error context
|
|
254
|
+
*/
|
|
255
|
+
sendError(requestId, code, message, data) {
|
|
256
|
+
if (!requestId) {
|
|
257
|
+
// No ID = broker can't route error, so silently drop
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (!this.isConnected) {
|
|
261
|
+
throw new KadiError('Not connected to broker', ErrorCode.BROKER_NOT_CONNECTED, 503, { broker: this.config.name });
|
|
262
|
+
}
|
|
263
|
+
// Send proper JSON-RPC error response with matching id
|
|
264
|
+
const response = {
|
|
265
|
+
jsonrpc: '2.0',
|
|
266
|
+
error: {
|
|
267
|
+
code: -32000, // Application error code range
|
|
268
|
+
message: `${code}: ${message}`,
|
|
269
|
+
data
|
|
270
|
+
},
|
|
271
|
+
id: requestId
|
|
272
|
+
};
|
|
273
|
+
this.send(response);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Send raw data to broker
|
|
277
|
+
*
|
|
278
|
+
* @param data - Data to send (request, response, or notification)
|
|
279
|
+
*/
|
|
280
|
+
send(data) {
|
|
281
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
282
|
+
throw new KadiError('WebSocket not open', ErrorCode.BROKER_NOT_CONNECTED, 503, { broker: this.config.name });
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
const message = JSON.stringify(data);
|
|
286
|
+
this.ws.send(message);
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
throw new KadiError(`Failed to send message: ${error instanceof Error ? error.message : String(error)}`, ErrorCode.TRANSPORT_SEND_FAILED, 500, { broker: this.config.name });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Handle incoming WebSocket message
|
|
294
|
+
*
|
|
295
|
+
* @param data - Raw message data
|
|
296
|
+
*/
|
|
297
|
+
handleMessage(data) {
|
|
298
|
+
try {
|
|
299
|
+
const message = JSON.parse(data.toString());
|
|
300
|
+
// Check if this is a response to a pending request
|
|
301
|
+
if ('id' in message && message.id !== undefined) {
|
|
302
|
+
const pending = this.pendingRequests.get(message.id);
|
|
303
|
+
if (pending) {
|
|
304
|
+
clearTimeout(pending.timeout);
|
|
305
|
+
this.pendingRequests.delete(message.id);
|
|
306
|
+
const response = message;
|
|
307
|
+
if (response.error) {
|
|
308
|
+
pending.reject(new KadiError(response.error.message, ErrorCode.BROKER_RESPONSE_ERROR, 500, { broker: this.config.name, errorCode: response.error.code, errorData: response.error.data }));
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
pending.resolve(response.result);
|
|
312
|
+
}
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// Emit as general message (notification or unsolicited response)
|
|
317
|
+
this.emit('message', message);
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
this.emit('error', new KadiError(`Failed to parse message: ${error instanceof Error ? error.message : String(error)}`, ErrorCode.INVALID_MESSAGE_FORMAT, 400, { broker: this.config.name }));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Handle WebSocket close event
|
|
325
|
+
*
|
|
326
|
+
* @param code - Close code
|
|
327
|
+
* @param reason - Close reason
|
|
328
|
+
*/
|
|
329
|
+
handleClose(code, reason) {
|
|
330
|
+
this.setState(ConnectionState.DISCONNECTED);
|
|
331
|
+
this.cleanup();
|
|
332
|
+
this.emit('disconnected', code, reason);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Setup heartbeat timer
|
|
336
|
+
*/
|
|
337
|
+
setupHeartbeat() {
|
|
338
|
+
if (this.heartbeatTimer) {
|
|
339
|
+
clearInterval(this.heartbeatTimer);
|
|
340
|
+
}
|
|
341
|
+
if (this.config.heartbeatInterval && this.config.heartbeatInterval > 0) {
|
|
342
|
+
this.heartbeatTimer = setInterval(() => {
|
|
343
|
+
this._lastHeartbeat = Date.now();
|
|
344
|
+
// Heartbeat logic handled by BrokerProtocol
|
|
345
|
+
}, this.config.heartbeatInterval);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Cleanup connection resources
|
|
350
|
+
*/
|
|
351
|
+
cleanup() {
|
|
352
|
+
if (this.heartbeatTimer) {
|
|
353
|
+
clearInterval(this.heartbeatTimer);
|
|
354
|
+
this.heartbeatTimer = null;
|
|
355
|
+
}
|
|
356
|
+
// Reject all pending requests
|
|
357
|
+
for (const [id, pending] of this.pendingRequests) {
|
|
358
|
+
clearTimeout(pending.timeout);
|
|
359
|
+
pending.reject(new KadiError('Connection closed', ErrorCode.CONNECTION_CLOSED, 503, { broker: this.config.name, requestId: id }));
|
|
360
|
+
}
|
|
361
|
+
this.pendingRequests.clear();
|
|
362
|
+
if (this.ws) {
|
|
363
|
+
this.ws.removeAllListeners();
|
|
364
|
+
if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {
|
|
365
|
+
this.ws.close();
|
|
366
|
+
}
|
|
367
|
+
this.ws = null;
|
|
368
|
+
}
|
|
369
|
+
this._connectedAt = null;
|
|
370
|
+
this._lastHeartbeat = null;
|
|
371
|
+
this.setState(ConnectionState.DISCONNECTED);
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Set connection state and emit event
|
|
375
|
+
*
|
|
376
|
+
* @param newState - New state
|
|
377
|
+
*/
|
|
378
|
+
setState(newState) {
|
|
379
|
+
const oldState = this._state;
|
|
380
|
+
if (oldState !== newState) {
|
|
381
|
+
this._state = newState;
|
|
382
|
+
this.emit('stateChange', oldState, newState);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Get broker name
|
|
387
|
+
*/
|
|
388
|
+
get name() {
|
|
389
|
+
return this.config.name;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Get broker URL
|
|
393
|
+
*/
|
|
394
|
+
get url() {
|
|
395
|
+
return this.config.url;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Get current connection state
|
|
399
|
+
*/
|
|
400
|
+
get state() {
|
|
401
|
+
return this._state;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Check if connected
|
|
405
|
+
*/
|
|
406
|
+
get isConnected() {
|
|
407
|
+
return this._state === ConnectionState.CONNECTED || this._state === ConnectionState.AUTHENTICATED;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Get assigned agent ID
|
|
411
|
+
*/
|
|
412
|
+
get agentId() {
|
|
413
|
+
return this._agentId;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Set agent ID (called after handshake)
|
|
417
|
+
*/
|
|
418
|
+
set agentId(id) {
|
|
419
|
+
this._agentId = id;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Get connection timestamp
|
|
423
|
+
*/
|
|
424
|
+
get connectedAt() {
|
|
425
|
+
return this._connectedAt;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Get last heartbeat timestamp
|
|
429
|
+
*/
|
|
430
|
+
get lastHeartbeat() {
|
|
431
|
+
return this._lastHeartbeat;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
//# sourceMappingURL=BrokerConnection.js.map
|