@agentvault/agentvault 0.13.4 → 0.13.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
@@ -44880,6 +44880,7 @@ var DoubleRatchet = class _DoubleRatchet {
44880
44880
  serialize() {
44881
44881
  const s2 = this.state;
44882
44882
  return JSON.stringify({
44883
+ version: 1,
44883
44884
  rootKey: libsodium_wrappers_default.to_hex(s2.rootKey),
44884
44885
  sendingChain: s2.sendingChain ? {
44885
44886
  chainKey: libsodium_wrappers_default.to_hex(s2.sendingChain.chainKey),
@@ -44907,33 +44908,59 @@ var DoubleRatchet = class _DoubleRatchet {
44907
44908
  });
44908
44909
  }
44909
44910
  static deserialize(json) {
44910
- const d2 = JSON.parse(json);
44911
- return new _DoubleRatchet({
44912
- rootKey: libsodium_wrappers_default.from_hex(d2.rootKey),
44913
- sendingChain: d2.sendingChain ? {
44914
- chainKey: libsodium_wrappers_default.from_hex(d2.sendingChain.chainKey),
44915
- messageNumber: d2.sendingChain.messageNumber
44916
- } : null,
44917
- receivingChain: d2.receivingChain ? {
44918
- chainKey: libsodium_wrappers_default.from_hex(d2.receivingChain.chainKey),
44919
- messageNumber: d2.receivingChain.messageNumber
44920
- } : null,
44921
- dhSendingKeypair: {
44922
- publicKey: libsodium_wrappers_default.from_hex(d2.dhSendingKeypair.publicKey),
44923
- privateKey: libsodium_wrappers_default.from_hex(d2.dhSendingKeypair.privateKey)
44924
- },
44925
- dhReceivingPublicKey: d2.dhReceivingPublicKey ? libsodium_wrappers_default.from_hex(d2.dhReceivingPublicKey) : null,
44926
- identityKeypair: {
44927
- publicKey: libsodium_wrappers_default.from_hex(d2.identityKeypair.publicKey),
44928
- privateKey: libsodium_wrappers_default.from_hex(d2.identityKeypair.privateKey)
44929
- },
44930
- previousSendingChainLength: d2.previousSendingChainLength,
44931
- skippedKeys: d2.skippedKeys.map((sk) => ({
44932
- dhPub: sk.dhPub,
44933
- n: sk.n,
44934
- messageKey: libsodium_wrappers_default.from_hex(sk.messageKey)
44935
- }))
44936
- });
44911
+ let d2;
44912
+ try {
44913
+ d2 = JSON.parse(json);
44914
+ } catch {
44915
+ throw new Error("Ratchet state: corrupt JSON");
44916
+ }
44917
+ if (d2.version !== void 0 && d2.version !== 1) {
44918
+ throw new Error(`Ratchet state version ${d2.version} not supported`);
44919
+ }
44920
+ if (typeof d2.rootKey !== "string") {
44921
+ throw new Error("Ratchet state: missing required field rootKey");
44922
+ }
44923
+ const dhSend = d2.dhSendingKeypair;
44924
+ if (!dhSend || typeof dhSend.publicKey !== "string" || typeof dhSend.privateKey !== "string") {
44925
+ throw new Error("Ratchet state: missing required field dhSendingKeypair");
44926
+ }
44927
+ const idKp = d2.identityKeypair;
44928
+ if (!idKp || typeof idKp.publicKey !== "string" || typeof idKp.privateKey !== "string") {
44929
+ throw new Error("Ratchet state: missing required field identityKeypair");
44930
+ }
44931
+ try {
44932
+ return new _DoubleRatchet({
44933
+ rootKey: libsodium_wrappers_default.from_hex(d2.rootKey),
44934
+ sendingChain: d2.sendingChain ? {
44935
+ chainKey: libsodium_wrappers_default.from_hex(d2.sendingChain.chainKey),
44936
+ messageNumber: d2.sendingChain.messageNumber
44937
+ } : null,
44938
+ receivingChain: d2.receivingChain ? {
44939
+ chainKey: libsodium_wrappers_default.from_hex(d2.receivingChain.chainKey),
44940
+ messageNumber: d2.receivingChain.messageNumber
44941
+ } : null,
44942
+ dhSendingKeypair: {
44943
+ publicKey: libsodium_wrappers_default.from_hex(dhSend.publicKey),
44944
+ privateKey: libsodium_wrappers_default.from_hex(dhSend.privateKey)
44945
+ },
44946
+ dhReceivingPublicKey: d2.dhReceivingPublicKey ? libsodium_wrappers_default.from_hex(d2.dhReceivingPublicKey) : null,
44947
+ identityKeypair: {
44948
+ publicKey: libsodium_wrappers_default.from_hex(idKp.publicKey),
44949
+ privateKey: libsodium_wrappers_default.from_hex(idKp.privateKey)
44950
+ },
44951
+ previousSendingChainLength: d2.previousSendingChainLength,
44952
+ skippedKeys: d2.skippedKeys.map((sk) => ({
44953
+ dhPub: sk.dhPub,
44954
+ n: sk.n,
44955
+ messageKey: libsodium_wrappers_default.from_hex(sk.messageKey)
44956
+ }))
44957
+ });
44958
+ } catch (err) {
44959
+ if (err instanceof Error && err.message.startsWith("Ratchet state")) {
44960
+ throw err;
44961
+ }
44962
+ throw new Error(`Ratchet state: corrupt hex data \u2014 ${err instanceof Error ? err.message : String(err)}`);
44963
+ }
44937
44964
  }
44938
44965
  };
44939
44966
 
@@ -45243,6 +45270,69 @@ function buildErrorSpan(opts) {
45243
45270
  status: { code: 2, message: opts.errorMessage }
45244
45271
  };
45245
45272
  }
45273
+ function buildHttpSpan(opts) {
45274
+ const now = Date.now();
45275
+ const attributes = {
45276
+ "ai.agent.http.method": opts.method,
45277
+ "ai.agent.http.url": opts.url,
45278
+ "ai.agent.http.status_code": opts.statusCode,
45279
+ "ai.agent.http.latency_ms": opts.latencyMs
45280
+ };
45281
+ const isError = opts.status === "error" || opts.statusCode >= 400;
45282
+ const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
45283
+ return {
45284
+ traceId: opts.traceId ?? generateTraceId(),
45285
+ spanId: opts.spanId ?? generateSpanId(),
45286
+ parentSpanId: opts.parentSpanId,
45287
+ name: "http.request",
45288
+ kind: "client",
45289
+ startTime: now - opts.latencyMs,
45290
+ endTime: now,
45291
+ attributes,
45292
+ status
45293
+ };
45294
+ }
45295
+ function buildActionSpan(opts) {
45296
+ const now = Date.now();
45297
+ const attributes = {
45298
+ "ai.agent.action.type": opts.actionType,
45299
+ "ai.agent.action.target": opts.target,
45300
+ "ai.agent.action.latency_ms": opts.latencyMs,
45301
+ "ai.agent.action.success": opts.success
45302
+ };
45303
+ const status = opts.success ? { code: 0 } : { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} };
45304
+ return {
45305
+ traceId: opts.traceId ?? generateTraceId(),
45306
+ spanId: opts.spanId ?? generateSpanId(),
45307
+ parentSpanId: opts.parentSpanId,
45308
+ name: "action.execute",
45309
+ kind: "internal",
45310
+ startTime: now - opts.latencyMs,
45311
+ endTime: now,
45312
+ attributes,
45313
+ status
45314
+ };
45315
+ }
45316
+ function buildNavSpan(opts) {
45317
+ const now = Date.now();
45318
+ const attributes = {
45319
+ "ai.agent.nav.to_url": opts.toUrl,
45320
+ "ai.agent.nav.latency_ms": opts.latencyMs
45321
+ };
45322
+ const isError = opts.status === "error";
45323
+ const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
45324
+ return {
45325
+ traceId: opts.traceId ?? generateTraceId(),
45326
+ spanId: opts.spanId ?? generateSpanId(),
45327
+ parentSpanId: opts.parentSpanId,
45328
+ name: "nav.navigate",
45329
+ kind: "internal",
45330
+ startTime: now - opts.latencyMs,
45331
+ endTime: now,
45332
+ attributes,
45333
+ status
45334
+ };
45335
+ }
45246
45336
 
