@agentvault/grok-bridge 0.4.5 → 0.4.6

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 (2) hide show
  1. package/dist/index.js +91 -55
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -64605,11 +64605,11 @@ var init_mls_kp_pool = __esm2({
64605
64605
  }
64606
64606
  });
64607
64607
  function ownIdentity() {
64608
- const v2 = true ? "0.23.32" : FALLBACK;
64608
+ const v2 = true ? "0.23.33" : FALLBACK;
64609
64609
  return `${PACKAGE}@${v2}`;
64610
64610
  }
64611
64611
  function buildSha() {
64612
- const raw = true ? "564f8b1-dirty" : "";
64612
+ const raw = true ? "7b91f2f-dirty" : "";
64613
64613
  const cleaned = (raw ?? "").trim();
64614
64614
  return !cleaned || cleaned === "unknown" ? null : cleaned;
64615
64615
  }
@@ -65524,6 +65524,7 @@ var OUTBOUND_DEDUPE_MAX;
65524
65524
  var OUTBOUND_DEDUPE_TYPES;
65525
65525
  var RETRY_CANDIDATE_TTL_MS;
65526
65526
  var RETRY_CANDIDATE_MAX;
65527
+ var ROOM_FULFIL_COOLDOWN_MS;
65527
65528
  var SecureChannel;
