@agentvault/agentvault 0.20.32 → 0.20.34

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/cli.js CHANGED
@@ -63715,6 +63715,7 @@ var init_channel = __esm({
63715
63715
  _syncMessageIds = null;
63716
63716
  _deliveryHeartbeat = null;
63717
63717
  _deliveryPulling = false;
63718
+ _drDeliveryPulling = false;
63718
63719
  /** MLS group managers per room/conversation (roomId or conv:conversationId -> MLSGroupManager) */
63719
63720
  _mlsGroups = /* @__PURE__ */ new Map();
63720
63721
  /** Cached MLS KeyPackage bundle for this device (regenerated on each connect). */
@@ -64060,7 +64061,7 @@ var init_channel = __esm({
64060
64061
  try {
64061
64062
  const mlsGroup = this._mlsGroups.get(`conv:${convId}`);
64062
64063
  const mlsGroupId = this._persisted?.mlsConversations?.[convId]?.mlsGroupId;
64063
- if (mlsGroup?.isInitialized && mlsGroupId && this._state === "ready" && this._ws) {
64064
+ if (mlsGroup?.isInitialized && mlsGroupId && Number(mlsGroup.epoch) > 0 && this._state === "ready" && this._ws) {
64064
64065
  const plaintextBytes = new TextEncoder().encode(plaintext);
64065
64066
  const cipherBytes = await mlsGroup.encrypt(plaintextBytes);
64066
64067
  await saveMlsState(this.config.dataDir, mlsGroupId, JSON.stringify(mlsGroup.exportState()));
@@ -65598,6 +65599,7 @@ var init_channel = __esm({
65598
65599
  this._startWakeDetector();
65599
65600
  this._startPendingPoll();
65600
65601
  await this._syncMissedMessages();
65602
+ await this._pullDrDeliveryQueue();
65601
65603
  await this._flushOutboundQueue();
65602
65604
  this._setState("ready");
65603
65605
  if (this.config.enableScanning) {
@@ -65827,6 +65829,11 @@ var init_channel = __esm({
65827
65829
  console.warn("[SecureChannel] Delivery pull on ping failed:", err);
65828
65830
  });
65829
65831
  }
65832
+ if (data.event === "dr_delivery") {
65833
+ this._pullDrDeliveryQueue().catch((err) => {
65834
+ console.warn("[SecureChannel] DR delivery pull on ping failed:", err);
65835
+ });
65836
+ }
65830
65837
  if (data.event === "mls_welcome_requested") {
65831
65838
  console.log(`[SecureChannel] mls_welcome_requested for group ${(data.data?.group_id || "").slice(0, 8)} \u2014 pulling deliveries`);
65832
65839
  this._pullDeliveryQueue().catch((err) => {
@@ -67764,6 +67771,165 @@ ${messageText}`;
67764
67771
  this._deliveryPulling = false;
67765
67772
  }
67766
67773
  }
67774
+ /**
67775
+ * Pull pending DR (Double Ratchet) messages from the delivery queue.
67776
+ * Signal-model queue-first: called on WS connect and on dr_delivery ping.
67777
+ */
67778
+ async _pullDrDeliveryQueue() {
67779
+ if (!this._deviceId || !this._deviceJwt || this._drDeliveryPulling) return;
67780
+ this._drDeliveryPulling = true;
67781
+ try {
67782
+ const res = await fetch(
67783
+ `${this.config.apiUrl}/api/v1/dr/delivery?device_id=${this._deviceId}`,
67784
+ { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
67785
+ );
67786
+ if (!res.ok) {
67787
+ console.warn(`[SecureChannel] DR delivery pull failed: ${res.status}`);
67788
+ return;
67789
+ }
67790
+ const { messages } = await res.json();
67791
+ if (!messages || messages.length === 0) return;
67792
+ const ackedIds = [];
67793
+ const nackedIds = [];
67794
+ for (const msg of messages) {
67795
+ try {
67796
+ if (msg.sender_device_id === this._deviceId) {
67797
+ ackedIds.push(msg.queue_id);
67798
+ continue;
67799
+ }
67800
+ if (msg.message_id && this._seenMessageIds.has(msg.message_id)) {
67801
+ ackedIds.push(msg.queue_id);
67802
+ continue;
67803
+ }
67804
+ let isRoom = false;
67805
+ if (this._persisted?.rooms) {
67806
+ for (const room of Object.values(this._persisted.rooms)) {
67807
+ if (room.conversationIds?.includes(msg.conversation_id)) {
67808
+ isRoom = true;
67809
+ break;
67810
+ }
67811
+ }
67812
+ }
67813
+ if (isRoom) {
67814
+ ackedIds.push(msg.queue_id);
67815
+ continue;
67816
+ }
67817
+ if (!msg.header_blob || !msg.ciphertext) {
67818
+ ackedIds.push(msg.queue_id);
67819
+ continue;
67820
+ }
67821
+ const session = this._sessions.get(msg.conversation_id);
67822
+ if (!session) {
67823
+ console.warn(`[SecureChannel] DR delivery: no session for conv ${msg.conversation_id.slice(0, 8)}, skipping`);
67824
+ continue;
67825
+ }
67826
+ const encrypted = transportToEncryptedMessage({
67827
+ header_blob: msg.header_blob,
67828
+ ciphertext: msg.ciphertext
67829
+ });
67830
+ const ratchetSnapshot = session.ratchet.serialize();
67831
+ let plaintext;
67832
+ try {
67833
+ plaintext = session.ratchet.decrypt(encrypted);
67834
+ } catch (decryptErr) {
67835
+ console.error(`[SecureChannel] DR delivery decrypt failed for conv ${msg.conversation_id.slice(0, 8)} \u2014 restoring ratchet:`, decryptErr);
67836
+ try {
67837
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
67838
+ } catch {
67839
+ }
67840
+ nackedIds.push(msg.queue_id);
67841
+ continue;
67842
+ }
67843
+ if (msg.message_id) {
67844
+ this._seenMessageIds.add(msg.message_id);
67845
+ if (this._seenMessageIds.size > _SecureChannel.SEEN_MSG_MAX) {
67846
+ const first = this._seenMessageIds.values().next().value;
67847
+ if (first) this._seenMessageIds.delete(first);
67848
+ }
67849
+ }
67850
+ this._sendAck(msg.message_id);
67851
+ if (!session.activated) {
67852
+ session.activated = true;
67853
+ console.log(`[SecureChannel] Session ${msg.conversation_id.slice(0, 8)}... activated via DR delivery`);
67854
+ if (this._persisted?.sessions[msg.conversation_id]) {
67855
+ this._persisted.sessions[msg.conversation_id].activated = true;
67856
+ }
67857
+ this._activateSiblings(msg.conversation_id);
67858
+ await this._persistState();
67859
+ }
67860
+ let messageText;
67861
+ let messageType;
67862
+ try {
67863
+ const parsed = JSON.parse(plaintext);
67864
+ messageType = parsed.type || "message";
67865
+ messageText = parsed.text || plaintext;
67866
+ } catch {
67867
+ messageType = "message";
67868
+ messageText = plaintext;
67869
+ }
67870
+ if (messageType === "session_init") {
67871
+ console.log(`[SecureChannel] session_init received via DR delivery for ${msg.conversation_id.slice(0, 8)}...`);
67872
+ await this._replayHistoryToSession(msg.conversation_id);
67873
+ await this._persistState();
67874
+ ackedIds.push(msg.queue_id);
67875
+ continue;
67876
+ }
67877
+ if (messageType === "message") {
67878
+ const topicId = msg.topic_id;
67879
+ this._appendHistory("owner", messageText, topicId);
67880
+ const metadata = {
67881
+ messageId: msg.message_id,
67882
+ conversationId: msg.conversation_id,
67883
+ timestamp: msg.created_at,
67884
+ topicId
67885
+ };
67886
+ this.emit("message", messageText, metadata);
67887
+ Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
67888
+ console.error("[SecureChannel] onMessage callback error:", err);
67889
+ });
67890
+ }
67891
+ this._persisted.lastMessageTimestamp = msg.created_at;
67892
+ ackedIds.push(msg.queue_id);
67893
+ } catch (err) {
67894
+ console.warn(`[SecureChannel] DR delivery processing failed for ${msg.message_id?.slice(0, 8)}:`, err);
67895
+ nackedIds.push(msg.queue_id);
67896
+ }
67897
+ }
67898
+ await this._persistState();
67899
+ if (nackedIds.length > 0) {
67900
+ try {
67901
+ await fetch(`${this.config.apiUrl}/api/v1/dr/delivery/nack`, {
67902
+ method: "POST",
67903
+ headers: {
67904
+ Authorization: `Bearer ${this._deviceJwt}`,
67905
+ "Content-Type": "application/json"
67906
+ },
67907
+ body: JSON.stringify({ queue_ids: nackedIds })
67908
+ });
67909
+ } catch {
67910
+ }
67911
+ }
67912
+ if (ackedIds.length > 0) {
67913
+ try {
67914
+ await fetch(`${this.config.apiUrl}/api/v1/dr/delivery/ack`, {
67915
+ method: "POST",
67916
+ headers: {
67917
+ Authorization: `Bearer ${this._deviceJwt}`,
67918
+ "Content-Type": "application/json"
67919
+ },
67920
+ body: JSON.stringify({ queue_ids: ackedIds, device_id: this._deviceId })
67921
+ });
67922
+ console.log(`[SecureChannel] DR delivery acked ${ackedIds.length}/${messages.length}`);
67923
+ } catch (ackErr) {
67924
+ console.warn("[SecureChannel] DR delivery ack failed:", ackErr);
67925
+ }
67926
+ }
67927
+ } catch (err) {
67928
+ console.warn("[SecureChannel] DR delivery pull error:", err);
67929
+ } finally {
67930
+ this._drDeliveryPulling = false;
67931
+ }
67932
+ }
67767
67933
  async _handleMlsSyncResponse(data) {
67768
67934
  const action = data.action;
67769
67935
  const groupId = data.group_id;
@@ -89123,7 +89289,7 @@ var init_index = __esm({
89123
89289
  init_skill_invoker();
89124
89290
  await init_skill_telemetry();
89125
89291
  await init_policy_enforcer();
89126
- VERSION = true ? "0.20.32" : "0.0.0-dev";
89292
+ VERSION = true ? "0.20.34" : "0.0.0-dev";
89127
89293
  }
89128
89294
  });
89129
89295