45247
45337
  // ../crypto/dist/telemetry-reporter.js
45248
45338
  function toOtlpAttributes(attrs) {
@@ -45310,6 +45400,18 @@ var TelemetryReporter = class {
45310
45400
  reportError(opts) {
45311
45401
  this._buffer.push(buildErrorSpan(opts));
45312
45402
  }
45403
+ /** Record an HTTP request call. */
45404
+ reportHttpCall(opts) {
45405
+ this._buffer.push(buildHttpSpan(opts));
45406
+ }
45407
+ /** Record an action execution. */
45408
+ reportActionCall(opts) {
45409
+ this._buffer.push(buildActionSpan(opts));
45410
+ }
45411
+ /** Record a navigation event. */
45412
+ reportNavCall(opts) {
45413
+ this._buffer.push(buildNavSpan(opts));
45414
+ }
45313
45415
  /** Record an arbitrary pre-built span. */
45314
45416
  reportCustomSpan(span) {
45315
45417
  this._buffer.push(span);
@@ -47042,7 +47144,15 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
47042
47144
  nonce: hexToBytes(msgData.nonce)
47043
47145
  };
47044
47146
  const ratchet = DoubleRatchet.deserialize(channelEntry.session.ratchetState);
47045
- const plaintext = ratchet.decrypt(encryptedMessage);
47147
+ const ratchetSnapshot = channelEntry.session.ratchetState;
47148
+ let a2aPlaintext;
47149
+ try {
47150
+ a2aPlaintext = ratchet.decrypt(encryptedMessage);
47151
+ } catch (decryptErr) {
47152
+ console.error(`[SecureChannel] A2A decrypt failed \u2014 restoring ratchet state:`, decryptErr);
47153
+ channelEntry.session.ratchetState = ratchetSnapshot;
47154
+ return;
47155
+ }
47046
47156
  channelEntry.session.ratchetState = ratchet.serialize();
47047
47157
  if (channelEntry.role === "responder" && !channelEntry.session.activated) {
47048
47158
  channelEntry.session.activated = true;
@@ -47065,7 +47175,7 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
47065
47175
  }
47066
47176
  await this._persistState();
47067
47177
  const a2aMsg = {
47068
- text: plaintext,
47178
+ text: a2aPlaintext,
47069
47179
  fromHubAddress: msgData.from_hub_address || msgData.hub_address || "",
47070
47180
  channelId,
47071
47181
  conversationId: msgData.conversation_id || "",
@@ -47136,7 +47246,19 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
47136
47246
  header_blob: msgData.header_blob,
47137
47247
  ciphertext: msgData.ciphertext
47138
47248
  });
47139
- const plaintext = session.ratchet.decrypt(encrypted);
47249
+ const ratchetSnapshot = session.ratchet.serialize();
47250
+ let plaintext;
47251
+ try {
47252
+ plaintext = session.ratchet.decrypt(encrypted);
47253
+ } catch (decryptErr) {
47254
+ console.error(`[SecureChannel] Decrypt failed for conv ${convId.slice(0, 8)}... \u2014 restoring ratchet:`, decryptErr);
47255
+ try {
47256
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
47257
+ } catch (restoreErr) {
47258
+ console.error("[SecureChannel] Ratchet restore failed:", restoreErr);
47259
+ }
47260
+ return;
47261
+ }
47140
47262
  this._sendAck(msgData.message_id);
47141
47263
  if (!session.activated) {
47142
47264
  session.activated = true;
@@ -47524,9 +47646,14 @@ ${messageText}`;
47524
47646
  ciphertext: msgData.ciphertext
47525
47647
  });
47526
47648
  let plaintext;
47649
+ const ratchetSnapshot = session.ratchet.serialize();
47527
47650
  try {
47528
47651
  plaintext = session.ratchet.decrypt(encrypted);
47529
47652
  } catch (decryptErr) {
47653
+ try {
47654
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
47655
+ } catch {
47656
+ }
47530
47657
  console.warn(
47531
47658
  `[SecureChannel] Room decrypt failed for conv ${convId.slice(0, 8)}...: ${String(decryptErr)}, re-initializing ratchet`
47532
47659
  );
@@ -47672,7 +47799,20 @@ ${messageText}`;
47672
47799
  header_blob: msg.header_blob,
47673
47800
  ciphertext: msg.ciphertext
47674
47801
  });
