agentxjs 0.1.9 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/browser.cjs CHANGED
@@ -1,19 +1,24 @@
1
1
  'use strict';
2
2
 
3
+ var __defProp = Object.defineProperty;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
5
  var __esm = (fn, res) => function __init() {
5
6
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
7
  };
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
7
12
 
8
13
  // ../common/dist/index.js
9
14
  function createLogger(name) {
10
15
  return LoggerFactoryImpl.getLogger(name);
11
16
  }
12
- var __defProp, __defNormalProp, __publicField, _ConsoleLogger, ConsoleLogger, externalFactory, LoggerFactoryImpl;
17
+ var __defProp2, __defNormalProp, __publicField, _ConsoleLogger, ConsoleLogger, externalFactory, LoggerFactoryImpl;
13
18
  var init_dist = __esm({
14
19
  "../common/dist/index.js"() {
15
- __defProp = Object.defineProperty;
16
- __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
20
+ __defProp2 = Object.defineProperty;
21
+ __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
17
22
  __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
18
23
  _ConsoleLogger = class _ConsoleLogger2 {
19
24
  constructor(name, options = {}) {
@@ -179,6 +184,471 @@ var init_dist = __esm({
179
184
  }
180
185
  });
181
186
 
187
+ // ../network/dist/chunk-63P5VUHB.js
188
+ async function createWebSocketClient(options) {
189
+ if (isBrowser) {
190
+ const client = new BrowserWebSocketClient(options);
191
+ await client.connect();
192
+ return client;
193
+ } else {
194
+ const client = new WebSocketClient(options);
195
+ await client.connect();
196
+ return client;
197
+ }
198
+ }
199
+ var __defProp3, __defNormalProp2, __publicField2, logger, isBrowser, WebSocketClient, BrowserWebSocketClient;
200
+ var init_chunk_63P5VUHB = __esm({
201
+ "../network/dist/chunk-63P5VUHB.js"() {
202
+ init_dist();
203
+ __defProp3 = Object.defineProperty;
204
+ __defNormalProp2 = (obj, key, value) => key in obj ? __defProp3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
205
+ __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
206
+ logger = createLogger("network/WebSocketClient");
207
+ isBrowser = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined" && typeof globalThis.window.WebSocket !== "undefined";
208
+ WebSocketClient = class {
209
+ constructor(options) {
210
+ __publicField2(this, "ws", null);
211
+ __publicField2(this, "serverUrl");
212
+ __publicField2(this, "messageHandlers", /* @__PURE__ */ new Set());
213
+ __publicField2(this, "openHandlers", /* @__PURE__ */ new Set());
214
+ __publicField2(this, "closeHandlers", /* @__PURE__ */ new Set());
215
+ __publicField2(this, "errorHandlers", /* @__PURE__ */ new Set());
216
+ if (isBrowser) {
217
+ throw new Error(
218
+ "Use createBrowserWebSocketClient() in browser environment for auto-reconnect support"
219
+ );
220
+ }
221
+ this.serverUrl = options.serverUrl;
222
+ }
223
+ get readyState() {
224
+ if (!this.ws) return "closed";
225
+ const state = this.ws.readyState;
226
+ if (state === 0) return "connecting";
227
+ if (state === 1) return "open";
228
+ if (state === 2) return "closing";
229
+ return "closed";
230
+ }
231
+ async connect() {
232
+ if (this.ws) {
233
+ throw new Error("Already connected or connecting");
234
+ }
235
+ const { WebSocket: NodeWebSocket } = await import('ws');
236
+ this.ws = new NodeWebSocket(this.serverUrl);
237
+ return new Promise((resolve, reject) => {
238
+ const onOpen = () => {
239
+ logger.info("WebSocket connected", { serverUrl: this.serverUrl });
240
+ for (const handler of this.openHandlers) {
241
+ handler();
242
+ }
243
+ resolve();
244
+ };
245
+ const onError = (err) => {
246
+ logger.error("WebSocket connection failed", {
247
+ serverUrl: this.serverUrl,
248
+ error: err?.message
249
+ });
250
+ reject(err || new Error("WebSocket connection failed"));
251
+ };
252
+ this.ws.once("open", onOpen);
253
+ this.ws.once("error", onError);
254
+ this.ws.on("message", (data) => {
255
+ const message = data.toString();
256
+ for (const handler of this.messageHandlers) {
257
+ handler(message);
258
+ }
259
+ });
260
+ this.ws.on("close", () => {
261
+ logger.warn("WebSocket closed");
262
+ for (const handler of this.closeHandlers) {
263
+ handler();
264
+ }
265
+ });
266
+ this.ws.on("error", (err) => {
267
+ logger.error("WebSocket error", { error: err.message });
268
+ for (const handler of this.errorHandlers) {
269
+ handler(err);
270
+ }
271
+ });
272
+ });
273
+ }
274
+ send(message) {
275
+ if (!this.ws || this.ws.readyState !== 1) {
276
+ throw new Error("WebSocket is not open");
277
+ }
278
+ this.ws.send(message);
279
+ }
280
+ onMessage(handler) {
281
+ this.messageHandlers.add(handler);
282
+ return () => {
283
+ this.messageHandlers.delete(handler);
284
+ };
285
+ }
286
+ onOpen(handler) {
287
+ this.openHandlers.add(handler);
288
+ return () => {
289
+ this.openHandlers.delete(handler);
290
+ };
291
+ }
292
+ onClose(handler) {
293
+ this.closeHandlers.add(handler);
294
+ return () => {
295
+ this.closeHandlers.delete(handler);
296
+ };
297
+ }
298
+ onError(handler) {
299
+ this.errorHandlers.add(handler);
300
+ return () => {
301
+ this.errorHandlers.delete(handler);
302
+ };
303
+ }
304
+ close() {
305
+ if (this.ws) {
306
+ this.ws.close();
307
+ this.ws = null;
308
+ }
309
+ }
310
+ dispose() {
311
+ this.close();
312
+ this.messageHandlers.clear();
313
+ this.openHandlers.clear();
314
+ this.closeHandlers.clear();
315
+ this.errorHandlers.clear();
316
+ }
317
+ };
318
+ BrowserWebSocketClient = class {
319
+ // Track if this is a reconnection
320
+ constructor(options) {
321
+ __publicField2(this, "ws", null);
322
+ __publicField2(this, "serverUrl");
323
+ __publicField2(this, "options");
324
+ __publicField2(this, "messageHandlers", /* @__PURE__ */ new Set());
325
+ __publicField2(this, "openHandlers", /* @__PURE__ */ new Set());
326
+ __publicField2(this, "closeHandlers", /* @__PURE__ */ new Set());
327
+ __publicField2(this, "errorHandlers", /* @__PURE__ */ new Set());
328
+ __publicField2(this, "hasConnectedBefore", false);
329
+ if (!isBrowser) {
330
+ throw new Error("BrowserWebSocketClient can only be used in browser environment");
331
+ }
332
+ this.serverUrl = options.serverUrl;
333
+ this.options = {
334
+ autoReconnect: true,
335
+ minReconnectionDelay: 1e3,
336
+ maxReconnectionDelay: 1e4,
337
+ maxRetries: Infinity,
338
+ connectionTimeout: 4e3,
339
+ debug: false,
340
+ ...options
341
+ };
342
+ }
343
+ get readyState() {
344
+ if (!this.ws) return "closed";
345
+ const state = this.ws.readyState;
346
+ if (state === 0) return "connecting";
347
+ if (state === 1) return "open";
348
+ if (state === 2) return "closing";
349
+ return "closed";
350
+ }
351
+ async connect() {
352
+ if (this.ws) {
353
+ throw new Error("Already connected or connecting");
354
+ }
355
+ if (this.options.autoReconnect) {
356
+ const ReconnectingWebSocket = (await import('reconnecting-websocket')).default;
357
+ this.ws = new ReconnectingWebSocket(this.serverUrl, [], {
358
+ maxReconnectionDelay: this.options.maxReconnectionDelay,
359
+ minReconnectionDelay: this.options.minReconnectionDelay,
360
+ reconnectionDelayGrowFactor: 1.3,
361
+ connectionTimeout: this.options.connectionTimeout,
362
+ maxRetries: this.options.maxRetries,
363
+ debug: this.options.debug
364
+ });
365
+ } else {
366
+ this.ws = new WebSocket(this.serverUrl);
367
+ }
368
+ return new Promise((resolve, reject) => {
369
+ const onOpen = () => {
370
+ if (this.hasConnectedBefore) {
371
+ logger.info("WebSocket reconnected successfully", { serverUrl: this.serverUrl });
372
+ } else {
373
+ logger.info("WebSocket connected", { serverUrl: this.serverUrl });
374
+ this.hasConnectedBefore = true;
375
+ }
376
+ for (const handler of this.openHandlers) {
377
+ handler();
378
+ }
379
+ resolve();
380
+ };
381
+ const onError = (_event) => {
382
+ logger.error("WebSocket connection failed", { serverUrl: this.serverUrl });
383
+ const error = new Error("WebSocket connection failed");
384
+ for (const handler of this.errorHandlers) {
385
+ handler(error);
386
+ }
387
+ reject(error);
388
+ };
389
+ this.ws.addEventListener("open", onOpen, { once: true });
390
+ this.ws.addEventListener("error", onError, { once: true });
391
+ this.ws.addEventListener("message", ((event) => {
392
+ const message = event.data;
393
+ for (const handler of this.messageHandlers) {
394
+ handler(message);
395
+ }
396
+ }));
397
+ this.ws.addEventListener("close", (() => {
398
+ logger.info("WebSocket closed, attempting to reconnect...");
399
+ for (const handler of this.closeHandlers) {
400
+ handler();
401
+ }
402
+ }));
403
+ this.ws.addEventListener("error", ((_event) => {
404
+ logger.error("WebSocket error");
405
+ const error = new Error("WebSocket error");
406
+ for (const handler of this.errorHandlers) {
407
+ handler(error);
408
+ }
409
+ }));
410
+ });
411
+ }
412
+ send(message) {
413
+ if (!this.ws || this.ws.readyState !== 1) {
414
+ throw new Error("WebSocket is not open");
415
+ }
416
+ this.ws.send(message);
417
+ }
418
+ onMessage(handler) {
419
+ this.messageHandlers.add(handler);
420
+ return () => {
421
+ this.messageHandlers.delete(handler);
422
+ };
423
+ }
424
+ onOpen(handler) {
425
+ this.openHandlers.add(handler);
426
+ return () => {
427
+ this.openHandlers.delete(handler);
428
+ };
429
+ }
430
+ onClose(handler) {
431
+ this.closeHandlers.add(handler);
432
+ return () => {
433
+ this.closeHandlers.delete(handler);
434
+ };
435
+ }
436
+ onError(handler) {
437
+ this.errorHandlers.add(handler);
438
+ return () => {
439
+ this.errorHandlers.delete(handler);
440
+ };
441
+ }
442
+ close() {
443
+ if (this.ws) {
444
+ this.ws.close();
445
+ this.ws = null;
446
+ }
447
+ }
448
+ dispose() {
449
+ this.close();
450
+ this.messageHandlers.clear();
451
+ this.openHandlers.clear();
452
+ this.closeHandlers.clear();
453
+ this.errorHandlers.clear();
454
+ }
455
+ };
456
+ }
457
+ });
458
+
459
+ // ../network/dist/index.js
460
+ var dist_exports = {};
461
+ __export(dist_exports, {
462
+ WebSocketClient: () => WebSocketClient,
463
+ WebSocketServer: () => WebSocketServer,
464
+ createWebSocketClient: () => createWebSocketClient
465
+ });
466
+ var logger2, WebSocketConnection, WebSocketServer;
467
+ var init_dist2 = __esm({
468
+ "../network/dist/index.js"() {
469
+ init_chunk_63P5VUHB();
470
+ init_dist();
471
+ logger2 = createLogger("network/WebSocketServer");
472
+ WebSocketConnection = class {
473
+ constructor(ws, options) {
474
+ __publicField2(this, "id");
475
+ __publicField2(this, "ws");
476
+ __publicField2(this, "messageHandlers", /* @__PURE__ */ new Set());
477
+ __publicField2(this, "closeHandlers", /* @__PURE__ */ new Set());
478
+ __publicField2(this, "errorHandlers", /* @__PURE__ */ new Set());
479
+ __publicField2(this, "heartbeatInterval");
480
+ __publicField2(this, "isAlive", true);
481
+ this.ws = ws;
482
+ this.id = `conn_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
483
+ if (options.heartbeat !== false) {
484
+ const interval = options.heartbeatInterval || 3e4;
485
+ ws.on("pong", () => {
486
+ this.isAlive = true;
487
+ logger2.debug("Heartbeat pong received", { id: this.id });
488
+ });
489
+ this.heartbeatInterval = setInterval(() => {
490
+ if (!this.isAlive) {
491
+ logger2.warn("Client heartbeat timeout, terminating connection", { id: this.id });
492
+ clearInterval(this.heartbeatInterval);
493
+ ws.terminate();
494
+ return;
495
+ }
496
+ this.isAlive = false;
497
+ ws.ping();
498
+ logger2.debug("Heartbeat ping sent", { id: this.id });
499
+ }, interval);
500
+ }
501
+ ws.on("message", (data) => {
502
+ const message = data.toString();
503
+ for (const handler of this.messageHandlers) {
504
+ handler(message);
505
+ }
506
+ });
507
+ ws.on("close", () => {
508
+ if (this.heartbeatInterval) {
509
+ clearInterval(this.heartbeatInterval);
510
+ }
511
+ for (const handler of this.closeHandlers) {
512
+ handler();
513
+ }
514
+ });
515
+ ws.on("error", (err) => {
516
+ if (this.heartbeatInterval) {
517
+ clearInterval(this.heartbeatInterval);
518
+ }
519
+ for (const handler of this.errorHandlers) {
520
+ handler(err);
521
+ }
522
+ });
523
+ }
524
+ send(message) {
525
+ if (this.ws.readyState === 1) {
526
+ this.ws.send(message);
527
+ }
528
+ }
529
+ onMessage(handler) {
530
+ this.messageHandlers.add(handler);
531
+ return () => {
532
+ this.messageHandlers.delete(handler);
533
+ };
534
+ }
535
+ onClose(handler) {
536
+ this.closeHandlers.add(handler);
537
+ return () => {
538
+ this.closeHandlers.delete(handler);
539
+ };
540
+ }
541
+ onError(handler) {
542
+ this.errorHandlers.add(handler);
543
+ return () => {
544
+ this.errorHandlers.delete(handler);
545
+ };
546
+ }
547
+ close() {
548
+ if (this.heartbeatInterval) {
549
+ clearInterval(this.heartbeatInterval);
550
+ }
551
+ this.ws.close();
552
+ }
553
+ };
554
+ WebSocketServer = class {
555
+ constructor(options = {}) {
556
+ __publicField2(this, "wss", null);
557
+ __publicField2(this, "connections", /* @__PURE__ */ new Set());
558
+ __publicField2(this, "connectionHandlers", /* @__PURE__ */ new Set());
559
+ __publicField2(this, "options");
560
+ __publicField2(this, "attachedToServer", false);
561
+ this.options = options;
562
+ }
563
+ async listen(port, host = "0.0.0.0") {
564
+ if (this.wss) {
565
+ throw new Error("Server already listening");
566
+ }
567
+ if (this.attachedToServer) {
568
+ throw new Error(
569
+ "Cannot listen when attached to existing server. The server should call listen() instead."
570
+ );
571
+ }
572
+ const { WebSocketServer: WSS } = await import('ws');
573
+ this.wss = new WSS({ port, host });
574
+ this.wss.on("connection", (ws) => {
575
+ this.handleConnection(ws);
576
+ });
577
+ logger2.info("WebSocket server listening", { port, host });
578
+ }
579
+ attach(server, path = "/ws") {
580
+ if (this.wss) {
581
+ throw new Error("Server already initialized");
582
+ }
583
+ import('ws').then(({ WebSocketServer: WSS }) => {
584
+ this.wss = new WSS({ noServer: true });
585
+ server.on("upgrade", (request, socket, head) => {
586
+ const url = new URL(request.url || "", `http://${request.headers.host}`);
587
+ if (url.pathname === path) {
588
+ this.wss.handleUpgrade(request, socket, head, (ws) => {
589
+ this.wss.emit("connection", ws, request);
590
+ });
591
+ } else {
592
+ socket.destroy();
593
+ }
594
+ });
595
+ this.wss.on("connection", (ws) => {
596
+ this.handleConnection(ws);
597
+ });
598
+ this.attachedToServer = true;
599
+ logger2.info("WebSocket attached to existing HTTP server", { path });
600
+ });
601
+ }
602
+ handleConnection(ws) {
603
+ const connection = new WebSocketConnection(ws, this.options);
604
+ this.connections.add(connection);
605
+ logger2.info("Client connected", {
606
+ connectionId: connection.id,
607
+ totalConnections: this.connections.size
608
+ });
609
+ connection.onClose(() => {
610
+ this.connections.delete(connection);
611
+ logger2.info("Client disconnected", {
612
+ connectionId: connection.id,
613
+ totalConnections: this.connections.size
614
+ });
615
+ });
616
+ for (const handler of this.connectionHandlers) {
617
+ handler(connection);
618
+ }
619
+ }
620
+ onConnection(handler) {
621
+ this.connectionHandlers.add(handler);
622
+ return () => {
623
+ this.connectionHandlers.delete(handler);
624
+ };
625
+ }
626
+ broadcast(message) {
627
+ for (const connection of this.connections) {
628
+ connection.send(message);
629
+ }
630
+ }
631
+ async close() {
632
+ if (!this.wss) return;
633
+ for (const connection of this.connections) {
634
+ connection.close();
635
+ }
636
+ this.connections.clear();
637
+ if (!this.attachedToServer) {
638
+ await new Promise((resolve) => {
639
+ this.wss.close(() => resolve());
640
+ });
641
+ }
642
+ this.wss = null;
643
+ }
644
+ async dispose() {
645
+ await this.close();
646
+ this.connectionHandlers.clear();
647
+ }
648
+ };
649
+ }
650
+ });
651
+
182
652
  // ../types/dist/agentx.js
