@agentvault/agentvault 0.20.31 → 0.20.33

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.
Files changed (66) hide show
  1. package/dist/cli.js +227 -3
  2. package/dist/cli.js.map +2 -2
  3. package/dist/index.js +227 -3
  4. package/dist/index.js.map +2 -2
  5. package/openclaw.plugin.json +1 -1
  6. package/package.json +1 -1
  7. package/dist/_cp.d.ts +0 -10
  8. package/dist/_cp.d.ts.map +0 -1
  9. package/dist/account-config.d.ts +0 -20
  10. package/dist/account-config.d.ts.map +0 -1
  11. package/dist/channel.d.ts +0 -418
  12. package/dist/channel.d.ts.map +0 -1
  13. package/dist/cli.d.ts +0 -2
  14. package/dist/cli.d.ts.map +0 -1
  15. package/dist/create-agent.d.ts +0 -28
  16. package/dist/create-agent.d.ts.map +0 -1
  17. package/dist/credential-store.d.ts +0 -62
  18. package/dist/credential-store.d.ts.map +0 -1
  19. package/dist/crypto-helpers.d.ts +0 -2
  20. package/dist/crypto-helpers.d.ts.map +0 -1
  21. package/dist/doctor.d.ts +0 -41
  22. package/dist/doctor.d.ts.map +0 -1
  23. package/dist/fetch-interceptor.d.ts +0 -32
  24. package/dist/fetch-interceptor.d.ts.map +0 -1
  25. package/dist/gateway-send.d.ts +0 -98
  26. package/dist/gateway-send.d.ts.map +0 -1
  27. package/dist/http-handlers.d.ts +0 -53
  28. package/dist/http-handlers.d.ts.map +0 -1
  29. package/dist/index.d.ts +0 -27
  30. package/dist/index.d.ts.map +0 -1
  31. package/dist/mcp-handlers.d.ts +0 -26
  32. package/dist/mcp-handlers.d.ts.map +0 -1
  33. package/dist/mcp-proxy-helpers.d.ts +0 -9
  34. package/dist/mcp-proxy-helpers.d.ts.map +0 -1
  35. package/dist/mcp-server.d.ts +0 -91
  36. package/dist/mcp-server.d.ts.map +0 -1
  37. package/dist/mls-state.d.ts +0 -54
  38. package/dist/mls-state.d.ts.map +0 -1
  39. package/dist/openclaw-compat.d.ts +0 -33
  40. package/dist/openclaw-compat.d.ts.map +0 -1
  41. package/dist/openclaw-entry.d.ts +0 -32
  42. package/dist/openclaw-entry.d.ts.map +0 -1
  43. package/dist/openclaw-plugin.d.ts +0 -102
  44. package/dist/openclaw-plugin.d.ts.map +0 -1
  45. package/dist/openclaw-types.d.ts +0 -186
  46. package/dist/openclaw-types.d.ts.map +0 -1
  47. package/dist/policy-enforcer.d.ts +0 -78
  48. package/dist/policy-enforcer.d.ts.map +0 -1
  49. package/dist/setup.d.ts +0 -27
  50. package/dist/setup.d.ts.map +0 -1
  51. package/dist/skill-invoker.d.ts +0 -30
  52. package/dist/skill-invoker.d.ts.map +0 -1
  53. package/dist/skill-manifest.d.ts +0 -30
  54. package/dist/skill-manifest.d.ts.map +0 -1
  55. package/dist/skill-telemetry.d.ts +0 -36
  56. package/dist/skill-telemetry.d.ts.map +0 -1
  57. package/dist/skills-publish.d.ts +0 -8
  58. package/dist/skills-publish.d.ts.map +0 -1
  59. package/dist/state.d.ts +0 -32
  60. package/dist/state.d.ts.map +0 -1
  61. package/dist/transport.d.ts +0 -24
  62. package/dist/transport.d.ts.map +0 -1
  63. package/dist/types.d.ts +0 -454
  64. package/dist/types.d.ts.map +0 -1
  65. package/dist/workspace-handlers.d.ts +0 -62
  66. package/dist/workspace-handlers.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -63714,12 +63714,15 @@ var init_channel = __esm({
63714
63714
  _syncMessageIds = null;
63715
63715
  _deliveryHeartbeat = null;
63716
63716
  _deliveryPulling = false;
63717
+ _drDeliveryPulling = false;
63717
63718
  /** MLS group managers per room/conversation (roomId or conv:conversationId -> MLSGroupManager) */
63718
63719
  _mlsGroups = /* @__PURE__ */ new Map();
63719
63720
  /** Cached MLS KeyPackage bundle for this device (regenerated on each connect). */
63720
63721
  _mlsKeyPackage = null;
63721
63722
  /** Pending KeyPackage bundle from request-Welcome flow (used by _handleMlsWelcome). */
63722
63723
  _pendingMlsKpBundle;
63724
+ /** Buffer for MLS commits received before Welcome (keyed by groupId, sorted by epoch). */
63725
+ _pendingMlsCommits = /* @__PURE__ */ new Map();
63723
63726
  /** In-memory credential store for renter-provided credentials (never persisted). */
63724
63727
  _credentialStore = new CredentialStore();
63725
63728
  /** Dedup buffer for A2A message IDs (prevents double-delivery via direct + Redis) */
@@ -65595,6 +65598,7 @@ var init_channel = __esm({
65595
65598
  this._startWakeDetector();
65596
65599
  this._startPendingPoll();
65597
65600
  await this._syncMissedMessages();
65601
+ await this._pullDrDeliveryQueue();
65598
65602
  await this._flushOutboundQueue();
65599
65603
  this._setState("ready");
65600
65604
  if (this.config.enableScanning) {
@@ -65824,6 +65828,11 @@ var init_channel = __esm({
65824
65828
  console.warn("[SecureChannel] Delivery pull on ping failed:", err);
65825
65829
  });
65826
65830
  }
65831
+ if (data.event === "dr_delivery") {
65832
+ this._pullDrDeliveryQueue().catch((err) => {
65833
+ console.warn("[SecureChannel] DR delivery pull on ping failed:", err);
65834
+ });
65835
+ }
65827
65836
  if (data.event === "mls_welcome_requested") {
65828
65837
  console.log(`[SecureChannel] mls_welcome_requested for group ${(data.data?.group_id || "").slice(0, 8)} \u2014 pulling deliveries`);
65829
65838
  this._pullDeliveryQueue().catch((err) => {
@@ -67029,6 +67038,11 @@ ${messageText}`;
67029
67038
  console.log(`[SecureChannel] MLS decrypt attempt room=${resolvedRoomId.slice(0, 8)} group=${groupId?.slice(0, 8)} loaded=${!!mlsGroup} init=${mlsGroup?.isInitialized} mlsGroupsKeys=[${Array.from(this._mlsGroups.keys()).join(",")}]`);
67030
67039
  if (!mlsGroup?.isInitialized) {
67031
67040
  console.warn(`[SecureChannel] MLS group not loaded for room ${resolvedRoomId.slice(0, 8)}, requesting Welcome`);
67041
+ const roomLockId = `room-kp-${groupId}`;
67042
+ if (!await acquireA2ASyncLock(this.config.dataDir, roomLockId)) {
67043
+ console.log(`[SecureChannel] Room KP publish locked for group ${groupId?.slice(0, 8)}, skipping`);
67044
+ return;
67045
+ }
67032
67046
  try {
67033
67047
  const { MLSGroupManager: MLS } = await init_dist().then(() => dist_exports);
67034
67048
  const mgr = new MLS();
@@ -67041,6 +67055,7 @@ ${messageText}`;
67041
67055
  body: JSON.stringify({ key_package: kpHex, device_id: this._deviceId })
67042
67056
  });
67043
67057
  this._pendingMlsKpBundle = kp;
67058
+ await savePendingKpBundle(this.config.dataDir, groupId, kp);
67044
67059
  await fetch(`${this.config.apiUrl}/api/v1/mls/groups/${groupId}/request-welcome`, {
67045
67060
  method: "POST",
67046
67061
  headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
@@ -67049,6 +67064,8 @@ ${messageText}`;
67049
67064
  console.log(`[SecureChannel] Welcome requested for room ${resolvedRoomId.slice(0, 8)} group ${groupId?.slice(0, 8)}`);
67050
67065
  } catch (reqErr) {
67051
67066
  console.warn(`[SecureChannel] Welcome request failed for room ${resolvedRoomId.slice(0, 8)}:`, reqErr);
67067
+ await releaseA2ASyncLock(this.config.dataDir, roomLockId).catch(() => {
67068
+ });
67052
67069
  }
67053
67070
  return;
67054
67071
  }
@@ -67181,6 +67198,7 @@ ${messageText}`;
67181
67198
  }
67182
67199
  async _handleMlsCommit(data) {
67183
67200
  const groupId = data.group_id;
67201
+ const epoch = typeof data.epoch === "number" ? data.epoch : 0;
67184
67202
  for (const [roomId, room] of Object.entries(this._persisted?.rooms ?? {})) {
67185
67203
  if (room.mlsGroupId === groupId) {
67186
67204
  const mlsGroup = this._mlsGroups.get(roomId);
@@ -67199,6 +67217,9 @@ ${messageText}`;
67199
67217
  throw err;
67200
67218
  }
67201
67219
  }
67220
+ } else {
67221
+ this._bufferMlsCommit(groupId, epoch, data);
67222
+ console.log(`[SecureChannel] Buffered MLS commit for room ${roomId.slice(0, 8)} (epoch=${epoch}, group not initialized)`);
67202
67223
  }
67203
67224
  return;
67204
67225
  }
@@ -67221,11 +67242,50 @@ ${messageText}`;
67221
67242
  throw err;
67222
67243
  }
67223
67244
  }
67245
+ } else {
67246
+ this._bufferMlsCommit(groupId, epoch, data);
67247
+ console.log(`[SecureChannel] Buffered MLS commit for A2A ${chId.slice(0, 8)} (epoch=${epoch}, group not initialized)`);
67224
67248
  }
67225
67249
  return;
67226
67250
  }
67227
67251
  }
67228
67252
  }
67253
+ /** Buffer an MLS commit for replay after Welcome join. Max 50 per group. */
67254
+ _bufferMlsCommit(groupId, epoch, data) {
67255
+ let buf = this._pendingMlsCommits.get(groupId);
67256
+ if (!buf) {
67257
+ buf = [];
67258
+ this._pendingMlsCommits.set(groupId, buf);
67259
+ }
67260
+ if (!buf.some((c2) => c2.epoch === epoch)) {
67261
+ buf.push({ epoch, data });
67262
+ buf.sort((a2, b2) => a2.epoch - b2.epoch);
67263
+ if (buf.length > 50) buf.splice(0, buf.length - 50);
67264
+ }
67265
+ }
67266
+ /** Apply buffered MLS commits after Welcome join. */
67267
+ async _applyBufferedMlsCommits(groupId, mgr) {
67268
+ const buf = this._pendingMlsCommits.get(groupId);
67269
+ if (!buf || buf.length === 0) return;
67270
+ console.log(`[SecureChannel] Applying ${buf.length} buffered MLS commits for group ${groupId.slice(0, 8)}`);
67271
+ let applied = 0;
67272
+ for (const entry of buf) {
67273
+ if (entry.epoch <= mgr.epoch) continue;
67274
+ try {
67275
+ const commitBytes = new Uint8Array(Buffer.from(entry.data.payload, "hex"));
67276
+ await mgr.processCommit(commitBytes);
67277
+ applied++;
67278
+ } catch (err) {
67279
+ console.warn(`[SecureChannel] Buffered commit epoch=${entry.epoch} failed: ${err?.message}`);
67280
+ break;
67281
+ }
67282
+ }
67283
+ this._pendingMlsCommits.delete(groupId);
67284
+ if (applied > 0) {
67285
+ await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mgr.exportState()));
67286
+ console.log(`[SecureChannel] Applied ${applied} buffered commits, now epoch=${mgr.epoch}`);
67287
+ }
67288
+ }
67229
67289
  async _handleMlsWelcome(data) {
67230
67290
  const groupId = data.group_id;
67231
67291
  const conversationId = data.conversation_id;
@@ -67246,8 +67306,8 @@ ${messageText}`;
67246
67306
  }
67247
67307
  }
67248
67308
  if (!kp) {
67249
- const identity = new TextEncoder().encode(this._deviceId);
67250
- kp = await mgr.generateKeyPackage(identity);
67309
+ console.error(`[SecureChannel] No matching KeyPackage found for Welcome \u2014 cannot join group ${groupId?.slice(0, 8)}. A fresh KP would fail because the Welcome is encrypted to the published KP's public key. The existing Welcome recovery mechanism will re-request.`);
67310
+ return;
67251
67311
  }
67252
67312
  console.log(`[SecureChannel] Welcome joinFromWelcome: group=${groupId?.slice(0, 8)} kpSource=${kpSource} welcomeLen=${welcomeBytes.length}`);
67253
67313
  await mgr.joinFromWelcome(welcomeBytes, kp);
@@ -67255,6 +67315,7 @@ ${messageText}`;
67255
67315
  const key = `conv:${conversationId}`;
67256
67316
  this._mlsGroups.set(key, mgr);
67257
67317
  await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mgr.exportState()));
67318
+ await this._applyBufferedMlsCommits(groupId, mgr);
67258
67319
  if (this._persisted) {
67259
67320
  if (!this._persisted.mlsConversations) this._persisted.mlsConversations = {};
67260
67321
  this._persisted.mlsConversations[conversationId] = { mlsGroupId: groupId };
@@ -67270,8 +67331,11 @@ ${messageText}`;
67270
67331
  this._mlsGroups.set(roomId, mgr);
67271
67332
  await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mgr.exportState()));