47675
- const plaintext = session.ratchet.decrypt(encrypted);
47802
+ const ratchetSnapshot = session.ratchet.serialize();
47803
+ let plaintext;
47804
+ try {
47805
+ plaintext = session.ratchet.decrypt(encrypted);
47806
+ } catch (decryptErr) {
47807
+ console.error(`[SecureChannel] Sync decrypt failed for ${msg.conversation_id.slice(0, 8)}... \u2014 restoring ratchet:`, decryptErr);
47808
+ try {
47809
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
47810
+ } catch {
47811
+ }
47812
+ this._persisted.lastMessageTimestamp = msg.created_at;
47813
+ since = msg.created_at;
47814
+ continue;
47815
+ }
47676
47816
  this._sendAck(msg.id);
47677
47817
  if (!session.activated) {
47678
47818
  session.activated = true;
@@ -47707,7 +47847,7 @@ ${messageText}`;
47707
47847
  totalProcessed++;
47708
47848
  } catch (err) {
47709
47849
  console.warn(
47710
- `[SecureChannel] Sync decrypt failed for msg ${msg.id.slice(0, 8)}... in conv ${msg.conversation_id.slice(0, 8)}...: ${String(err)}`
47850
+ `[SecureChannel] Sync failed for msg ${msg.id.slice(0, 8)}... in conv ${msg.conversation_id.slice(0, 8)}...: ${String(err)}`
47711
47851
  );
47712
47852
  this._persisted.lastMessageTimestamp = msg.created_at;
47713
47853
  since = msg.created_at;
@@ -47903,7 +48043,18 @@ ${messageText}`;
47903
48043
  header_blob: msg.header_blob,
47904
48044
  ciphertext: msg.ciphertext
47905
48045
  });
47906
- const plaintext = session.ratchet.decrypt(encrypted);
48046
+ const ratchetSnapshot = session.ratchet.serialize();
48047
+ let plaintext;
48048
+ try {
48049
+ plaintext = session.ratchet.decrypt(encrypted);
48050
+ } catch (decryptErr) {
48051
+ console.error(`[SecureChannel] Room sync decrypt failed for ${msg.conversation_id.slice(0, 8)}... \u2014 restoring ratchet:`, decryptErr);
48052
+ try {
48053
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
48054
+ } catch {
48055
+ }
48056
+ continue;
48057
+ }
47907
48058
  if (!session.activated) {
47908
48059
  session.activated = true;
47909
48060
  }