183
653
  function isRemoteConfig(config) {
184
654
  return "serverUrl" in config && typeof config.serverUrl === "string";
@@ -231,25 +701,22 @@ function isAgentEvent(event) {
231
701
  // src/createAgentX.ts
232
702
  init_dist();
233
703
  var remoteLogger = createLogger("agentx/RemoteClient");
234
- var isBrowser = typeof window !== "undefined" && typeof window.WebSocket !== "undefined";
235
704
  async function createRemoteAgentX(serverUrl) {
236
- const WebSocketImpl = isBrowser ? window.WebSocket : (await import('ws')).WebSocket;
237
- const ws = new WebSocketImpl(serverUrl);
705
+ const { createWebSocketClient: createWebSocketClient2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
706
+ const client = await createWebSocketClient2({
707
+ serverUrl,
708
+ autoReconnect: true,
709
+ minReconnectionDelay: 1e3,
710
+ maxReconnectionDelay: 1e4,
711
+ connectionTimeout: 4e3,
712
+ maxRetries: Infinity,
713
+ debug: false
714
+ });
238
715
  const handlers = /* @__PURE__ */ new Map();
239
716
  const pendingRequests = /* @__PURE__ */ new Map();
240
- await new Promise((resolve, reject) => {
241
- if (isBrowser) {
242
- ws.onopen = () => resolve();
243
- ws.onerror = () => reject(new Error("WebSocket connection failed"));
244
- } else {
245
- ws.on("open", () => resolve());
246
- ws.on("error", (err) => reject(err));
247
- }
248
- });
249
- const handleMessage = (data) => {
717
+ client.onMessage((message) => {
250
718
  try {
251
- const text = isBrowser ? data.data : data.toString();
252
- const event = JSON.parse(text);
719
+ const event = JSON.parse(message);
253
720
  remoteLogger.info("Received event", {
254
721
  type: event.type,
255
722
  category: event.category,
@@ -287,12 +754,13 @@ async function createRemoteAgentX(serverUrl) {
287
754
  }
288
755
  } catch {
289
756
  }
290
- };
291
- if (isBrowser) {
292
- ws.onmessage = handleMessage;
293
- } else {
294
- ws.on("message", handleMessage);
295
- }
757
+ });
758
+ client.onClose(() => {
759
+ remoteLogger.warn("WebSocket closed");
760
+ });
761
+ client.onError((error) => {
762
+ remoteLogger.error("WebSocket error", { error: error.message });
763
+ });
296
764
  function subscribe(type, handler) {
297
765
  if (!handlers.has(type)) {
298
766
  handlers.set(type, /* @__PURE__ */ new Set());
@@ -323,7 +791,7 @@ async function createRemoteAgentX(serverUrl) {
323
791
  category: "request",
324
792
  intent: "request"
325
793
  };
326
- ws.send(JSON.stringify(event));
794
+ client.send(JSON.stringify(event));
327
795
  });
328
796
  },
329
797
  on(type, handler) {
@@ -341,7 +809,7 @@ async function createRemoteAgentX(serverUrl) {
341
809
  category: type.toString().endsWith("_response") ? "response" : "request",
342
810
  intent: type.toString().endsWith("_response") ? "result" : "request"
343
811
  };
344
- ws.send(JSON.stringify(event));
812
+ client.send(JSON.stringify(event));
345
813
  },
346
814
  async listen() {
347
815
  throw new Error("Cannot listen in remote mode");
@@ -355,11 +823,7 @@ async function createRemoteAgentX(serverUrl) {
355
823
  }
356
824
  pendingRequests.clear();
357
825
  handlers.clear();
358
- if (isBrowser) {
359
- ws.close();
360
- } else {
361
- ws.close();
362
- }
826
+ client.dispose();
363
827
  }
364
828
  };
365
829
  }