67272
67333
  await this._persistState();
67334
+ await this._applyBufferedMlsCommits(groupId, mgr);
67273
67335
  console.log(`[SecureChannel] Joined MLS group for room ${roomId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
67274
67336
  this._pendingMlsKpBundle = void 0;
67337
+ await releaseA2ASyncLock(this.config.dataDir, `room-kp-${groupId}`).catch(() => {
67338
+ });
67275
67339
  return;
67276
67340
  }
67277
67341
  }
@@ -67282,6 +67346,7 @@ ${messageText}`;
67282
67346
  this._mlsGroups.set(`a2a:${channelId}`, mgr);
67283
67347
  await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mgr.exportState()));
67284
67348
  await this._persistState();
67349
+ await this._applyBufferedMlsCommits(groupId, mgr);
67285
67350
  await clearPendingWelcome(this.config.dataDir, groupId).catch(() => {
67286
67351
  });
67287
67352
  await releaseA2ASyncLock(this.config.dataDir, channelId).catch(() => {
@@ -67705,6 +67770,165 @@ ${messageText}`;
67705
67770
  this._deliveryPulling = false;
67706
67771
  }
67707
67772
  }
67773
+ /**
67774
+ * Pull pending DR (Double Ratchet) messages from the delivery queue.
67775
+ * Signal-model queue-first: called on WS connect and on dr_delivery ping.
67776
+ */
67777
+ async _pullDrDeliveryQueue() {
67778
+ if (!this._deviceId || !this._deviceJwt || this._drDeliveryPulling) return;
67779
+ this._drDeliveryPulling = true;
67780
+ try {
67781
+ const res = await fetch(
67782
+ `${this.config.apiUrl}/api/v1/dr/delivery?device_id=${this._deviceId}`,
67783
+ { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
67784
+ );
67785
+ if (!res.ok) {
67786
+ console.warn(`[SecureChannel] DR delivery pull failed: ${res.status}`);
67787
+ return;
67788
+ }
67789
+ const { messages } = await res.json();
67790
+ if (!messages || messages.length === 0) return;
67791
+ const ackedIds = [];
67792
+ const nackedIds = [];
67793
+ for (const msg of messages) {
67794
+ try {
67795
+ if (msg.sender_device_id === this._deviceId) {
67796
+ ackedIds.push(msg.queue_id);
67797
+ continue;
67798
+ }
67799
+ if (msg.message_id && this._seenMessageIds.has(msg.message_id)) {
67800
+ ackedIds.push(msg.queue_id);
67801
+ continue;
67802
+ }
67803
+ let isRoom = false;
67804
+ if (this._persisted?.rooms) {
67805
+ for (const room of Object.values(this._persisted.rooms)) {
67806
+ if (room.conversationIds?.includes(msg.conversation_id)) {
67807
+ isRoom = true;
67808
+ break;
67809
+ }
67810
+ }
67811
+ }
67812
+ if (isRoom) {
67813
+ ackedIds.push(msg.queue_id);
67814
+ continue;
67815
+ }
67816
+ if (!msg.header_blob || !msg.ciphertext) {
67817
+ ackedIds.push(msg.queue_id);
67818
+ continue;
67819
+ }
67820
+ const session = this._sessions.get(msg.conversation_id);
67821
+ if (!session) {
67822
+ console.warn(`[SecureChannel] DR delivery: no session for conv ${msg.conversation_id.slice(0, 8)}, skipping`);
67823
+ continue;
67824
+ }
67825
+ const encrypted = transportToEncryptedMessage({
67826
+ header_blob: msg.header_blob,
67827
+ ciphertext: msg.ciphertext
67828
+ });
67829
+ const ratchetSnapshot = session.ratchet.serialize();
67830
+ let plaintext;
67831
+ try {
67832
+ plaintext = session.ratchet.decrypt(encrypted);
67833
+ } catch (decryptErr) {
67834
+ console.error(`[SecureChannel] DR delivery decrypt failed for conv ${msg.conversation_id.slice(0, 8)} \u2014 restoring ratchet:`, decryptErr);
67835
+ try {
67836
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
67837
+ } catch {
67838
+ }
67839
+ nackedIds.push(msg.queue_id);
67840
+ continue;
67841
+ }
67842
+ if (msg.message_id) {
67843
+ this._seenMessageIds.add(msg.message_id);
67844
+ if (this._seenMessageIds.size > _SecureChannel.SEEN_MSG_MAX) {
67845
+ const first = this._seenMessageIds.values().next().value;
67846
+ if (first) this._seenMessageIds.delete(first);
67847
+ }
67848
+ }
67849
+ this._sendAck(msg.message_id);
67850
+ if (!session.activated) {
67851
+ session.activated = true;
67852
+ console.log(`[SecureChannel] Session ${msg.conversation_id.slice(0, 8)}... activated via DR delivery`);
67853
+ if (this._persisted?.sessions[msg.conversation_id]) {
67854
+ this._persisted.sessions[msg.conversation_id].activated = true;
67855
+ }
67856
+ this._activateSiblings(msg.conversation_id);
67857
+ await this._persistState();
67858
+ }
67859
+ let messageText;
67860
+ let messageType;
67861
+ try {
67862
+ const parsed = JSON.parse(plaintext);
67863
+ messageType = parsed.type || "message";
67864
+ messageText = parsed.text || plaintext;
67865
+ } catch {
67866
+ messageType = "message";
67867
+ messageText = plaintext;
67868
+ }
67869
+ if (messageType === "session_init") {
67870
+ console.log(`[SecureChannel] session_init received via DR delivery for ${msg.conversation_id.slice(0, 8)}...`);
67871
+ await this._replayHistoryToSession(msg.conversation_id);
67872
+ await this._persistState();
67873
+ ackedIds.push(msg.queue_id);
67874
+ continue;
67875
+ }
67876
+ if (messageType === "message") {
67877
+ const topicId = msg.topic_id;
67878
+ this._appendHistory("owner", messageText, topicId);
67879
+ const metadata = {
67880
+ messageId: msg.message_id,
67881
+ conversationId: msg.conversation_id,
67882
+ timestamp: msg.created_at,
67883
+ topicId
67884
+ };
67885
+ this.emit("message", messageText, metadata);
67886
+ Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
67887
+ console.error("[SecureChannel] onMessage callback error:", err);
67888
+ });
67889
+ }
67890
+ this._persisted.lastMessageTimestamp = msg.created_at;
67891
+ ackedIds.push(msg.queue_id);
67892
+ } catch (err) {
67893
+ console.warn(`[SecureChannel] DR delivery processing failed for ${msg.message_id?.slice(0, 8)}:`, err);
67894
+ nackedIds.push(msg.queue_id);
67895
+ }
67896
+ }
67897
+ await this._persistState();
67898
+ if (nackedIds.length > 0) {
67899
+ try {
67900
+ await fetch(`${this.config.apiUrl}/api/v1/dr/delivery/nack`, {
67901
+ method: "POST",
67902
+ headers: {
67903
+ Authorization: `Bearer ${this._deviceJwt}`,
67904
+ "Content-Type": "application/json"
67905
+ },
67906
+ body: JSON.stringify({ queue_ids: nackedIds })
67907
+ });
67908
+ } catch {
67909
+ }
67910
+ }
67911
+ if (ackedIds.length > 0) {
67912
+ try {
67913
+ await fetch(`${this.config.apiUrl}/api/v1/dr/delivery/ack`, {
67914
+ method: "POST",
67915
+ headers: {
67916
+ Authorization: `Bearer ${this._deviceJwt}`,
67917
+ "Content-Type": "application/json"
67918
+ },
67919
+ body: JSON.stringify({ queue_ids: ackedIds, device_id: this._deviceId })
67920
+ });
67921
+ console.log(`[SecureChannel] DR delivery acked ${ackedIds.length}/${messages.length}`);
67922
+ } catch (ackErr) {
67923
+ console.warn("[SecureChannel] DR delivery ack failed:", ackErr);
67924
+ }
67925
+ }
67926
+ } catch (err) {
67927
+ console.warn("[SecureChannel] DR delivery pull error:", err);
67928
+ } finally {
67929
+ this._drDeliveryPulling = false;
67930
+ }
67931
+ }
67708
67932
  async _handleMlsSyncResponse(data) {
67709
67933
  const action = data.action;
67710
67934
  const groupId = data.group_id;
@@ -94962,7 +95186,7 @@ var init_index = __esm({
94962
95186
  init_skill_invoker();
94963
95187
  await init_skill_telemetry();
94964
95188
  await init_policy_enforcer();
94965
- VERSION = true ? "0.20.31" : "0.0.0-dev";
95189
+ VERSION = true ? "0.20.33" : "0.0.0-dev";
94966
95190
  }
94967
95191
  });
94968
95192
  await init_index();