@agentxjs/core 1.9.10-dev → 2.0.0
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 +342 -0
- package/dist/RpcClient-BcJ_zAGu.d.ts +304 -0
- package/dist/agent/engine/internal/index.d.ts +20 -15
- package/dist/agent/engine/internal/index.js +1 -2
- package/dist/agent/engine/mealy/index.js +0 -1
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +15 -15
- package/dist/agent/types/index.d.ts +4 -4
- package/dist/agent/types/index.js +1 -2
- package/dist/bash/index.d.ts +29 -0
- package/dist/bash/index.js +7 -0
- package/dist/{bus-uF1DM2ox.d.ts → bus-C9FLWIu8.d.ts} +3 -1
- package/dist/{chunk-K6WXQ2RW.js → chunk-23UUBQXR.js} +1 -2
- package/dist/chunk-23UUBQXR.js.map +1 -0
- package/dist/chunk-BHOD5PKR.js +55 -0
- package/dist/chunk-BHOD5PKR.js.map +1 -0
- package/dist/{chunk-I7GYR3MN.js → chunk-DEAR6N3O.js} +77 -91
- package/dist/chunk-DEAR6N3O.js.map +1 -0
- package/dist/chunk-FI7WQFGV.js +37 -0
- package/dist/chunk-FI7WQFGV.js.map +1 -0
- package/dist/{chunk-AT5P47YA.js → chunk-JTKCV7IS.js} +9 -9
- package/dist/chunk-JTKCV7IS.js.map +1 -0
- package/dist/{chunk-E5FPOAPO.js → chunk-LTVNPHST.js} +1 -1
- package/dist/chunk-LTVNPHST.js.map +1 -0
- package/dist/chunk-SKS7S2RY.js +1 -0
- package/dist/common/logger/index.js +0 -2
- package/dist/common/logger/index.js.map +1 -1
- package/dist/container/index.d.ts +3 -4
- package/dist/container/index.js +0 -2
- package/dist/container/index.js.map +1 -1
- package/dist/driver/index.d.ts +2 -310
- package/dist/event/index.d.ts +4 -4
- package/dist/event/index.js +1 -2
- package/dist/event/types/index.d.ts +4 -10
- package/dist/event/types/index.js +1 -2
- package/dist/{event-CDuTzs__.d.ts → event-DNWOBSBO.d.ts} +3 -4
- package/dist/image/index.d.ts +9 -5
- package/dist/image/index.js +5 -2
- package/dist/image/index.js.map +1 -1
- package/dist/index-CuS1i5V-.d.ts +609 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +16 -16
- package/dist/{message-BMrMm1pq.d.ts → message-03TJzvIX.d.ts} +10 -33
- package/dist/mq/index.js +0 -2
- package/dist/mq/index.js.map +1 -1
- package/dist/network/index.d.ts +3 -291
- package/dist/network/index.js +3 -14
- package/dist/network/index.js.map +1 -1
- package/dist/persistence/index.d.ts +2 -155
- package/dist/platform/index.d.ts +76 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/runtime/index.d.ts +26 -59
- package/dist/runtime/index.js +117 -33
- package/dist/runtime/index.js.map +1 -1
- package/dist/session/index.d.ts +4 -52
- package/dist/session/index.js +4 -51
- package/dist/session/index.js.map +1 -1
- package/dist/types-aE74Eo6G.d.ts +90 -0
- package/package.json +10 -5
- package/src/agent/__tests__/engine/internal/messageAssemblerProcessor.test.ts +291 -87
- package/src/agent/__tests__/engine/internal/turnTrackerProcessor.test.ts +56 -75
- package/src/agent/engine/MealyMachine.ts +1 -1
- package/src/agent/engine/internal/messageAssemblerProcessor.ts +99 -114
- package/src/agent/engine/internal/turnTrackerProcessor.ts +23 -27
- package/src/agent/types/event.ts +0 -4
- package/src/agent/types/index.ts +1 -3
- package/src/agent/types/message.ts +9 -43
- package/src/bash/index.ts +21 -0
- package/src/bash/tool.ts +57 -0
- package/src/bash/types.ts +108 -0
- package/src/driver/index.ts +1 -0
- package/src/driver/types.ts +122 -4
- package/src/event/__tests__/EventBus.test.ts +1 -1
- package/src/event/types/agent.ts +0 -11
- package/src/event/types/command.ts +3 -1
- package/src/image/Image.ts +11 -1
- package/src/image/types.ts +8 -2
- package/src/network/RpcClient.ts +21 -20
- package/src/network/index.ts +1 -1
- package/src/persistence/types.ts +5 -2
- package/src/platform/index.ts +21 -0
- package/src/platform/types.ts +84 -0
- package/src/runtime/AgentXRuntime.ts +184 -57
- package/src/runtime/__tests__/AgentXRuntime.test.ts +343 -0
- package/src/runtime/index.ts +7 -19
- package/src/runtime/types.ts +10 -62
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-AT5P47YA.js.map +0 -1
- package/dist/chunk-E5FPOAPO.js.map +0 -1
- package/dist/chunk-I7GYR3MN.js.map +0 -1
- package/dist/chunk-K6WXQ2RW.js.map +0 -1
- package/dist/workspace/index.d.ts +0 -111
- package/dist/wrapper-Y3UTVU2E.js +0 -3635
- package/dist/wrapper-Y3UTVU2E.js.map +0 -1
- package/src/workspace/index.ts +0 -27
- package/src/workspace/types.ts +0 -131
- /package/dist/{workspace → bash}/index.js.map +0 -0
- /package/dist/{chunk-7D4SUZUM.js.map → chunk-SKS7S2RY.js.map} +0 -0
- /package/dist/{workspace → platform}/index.js +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This file defines:
|
|
5
5
|
* - Content Parts: TextPart, ThinkingPart, ImagePart, FilePart, ToolCallPart, ToolResultPart
|
|
6
|
-
* - Message Types: UserMessage, AssistantMessage,
|
|
6
|
+
* - Message Types: UserMessage, AssistantMessage, ToolResultMessage, ErrorMessage
|
|
7
7
|
* - Message Role and Subtype discriminators
|
|
8
8
|
*
|
|
9
9
|
* @packageDocumentation
|
|
@@ -170,7 +170,7 @@ type MessageRole = "user" | "assistant" | "tool" | "system" | "error";
|
|
|
170
170
|
* Represents the specific type/category of the message.
|
|
171
171
|
* Used together with role for serialization and type discrimination.
|
|
172
172
|
*/
|
|
173
|
-
type MessageSubtype = "user" | "assistant" | "tool-
|
|
173
|
+
type MessageSubtype = "user" | "assistant" | "tool-result" | "error";
|
|
174
174
|
/**
|
|
175
175
|
* Token usage information
|
|
176
176
|
*/
|
|
@@ -203,9 +203,9 @@ interface UserMessage {
|
|
|
203
203
|
* Assistant Message
|
|
204
204
|
*
|
|
205
205
|
* Message generated by the AI assistant.
|
|
206
|
-
* Contains text, thinking process,
|
|
207
|
-
*
|
|
208
|
-
*
|
|
206
|
+
* Contains text, thinking process, files, and tool calls.
|
|
207
|
+
* Tool calls are content blocks within the assistant message,
|
|
208
|
+
* matching the mainstream API pattern (Anthropic, OpenAI).
|
|
209
209
|
*/
|
|
210
210
|
interface AssistantMessage {
|
|
211
211
|
/** Unique identifier */
|
|
@@ -214,8 +214,8 @@ interface AssistantMessage {
|
|
|
214
214
|
role: "assistant";
|
|
215
215
|
/** Message subtype for serialization */
|
|
216
216
|
subtype: "assistant";
|
|
217
|
-
/** Message content - can be simple string or array of parts */
|
|
218
|
-
content: string | Array<TextPart | ThinkingPart | FilePart>;
|
|
217
|
+
/** Message content - can be simple string or array of parts (including tool calls) */
|
|
218
|
+
content: string | Array<TextPart | ThinkingPart | FilePart | ToolCallPart>;
|
|
219
219
|
/** When this message was created (Unix timestamp in milliseconds) */
|
|
220
220
|
timestamp: number;
|
|
221
221
|
/** Parent message ID for threading (optional) */
|
|
@@ -223,29 +223,6 @@ interface AssistantMessage {
|
|
|
223
223
|
/** Token usage for this AI response (optional) */
|
|
224
224
|
usage?: TokenUsage;
|
|
225
225
|
}
|
|
226
|
-
/**
|
|
227
|
-
* Tool Call Message
|
|
228
|
-
*
|
|
229
|
-
* Represents AI's request to invoke a tool.
|
|
230
|
-
* Emitted when tool call parameters are fully assembled.
|
|
231
|
-
*
|
|
232
|
-
* Subject: Assistant (AI decided to call a tool)
|
|
233
|
-
* Timing: At tool_use_content_block_stop
|
|
234
|
-
*/
|
|
235
|
-
interface ToolCallMessage {
|
|
236
|
-
/** Unique message identifier */
|
|
237
|
-
id: string;
|
|
238
|
-
/** Message role - assistant initiates tool calls */
|
|
239
|
-
role: "assistant";
|
|
240
|
-
/** Message subtype for serialization */
|
|
241
|
-
subtype: "tool-call";
|
|
242
|
-
/** Tool call details */
|
|
243
|
-
toolCall: ToolCallPart;
|
|
244
|
-
/** When this message was created (Unix timestamp in milliseconds) */
|
|
245
|
-
timestamp: number;
|
|
246
|
-
/** Parent message ID (the assistant message that triggered this) */
|
|
247
|
-
parentId?: string;
|
|
248
|
-
}
|
|
249
226
|
/**
|
|
250
227
|
* Tool Result Message
|
|
251
228
|
*
|
|
@@ -298,8 +275,8 @@ interface ErrorMessage {
|
|
|
298
275
|
* Use `subtype` field for precise type discrimination.
|
|
299
276
|
*
|
|
300
277
|
* Role: Who sent it (user, assistant, tool, system, error)
|
|
301
|
-
* Subtype: What type of message (user, assistant, tool-
|
|
278
|
+
* Subtype: What type of message (user, assistant, tool-result, error)
|
|
302
279
|
*/
|
|
303
|
-
type Message = UserMessage | AssistantMessage |
|
|
280
|
+
type Message = UserMessage | AssistantMessage | ToolResultMessage | ErrorMessage;
|
|
304
281
|
|
|
305
|
-
export type { AssistantMessage as A, ContentPart as C, ErrorMessage as E, FilePart as F, ImagePart as I, Message as M,
|
|
282
|
+
export type { AssistantMessage as A, ContentPart as C, ErrorMessage as E, FilePart as F, ImagePart as I, Message as M, ToolResultMessage as T, UserMessage as U, TokenUsage as a, UserContentPart as b, TextPart as c, ThinkingPart as d, ToolCallPart as e, ToolResultOutput as f, ToolResultPart as g, MessageRole as h, MessageSubtype as i };
|
package/dist/mq/index.js
CHANGED
package/dist/mq/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mq/OffsetGenerator.ts"],"sourcesContent":["/**\n * OffsetGenerator - Generates monotonically increasing offsets\n *\n * Format: \"{timestamp_base36}-{sequence_padded}\"\n * Example: \"lq5x4g2-0001\"\n *\n * This format ensures:\n * - Lexicographic ordering matches temporal ordering\n * - Multiple events in same millisecond get unique offsets\n * - Human-readable and compact\n */\nexport class OffsetGenerator {\n private lastTimestamp = 0;\n private sequence = 0;\n\n /**\n * Generate a new offset\n */\n generate(): string {\n const now = Date.now();\n\n if (now === this.lastTimestamp) {\n this.sequence++;\n } else {\n this.lastTimestamp = now;\n this.sequence = 0;\n }\n\n const timestampPart = now.toString(36);\n const sequencePart = this.sequence.toString().padStart(4, \"0\");\n\n return `${timestampPart}-${sequencePart}`;\n }\n\n /**\n * Compare two offsets\n * @returns negative if a < b, 0 if a == b, positive if a > b\n */\n static compare(a: string, b: string): number {\n const [aTime, aSeq] = a.split(\"-\");\n const [bTime, bSeq] = b.split(\"-\");\n\n const timeDiff = parseInt(aTime, 36) - parseInt(bTime, 36);\n if (timeDiff !== 0) return timeDiff;\n\n return parseInt(aSeq) - parseInt(bSeq);\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/mq/OffsetGenerator.ts"],"sourcesContent":["/**\n * OffsetGenerator - Generates monotonically increasing offsets\n *\n * Format: \"{timestamp_base36}-{sequence_padded}\"\n * Example: \"lq5x4g2-0001\"\n *\n * This format ensures:\n * - Lexicographic ordering matches temporal ordering\n * - Multiple events in same millisecond get unique offsets\n * - Human-readable and compact\n */\nexport class OffsetGenerator {\n private lastTimestamp = 0;\n private sequence = 0;\n\n /**\n * Generate a new offset\n */\n generate(): string {\n const now = Date.now();\n\n if (now === this.lastTimestamp) {\n this.sequence++;\n } else {\n this.lastTimestamp = now;\n this.sequence = 0;\n }\n\n const timestampPart = now.toString(36);\n const sequencePart = this.sequence.toString().padStart(4, \"0\");\n\n return `${timestampPart}-${sequencePart}`;\n }\n\n /**\n * Compare two offsets\n * @returns negative if a < b, 0 if a == b, positive if a > b\n */\n static compare(a: string, b: string): number {\n const [aTime, aSeq] = a.split(\"-\");\n const [bTime, bSeq] = b.split(\"-\");\n\n const timeDiff = parseInt(aTime, 36) - parseInt(bTime, 36);\n if (timeDiff !== 0) return timeDiff;\n\n return parseInt(aSeq) - parseInt(bSeq);\n }\n}\n"],"mappings":";AAWO,IAAM,kBAAN,MAAsB;AAAA,EACnB,gBAAgB;AAAA,EAChB,WAAW;AAAA;AAAA;AAAA;AAAA,EAKnB,WAAmB;AACjB,UAAM,MAAM,KAAK,IAAI;AAErB,QAAI,QAAQ,KAAK,eAAe;AAC9B,WAAK;AAAA,IACP,OAAO;AACL,WAAK,gBAAgB;AACrB,WAAK,WAAW;AAAA,IAClB;AAEA,UAAM,gBAAgB,IAAI,SAAS,EAAE;AACrC,UAAM,eAAe,KAAK,SAAS,SAAS,EAAE,SAAS,GAAG,GAAG;AAE7D,WAAO,GAAG,aAAa,IAAI,YAAY;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,QAAQ,GAAW,GAAmB;AAC3C,UAAM,CAAC,OAAO,IAAI,IAAI,EAAE,MAAM,GAAG;AACjC,UAAM,CAAC,OAAO,IAAI,IAAI,EAAE,MAAM,GAAG;AAEjC,UAAM,WAAW,SAAS,OAAO,EAAE,IAAI,SAAS,OAAO,EAAE;AACzD,QAAI,aAAa,EAAG,QAAO;AAE3B,WAAO,SAAS,IAAI,IAAI,SAAS,IAAI;AAAA,EACvC;AACF;","names":[]}
|
package/dist/network/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
export { C as ControlAckParams, N as NotificationMethod, y as RpcClient, w as RpcClientConfig, x as RpcClientState, e as RpcErrorCodes, c as RpcErrorResponse, R as RpcMethod, d as RpcNotification, a as RpcRequest, b as RpcSuccessResponse, S as StreamEventParams, W as WebSocketFactory, i as createAckNotification, k as createErrorResponse, g as createNotification, f as createRequest, h as createStreamEvent, j as createSuccessResponse, u as eventTypeToRpcMethod, t as isControlAck, q as isErrorResponse, r as isInvalid, n as isNotification, m as isRequest, s as isStreamEvent, o as isSuccessResponse, p as parseMessage, l as parseMessageObject, v as rpcMethodToResponseType } from '../RpcClient-BcJ_zAGu.js';
|
|
2
2
|
export { JsonRpcError } from 'jsonrpc-lite';
|
|
3
|
-
import
|
|
3
|
+
import '../base-m40r3Qgu.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Network Types - Channel interfaces for client-server communication
|
|
@@ -276,292 +276,4 @@ declare function unwrapMessage(wrapper: ReliableWrapper): string;
|
|
|
276
276
|
*/
|
|
277
277
|
declare function generateMessageId(): string;
|
|
278
278
|
|
|
279
|
-
|
|
280
|
-
* JSON-RPC 2.0 Protocol for AgentX Network Communication
|
|
281
|
-
*
|
|
282
|
-
* Uses jsonrpc-lite for message parsing/serialization.
|
|
283
|
-
*
|
|
284
|
-
* Message Types:
|
|
285
|
-
* - Request: Client → Server (has id, expects response)
|
|
286
|
-
* - Response: Server → Client (success or error)
|
|
287
|
-
* - Notification: Server → Client (no id, stream events)
|
|
288
|
-
*
|
|
289
|
-
* @see https://www.jsonrpc.org/specification
|
|
290
|
-
*/
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* All RPC method names supported by AgentX
|
|
294
|
-
*/
|
|
295
|
-
type RpcMethod = "container.create" | "container.get" | "container.list" | "image.create" | "image.get" | "image.list" | "image.delete" | "image.run" | "image.stop" | "image.update" | "image.messages" | "agent.get" | "agent.list" | "agent.destroy" | "agent.destroyAll" | "agent.interrupt" | "message.send";
|
|
296
|
-
/**
|
|
297
|
-
* Notification method names (server push)
|
|
298
|
-
*/
|
|
299
|
-
type NotificationMethod = "stream.event" | "control.ack";
|
|
300
|
-
/**
|
|
301
|
-
* JSON-RPC Request structure
|
|
302
|
-
*/
|
|
303
|
-
interface RpcRequest<M extends RpcMethod = RpcMethod, P = unknown> {
|
|
304
|
-
jsonrpc: "2.0";
|
|
305
|
-
method: M;
|
|
306
|
-
params: P;
|
|
307
|
-
id: string | number;
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* JSON-RPC Success Response structure
|
|
311
|
-
*/
|
|
312
|
-
interface RpcSuccessResponse<R = unknown> {
|
|
313
|
-
jsonrpc: "2.0";
|
|
314
|
-
result: R;
|
|
315
|
-
id: string | number;
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* JSON-RPC Error Response structure
|
|
319
|
-
*/
|
|
320
|
-
interface RpcErrorResponse {
|
|
321
|
-
jsonrpc: "2.0";
|
|
322
|
-
error: {
|
|
323
|
-
code: number;
|
|
324
|
-
message: string;
|
|
325
|
-
data?: unknown;
|
|
326
|
-
};
|
|
327
|
-
id: string | number | null;
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* JSON-RPC Notification structure (no id, no response expected)
|
|
331
|
-
*/
|
|
332
|
-
interface RpcNotification<M extends NotificationMethod = NotificationMethod, P = unknown> {
|
|
333
|
-
jsonrpc: "2.0";
|
|
334
|
-
method: M;
|
|
335
|
-
params: P;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Stream event notification params
|
|
339
|
-
*/
|
|
340
|
-
interface StreamEventParams {
|
|
341
|
-
topic: string;
|
|
342
|
-
event: SystemEvent;
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Control ACK notification params
|
|
346
|
-
*/
|
|
347
|
-
interface ControlAckParams {
|
|
348
|
-
msgId: string;
|
|
349
|
-
}
|
|
350
|
-
declare const RpcErrorCodes: {
|
|
351
|
-
readonly PARSE_ERROR: -32700;
|
|
352
|
-
readonly INVALID_REQUEST: -32600;
|
|
353
|
-
readonly METHOD_NOT_FOUND: -32601;
|
|
354
|
-
readonly INVALID_PARAMS: -32602;
|
|
355
|
-
readonly INTERNAL_ERROR: -32603;
|
|
356
|
-
readonly SERVER_ERROR: -32000;
|
|
357
|
-
readonly NOT_FOUND: 404;
|
|
358
|
-
readonly UNAUTHORIZED: 401;
|
|
359
|
-
readonly FORBIDDEN: 403;
|
|
360
|
-
readonly TIMEOUT: 408;
|
|
361
|
-
};
|
|
362
|
-
/**
|
|
363
|
-
* Create a JSON-RPC request
|
|
364
|
-
*/
|
|
365
|
-
declare function createRequest(id: string | number, method: RpcMethod | string, params: unknown): JsonRpc;
|
|
366
|
-
/**
|
|
367
|
-
* Create a JSON-RPC notification (no response expected)
|
|
368
|
-
*/
|
|
369
|
-
declare function createNotification(method: NotificationMethod | string, params: unknown): JsonRpc;
|
|
370
|
-
/**
|
|
371
|
-
* Create a stream event notification
|
|
372
|
-
*/
|
|
373
|
-
declare function createStreamEvent(topic: string, event: SystemEvent): JsonRpc;
|
|
374
|
-
/**
|
|
375
|
-
* Create an ACK notification
|
|
376
|
-
*/
|
|
377
|
-
declare function createAckNotification(msgId: string): JsonRpc;
|
|
378
|
-
/**
|
|
379
|
-
* Create a success response
|
|
380
|
-
*/
|
|
381
|
-
declare function createSuccessResponse(id: string | number, result: unknown): JsonRpc;
|
|
382
|
-
/**
|
|
383
|
-
* Create an error response
|
|
384
|
-
*/
|
|
385
|
-
declare function createErrorResponse(id: string | number | null, code: number, message: string, data?: unknown): JsonRpc;
|
|
386
|
-
/**
|
|
387
|
-
* Parse a JSON-RPC message string
|
|
388
|
-
*/
|
|
389
|
-
declare function parseMessage(message: string): IParsedObject | IParsedObject[];
|
|
390
|
-
/**
|
|
391
|
-
* Parse a JSON-RPC message object
|
|
392
|
-
*/
|
|
393
|
-
declare function parseMessageObject(obj: unknown): IParsedObject;
|
|
394
|
-
/**
|
|
395
|
-
* Check if parsed message is a request
|
|
396
|
-
*/
|
|
397
|
-
declare function isRequest(parsed: IParsedObject): boolean;
|
|
398
|
-
/**
|
|
399
|
-
* Check if parsed message is a notification
|
|
400
|
-
*/
|
|
401
|
-
declare function isNotification(parsed: IParsedObject): boolean;
|
|
402
|
-
/**
|
|
403
|
-
* Check if parsed message is a success response
|
|
404
|
-
*/
|
|
405
|
-
declare function isSuccessResponse(parsed: IParsedObject): boolean;
|
|
406
|
-
/**
|
|
407
|
-
* Check if parsed message is an error response
|
|
408
|
-
*/
|
|
409
|
-
declare function isErrorResponse(parsed: IParsedObject): boolean;
|
|
410
|
-
/**
|
|
411
|
-
* Check if parsed message is invalid
|
|
412
|
-
*/
|
|
413
|
-
declare function isInvalid(parsed: IParsedObject): boolean;
|
|
414
|
-
/**
|
|
415
|
-
* Check if notification is a stream event
|
|
416
|
-
*/
|
|
417
|
-
declare function isStreamEvent(parsed: IParsedObject): parsed is IParsedObject & {
|
|
418
|
-
payload: RpcNotification<"stream.event", StreamEventParams>;
|
|
419
|
-
};
|
|
420
|
-
/**
|
|
421
|
-
* Check if notification is a control ACK
|
|
422
|
-
*/
|
|
423
|
-
declare function isControlAck(parsed: IParsedObject): parsed is IParsedObject & {
|
|
424
|
-
payload: RpcNotification<"control.ack", ControlAckParams>;
|
|
425
|
-
};
|
|
426
|
-
/**
|
|
427
|
-
* Map old event type names to new RPC method names
|
|
428
|
-
*/
|
|
429
|
-
declare const eventTypeToRpcMethod: Record<string, RpcMethod>;
|
|
430
|
-
/**
|
|
431
|
-
* Map RPC method names back to response event types
|
|
432
|
-
*/
|
|
433
|
-
declare const rpcMethodToResponseType: Record<RpcMethod, string>;
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* RpcClient - JSON-RPC 2.0 Client over WebSocket
|
|
437
|
-
*
|
|
438
|
-
* Provides:
|
|
439
|
-
* - Request/Response with automatic ID matching
|
|
440
|
-
* - Notification handling (stream events)
|
|
441
|
-
* - Timeout management
|
|
442
|
-
* - Reconnection support
|
|
443
|
-
*
|
|
444
|
-
* @example
|
|
445
|
-
* ```typescript
|
|
446
|
-
* const client = new RpcClient({ url: "ws://localhost:5200" });
|
|
447
|
-
* await client.connect();
|
|
448
|
-
*
|
|
449
|
-
* // RPC call
|
|
450
|
-
* const result = await client.call("container.list", {});
|
|
451
|
-
*
|
|
452
|
-
* // Stream events
|
|
453
|
-
* client.onNotification("stream.event", (params) => {
|
|
454
|
-
* console.log("Event:", params.event);
|
|
455
|
-
* });
|
|
456
|
-
*
|
|
457
|
-
* // Subscribe to topic
|
|
458
|
-
* client.notify("subscribe", { topic: "session-123" });
|
|
459
|
-
* ```
|
|
460
|
-
*/
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* RpcClient configuration
|
|
464
|
-
*/
|
|
465
|
-
interface RpcClientConfig {
|
|
466
|
-
/**
|
|
467
|
-
* WebSocket URL
|
|
468
|
-
*/
|
|
469
|
-
url: string;
|
|
470
|
-
/**
|
|
471
|
-
* Request timeout in milliseconds (default: 30000)
|
|
472
|
-
*/
|
|
473
|
-
timeout?: number;
|
|
474
|
-
/**
|
|
475
|
-
* Auto reconnect on disconnect (default: true)
|
|
476
|
-
*/
|
|
477
|
-
autoReconnect?: boolean;
|
|
478
|
-
/**
|
|
479
|
-
* Reconnect delay in milliseconds (default: 3000)
|
|
480
|
-
*/
|
|
481
|
-
reconnectDelay?: number;
|
|
482
|
-
/**
|
|
483
|
-
* Headers for authentication (Node.js only, sent in first message for browser)
|
|
484
|
-
*/
|
|
485
|
-
headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
|
486
|
-
/**
|
|
487
|
-
* Debug logging
|
|
488
|
-
*/
|
|
489
|
-
debug?: boolean;
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* Notification handler
|
|
493
|
-
*/
|
|
494
|
-
type NotificationHandler = (method: string, params: unknown) => void;
|
|
495
|
-
/**
|
|
496
|
-
* Stream event handler
|
|
497
|
-
*/
|
|
498
|
-
type StreamEventHandler = (topic: string, event: SystemEvent) => void;
|
|
499
|
-
/**
|
|
500
|
-
* Connection state
|
|
501
|
-
*/
|
|
502
|
-
type RpcClientState = "disconnected" | "connecting" | "connected";
|
|
503
|
-
/**
|
|
504
|
-
* JSON-RPC 2.0 Client
|
|
505
|
-
*/
|
|
506
|
-
declare class RpcClient {
|
|
507
|
-
private readonly config;
|
|
508
|
-
private readonly timeout;
|
|
509
|
-
private readonly pendingRequests;
|
|
510
|
-
private readonly notificationHandlers;
|
|
511
|
-
private readonly streamEventHandlers;
|
|
512
|
-
private ws;
|
|
513
|
-
private state;
|
|
514
|
-
private requestId;
|
|
515
|
-
private reconnectTimer;
|
|
516
|
-
private disposed;
|
|
517
|
-
constructor(config: RpcClientConfig);
|
|
518
|
-
/**
|
|
519
|
-
* Current connection state
|
|
520
|
-
*/
|
|
521
|
-
get connectionState(): RpcClientState;
|
|
522
|
-
/**
|
|
523
|
-
* Whether client is connected
|
|
524
|
-
*/
|
|
525
|
-
get connected(): boolean;
|
|
526
|
-
/**
|
|
527
|
-
* Connect to server
|
|
528
|
-
*/
|
|
529
|
-
connect(): Promise<void>;
|
|
530
|
-
/**
|
|
531
|
-
* Disconnect from server
|
|
532
|
-
*/
|
|
533
|
-
disconnect(): void;
|
|
534
|
-
/**
|
|
535
|
-
* Dispose client and clean up resources
|
|
536
|
-
*/
|
|
537
|
-
dispose(): void;
|
|
538
|
-
private scheduleReconnect;
|
|
539
|
-
/**
|
|
540
|
-
* Call an RPC method and wait for response
|
|
541
|
-
*/
|
|
542
|
-
call<T = unknown>(method: RpcMethod, params: unknown): Promise<T>;
|
|
543
|
-
/**
|
|
544
|
-
* Send a notification (no response expected)
|
|
545
|
-
*/
|
|
546
|
-
notify(method: NotificationMethod | string, params: unknown): void;
|
|
547
|
-
/**
|
|
548
|
-
* Subscribe to a topic (convenience method)
|
|
549
|
-
*/
|
|
550
|
-
subscribe(topic: string): void;
|
|
551
|
-
/**
|
|
552
|
-
* Unsubscribe from a topic (convenience method)
|
|
553
|
-
*/
|
|
554
|
-
unsubscribe(topic: string): void;
|
|
555
|
-
/**
|
|
556
|
-
* Register handler for all notifications
|
|
557
|
-
*/
|
|
558
|
-
onNotification(handler: NotificationHandler): () => void;
|
|
559
|
-
/**
|
|
560
|
-
* Register handler for stream events
|
|
561
|
-
*/
|
|
562
|
-
onStreamEvent(handler: StreamEventHandler): () => void;
|
|
563
|
-
private handleMessage;
|
|
564
|
-
private handleParsedMessage;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
export { type AckMessage, type ChannelClient, type ChannelClientOptions, type ChannelClientProvider, type ChannelConnection, type ChannelServer, type ChannelServerOptions, type ChannelServerProvider, type ConnectionState, type ControlAckParams, type MinimalHTTPServer, type NotificationMethod, type ReliableWrapper, RpcClient, type RpcClientConfig, type RpcClientState, RpcErrorCodes, type RpcErrorResponse, type RpcMethod, type RpcNotification, type RpcRequest, type RpcSuccessResponse, type SendReliableOptions, type StreamEventParams, type Unsubscribe, createAck, createAckNotification, createErrorResponse, createNotification, createRequest, createStreamEvent, createSuccessResponse, eventTypeToRpcMethod, generateMessageId, isAckMessage, isControlAck, isErrorResponse, isInvalid, isNotification, isReliableWrapper, isRequest, isStreamEvent, isSuccessResponse, parseMessage, parseMessageObject, rpcMethodToResponseType, unwrapMessage, wrapMessage };
|
|
279
|
+
export { type AckMessage, type ChannelClient, type ChannelClientOptions, type ChannelClientProvider, type ChannelConnection, type ChannelServer, type ChannelServerOptions, type ChannelServerProvider, type ConnectionState, type MinimalHTTPServer, type ReliableWrapper, type SendReliableOptions, type Unsubscribe, createAck, generateMessageId, isAckMessage, isReliableWrapper, unwrapMessage, wrapMessage };
|
package/dist/network/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import "../chunk-7D4SUZUM.js";
|
|
2
|
-
|
|
3
1
|
// src/network/protocol.ts
|
|
4
2
|
function isReliableWrapper(data) {
|
|
5
3
|
return typeof data === "object" && data !== null && "__msgId" in data && "__payload" in data;
|
|
@@ -145,10 +143,6 @@ var rpcMethodToResponseType = {
|
|
|
145
143
|
};
|
|
146
144
|
|
|
147
145
|
// src/network/RpcClient.ts
|
|
148
|
-
function isBrowser() {
|
|
149
|
-
const globalWindow = typeof globalThis !== "undefined" ? globalThis.window : void 0;
|
|
150
|
-
return globalWindow?.document !== void 0;
|
|
151
|
-
}
|
|
152
146
|
var RpcClient = class {
|
|
153
147
|
config;
|
|
154
148
|
timeout;
|
|
@@ -190,13 +184,8 @@ var RpcClient = class {
|
|
|
190
184
|
}
|
|
191
185
|
this.state = "connecting";
|
|
192
186
|
const url = this.config.url;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
ws = new WebSocket(url);
|
|
196
|
-
} else {
|
|
197
|
-
const { default: WS } = await import("../wrapper-Y3UTVU2E.js");
|
|
198
|
-
ws = new WS(url);
|
|
199
|
-
}
|
|
187
|
+
const factory = this.config.createWebSocket ?? ((u) => new WebSocket(u));
|
|
188
|
+
const ws = factory(url);
|
|
200
189
|
this.ws = ws;
|
|
201
190
|
return new Promise((resolve, reject) => {
|
|
202
191
|
ws.onopen = async () => {
|
|
@@ -204,7 +193,7 @@ var RpcClient = class {
|
|
|
204
193
|
if (this.config.debug) {
|
|
205
194
|
console.log("[RpcClient] Connected to", url);
|
|
206
195
|
}
|
|
207
|
-
if (
|
|
196
|
+
if (this.config.headers) {
|
|
208
197
|
const headers = typeof this.config.headers === "function" ? await this.config.headers() : this.config.headers;
|
|
209
198
|
this.notify("auth", { headers });
|
|
210
199
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/network/protocol.ts","../../src/network/jsonrpc.ts","../../src/network/RpcClient.ts"],"sourcesContent":["/**\n * Reliable Message Protocol\n *\n * Internal protocol for message acknowledgment between server and client.\n * This is transparent to the application layer.\n *\n * Flow:\n * 1. Server sends: { __msgId: \"xxx\", __payload: \"actual message\" }\n * 2. Client receives, extracts payload, sends: { __ack: \"xxx\" }\n * 3. Server receives ACK, triggers onAck callback\n */\n\n// ============================================================================\n// Protocol Types\n// ============================================================================\n\n/**\n * ReliableWrapper - Wrapper for reliable messages (server → client)\n *\n * Contains the original message payload with a unique ID for tracking.\n */\nexport interface ReliableWrapper {\n /** Unique message ID for tracking */\n __msgId: string;\n /** Original message payload */\n __payload: string;\n}\n\n/**\n * AckMessage - Acknowledgment message (client → server)\n *\n * Sent automatically by client when receiving a reliable message.\n */\nexport interface AckMessage {\n /** Message ID being acknowledged */\n __ack: string;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Check if data is a ReliableWrapper\n */\nexport function isReliableWrapper(data: unknown): data is ReliableWrapper {\n return typeof data === \"object\" && data !== null && \"__msgId\" in data && \"__payload\" in data;\n}\n\n/**\n * Check if data is an AckMessage\n */\nexport function isAckMessage(data: unknown): data is AckMessage {\n return typeof data === \"object\" && data !== null && \"__ack\" in data;\n}\n\n// ============================================================================\n// Protocol Helpers\n// ============================================================================\n\n/**\n * Wrap a message for reliable delivery\n */\nexport function wrapMessage(msgId: string, payload: string): ReliableWrapper {\n return { __msgId: msgId, __payload: payload };\n}\n\n/**\n * Create an ACK message\n */\nexport function createAck(msgId: string): AckMessage {\n return { __ack: msgId };\n}\n\n/**\n * Unwrap a reliable message, returning the original payload\n */\nexport function unwrapMessage(wrapper: ReliableWrapper): string {\n return wrapper.__payload;\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n","/**\n * JSON-RPC 2.0 Protocol for AgentX Network Communication\n *\n * Uses jsonrpc-lite for message parsing/serialization.\n *\n * Message Types:\n * - Request: Client → Server (has id, expects response)\n * - Response: Server → Client (success or error)\n * - Notification: Server → Client (no id, stream events)\n *\n * @see https://www.jsonrpc.org/specification\n */\n\nimport {\n request as jsonrpcRequest,\n notification as jsonrpcNotification,\n success as jsonrpcSuccess,\n error as jsonrpcError,\n parse as jsonrpcParse,\n parseObject as jsonrpcParseObject,\n JsonRpcError,\n} from \"jsonrpc-lite\";\nimport type { IParsedObject, JsonRpc } from \"jsonrpc-lite\";\nimport type { SystemEvent } from \"../event/types/base\";\n\n// ============================================================================\n// Re-export jsonrpc-lite types and functions\n// ============================================================================\n\nexport { JsonRpcError };\nexport type { IParsedObject, JsonRpc };\n\n// ============================================================================\n// RPC Method Names\n// ============================================================================\n\n/**\n * All RPC method names supported by AgentX\n */\nexport type RpcMethod =\n // Container\n | \"container.create\"\n | \"container.get\"\n | \"container.list\"\n // Image\n | \"image.create\"\n | \"image.get\"\n | \"image.list\"\n | \"image.delete\"\n | \"image.run\"\n | \"image.stop\"\n | \"image.update\"\n | \"image.messages\"\n // Agent\n | \"agent.get\"\n | \"agent.list\"\n | \"agent.destroy\"\n | \"agent.destroyAll\"\n | \"agent.interrupt\"\n // Message\n | \"message.send\";\n\n/**\n * Notification method names (server push)\n */\nexport type NotificationMethod =\n | \"stream.event\" // Stream events (text_delta, tool_call, etc.)\n | \"control.ack\"; // ACK for reliable delivery\n\n// ============================================================================\n// Request/Response Type Definitions\n// ============================================================================\n\n/**\n * JSON-RPC Request structure\n */\nexport interface RpcRequest<M extends RpcMethod = RpcMethod, P = unknown> {\n jsonrpc: \"2.0\";\n method: M;\n params: P;\n id: string | number;\n}\n\n/**\n * JSON-RPC Success Response structure\n */\nexport interface RpcSuccessResponse<R = unknown> {\n jsonrpc: \"2.0\";\n result: R;\n id: string | number;\n}\n\n/**\n * JSON-RPC Error Response structure\n */\nexport interface RpcErrorResponse {\n jsonrpc: \"2.0\";\n error: {\n code: number;\n message: string;\n data?: unknown;\n };\n id: string | number | null;\n}\n\n/**\n * JSON-RPC Notification structure (no id, no response expected)\n */\nexport interface RpcNotification<M extends NotificationMethod = NotificationMethod, P = unknown> {\n jsonrpc: \"2.0\";\n method: M;\n params: P;\n}\n\n/**\n * Stream event notification params\n */\nexport interface StreamEventParams {\n topic: string;\n event: SystemEvent;\n}\n\n/**\n * Control ACK notification params\n */\nexport interface ControlAckParams {\n msgId: string;\n}\n\n// ============================================================================\n// Standard JSON-RPC Error Codes\n// ============================================================================\n\nexport const RpcErrorCodes = {\n // Standard JSON-RPC errors\n PARSE_ERROR: -32700,\n INVALID_REQUEST: -32600,\n METHOD_NOT_FOUND: -32601,\n INVALID_PARAMS: -32602,\n INTERNAL_ERROR: -32603,\n // Server errors (reserved: -32000 to -32099)\n SERVER_ERROR: -32000,\n // Application errors (custom)\n NOT_FOUND: 404,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n TIMEOUT: 408,\n} as const;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Create a JSON-RPC request\n */\nexport function createRequest(\n id: string | number,\n method: RpcMethod | string,\n params: unknown\n): JsonRpc {\n return jsonrpcRequest(id, method, params as Record<string, unknown>);\n}\n\n/**\n * Create a JSON-RPC notification (no response expected)\n */\nexport function createNotification(method: NotificationMethod | string, params: unknown): JsonRpc {\n return jsonrpcNotification(method, params as Record<string, unknown>);\n}\n\n/**\n * Create a stream event notification\n */\nexport function createStreamEvent(topic: string, event: SystemEvent): JsonRpc {\n return jsonrpcNotification(\"stream.event\", { topic, event });\n}\n\n/**\n * Create an ACK notification\n */\nexport function createAckNotification(msgId: string): JsonRpc {\n return jsonrpcNotification(\"control.ack\", { msgId });\n}\n\n/**\n * Create a success response\n */\nexport function createSuccessResponse(id: string | number, result: unknown): JsonRpc {\n return jsonrpcSuccess(id, result as Record<string, unknown>);\n}\n\n/**\n * Create an error response\n */\nexport function createErrorResponse(\n id: string | number | null,\n code: number,\n message: string,\n data?: unknown\n): JsonRpc {\n return jsonrpcError(id, new JsonRpcError(message, code, data));\n}\n\n/**\n * Parse a JSON-RPC message string\n */\nexport function parseMessage(message: string): IParsedObject | IParsedObject[] {\n return jsonrpcParse(message);\n}\n\n/**\n * Parse a JSON-RPC message object\n */\nexport function parseMessageObject(obj: unknown): IParsedObject {\n return jsonrpcParseObject(obj);\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Check if parsed message is a request\n */\nexport function isRequest(parsed: IParsedObject): boolean {\n return parsed.type === \"request\";\n}\n\n/**\n * Check if parsed message is a notification\n */\nexport function isNotification(parsed: IParsedObject): boolean {\n return parsed.type === \"notification\";\n}\n\n/**\n * Check if parsed message is a success response\n */\nexport function isSuccessResponse(parsed: IParsedObject): boolean {\n return parsed.type === \"success\";\n}\n\n/**\n * Check if parsed message is an error response\n */\nexport function isErrorResponse(parsed: IParsedObject): boolean {\n return parsed.type === \"error\";\n}\n\n/**\n * Check if parsed message is invalid\n */\nexport function isInvalid(parsed: IParsedObject): boolean {\n return parsed.type === \"invalid\";\n}\n\n/**\n * Check if notification is a stream event\n */\nexport function isStreamEvent(parsed: IParsedObject): parsed is IParsedObject & {\n payload: RpcNotification<\"stream.event\", StreamEventParams>;\n} {\n if (parsed.type !== \"notification\") return false;\n const payload = parsed.payload as RpcNotification;\n return payload.method === \"stream.event\";\n}\n\n/**\n * Check if notification is a control ACK\n */\nexport function isControlAck(parsed: IParsedObject): parsed is IParsedObject & {\n payload: RpcNotification<\"control.ack\", ControlAckParams>;\n} {\n if (parsed.type !== \"notification\") return false;\n const payload = parsed.payload as RpcNotification;\n return payload.method === \"control.ack\";\n}\n\n// ============================================================================\n// Method Name Mapping (for backward compatibility)\n// ============================================================================\n\n/**\n * Map old event type names to new RPC method names\n */\nexport const eventTypeToRpcMethod: Record<string, RpcMethod> = {\n // Container\n container_create_request: \"container.create\",\n container_get_request: \"container.get\",\n container_list_request: \"container.list\",\n // Image\n image_create_request: \"image.create\",\n image_get_request: \"image.get\",\n image_list_request: \"image.list\",\n image_delete_request: \"image.delete\",\n image_run_request: \"image.run\",\n image_stop_request: \"image.stop\",\n image_update_request: \"image.update\",\n image_messages_request: \"image.messages\",\n // Agent\n agent_get_request: \"agent.get\",\n agent_list_request: \"agent.list\",\n agent_destroy_request: \"agent.destroy\",\n agent_destroy_all_request: \"agent.destroyAll\",\n agent_interrupt_request: \"agent.interrupt\",\n // Message\n message_send_request: \"message.send\",\n};\n\n/**\n * Map RPC method names back to response event types\n */\nexport const rpcMethodToResponseType: Record<RpcMethod, string> = {\n // Container\n \"container.create\": \"container_create_response\",\n \"container.get\": \"container_get_response\",\n \"container.list\": \"container_list_response\",\n // Image\n \"image.create\": \"image_create_response\",\n \"image.get\": \"image_get_response\",\n \"image.list\": \"image_list_response\",\n \"image.delete\": \"image_delete_response\",\n \"image.run\": \"image_run_response\",\n \"image.stop\": \"image_stop_response\",\n \"image.update\": \"image_update_response\",\n \"image.messages\": \"image_messages_response\",\n // Agent\n \"agent.get\": \"agent_get_response\",\n \"agent.list\": \"agent_list_response\",\n \"agent.destroy\": \"agent_destroy_response\",\n \"agent.destroyAll\": \"agent_destroy_all_response\",\n \"agent.interrupt\": \"agent_interrupt_response\",\n // Message\n \"message.send\": \"message_send_response\",\n};\n","/**\n * RpcClient - JSON-RPC 2.0 Client over WebSocket\n *\n * Provides:\n * - Request/Response with automatic ID matching\n * - Notification handling (stream events)\n * - Timeout management\n * - Reconnection support\n *\n * @example\n * ```typescript\n * const client = new RpcClient({ url: \"ws://localhost:5200\" });\n * await client.connect();\n *\n * // RPC call\n * const result = await client.call(\"container.list\", {});\n *\n * // Stream events\n * client.onNotification(\"stream.event\", (params) => {\n * console.log(\"Event:\", params.event);\n * });\n *\n * // Subscribe to topic\n * client.notify(\"subscribe\", { topic: \"session-123\" });\n * ```\n */\n\nimport {\n createRequest,\n createNotification,\n parseMessage,\n isSuccessResponse,\n isErrorResponse,\n isNotification,\n isStreamEvent,\n type RpcMethod,\n type NotificationMethod,\n type StreamEventParams,\n} from \"./jsonrpc\";\nimport type { SystemEvent } from \"../event/types/base\";\n\n/**\n * Check if running in browser environment\n */\nfunction isBrowser(): boolean {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const globalWindow = typeof globalThis !== \"undefined\" ? (globalThis as any).window : undefined;\n return globalWindow?.document !== undefined;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * RpcClient configuration\n */\nexport interface RpcClientConfig {\n /**\n * WebSocket URL\n */\n url: string;\n\n /**\n * Request timeout in milliseconds (default: 30000)\n */\n timeout?: number;\n\n /**\n * Auto reconnect on disconnect (default: true)\n */\n autoReconnect?: boolean;\n\n /**\n * Reconnect delay in milliseconds (default: 3000)\n */\n reconnectDelay?: number;\n\n /**\n * Headers for authentication (Node.js only, sent in first message for browser)\n */\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n\n /**\n * Debug logging\n */\n debug?: boolean;\n}\n\n/**\n * Pending request state\n */\ninterface PendingRequest {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Notification handler\n */\ntype NotificationHandler = (method: string, params: unknown) => void;\n\n/**\n * Stream event handler\n */\ntype StreamEventHandler = (topic: string, event: SystemEvent) => void;\n\n/**\n * Connection state\n */\nexport type RpcClientState = \"disconnected\" | \"connecting\" | \"connected\";\n\n// ============================================================================\n// RpcClient Implementation\n// ============================================================================\n\n/**\n * JSON-RPC 2.0 Client\n */\nexport class RpcClient {\n private readonly config: RpcClientConfig;\n private readonly timeout: number;\n private readonly pendingRequests = new Map<string | number, PendingRequest>();\n private readonly notificationHandlers = new Set<NotificationHandler>();\n private readonly streamEventHandlers = new Set<StreamEventHandler>();\n\n private ws: WebSocket | null = null;\n private state: RpcClientState = \"disconnected\";\n private requestId = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n\n constructor(config: RpcClientConfig) {\n this.config = config;\n this.timeout = config.timeout ?? 30000;\n }\n\n // ==================== Properties ====================\n\n /**\n * Current connection state\n */\n get connectionState(): RpcClientState {\n return this.state;\n }\n\n /**\n * Whether client is connected\n */\n get connected(): boolean {\n return this.state === \"connected\";\n }\n\n // ==================== Connection ====================\n\n /**\n * Connect to server\n */\n async connect(): Promise<void> {\n if (this.disposed) {\n throw new Error(\"Client has been disposed\");\n }\n\n if (this.state === \"connected\") {\n return;\n }\n\n this.state = \"connecting\";\n\n const url = this.config.url;\n\n // Create WebSocket (browser or Node.js)\n let ws: WebSocket;\n if (isBrowser()) {\n ws = new WebSocket(url);\n } else {\n const { default: WS } = await import(\"ws\");\n ws = new WS(url) as unknown as WebSocket;\n }\n\n this.ws = ws;\n\n return new Promise((resolve, reject) => {\n ws.onopen = async () => {\n this.state = \"connected\";\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Connected to\", url);\n }\n\n // Send auth if in browser (headers not supported in WebSocket API)\n if (isBrowser() && this.config.headers) {\n const headers =\n typeof this.config.headers === \"function\"\n ? await this.config.headers()\n : this.config.headers;\n this.notify(\"auth\" as NotificationMethod, { headers });\n }\n\n resolve();\n };\n\n ws.onclose = () => {\n this.state = \"disconnected\";\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Disconnected\");\n }\n\n // Auto reconnect\n if (!this.disposed && this.config.autoReconnect !== false) {\n this.scheduleReconnect();\n }\n };\n\n ws.onerror = (err) => {\n if (this.config.debug) {\n console.error(\"[RpcClient] WebSocket error:\", err);\n }\n\n if (this.state === \"connecting\") {\n this.state = \"disconnected\";\n reject(new Error(\"Failed to connect to server\"));\n }\n };\n\n ws.onmessage = (event) => {\n this.handleMessage(event.data as string);\n };\n });\n }\n\n /**\n * Disconnect from server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n\n this.state = \"disconnected\";\n }\n\n /**\n * Dispose client and clean up resources\n */\n dispose(): void {\n this.disposed = true;\n\n // Reject all pending requests\n for (const [id, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(\"Client disposed\"));\n this.pendingRequests.delete(id);\n }\n\n this.disconnect();\n this.notificationHandlers.clear();\n this.streamEventHandlers.clear();\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Disposed\");\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return;\n\n const delay = this.config.reconnectDelay ?? 3000;\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = null;\n\n if (!this.disposed && this.state === \"disconnected\") {\n if (this.config.debug) {\n console.log(\"[RpcClient] Attempting to reconnect...\");\n }\n\n try {\n await this.connect();\n } catch {\n this.scheduleReconnect();\n }\n }\n }, delay);\n }\n\n // ==================== RPC Methods ====================\n\n /**\n * Call an RPC method and wait for response\n */\n async call<T = unknown>(method: RpcMethod, params: unknown): Promise<T> {\n if (!this.connected || !this.ws) {\n throw new Error(\"Not connected to server\");\n }\n\n const id = ++this.requestId;\n const request = createRequest(id, method, params);\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request timeout: ${method}`));\n }, this.timeout);\n\n this.pendingRequests.set(id, {\n resolve: resolve as (result: unknown) => void,\n reject,\n timer,\n });\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Sending request:\", method, params);\n }\n\n this.ws!.send(JSON.stringify(request));\n });\n }\n\n /**\n * Send a notification (no response expected)\n */\n notify(method: NotificationMethod | string, params: unknown): void {\n if (!this.connected || !this.ws) {\n if (this.config.debug) {\n console.warn(\"[RpcClient] Cannot send notification: not connected\");\n }\n return;\n }\n\n const notification = createNotification(method as NotificationMethod, params);\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Sending notification:\", method, params);\n }\n\n this.ws.send(JSON.stringify(notification));\n }\n\n /**\n * Subscribe to a topic (convenience method)\n */\n subscribe(topic: string): void {\n this.notify(\"subscribe\", { topic });\n }\n\n /**\n * Unsubscribe from a topic (convenience method)\n */\n unsubscribe(topic: string): void {\n this.notify(\"unsubscribe\", { topic });\n }\n\n // ==================== Event Handlers ====================\n\n /**\n * Register handler for all notifications\n */\n onNotification(handler: NotificationHandler): () => void {\n this.notificationHandlers.add(handler);\n return () => this.notificationHandlers.delete(handler);\n }\n\n /**\n * Register handler for stream events\n */\n onStreamEvent(handler: StreamEventHandler): () => void {\n this.streamEventHandlers.add(handler);\n return () => this.streamEventHandlers.delete(handler);\n }\n\n // ==================== Message Handling ====================\n\n private handleMessage(data: string): void {\n try {\n const parsed = parseMessage(data);\n\n // Handle single message\n if (!Array.isArray(parsed)) {\n this.handleParsedMessage(parsed);\n } else {\n // Batch response (rare)\n for (const item of parsed) {\n this.handleParsedMessage(item);\n }\n }\n } catch (err) {\n if (this.config.debug) {\n console.error(\"[RpcClient] Failed to parse message:\", err);\n }\n }\n }\n\n private handleParsedMessage(parsed: import(\"jsonrpc-lite\").IParsedObject): void {\n if (isSuccessResponse(parsed)) {\n // Success response - resolve pending request\n const payload = parsed.payload as { id: string | number; result: unknown };\n const pending = this.pendingRequests.get(payload.id);\n\n if (pending) {\n this.pendingRequests.delete(payload.id);\n clearTimeout(pending.timer);\n pending.resolve(payload.result);\n }\n } else if (isErrorResponse(parsed)) {\n // Error response - reject pending request\n const payload = parsed.payload as {\n id: string | number | null;\n error: { code: number; message: string; data?: unknown };\n };\n\n if (payload.id !== null) {\n const pending = this.pendingRequests.get(payload.id);\n\n if (pending) {\n this.pendingRequests.delete(payload.id);\n clearTimeout(pending.timer);\n pending.reject(new Error(payload.error.message));\n }\n }\n } else if (isNotification(parsed)) {\n // Notification - stream event or control message\n const payload = parsed.payload as { method: string; params: unknown };\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Received notification:\", payload.method);\n }\n\n // Notify all handlers\n for (const handler of this.notificationHandlers) {\n handler(payload.method, payload.params);\n }\n\n // Handle stream events specially\n if (isStreamEvent(parsed)) {\n const streamPayload = parsed.payload as { params: StreamEventParams };\n const { topic, event } = streamPayload.params;\n\n for (const handler of this.streamEventHandlers) {\n handler(topic, event);\n }\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/network/protocol.ts","../../src/network/jsonrpc.ts","../../src/network/RpcClient.ts"],"sourcesContent":["/**\n * Reliable Message Protocol\n *\n * Internal protocol for message acknowledgment between server and client.\n * This is transparent to the application layer.\n *\n * Flow:\n * 1. Server sends: { __msgId: \"xxx\", __payload: \"actual message\" }\n * 2. Client receives, extracts payload, sends: { __ack: \"xxx\" }\n * 3. Server receives ACK, triggers onAck callback\n */\n\n// ============================================================================\n// Protocol Types\n// ============================================================================\n\n/**\n * ReliableWrapper - Wrapper for reliable messages (server → client)\n *\n * Contains the original message payload with a unique ID for tracking.\n */\nexport interface ReliableWrapper {\n /** Unique message ID for tracking */\n __msgId: string;\n /** Original message payload */\n __payload: string;\n}\n\n/**\n * AckMessage - Acknowledgment message (client → server)\n *\n * Sent automatically by client when receiving a reliable message.\n */\nexport interface AckMessage {\n /** Message ID being acknowledged */\n __ack: string;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Check if data is a ReliableWrapper\n */\nexport function isReliableWrapper(data: unknown): data is ReliableWrapper {\n return typeof data === \"object\" && data !== null && \"__msgId\" in data && \"__payload\" in data;\n}\n\n/**\n * Check if data is an AckMessage\n */\nexport function isAckMessage(data: unknown): data is AckMessage {\n return typeof data === \"object\" && data !== null && \"__ack\" in data;\n}\n\n// ============================================================================\n// Protocol Helpers\n// ============================================================================\n\n/**\n * Wrap a message for reliable delivery\n */\nexport function wrapMessage(msgId: string, payload: string): ReliableWrapper {\n return { __msgId: msgId, __payload: payload };\n}\n\n/**\n * Create an ACK message\n */\nexport function createAck(msgId: string): AckMessage {\n return { __ack: msgId };\n}\n\n/**\n * Unwrap a reliable message, returning the original payload\n */\nexport function unwrapMessage(wrapper: ReliableWrapper): string {\n return wrapper.__payload;\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n","/**\n * JSON-RPC 2.0 Protocol for AgentX Network Communication\n *\n * Uses jsonrpc-lite for message parsing/serialization.\n *\n * Message Types:\n * - Request: Client → Server (has id, expects response)\n * - Response: Server → Client (success or error)\n * - Notification: Server → Client (no id, stream events)\n *\n * @see https://www.jsonrpc.org/specification\n */\n\nimport {\n request as jsonrpcRequest,\n notification as jsonrpcNotification,\n success as jsonrpcSuccess,\n error as jsonrpcError,\n parse as jsonrpcParse,\n parseObject as jsonrpcParseObject,\n JsonRpcError,\n} from \"jsonrpc-lite\";\nimport type { IParsedObject, JsonRpc } from \"jsonrpc-lite\";\nimport type { SystemEvent } from \"../event/types/base\";\n\n// ============================================================================\n// Re-export jsonrpc-lite types and functions\n// ============================================================================\n\nexport { JsonRpcError };\nexport type { IParsedObject, JsonRpc };\n\n// ============================================================================\n// RPC Method Names\n// ============================================================================\n\n/**\n * All RPC method names supported by AgentX\n */\nexport type RpcMethod =\n // Container\n | \"container.create\"\n | \"container.get\"\n | \"container.list\"\n // Image\n | \"image.create\"\n | \"image.get\"\n | \"image.list\"\n | \"image.delete\"\n | \"image.run\"\n | \"image.stop\"\n | \"image.update\"\n | \"image.messages\"\n // Agent\n | \"agent.get\"\n | \"agent.list\"\n | \"agent.destroy\"\n | \"agent.destroyAll\"\n | \"agent.interrupt\"\n // Message\n | \"message.send\";\n\n/**\n * Notification method names (server push)\n */\nexport type NotificationMethod =\n | \"stream.event\" // Stream events (text_delta, tool_call, etc.)\n | \"control.ack\"; // ACK for reliable delivery\n\n// ============================================================================\n// Request/Response Type Definitions\n// ============================================================================\n\n/**\n * JSON-RPC Request structure\n */\nexport interface RpcRequest<M extends RpcMethod = RpcMethod, P = unknown> {\n jsonrpc: \"2.0\";\n method: M;\n params: P;\n id: string | number;\n}\n\n/**\n * JSON-RPC Success Response structure\n */\nexport interface RpcSuccessResponse<R = unknown> {\n jsonrpc: \"2.0\";\n result: R;\n id: string | number;\n}\n\n/**\n * JSON-RPC Error Response structure\n */\nexport interface RpcErrorResponse {\n jsonrpc: \"2.0\";\n error: {\n code: number;\n message: string;\n data?: unknown;\n };\n id: string | number | null;\n}\n\n/**\n * JSON-RPC Notification structure (no id, no response expected)\n */\nexport interface RpcNotification<M extends NotificationMethod = NotificationMethod, P = unknown> {\n jsonrpc: \"2.0\";\n method: M;\n params: P;\n}\n\n/**\n * Stream event notification params\n */\nexport interface StreamEventParams {\n topic: string;\n event: SystemEvent;\n}\n\n/**\n * Control ACK notification params\n */\nexport interface ControlAckParams {\n msgId: string;\n}\n\n// ============================================================================\n// Standard JSON-RPC Error Codes\n// ============================================================================\n\nexport const RpcErrorCodes = {\n // Standard JSON-RPC errors\n PARSE_ERROR: -32700,\n INVALID_REQUEST: -32600,\n METHOD_NOT_FOUND: -32601,\n INVALID_PARAMS: -32602,\n INTERNAL_ERROR: -32603,\n // Server errors (reserved: -32000 to -32099)\n SERVER_ERROR: -32000,\n // Application errors (custom)\n NOT_FOUND: 404,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n TIMEOUT: 408,\n} as const;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Create a JSON-RPC request\n */\nexport function createRequest(\n id: string | number,\n method: RpcMethod | string,\n params: unknown\n): JsonRpc {\n return jsonrpcRequest(id, method, params as Record<string, unknown>);\n}\n\n/**\n * Create a JSON-RPC notification (no response expected)\n */\nexport function createNotification(method: NotificationMethod | string, params: unknown): JsonRpc {\n return jsonrpcNotification(method, params as Record<string, unknown>);\n}\n\n/**\n * Create a stream event notification\n */\nexport function createStreamEvent(topic: string, event: SystemEvent): JsonRpc {\n return jsonrpcNotification(\"stream.event\", { topic, event });\n}\n\n/**\n * Create an ACK notification\n */\nexport function createAckNotification(msgId: string): JsonRpc {\n return jsonrpcNotification(\"control.ack\", { msgId });\n}\n\n/**\n * Create a success response\n */\nexport function createSuccessResponse(id: string | number, result: unknown): JsonRpc {\n return jsonrpcSuccess(id, result as Record<string, unknown>);\n}\n\n/**\n * Create an error response\n */\nexport function createErrorResponse(\n id: string | number | null,\n code: number,\n message: string,\n data?: unknown\n): JsonRpc {\n return jsonrpcError(id, new JsonRpcError(message, code, data));\n}\n\n/**\n * Parse a JSON-RPC message string\n */\nexport function parseMessage(message: string): IParsedObject | IParsedObject[] {\n return jsonrpcParse(message);\n}\n\n/**\n * Parse a JSON-RPC message object\n */\nexport function parseMessageObject(obj: unknown): IParsedObject {\n return jsonrpcParseObject(obj);\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Check if parsed message is a request\n */\nexport function isRequest(parsed: IParsedObject): boolean {\n return parsed.type === \"request\";\n}\n\n/**\n * Check if parsed message is a notification\n */\nexport function isNotification(parsed: IParsedObject): boolean {\n return parsed.type === \"notification\";\n}\n\n/**\n * Check if parsed message is a success response\n */\nexport function isSuccessResponse(parsed: IParsedObject): boolean {\n return parsed.type === \"success\";\n}\n\n/**\n * Check if parsed message is an error response\n */\nexport function isErrorResponse(parsed: IParsedObject): boolean {\n return parsed.type === \"error\";\n}\n\n/**\n * Check if parsed message is invalid\n */\nexport function isInvalid(parsed: IParsedObject): boolean {\n return parsed.type === \"invalid\";\n}\n\n/**\n * Check if notification is a stream event\n */\nexport function isStreamEvent(parsed: IParsedObject): parsed is IParsedObject & {\n payload: RpcNotification<\"stream.event\", StreamEventParams>;\n} {\n if (parsed.type !== \"notification\") return false;\n const payload = parsed.payload as RpcNotification;\n return payload.method === \"stream.event\";\n}\n\n/**\n * Check if notification is a control ACK\n */\nexport function isControlAck(parsed: IParsedObject): parsed is IParsedObject & {\n payload: RpcNotification<\"control.ack\", ControlAckParams>;\n} {\n if (parsed.type !== \"notification\") return false;\n const payload = parsed.payload as RpcNotification;\n return payload.method === \"control.ack\";\n}\n\n// ============================================================================\n// Method Name Mapping (for backward compatibility)\n// ============================================================================\n\n/**\n * Map old event type names to new RPC method names\n */\nexport const eventTypeToRpcMethod: Record<string, RpcMethod> = {\n // Container\n container_create_request: \"container.create\",\n container_get_request: \"container.get\",\n container_list_request: \"container.list\",\n // Image\n image_create_request: \"image.create\",\n image_get_request: \"image.get\",\n image_list_request: \"image.list\",\n image_delete_request: \"image.delete\",\n image_run_request: \"image.run\",\n image_stop_request: \"image.stop\",\n image_update_request: \"image.update\",\n image_messages_request: \"image.messages\",\n // Agent\n agent_get_request: \"agent.get\",\n agent_list_request: \"agent.list\",\n agent_destroy_request: \"agent.destroy\",\n agent_destroy_all_request: \"agent.destroyAll\",\n agent_interrupt_request: \"agent.interrupt\",\n // Message\n message_send_request: \"message.send\",\n};\n\n/**\n * Map RPC method names back to response event types\n */\nexport const rpcMethodToResponseType: Record<RpcMethod, string> = {\n // Container\n \"container.create\": \"container_create_response\",\n \"container.get\": \"container_get_response\",\n \"container.list\": \"container_list_response\",\n // Image\n \"image.create\": \"image_create_response\",\n \"image.get\": \"image_get_response\",\n \"image.list\": \"image_list_response\",\n \"image.delete\": \"image_delete_response\",\n \"image.run\": \"image_run_response\",\n \"image.stop\": \"image_stop_response\",\n \"image.update\": \"image_update_response\",\n \"image.messages\": \"image_messages_response\",\n // Agent\n \"agent.get\": \"agent_get_response\",\n \"agent.list\": \"agent_list_response\",\n \"agent.destroy\": \"agent_destroy_response\",\n \"agent.destroyAll\": \"agent_destroy_all_response\",\n \"agent.interrupt\": \"agent_interrupt_response\",\n // Message\n \"message.send\": \"message_send_response\",\n};\n","/**\n * RpcClient - JSON-RPC 2.0 Client over WebSocket\n *\n * Provides:\n * - Request/Response with automatic ID matching\n * - Notification handling (stream events)\n * - Timeout management\n * - Reconnection support\n *\n * @example\n * ```typescript\n * const client = new RpcClient({ url: \"ws://localhost:5200\" });\n * await client.connect();\n *\n * // RPC call\n * const result = await client.call(\"container.list\", {});\n *\n * // Stream events\n * client.onNotification(\"stream.event\", (params) => {\n * console.log(\"Event:\", params.event);\n * });\n *\n * // Subscribe to topic\n * client.notify(\"subscribe\", { topic: \"session-123\" });\n * ```\n */\n\nimport {\n createRequest,\n createNotification,\n parseMessage,\n isSuccessResponse,\n isErrorResponse,\n isNotification,\n isStreamEvent,\n type RpcMethod,\n type NotificationMethod,\n type StreamEventParams,\n} from \"./jsonrpc\";\nimport type { SystemEvent } from \"../event/types/base\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Factory function for creating WebSocket instances.\n * Platform layer provides the implementation:\n * - Browser: native WebSocket (default)\n * - Node.js: ws library (via @agentxjs/node-platform)\n */\nexport type WebSocketFactory = (url: string) => WebSocket;\n\n/**\n * RpcClient configuration\n */\nexport interface RpcClientConfig {\n /**\n * WebSocket URL\n */\n url: string;\n\n /**\n * Factory for creating WebSocket instances.\n * If not provided, falls back to the global WebSocket constructor.\n */\n createWebSocket?: WebSocketFactory;\n\n /**\n * Request timeout in milliseconds (default: 30000)\n */\n timeout?: number;\n\n /**\n * Auto reconnect on disconnect (default: true)\n */\n autoReconnect?: boolean;\n\n /**\n * Reconnect delay in milliseconds (default: 3000)\n */\n reconnectDelay?: number;\n\n /**\n * Headers for authentication (sent in first message after connection)\n */\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n\n /**\n * Debug logging\n */\n debug?: boolean;\n}\n\n/**\n * Pending request state\n */\ninterface PendingRequest {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Notification handler\n */\ntype NotificationHandler = (method: string, params: unknown) => void;\n\n/**\n * Stream event handler\n */\ntype StreamEventHandler = (topic: string, event: SystemEvent) => void;\n\n/**\n * Connection state\n */\nexport type RpcClientState = \"disconnected\" | \"connecting\" | \"connected\";\n\n// ============================================================================\n// RpcClient Implementation\n// ============================================================================\n\n/**\n * JSON-RPC 2.0 Client\n */\nexport class RpcClient {\n private readonly config: RpcClientConfig;\n private readonly timeout: number;\n private readonly pendingRequests = new Map<string | number, PendingRequest>();\n private readonly notificationHandlers = new Set<NotificationHandler>();\n private readonly streamEventHandlers = new Set<StreamEventHandler>();\n\n private ws: WebSocket | null = null;\n private state: RpcClientState = \"disconnected\";\n private requestId = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n\n constructor(config: RpcClientConfig) {\n this.config = config;\n this.timeout = config.timeout ?? 30000;\n }\n\n // ==================== Properties ====================\n\n /**\n * Current connection state\n */\n get connectionState(): RpcClientState {\n return this.state;\n }\n\n /**\n * Whether client is connected\n */\n get connected(): boolean {\n return this.state === \"connected\";\n }\n\n // ==================== Connection ====================\n\n /**\n * Connect to server\n */\n async connect(): Promise<void> {\n if (this.disposed) {\n throw new Error(\"Client has been disposed\");\n }\n\n if (this.state === \"connected\") {\n return;\n }\n\n this.state = \"connecting\";\n\n const url = this.config.url;\n\n // Create WebSocket via injected factory or global WebSocket\n const factory = this.config.createWebSocket ?? ((u: string) => new WebSocket(u));\n const ws = factory(url);\n\n this.ws = ws;\n\n return new Promise((resolve, reject) => {\n ws.onopen = async () => {\n this.state = \"connected\";\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Connected to\", url);\n }\n\n // Send auth headers after connection (for environments where\n // WebSocket constructor doesn't support headers, e.g. browser)\n if (this.config.headers) {\n const headers =\n typeof this.config.headers === \"function\"\n ? await this.config.headers()\n : this.config.headers;\n this.notify(\"auth\" as NotificationMethod, { headers });\n }\n\n resolve();\n };\n\n ws.onclose = () => {\n this.state = \"disconnected\";\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Disconnected\");\n }\n\n // Auto reconnect\n if (!this.disposed && this.config.autoReconnect !== false) {\n this.scheduleReconnect();\n }\n };\n\n ws.onerror = (err) => {\n if (this.config.debug) {\n console.error(\"[RpcClient] WebSocket error:\", err);\n }\n\n if (this.state === \"connecting\") {\n this.state = \"disconnected\";\n reject(new Error(\"Failed to connect to server\"));\n }\n };\n\n ws.onmessage = (event) => {\n this.handleMessage(event.data as string);\n };\n });\n }\n\n /**\n * Disconnect from server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n\n this.state = \"disconnected\";\n }\n\n /**\n * Dispose client and clean up resources\n */\n dispose(): void {\n this.disposed = true;\n\n // Reject all pending requests\n for (const [id, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(\"Client disposed\"));\n this.pendingRequests.delete(id);\n }\n\n this.disconnect();\n this.notificationHandlers.clear();\n this.streamEventHandlers.clear();\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Disposed\");\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return;\n\n const delay = this.config.reconnectDelay ?? 3000;\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = null;\n\n if (!this.disposed && this.state === \"disconnected\") {\n if (this.config.debug) {\n console.log(\"[RpcClient] Attempting to reconnect...\");\n }\n\n try {\n await this.connect();\n } catch {\n this.scheduleReconnect();\n }\n }\n }, delay);\n }\n\n // ==================== RPC Methods ====================\n\n /**\n * Call an RPC method and wait for response\n */\n async call<T = unknown>(method: RpcMethod, params: unknown): Promise<T> {\n if (!this.connected || !this.ws) {\n throw new Error(\"Not connected to server\");\n }\n\n const id = ++this.requestId;\n const request = createRequest(id, method, params);\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request timeout: ${method}`));\n }, this.timeout);\n\n this.pendingRequests.set(id, {\n resolve: resolve as (result: unknown) => void,\n reject,\n timer,\n });\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Sending request:\", method, params);\n }\n\n this.ws!.send(JSON.stringify(request));\n });\n }\n\n /**\n * Send a notification (no response expected)\n */\n notify(method: NotificationMethod | string, params: unknown): void {\n if (!this.connected || !this.ws) {\n if (this.config.debug) {\n console.warn(\"[RpcClient] Cannot send notification: not connected\");\n }\n return;\n }\n\n const notification = createNotification(method as NotificationMethod, params);\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Sending notification:\", method, params);\n }\n\n this.ws.send(JSON.stringify(notification));\n }\n\n /**\n * Subscribe to a topic (convenience method)\n */\n subscribe(topic: string): void {\n this.notify(\"subscribe\", { topic });\n }\n\n /**\n * Unsubscribe from a topic (convenience method)\n */\n unsubscribe(topic: string): void {\n this.notify(\"unsubscribe\", { topic });\n }\n\n // ==================== Event Handlers ====================\n\n /**\n * Register handler for all notifications\n */\n onNotification(handler: NotificationHandler): () => void {\n this.notificationHandlers.add(handler);\n return () => this.notificationHandlers.delete(handler);\n }\n\n /**\n * Register handler for stream events\n */\n onStreamEvent(handler: StreamEventHandler): () => void {\n this.streamEventHandlers.add(handler);\n return () => this.streamEventHandlers.delete(handler);\n }\n\n // ==================== Message Handling ====================\n\n private handleMessage(data: string): void {\n try {\n const parsed = parseMessage(data);\n\n // Handle single message\n if (!Array.isArray(parsed)) {\n this.handleParsedMessage(parsed);\n } else {\n // Batch response (rare)\n for (const item of parsed) {\n this.handleParsedMessage(item);\n }\n }\n } catch (err) {\n if (this.config.debug) {\n console.error(\"[RpcClient] Failed to parse message:\", err);\n }\n }\n }\n\n private handleParsedMessage(parsed: import(\"jsonrpc-lite\").IParsedObject): void {\n if (isSuccessResponse(parsed)) {\n // Success response - resolve pending request\n const payload = parsed.payload as { id: string | number; result: unknown };\n const pending = this.pendingRequests.get(payload.id);\n\n if (pending) {\n this.pendingRequests.delete(payload.id);\n clearTimeout(pending.timer);\n pending.resolve(payload.result);\n }\n } else if (isErrorResponse(parsed)) {\n // Error response - reject pending request\n const payload = parsed.payload as {\n id: string | number | null;\n error: { code: number; message: string; data?: unknown };\n };\n\n if (payload.id !== null) {\n const pending = this.pendingRequests.get(payload.id);\n\n if (pending) {\n this.pendingRequests.delete(payload.id);\n clearTimeout(pending.timer);\n pending.reject(new Error(payload.error.message));\n }\n }\n } else if (isNotification(parsed)) {\n // Notification - stream event or control message\n const payload = parsed.payload as { method: string; params: unknown };\n\n if (this.config.debug) {\n console.log(\"[RpcClient] Received notification:\", payload.method);\n }\n\n // Notify all handlers\n for (const handler of this.notificationHandlers) {\n handler(payload.method, payload.params);\n }\n\n // Handle stream events specially\n if (isStreamEvent(parsed)) {\n const streamPayload = parsed.payload as { params: StreamEventParams };\n const { topic, event } = streamPayload.params;\n\n for (const handler of this.streamEventHandlers) {\n handler(topic, event);\n }\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|