@voidly/agent-sdk 3.2.0 → 3.2.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/index.js CHANGED
@@ -2230,22 +2230,22 @@ var require_nacl_fast = __commonJS({
2230
2230
  randombytes = fn;
2231
2231
  };
2232
2232
  (function() {
2233
- var crypto2 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
2234
- if (crypto2 && crypto2.getRandomValues) {
2233
+ var crypto = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
2234
+ if (crypto && crypto.getRandomValues) {
2235
2235
  var QUOTA = 65536;
2236
2236
  nacl2.setPRNG(function(x, n) {
2237
2237
  var i, v = new Uint8Array(n);
2238
2238
  for (i = 0; i < n; i += QUOTA) {
2239
- crypto2.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
2239
+ crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
2240
2240
  }
2241
2241
  for (i = 0; i < n; i++) x[i] = v[i];
2242
2242
  cleanup(v);
2243
2243
  });
2244
2244
  } else if (typeof require !== "undefined") {
2245
- crypto2 = require("crypto");
2246
- if (crypto2 && crypto2.randomBytes) {
2245
+ crypto = require("crypto");
2246
+ if (crypto && crypto.randomBytes) {
2247
2247
  nacl2.setPRNG(function(x, n) {
2248
- var i, v = crypto2.randomBytes(n);
2248
+ var i, v = crypto.randomBytes(n);
2249
2249
  for (i = 0; i < n; i++) x[i] = v[i];
2250
2250
  cleanup(v);
2251
2251
  });
@@ -4578,7 +4578,7 @@ var VoidlyAgent = class _VoidlyAgent {
4578
4578
  const combined = new Uint8Array(x25519Shared.length + pqShared.length);
4579
4579
  combined.set(x25519Shared, 0);
4580
4580
  combined.set(pqShared, x25519Shared.length);
4581
- initialKey = new Uint8Array(await crypto.subtle.digest("SHA-256", combined));
4581
+ initialKey = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", combined));
4582
4582
  } catch {
4583
4583
  initialKey = x25519Shared;
4584
4584
  }
@@ -4798,7 +4798,7 @@ var VoidlyAgent = class _VoidlyAgent {
4798
4798
  const combined = new Uint8Array(x25519Shared.length + pqShared.length);
4799
4799
  combined.set(x25519Shared, 0);
4800
4800
  combined.set(pqShared, x25519Shared.length);
4801
- initialKey = new Uint8Array(await crypto.subtle.digest("SHA-256", combined));
4801
+ initialKey = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", combined));
4802
4802
  } catch {
4803
4803
  initialKey = x25519Shared;
4804
4804
  }
@@ -6303,54 +6303,79 @@ var VoidlyAgent = class _VoidlyAgent {
6303
6303
  lastSeen = messages[messages.length - 1].timestamp;
6304
6304
  }
6305
6305
  };
6306
+ let lastEventId = "";
6307
+ let sseFailures = 0;
6306
6308
  const startSSE = async () => {
6307
6309
  try {
6308
6310
  const params = new URLSearchParams();
6309
6311
  if (lastSeen) params.set("since", lastSeen);
6310
6312
  if (options.from) params.set("from", options.from);
6311
6313
  const sseUrl = `${this.baseUrl}/v1/agent/receive/sse?${params}`;
6312
- const res = await this._timedFetch(sseUrl, {
6313
- headers: { "X-Agent-Key": this.apiKey }
6314
- });
6315
- if (!res.ok || !res.body) return false;
6314
+ const headers = { "X-Agent-Key": this.apiKey };
6315
+ if (lastEventId) headers["Last-Event-ID"] = lastEventId;
6316
+ const controller = new AbortController();
6317
+ const sseTimeout = setTimeout(() => controller.abort(), 6e4);
6318
+ let res;
6319
+ try {
6320
+ res = await fetch(sseUrl, { headers, signal: controller.signal });
6321
+ } catch (e) {
6322
+ clearTimeout(sseTimeout);
6323
+ throw e;
6324
+ }
6325
+ if (!res.ok || !res.body) {
6326
+ clearTimeout(sseTimeout);
6327
+ return false;
6328
+ }
6316
6329
  const reader = res.body.getReader();
6317
6330
  const decoder = new TextDecoder();
6318
6331
  let buffer = "";
6319
- while (active && !options.signal?.aborted) {
6320
- const { done: streamDone, value } = await reader.read();
6321
- if (streamDone) break;
6322
- buffer += decoder.decode(value, { stream: true });
6323
- const lines = buffer.split("\n");
6324
- buffer = lines.pop() || "";
6325
- let eventType = "";
6326
- let dataStr = "";
6327
- for (const line of lines) {
6328
- if (line.startsWith("event: ")) {
6329
- eventType = line.slice(7).trim();
6330
- } else if (line.startsWith("data: ")) {
6331
- dataStr = line.slice(6);
6332
- } else if (line === "" && dataStr) {
6333
- if (eventType === "message" && dataStr) {
6334
- try {
6335
- const rawMsg = JSON.parse(dataStr);
6336
- const decrypted = await this._decryptMessages([rawMsg]);
6337
- if (decrypted.length > 0) {
6338
- consecutiveEmpty = 0;
6339
- await deliverMessages(decrypted);
6332
+ try {
6333
+ while (active && !options.signal?.aborted) {
6334
+ const { done: streamDone, value } = await reader.read();
6335
+ if (streamDone) break;
6336
+ buffer += decoder.decode(value, { stream: true });
6337
+ const lines = buffer.split("\n");
6338
+ buffer = lines.pop() || "";
6339
+ let eventType = "";
6340
+ let dataStr = "";
6341
+ let eventId = "";
6342
+ for (const line of lines) {
6343
+ if (line.startsWith("event: ")) {
6344
+ eventType = line.slice(7).trim();
6345
+ } else if (line.startsWith("data: ")) {
6346
+ dataStr += (dataStr ? "\n" : "") + line.slice(6);
6347
+ } else if (line.startsWith("id: ")) {
6348
+ eventId = line.slice(4).trim();
6349
+ } else if (line === "" && (dataStr || eventType)) {
6350
+ if (eventId) lastEventId = eventId;
6351
+ if (eventType === "message" && dataStr) {
6352
+ try {
6353
+ const rawMsg = JSON.parse(dataStr);
6354
+ const decrypted = await this._decryptMessages([rawMsg]);
6355
+ if (decrypted.length > 0) {
6356
+ consecutiveEmpty = 0;
6357
+ sseFailures = 0;
6358
+ await deliverMessages(decrypted);
6359
+ }
6360
+ } catch {
6340
6361
  }
6341
- } catch {
6362
+ } else if (eventType === "reconnect") {
6363
+ break;
6342
6364
  }
6343
- } else if (eventType === "reconnect") {
6344
- break;
6365
+ eventType = "";
6366
+ dataStr = "";
6367
+ eventId = "";
6345
6368
  }
6346
- eventType = "";
6347
- dataStr = "";
6348
6369
  }
6349
6370
  }
6371
+ } finally {
6372
+ reader.releaseLock();
6373
+ clearTimeout(sseTimeout);
6350
6374
  }
6351
- reader.releaseLock();
6375
+ sseFailures = 0;
6352
6376
  return true;
6353
6377
  } catch {
6378
+ sseFailures++;
6354
6379
  return false;
6355
6380
  }
6356
6381
  };
@@ -6359,8 +6384,13 @@ var VoidlyAgent = class _VoidlyAgent {
6359
6384
  const ok = await startSSE();
6360
6385
  if (!active || options.signal?.aborted) break;
6361
6386
  if (!ok) {
6362
- poll();
6363
- return;
6387
+ if (sseFailures >= 3) {
6388
+ poll();
6389
+ return;
6390
+ }
6391
+ const backoff = Math.min(1e3 * Math.pow(2, sseFailures - 1), 4e3);
6392
+ await new Promise((r) => setTimeout(r, backoff));
6393
+ continue;
6364
6394
  }
6365
6395
  await new Promise((r) => setTimeout(r, 500));
6366
6396
  }
@@ -6735,7 +6765,12 @@ var VoidlyAgent = class _VoidlyAgent {
6735
6765
  for (const relay of relays) {
6736
6766
  try {
6737
6767
  const res = await this._timedFetch(`${relay}${path}`, init);
6738
- if (res.ok || res.status >= 400 && res.status < 500) return res;
6768
+ if (res.ok || res.status >= 400 && res.status < 500 && res.status !== 429) return res;
6769
+ if (res.status === 429) {
6770
+ const retryAfter = res.headers.get("Retry-After");
6771
+ const waitMs = retryAfter ? Math.min(parseInt(retryAfter, 10) * 1e3, 5e3) : 1e3;
6772
+ await new Promise((r) => setTimeout(r, waitMs));
6773
+ }
6739
6774
  } catch (err) {
6740
6775
  lastError = err instanceof Error ? err : new Error(String(err));
6741
6776
  }
package/dist/index.mjs CHANGED
@@ -2230,22 +2230,22 @@ var require_nacl_fast = __commonJS({
2230
2230
  randombytes = fn;
2231
2231
  };
2232
2232
  (function() {
2233
- var crypto2 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
2234
- if (crypto2 && crypto2.getRandomValues) {
2233
+ var crypto = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
2234
+ if (crypto && crypto.getRandomValues) {
2235
2235
  var QUOTA = 65536;
2236
2236
  nacl2.setPRNG(function(x, n) {
2237
2237
  var i, v = new Uint8Array(n);
2238
2238
  for (i = 0; i < n; i += QUOTA) {
2239
- crypto2.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
2239
+ crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
2240
2240
  }
2241
2241
  for (i = 0; i < n; i++) x[i] = v[i];
2242
2242
  cleanup(v);
2243
2243
  });
2244
2244
  } else if (typeof __require !== "undefined") {
2245
- crypto2 = __require("crypto");
2246
- if (crypto2 && crypto2.randomBytes) {
2245
+ crypto = __require("crypto");
2246
+ if (crypto && crypto.randomBytes) {
2247
2247
  nacl2.setPRNG(function(x, n) {
2248
- var i, v = crypto2.randomBytes(n);
2248
+ var i, v = crypto.randomBytes(n);
2249
2249
  for (i = 0; i < n; i++) x[i] = v[i];
2250
2250
  cleanup(v);
2251
2251
  });
@@ -4567,7 +4567,7 @@ var VoidlyAgent = class _VoidlyAgent {
4567
4567
  const combined = new Uint8Array(x25519Shared.length + pqShared.length);
4568
4568
  combined.set(x25519Shared, 0);
4569
4569
  combined.set(pqShared, x25519Shared.length);
4570
- initialKey = new Uint8Array(await crypto.subtle.digest("SHA-256", combined));
4570
+ initialKey = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", combined));
4571
4571
  } catch {
4572
4572
  initialKey = x25519Shared;
4573
4573
  }
@@ -4787,7 +4787,7 @@ var VoidlyAgent = class _VoidlyAgent {
4787
4787
  const combined = new Uint8Array(x25519Shared.length + pqShared.length);
4788
4788
  combined.set(x25519Shared, 0);
4789
4789
  combined.set(pqShared, x25519Shared.length);
4790
- initialKey = new Uint8Array(await crypto.subtle.digest("SHA-256", combined));
4790
+ initialKey = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", combined));
4791
4791
  } catch {
4792
4792
  initialKey = x25519Shared;
4793
4793
  }
@@ -6292,54 +6292,79 @@ var VoidlyAgent = class _VoidlyAgent {
6292
6292
  lastSeen = messages[messages.length - 1].timestamp;
6293
6293
  }
6294
6294
  };
6295
+ let lastEventId = "";
6296
+ let sseFailures = 0;
6295
6297
  const startSSE = async () => {
6296
6298
  try {
6297
6299
  const params = new URLSearchParams();
6298
6300
  if (lastSeen) params.set("since", lastSeen);
6299
6301
  if (options.from) params.set("from", options.from);
6300
6302
  const sseUrl = `${this.baseUrl}/v1/agent/receive/sse?${params}`;
6301
- const res = await this._timedFetch(sseUrl, {
6302
- headers: { "X-Agent-Key": this.apiKey }
6303
- });
6304
- if (!res.ok || !res.body) return false;
6303
+ const headers = { "X-Agent-Key": this.apiKey };
6304
+ if (lastEventId) headers["Last-Event-ID"] = lastEventId;
6305
+ const controller = new AbortController();
6306
+ const sseTimeout = setTimeout(() => controller.abort(), 6e4);
6307
+ let res;
6308
+ try {
6309
+ res = await fetch(sseUrl, { headers, signal: controller.signal });
6310
+ } catch (e) {
6311
+ clearTimeout(sseTimeout);
6312
+ throw e;
6313
+ }
6314
+ if (!res.ok || !res.body) {
6315
+ clearTimeout(sseTimeout);
6316
+ return false;
6317
+ }
6305
6318
  const reader = res.body.getReader();
6306
6319
  const decoder = new TextDecoder();
6307
6320
  let buffer = "";
6308
- while (active && !options.signal?.aborted) {
6309
- const { done: streamDone, value } = await reader.read();
6310
- if (streamDone) break;
6311
- buffer += decoder.decode(value, { stream: true });
6312
- const lines = buffer.split("\n");
6313
- buffer = lines.pop() || "";
6314
- let eventType = "";
6315
- let dataStr = "";
6316
- for (const line of lines) {
6317
- if (line.startsWith("event: ")) {
6318
- eventType = line.slice(7).trim();
6319
- } else if (line.startsWith("data: ")) {
6320
- dataStr = line.slice(6);
6321
- } else if (line === "" && dataStr) {
6322
- if (eventType === "message" && dataStr) {
6323
- try {
6324
- const rawMsg = JSON.parse(dataStr);
6325
- const decrypted = await this._decryptMessages([rawMsg]);
6326
- if (decrypted.length > 0) {
6327
- consecutiveEmpty = 0;
6328
- await deliverMessages(decrypted);
6321
+ try {
6322
+ while (active && !options.signal?.aborted) {
6323
+ const { done: streamDone, value } = await reader.read();
6324
+ if (streamDone) break;
6325
+ buffer += decoder.decode(value, { stream: true });
6326
+ const lines = buffer.split("\n");
6327
+ buffer = lines.pop() || "";
6328
+ let eventType = "";
6329
+ let dataStr = "";
6330
+ let eventId = "";
6331
+ for (const line of lines) {
6332
+ if (line.startsWith("event: ")) {
6333
+ eventType = line.slice(7).trim();
6334
+ } else if (line.startsWith("data: ")) {
6335
+ dataStr += (dataStr ? "\n" : "") + line.slice(6);
6336
+ } else if (line.startsWith("id: ")) {
6337
+ eventId = line.slice(4).trim();
6338
+ } else if (line === "" && (dataStr || eventType)) {
6339
+ if (eventId) lastEventId = eventId;
6340
+ if (eventType === "message" && dataStr) {
6341
+ try {
6342
+ const rawMsg = JSON.parse(dataStr);
6343
+ const decrypted = await this._decryptMessages([rawMsg]);
6344
+ if (decrypted.length > 0) {
6345
+ consecutiveEmpty = 0;
6346
+ sseFailures = 0;
6347
+ await deliverMessages(decrypted);
6348
+ }
6349
+ } catch {
6329
6350
  }
6330
- } catch {
6351
+ } else if (eventType === "reconnect") {
6352
+ break;
6331
6353
  }
6332
- } else if (eventType === "reconnect") {
6333
- break;
6354
+ eventType = "";
6355
+ dataStr = "";
6356
+ eventId = "";
6334
6357
  }
6335
- eventType = "";
6336
- dataStr = "";
6337
6358
  }
6338
6359
  }
6360
+ } finally {
6361
+ reader.releaseLock();
6362
+ clearTimeout(sseTimeout);
6339
6363
  }
6340
- reader.releaseLock();
6364
+ sseFailures = 0;
6341
6365
  return true;
6342
6366
  } catch {
6367
+ sseFailures++;
6343
6368
  return false;
6344
6369
  }
6345
6370
  };
@@ -6348,8 +6373,13 @@ var VoidlyAgent = class _VoidlyAgent {
6348
6373
  const ok = await startSSE();
6349
6374
  if (!active || options.signal?.aborted) break;
6350
6375
  if (!ok) {
6351
- poll();
6352
- return;
6376
+ if (sseFailures >= 3) {
6377
+ poll();
6378
+ return;
6379
+ }
6380
+ const backoff = Math.min(1e3 * Math.pow(2, sseFailures - 1), 4e3);
6381
+ await new Promise((r) => setTimeout(r, backoff));
6382
+ continue;
6353
6383
  }
6354
6384
  await new Promise((r) => setTimeout(r, 500));
6355
6385
  }
@@ -6724,7 +6754,12 @@ var VoidlyAgent = class _VoidlyAgent {
6724
6754
  for (const relay of relays) {
6725
6755
  try {
6726
6756
  const res = await this._timedFetch(`${relay}${path}`, init);
6727
- if (res.ok || res.status >= 400 && res.status < 500) return res;
6757
+ if (res.ok || res.status >= 400 && res.status < 500 && res.status !== 429) return res;
6758
+ if (res.status === 429) {
6759
+ const retryAfter = res.headers.get("Retry-After");
6760
+ const waitMs = retryAfter ? Math.min(parseInt(retryAfter, 10) * 1e3, 5e3) : 1e3;
6761
+ await new Promise((r) => setTimeout(r, waitMs));
6762
+ }
6728
6763
  } catch (err) {
6729
6764
  lastError = err instanceof Error ? err : new Error(String(err));
6730
6765
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidly/agent-sdk",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "E2E encrypted agent-to-agent communication SDK — Double Ratchet, X3DH, deniable auth, ML-KEM-768 post-quantum, SSE streaming, ratchet persistence, multi-relay federation",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",