65528
65529
  var init_channel = __esm2({
65529
65530
  async "src/channel.ts"() {
@@ -65569,6 +65570,7 @@ var init_channel = __esm2({
65569
65570
  OUTBOUND_DEDUPE_TYPES = /* @__PURE__ */ new Set(["text", "status_alert", "artifact", "attachment"]);
65570
65571
  RETRY_CANDIDATE_TTL_MS = 6e4;
65571
65572
  RETRY_CANDIDATE_MAX = 32;
65573
+ ROOM_FULFIL_COOLDOWN_MS = 6e4;
65572
65574
  SecureChannel = class _SecureChannel extends EventEmitter {
65573
65575
  constructor(config2) {
65574
65576
  super();
@@ -65638,6 +65640,8 @@ var init_channel = __esm2({
65638
65640
  _drDeliveryPulling = false;
65639
65641
  /** MLS group managers per room/conversation (roomId or conv:conversationId or 1to1-group:groupId -> MLSGroupManager) */
65640
65642
  _mlsGroups = /* @__PURE__ */ new Map();
65643
+ /** `${mlsGroupId}:${deviceId}` -> last re-admit ms (#1171). */
65644
+ _roomFulfilCooldown = /* @__PURE__ */ new Map();
65641
65645
  /** Maps conversationId -> conversation_group_id for shared 1:1 MLS groups */
65642
65646
  _sessionGroupIds = /* @__PURE__ */ new Map();
65643
65647
  /** Consecutive MLS decrypt failure count per group key for epoch recovery. */
@@ -66803,7 +66807,7 @@ var init_channel = __esm2({
66803
66807
  */
66804
66808
  sendActivitySpan(spanData) {
66805
66809
  if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
66806
- const pluginVersion = true ? "0.23.32" : "0.0.0-dev";
66810
+ const pluginVersion = true ? "0.23.33" : "0.0.0-dev";
66807
66811
  const agentName = this.config.agentName ?? "Agent";
66808
66812
  const resource = {
66809
66813
  "service.name": "agentvault-agent",
@@ -68741,7 +68745,7 @@ var init_channel = __esm2({
68741
68745
  agentVersion: this.config.agentVersion ?? "0.0.0",
68742
68746
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
68743
68747
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
68744
- pluginVersion: true ? "0.23.32" : "0.0.0-dev"
68748
+ pluginVersion: true ? "0.23.33" : "0.0.0-dev"
68745
68749
  });
68746
68750
  this._telemetryReporter.startAutoFlush(3e4);
68747
68751
  }
@@ -69065,7 +69069,7 @@ var init_channel = __esm2({
69065
69069
  agentVersion: this.config.agentVersion ?? "0.0.0",
69066
69070
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
69067
69071
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
69068
- pluginVersion: true ? "0.23.32" : "0.0.0-dev"
69072
+ pluginVersion: true ? "0.23.33" : "0.0.0-dev"
69069
69073
  });
69070
69074
  this._telemetryReporter.startAutoFlush(3e4);
69071
69075
  }
@@ -70754,13 +70758,7 @@ ${baseText}`;
70754
70758
  console.warn(`[SecureChannel] MLS epoch recovery for ${groupKey} (${mlsGroupId.slice(0, 8)})`);
70755
70759
  this._mlsGroups.delete(groupKey);
70756
70760
  this._mlsDecryptFailCounts.delete(groupKey);
70757
- try {
70758
- const { unlink: unlink2 } = await import("fs/promises");
70759
- const path2 = `${this.config.dataDir}/.mls-state/${mlsGroupId}.json`;
70760
- await unlink2(path2).catch(() => {
70761
- });
70762
- } catch {
70763
- }
70761
+ await deleteMlsState(this.config.dataDir, mlsGroupId);
70764
70762
  try {
70765
70763
  const mgr = new MLSGroupManager();
70766
70764
  const identity = new TextEncoder().encode(this._deviceId);
@@ -70835,19 +70833,26 @@ ${baseText}`;
70835
70833
  return 0;
70836
70834
  }
70837
70835
  const snapshot = mlsGroup.exportState();
70838
- const { commit, welcome } = await mlsGroup.addMembers(targets.map((t2) => t2.keyPackage));
70839
- const commitSent = await this._sendFrameConfirmed(
70840
- {
70841
- event: "mls_commit",
70842
- data: {
70843
- group_id: mlsGroupId,
70844
- epoch: Number(mlsGroup.epoch),
70845
- payload: Buffer.from(commit).toString("hex")
70846
- }
70847
- },
70848
- `${label} commit`
70849
- );
70850
- if (!commitSent) {
70836
+ const { commits, welcome } = await mlsGroup.reAdmitMembers(targets.map((t2) => t2.keyPackage));
70837
+ let sentCommits = 0;
70838
+ for (const c2 of commits) {
70839
+ const ok = await this._sendFrameConfirmed(
70840
+ {
70841
+ event: "mls_commit",
70842
+ data: {
70843
+ group_id: mlsGroupId,
70844
+ // The epoch this commit PRODUCED. After two commits the manager
70845
+ // only knows the last one, which is why the result carries them.
70846
+ epoch: Number(c2.epoch),
70847
+ payload: Buffer.from(c2.commit).toString("hex")
70848
+ }
70849
+ },
70850
+ `${label} commit ${sentCommits + 1}/${commits.length}`
70851
+ );
70852
+ if (!ok) break;
70853
+ sentCommits++;
70854
+ }
70855
+ if (sentCommits === 0) {
70851
70856
  mlsGroup.importState(snapshot);
70852
70857
  console.warn(
70853
70858
  `[SecureChannel] ${label}: commit was NOT written \u2014 rolled back to epoch ${Number(mlsGroup.epoch)}, nothing fulfilled, requests stay pending`
@@ -70855,6 +70860,12 @@ ${baseText}`;
70855
70860
  return 0;
70856
70861
  }
70857
70862
  await saveMlsState(this.config.dataDir, mlsGroupId, JSON.stringify(mlsGroup.exportState()));
70863
+ if (sentCommits < commits.length) {
70864
+ console.warn(
70865
+ `[SecureChannel] ${label}: only ${sentCommits}/${commits.length} commits reached the wire \u2014 requests stay PENDING for the next pull`
70866
+ );
70867
+ return 0;
70868
+ }
70858
70869
  if (!welcome) {
70859
70870
  console.warn(
70860
70871
  `[SecureChannel] ${label}: addMembers produced NO Welcome \u2014 ${targets.length} request(s) left pending rather than marked fulfilled`
@@ -71583,38 +71594,63 @@ ${baseText}`;
71583
71594
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
71584
71595
  );
71585
71596
  if (!pendingRes.ok) continue;
71586
- const pending = await pendingRes.json();
71597
+ let pending = await pendingRes.json();
71587
71598
  if (pending.length === 0) continue;
71588
71599
  console.log(`[SecureChannel] ${pending.length} pending Welcome requests for room ${roomId.slice(0, 8)}`);
71600
+ const nowMs = Date.now();
71601
+ const fresh = pending.filter((r2) => {
71602
+ const key = `${roomState.mlsGroupId}:${r2.requesting_device_id}`;
71603
+ const last = this._roomFulfilCooldown.get(key) ?? 0;
71604
+ if (nowMs - last < ROOM_FULFIL_COOLDOWN_MS) {
71605
+ console.log(
71606
+ `[SecureChannel] skipping ${r2.requesting_device_id.slice(0, 8)} in room ${roomId.slice(0, 8)} \u2014 re-admitted ${Math.round((nowMs - last) / 1e3)}s ago`
71607
+ );
71608
+ return false;
71609
+ }
71610
+ return true;
71611
+ });
71612
+ if (fresh.length === 0) continue;
71613
+ for (const r2 of fresh) {
71614
+ this._roomFulfilCooldown.set(`${roomState.mlsGroupId}:${r2.requesting_device_id}`, nowMs);
71615
+ }
71616
+ pending = fresh;
71617
+ const deviceIds = pending.map((r2) => r2.requesting_device_id);
71618
+ const kpRes = await fetch(
71619
+ `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${deviceIds.join(",")}`,
71620
+ { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
71621
+ );
71622
+ if (!kpRes.ok) continue;
71623
+ const kpData = await kpRes.json();
71624
+ const roomTargets = [];
71589
71625
  for (const req of pending) {
71590
- try {
71591
- const kpRes = await fetch(
71592
- `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${req.requesting_device_id}`,
71593
- { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
71626
+ const kpHex = kpData[req.requesting_device_id];
71627
+ if (!kpHex) {
71628
+ console.warn(`[SecureChannel] No KeyPackage for ${req.requesting_device_id.slice(0, 8)}, skipping`);
71629
+ continue;
71630
+ }
71631
+ const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
71632
+ roomTargets.push({
71633
+ requestId: req.id,
71634
+ deviceId: req.requesting_device_id,
71635
+ keyPackage: MLSGroupManager.deserializeKeyPackage(kpBytes)
71636
+ });
71637
+ }
71638
+ if (roomTargets.length === 0) continue;
71639
+ try {
71640
+ const done = await this._fulfilWelcomeRequests({
71641
+ mlsGroup,
71642
+ mlsGroupId: roomState.mlsGroupId,
71643
+ label: `room ${roomId.slice(0, 8)}`,
71644
+ welcomeFields: { room_id: roomId },
71645
+ targets: roomTargets
71646
+ });
71647
+ if (done > 0) {
71648
+ console.log(
71649
+ `[SecureChannel] Batched Welcome for ${done}/${roomTargets.length} device(s) in room ${roomId.slice(0, 8)} (epoch=${mlsGroup.epoch})`
71594
71650
  );
71595
- if (!kpRes.ok) continue;
71596
- const kpData = await kpRes.json();
71597
- const kpHex = kpData[req.requesting_device_id];
71598
- if (!kpHex) continue;
71599
- const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
71600
- const memberKp = MLSGroupManager.deserializeKeyPackage(kpBytes);
71601
- const done = await this._fulfilWelcomeRequests({
71602
- mlsGroup,
71603
- mlsGroupId: roomState.mlsGroupId,
71604
- label: `room ${roomId.slice(0, 8)}`,
71605
- welcomeFields: { room_id: roomId },
71606
- targets: [{
71607
- requestId: req.id,
71608
- deviceId: req.requesting_device_id,
71609
- keyPackage: memberKp
71610
- }]
71611
- });
71612
- if (done > 0) {
71613
- console.log(`[SecureChannel] Fulfilled Welcome for ${req.requesting_device_id.slice(0, 8)} in room ${roomId.slice(0, 8)}`);
71614
- }
71615
- } catch (fulfillErr) {
71616
- console.warn(`[SecureChannel] Welcome fulfill failed for ${req.requesting_device_id.slice(0, 8)}:`, fulfillErr);
71617
71651
  }
71652
+ } catch (fulfillErr) {
71653
+ console.warn(`[SecureChannel] Batched Welcome failed for room ${roomId.slice(0, 8)}:`, fulfillErr);
71618
71654
  }
71619
71655
  } catch {
71620
71656
  }
@@ -99425,7 +99461,7 @@ var init_index = __esm2({
99425
99461
  await init_skill_telemetry();
99426
99462
  await init_policy_enforcer();
99427
99463
  init_room_protocol();
99428
- VERSION = true ? "0.23.32" : "0.0.0-dev";
99464
+ VERSION = true ? "0.23.33" : "0.0.0-dev";
99429
99465
  }
99430
99466
  });
99431
99467
  await init_index();
@@ -100351,7 +100387,7 @@ async function main() {
100351
100387
  const info = parseInfoFlags(process.argv.slice(2));
100352
100388
  if (info.showVersion || info.showHelp) {
100353
100389
  const version2 = buildClientVersion2(
100354
- true ? "0.4.5" : void 0
100390
+ true ? "0.4.6" : void 0
100355
100391
  );
100356
100392
  if (info.showVersion) printLine(version2);
100357
100393
  if (info.showHelp) {
@@ -100404,7 +100440,7 @@ async function main() {
100404
100440
  agentName: cfg.agentName,
100405
100441
  platform: "node",
100406
100442
  clientVersion: buildClientVersion2(
100407
- true ? "0.4.5" : void 0
100443
+ true ? "0.4.6" : void 0
100408
100444
  )
100409
100445
  });
100410
100446
  channelRef = channel;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentvault/grok-bridge",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "type": "module",
5
5
  "description": "AgentVault Grok Bridge — daemon bridging a Grok agent into E2E-encrypted AgentVault direct messages and rooms.",
6
6
  "main": "dist/index.js",