@agentvault/agentvault 0.9.4 → 0.9.5

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
@@ -45292,6 +45292,8 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
45292
45292
  _lastWakeTick = Date.now();
45293
45293
  _pendingPollTimer = null;
45294
45294
  _syncMessageIds = null;
45295
+ /** Recently handled message IDs via WS — survives reconnects so sync skips them. Max 500. */
45296
+ _recentlyHandledIds = /* @__PURE__ */ new Set();
45295
45297
  /** Queued A2A messages for responder channels not yet activated (no first initiator message received). */
45296
45298
  _a2aPendingQueue = {};
45297
45299
  _scanEngine = null;
@@ -46405,7 +46407,9 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46405
46407
  };
46406
46408
  process.on("unhandledRejection", _onUnhandledRejection);
46407
46409
  process.on("uncaughtException", _onUncaughtException);
46408
- ws.on("close", () => {
46410
+ ws.on("close", (code, reason) => {
46411
+ const reasonStr = reason?.toString() || "";
46412
+ console.log(`[SecureChannel] WS CLOSED: code=${code} reason=${JSON.stringify(reasonStr)}`);
46409
46413
  process.removeListener("unhandledRejection", _onUnhandledRejection);
46410
46414
  process.removeListener("uncaughtException", _onUncaughtException);
46411
46415
  });
@@ -46428,8 +46432,10 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46428
46432
  return;
46429
46433
  }
46430
46434
  if (data.event === "message") {
46435
+ console.log(`[SecureChannel] \u2190 Direct message received: msg=${data.data?.message_id?.slice(0, 8) ?? "?"} conv=${data.data?.conversation_id?.slice(0, 8) ?? "?"}`);
46431
46436
  try {
46432
46437
  await this._handleIncomingMessage(data.data);
46438
+ console.log(`[SecureChannel] \u2190 Direct message processed OK: msg=${data.data?.message_id?.slice(0, 8) ?? "?"}`);
46433
46439
  } catch (msgErr) {
46434
46440
  console.error(
46435
46441
  `[SecureChannel] Message handler failed for conv ${data.data?.conversation_id?.slice(0, 8) ?? "?"}...:`,
@@ -46761,7 +46767,9 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46761
46767
  this.emit("error", err);
46762
46768
  }
46763
46769
  });
46764
- ws.on("close", () => {
46770
+ ws.on("close", (code, reason) => {
46771
+ const reasonStr = reason?.toString() || "";
46772
+ console.log(`[SecureChannel] WS close handler: code=${code} reason=${JSON.stringify(reasonStr)}`);
46765
46773
  this._stopPing();
46766
46774
  this._stopWakeDetector();
46767
46775
  this._stopPendingPoll();
@@ -46783,6 +46791,11 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46783
46791
  if (this._syncMessageIds?.has(msgData.message_id)) {
46784
46792
  return;
46785
46793
  }
46794
+ this._recentlyHandledIds.add(msgData.message_id);
46795
+ if (this._recentlyHandledIds.size > 500) {
46796
+ const all = [...this._recentlyHandledIds];
46797
+ this._recentlyHandledIds = new Set(all.slice(all.length - 400));
46798
+ }
46786
46799
  const convId = msgData.conversation_id;
46787
46800
  const session = this._sessions.get(convId);
46788
46801
  if (!session) {
@@ -46795,7 +46808,14 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46795
46808
  header_blob: msgData.header_blob,
46796
46809
  ciphertext: msgData.ciphertext
46797
46810
  });
46798
- const plaintext = session.ratchet.decrypt(encrypted);
46811
+ let plaintext;
46812
+ try {
46813
+ plaintext = session.ratchet.decrypt(encrypted);
46814
+ } catch (decryptErr) {
46815
+ console.error(`[SecureChannel] Direct message decrypt FAILED for conv ${convId.slice(0, 8)}...: ${String(decryptErr)}`);
46816
+ throw decryptErr;
46817
+ }
46818
+ console.log(`[SecureChannel] Direct message decrypted OK for conv ${convId.slice(0, 8)}...`);
46799
46819
  this._sendAck(msgData.message_id);
46800
46820
  if (!session.activated) {
46801
46821
  session.activated = true;
@@ -46888,7 +46908,13 @@ ${messageText}`;
46888
46908
  Promise.resolve(this.config.onMessage?.(emitText, metadata)).catch((err) => {
46889
46909
  console.error("[SecureChannel] onMessage callback error:", err);
46890
46910
  });
46891
- await this._relaySyncToSiblings(convId, session.ownerDeviceId, messageText, topicId);
46911
+ console.log(`[SecureChannel] Relaying sync to ${this._sessions.size - 1} siblings for conv ${convId.slice(0, 8)}...`);
46912
+ try {
46913
+ await this._relaySyncToSiblings(convId, session.ownerDeviceId, messageText, topicId);
46914
+ console.log(`[SecureChannel] Sync relay complete for conv ${convId.slice(0, 8)}...`);
46915
+ } catch (relayErr) {
46916
+ console.error(`[SecureChannel] Sync relay FAILED: ${String(relayErr)}`);
46917
+ }
46892
46918
  }
46893
46919
  if (this._persisted) {
46894
46920
  this._persisted.lastMessageTimestamp = msgData.created_at;
@@ -47013,22 +47039,29 @@ ${messageText}`;
47013
47039
  ts: (/* @__PURE__ */ new Date()).toISOString(),
47014
47040
  topicId
47015
47041
  });
47042
+ let relayed = 0;
47016
47043
  for (const [siblingConvId, siblingSession] of this._sessions) {
47017
47044
  if (siblingConvId === sourceConvId) continue;
47018
47045
  if (!siblingSession.activated) continue;
47019
- const syncEncrypted = siblingSession.ratchet.encrypt(syncPayload);
47020
- const syncTransport = encryptedMessageToTransport(syncEncrypted);
47021
- this._ws.send(
47022
- JSON.stringify({
47023
- event: "message",
47024
- data: {
47025
- conversation_id: siblingConvId,
47026
- header_blob: syncTransport.header_blob,
47027
- ciphertext: syncTransport.ciphertext
47028
- }
47029
- })
47030
- );
47046
+ try {
47047
+ const syncEncrypted = siblingSession.ratchet.encrypt(syncPayload);
47048
+ const syncTransport = encryptedMessageToTransport(syncEncrypted);
47049
+ this._ws.send(
47050
+ JSON.stringify({
47051
+ event: "message",
47052
+ data: {
47053
+ conversation_id: siblingConvId,
47054
+ header_blob: syncTransport.header_blob,
47055
+ ciphertext: syncTransport.ciphertext
47056
+ }
47057
+ })
47058
+ );
47059
+ relayed++;
47060
+ } catch (err) {
47061
+ console.error(`[SecureChannel] Sync send failed for sibling ${siblingConvId.slice(0, 8)}...: ${String(err)}`);
47062
+ }
47031
47063
  }
47064
+ console.log(`[SecureChannel] _relaySyncToSiblings: relayed to ${relayed}/${this._sessions.size - 1} siblings`);
47032
47065
  }
47033
47066
  /**
47034
47067
  * Send stored message history to a newly-activated session.
@@ -47265,6 +47298,7 @@ ${messageText}`;
47265
47298
  const PAGE_SIZE = 200;
47266
47299
  let since = this._persisted.lastMessageTimestamp;
47267
47300
  let totalProcessed = 0;
47301
+ let totalSkipped = 0;
47268
47302
  try {
47269
47303
  for (let page = 0; page < MAX_PAGES; page++) {
47270
47304
  const url = `${this.config.apiUrl}/api/v1/devices/${this._deviceId}/messages?since=${encodeURIComponent(since)}&limit=${PAGE_SIZE}`;
@@ -47274,15 +47308,24 @@ ${messageText}`;
47274
47308
  if (!res.ok) break;
47275
47309
  const messages = await res.json();
47276
47310
  if (messages.length === 0) break;
47311
+ console.log(`[SecureChannel] Sync page ${page}: ${messages.length} messages since ${since}`);
47277
47312
  for (const msg of messages) {
47278
47313
  if (msg.sender_device_id === this._deviceId) continue;
47279
47314
  if (this._syncMessageIds.has(msg.id)) continue;
47280
47315
  this._syncMessageIds.add(msg.id);
47316
+ if (this._recentlyHandledIds.has(msg.id)) {
47317
+ this._persisted.lastMessageTimestamp = msg.created_at;
47318
+ since = msg.created_at;
47319
+ totalSkipped++;
47320
+ continue;
47321
+ }
47281
47322
  const session = this._sessions.get(msg.conversation_id);
47282
47323
  if (!session) {
47283
47324
  console.warn(
47284
47325
  `[SecureChannel] No session for conversation ${msg.conversation_id} during sync, skipping`
47285
47326
  );
47327
+ this._persisted.lastMessageTimestamp = msg.created_at;
47328
+ since = msg.created_at;
47286
47329
  continue;
47287
47330
  }
47288
47331
  try {
@@ -47316,9 +47359,6 @@ ${messageText}`;
47316
47359
  topicId
47317
47360
  };
47318
47361
  this.emit("message", messageText, metadata);
47319
- Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
47320
- console.error("[SecureChannel] onMessage callback error:", err);
47321
- });
47322
47362
  }
47323
47363
  this._persisted.lastMessageTimestamp = msg.created_at;
47324
47364
  since = msg.created_at;
@@ -47335,10 +47375,15 @@ ${messageText}`;
47335
47375
  await this._persistState();
47336
47376
  if (messages.length < PAGE_SIZE) break;
47337
47377
  }
47338
- if (totalProcessed > 0) {
47339
- console.log(`[SecureChannel] Synced ${totalProcessed} missed messages`);
47378
+ if (totalProcessed > 0 || totalSkipped > 0) {
47379
+ console.log(`[SecureChannel] Sync complete: ${totalProcessed} processed, ${totalSkipped} skipped (already handled via WS)`);
47380
+ }
47381
+ } catch (outerErr) {
47382
+ console.warn(`[SecureChannel] Sync interrupted: ${String(outerErr)}`);
47383
+ try {
47384
+ await this._persistState();
47385
+ } catch {
47340
47386
  }
47341
- } catch {
47342
47387
  }
47343
47388
  this._syncMessageIds = null;
47344
47389
  }