@agentvault/agentvault 0.20.32 → 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.
package/dist/index.js CHANGED
@@ -63714,6 +63714,7 @@ 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). */
@@ -65597,6 +65598,7 @@ var init_channel = __esm({
65597
65598
  this._startWakeDetector();
65598
65599
  this._startPendingPoll();
65599
65600
  await this._syncMissedMessages();
65601
+ await this._pullDrDeliveryQueue();
65600
65602
  await this._flushOutboundQueue();
65601
65603
  this._setState("ready");
65602
65604
  if (this.config.enableScanning) {
@@ -65826,6 +65828,11 @@ var init_channel = __esm({
65826
65828
  console.warn("[SecureChannel] Delivery pull on ping failed:", err);
65827
65829
  });
65828
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
+ }
65829
65836
  if (data.event === "mls_welcome_requested") {
65830
65837
  console.log(`[SecureChannel] mls_welcome_requested for group ${(data.data?.group_id || "").slice(0, 8)} \u2014 pulling deliveries`);
65831
65838
  this._pullDeliveryQueue().catch((err) => {
@@ -67763,6 +67770,165 @@ ${messageText}`;
67763
67770
  this._deliveryPulling = false;
67764
67771
  }
67765
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
+ }
67766
67932
  async _handleMlsSyncResponse(data) {
67767
67933
  const action = data.action;
67768
67934
  const groupId = data.group_id;
@@ -95020,7 +95186,7 @@ var init_index = __esm({
95020
95186
  init_skill_invoker();
95021
95187
  await init_skill_telemetry();
95022
95188
  await init_policy_enforcer();
95023
- VERSION = true ? "0.20.32" : "0.0.0-dev";
95189
+ VERSION = true ? "0.20.33" : "0.0.0-dev";
95024
95190
  }
95025
95191
  });
95026
95192
  await init_index();