@agentvault/grok-bridge 0.4.22 → 0.4.24

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
@@ -43,6 +43,7 @@ import { readdir as readdir2, readFile as readFile4, writeFile as writeFile2, re
43
43
  import { join as join5 } from "node:path";
44
44
  import { randomUUID as randomUUID3 } from "node:crypto";
45
45
  import { EventEmitter } from "node:events";
46
+ import { AsyncLocalStorage } from "node:async_hooks";
46
47
  import { createServer } from "node:http";
47
48
  import { randomUUID as randomUUID4, createHash } from "node:crypto";
48
49
  import { readFileSync } from "node:fs";
@@ -52,7 +53,7 @@ import { join as join6 } from "node:path";
52
53
  import { readFile as readFile5 } from "node:fs/promises";
53
54
  import WebSocket from "ws";
54
55
  import { resolve as resolve2 } from "node:path";
55
- import { AsyncLocalStorage } from "node:async_hooks";
56
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
56
57
  import { Http2ServerRequest as Http2ServerRequest2 } from "http2";
57
58
  import { Http2ServerRequest } from "http2";
58
59
  import { Readable as Readable2 } from "stream";
@@ -11712,11 +11713,11 @@ async function joinWithFirstMatchingKp(welcomeBytes, candidates) {
11712
11713
  return null;
11713
11714
  }
11714
11715
  function ownIdentity() {
11715
- const v2 = true ? "0.23.51" : FALLBACK;
11716
+ const v2 = true ? "0.23.53" : FALLBACK;
11716
11717
  return `${PACKAGE}@${v2}`;
11717
11718
  }
11718
11719
  function buildSha() {
11719
- const raw = true ? "753de79" : "";
11720
+ const raw = true ? "3f2a933" : "";
11720
11721
  const cleaned = (raw ?? "").trim();
11721
11722
  return !cleaned || cleaned === "unknown" ? null : cleaned;
11722
11723
  }
@@ -12494,11 +12495,38 @@ function _resetCompatCacheForTest() {
12494
12495
  _agentEventFn = null;
12495
12496
  _transcriptFn = null;
12496
12497
  }
12498
+ function ownerRoutingFrom(parsed) {
12499
+ const out = {};
12500
+ if (parsed.conversation_id !== void 0) {
12501
+ if (typeof parsed.conversation_id !== "string" || !parsed.conversation_id) return "'conversation_id' must be a string";
12502
+ out.conversationId = parsed.conversation_id;
12503
+ }
12504
+ if (parsed.audience !== void 0) {
12505
+ if (parsed.audience !== "person" && parsed.audience !== "everyone") {
12506
+ return `'audience' must be "person" or "everyone"`;
12507
+ }
12508
+ out.audience = parsed.audience;
12509
+ }
12510
+ return out;
12511
+ }
12512
+ function ambiguousOwnerRequest(channel, routing) {
12513
+ const check = channel.isUntargetedOwnerAmbiguous;
12514
+ if (typeof check !== "function" || !check.call(channel, routing)) return null;
12515
+ return { status: 409, body: { ok: false, error: AMBIGUOUS_OWNER_ERROR } };
12516
+ }
12517
+ function statusOf(receipt) {
12518
+ if (receipt.ambiguous) return 409;
12519
+ return receipt.ok ? 200 : 500;
12520
+ }
12497
12521
  async function handleSendRequest(parsed, channel) {
12498
12522
  const text = parsed.text;
12499
12523
  if (!text || typeof text !== "string") {
12500
12524
  return { status: 400, body: { ok: false, error: "Missing 'text' field" } };
12501
12525
  }
12526
+ const routing = ownerRoutingFrom(parsed);
12527
+ if (typeof routing === "string") {
12528
+ return { status: 400, body: { ok: false, error: routing } };
12529
+ }
12502
12530
  try {
12503
12531
  let target;
12504
12532
  let a2aTarget = parsed.hub_address ?? parsed.a2a_address ?? parsed.a2aAddress;
@@ -12516,10 +12544,10 @@ async function handleSendRequest(parsed, channel) {
12516
12544
  const receipt2 = await channel.deliver(
12517
12545
  { kind: "owner" },
12518
12546
  { type: "attachment", text, filePath: parsed.file_path },
12519
- { topicId: parsed.topicId }
12547
+ { topicId: parsed.topicId, ...routing, refuseIfAmbiguous: true }
12520
12548
  );
12521
12549
  return {
12522
- status: receipt2.ok ? 200 : 500,
12550
+ status: statusOf(receipt2),
12523
12551
  body: {
12524
12552
  ok: receipt2.ok,
12525
12553
  destination: receipt2.destination,
@@ -12533,6 +12561,8 @@ async function handleSendRequest(parsed, channel) {
12533
12561
  target,
12534
12562
  { type: "text", text },
12535
12563
  {
12564
+ ...routing,
12565
+ refuseIfAmbiguous: true,
12536
12566
  topicId: parsed.topicId,
12537
12567
  priority: parsed.priority,
12538
12568
  metadata: {
@@ -12542,7 +12572,7 @@ async function handleSendRequest(parsed, channel) {
12542
12572
  }
12543
12573
  );
12544
12574
  return {
12545
- status: receipt.ok ? 200 : 500,
12575
+ status: statusOf(receipt),
12546
12576
  body: {
12547
12577
  ok: receipt.ok,
12548
12578
  destination: receipt.destination,
@@ -12557,6 +12587,10 @@ async function handleActionRequest(parsed, channel) {
12557
12587
  if (!parsed.action || typeof parsed.action !== "string") {
12558
12588
  return { status: 400, body: { ok: false, error: "Missing 'action' field" } };
12559
12589
  }
12590
+ const routing = ownerRoutingFrom(parsed);
12591
+ if (typeof routing === "string") {
12592
+ return { status: 400, body: { ok: false, error: routing } };
12593
+ }
12560
12594
  try {
12561
12595
  const confirmation = {
12562
12596
  action: parsed.action,
@@ -12566,12 +12600,10 @@ async function handleActionRequest(parsed, channel) {
12566
12600
  estimated_cost: parsed.estimated_cost
12567
12601
  };
12568
12602
  const target = parsed.room_id && typeof parsed.room_id === "string" ? { kind: "room", roomId: parsed.room_id } : { kind: "owner" };
12569
- const receipt = await channel.deliver(
12570
- target,
12571
- { type: "action_confirmation", confirmation }
12572
- );
12603
+ const content = { type: "action_confirmation", confirmation };
12604
+ const receipt = await channel.deliver(target, content, { ...routing, refuseIfAmbiguous: true });
12573
12605
  return {
12574
- status: receipt.ok ? 200 : 500,
12606
+ status: statusOf(receipt),
12575
12607
  body: {
12576
12608
  ok: receipt.ok,
12577
12609
  destination: receipt.destination,
@@ -12596,6 +12628,12 @@ async function handleDecisionRequest(parsed, channel) {
12596
12628
  return { status: 400, body: { ok: false, error: "Each option must have 'option_id' and 'label'" } };
12597
12629
  }
12598
12630
  }
12631
+ const routing = ownerRoutingFrom(parsed);
12632
+ if (typeof routing === "string") {
12633
+ return { status: 400, body: { ok: false, error: routing } };
12634
+ }
12635
+ const ambiguous = ambiguousOwnerRequest(channel, routing);
12636
+ if (ambiguous) return ambiguous;
12599
12637
  try {
12600
12638
  const decision_id = await channel.sendDecisionRequest({
12601
12639
  title,
@@ -12604,7 +12642,7 @@ async function handleDecisionRequest(parsed, channel) {
12604
12642
  context_refs: parsed.context_refs,
12605
12643
  deadline: parsed.deadline,
12606
12644
  auto_action: parsed.auto_action
12607
- });
12645
+ }, routing);
12608
12646
  return { status: 200, body: { ok: true, decision_id } };
12609
12647
  } catch (err) {
12610
12648
  return { status: 500, body: { ok: false, error: String(err) } };
@@ -13102,7 +13140,7 @@ async function _handleInbound(params) {
13102
13140
  core.error?.(`[AgentVault] session record failed: ${String(err)}`);
13103
13141
  }
13104
13142
  });
13105
- await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
13143
+ await channel.runForConversation(metadata.conversationId, () => core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
13106
13144
  ctx: ctxPayload,
13107
13145
  cfg,
13108
13146
  dispatcherOptions: {
@@ -13119,7 +13157,7 @@ async function _handleInbound(params) {
13119
13157
  }
13120
13158
  },
13121
13159
  replyOptions: {}
13122
- });
13160
+ }), { groupId: metadata.conversationGroupId });
13123
13161
  }
13124
13162
  function getErrorMap() {
13125
13163
  return overrideErrorMap;
@@ -17643,7 +17681,7 @@ function armSseKeepAlive(intervalMs, onTick) {
17643
17681
  timer.unref?.();
17644
17682
  return timer;
17645
17683
  }
17646
- var __create, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf, __hasOwnProp, __esm2, __commonJS, __export2, __copyProps, __toESM, SENTINEL, WRAPPERS, INSTRUCTION, init_abstention, init_envelope_text, init_mls_commit_classify, MENTION_RE, BROADCAST_NAMES, init_room_protocol, __filename, __dirname, url, path, Module, Module, root, window_, crypto_, randomValuesStandard, crypto2, randomValueNodeJS, _Module, libsodium_sumo_default, init_libsodium_sumo, a, r, t, c, libsodium_wrappers_default, init_libsodium_wrappers, init_keys, init_x3dh, MAX_SKIP, CHAIN_KEY_SEED, MSG_KEY_SEED, HEADER_KEY_SEED, DoubleRatchet, init_ratchet, init_file_crypto, DOMAIN_DID_DOCUMENT, DOMAIN_TRANSFER_INTENT, DOMAIN_TRANSFER_ACCEPT, BASE58_ALPHABET, init_did, BUILTIN_PATTERNS, ScanEngine, init_scan_engine, init_merkle, VC_CONTEXT_V2, AV_CREDENTIAL_CONTEXT, CRYPTOSUITE, BASE58_ALPHABET2, init_vc, init_transport, init_telemetry, TelemetryReporter, init_telemetry_reporter, CROCKFORD, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, BACKUP_VERSION, MAX_BACKUP_SIZE, init_backup, atitle, aobject, aopts, isLE, swap8IfBE, swap32IfBE, hasHexBuiltin, hexes, oidNist, init_utils, BSIGMA, init_blake, U32_MASK64, _32n, fromNumH, fromNumL, shrSH, shrSL, rotrSH, rotrSL, rotrBH, rotrBL, rotr32H, rotr32L, add3L, add3H, add4L, add4H, add5L, add5H, init_u64, HashMD, SHA256_IV, SHA384_IV, SHA512_IV, init_md, B2B_IV, BBUF, _BLAKE2, _BLAKE2b, blake2b, init_blake2, CROCKFORD2, SALT_BYTES2, NONCE_BYTES2, KEY_BYTES2, TAG_BYTES, ENVELOPE_OVERHEAD, AAD_PREFIX, UUID_RE, UUID_V4_RE, DIGEST_ID_RE, TIMESTAMP_RE, encoder, decoder, HISTORY_MAGIC, HISTORY_ARCHIVE_VERSION, HISTORY_MAX_ENTRIES, HISTORY_MAX_BLOB_BYTES, HISTORY_KDF_OPSLIMIT, HISTORY_KDF_MEMLIMIT, HistoryEntryTooLargeError, init_history_backup, init_approval, encVoid, init_tlsEncoder, uint8Encoder, encodeUint8, decodeUint8, uint16Encoder, encodeUint16, decodeUint16, uint32Encoder, encodeUint32, decodeUint32, uint64Encoder, encodeUint64, decodeUint64, init_number, init_tlsDecoder, init_enumHelpers, defaultProposalTypes, defaultProposalTypeEncoder, encodeDefaultProposalType, decodeDefaultProposalType, init_defaultProposalType, defaultExtensionTypes, defaultExtensionTypeEncoder, encodeDefaultExtensionType, decodeDefaultExtensionType, init_defaultExtensionType, acceptAll, init_incomingMessageAction, MlsError, ValidationError, CodecError, UsageError, DependencyError, CryptoVerificationError, CryptoError, InternalError, init_mlsError, init_byteArray, varLenDataEncoder, decodeVarLenData, init_variableLength, init_constantTimeCompare, extensionTypeEncoder, encodeExtensionType, decodeExtensionType, extensionEncoder, encodeExtension, decodeExtension, init_extension, credentialTypes, credentialTypeEncoder, encodeCredentialType, decodeCredentialType, init_credentialType, credentialBasicEncoder, encodeCredentialBasic, credentialX509Encoder, encodeCredentialX509, credentialCustomEncoder, encodeCredentialCustom, credentialEncoder, encodeCredential, decodeCredentialBasic, decodeCredentialX509, decodeCredential, init_credential, externalSenderEncoder, encodeExternalSender, decodeExternalSender, init_externalSender, init_hash, init_optional, ciphersuites, ciphersuiteEncoder, encodeCiphersuite, decodeCiphersuite, ciphersuiteValues, init_ciphersuite, init_signature, protocolVersions, protocolVersionEncoder, encodeProtocolVersion, decodeProtocolVersion, init_protocolVersion, capabilitiesEncoder, encodeCapabilities, decodeCapabilities, init_capabilities, leafNodeSources, leafNodeSourceEncoder, encodeLeafNodeSource, decodeLeafNodeSource, init_leafNodeSource, lifetimeEncoder, encodeLifetime, decodeLifetime, defaultLifetime, init_lifetime, leafNodeDataEncoder, encodeLeafNodeData, decodeLeafNodeData, leafNodeInfoKeyPackageEncoder, encodeLeafNodeInfoKeyPackage, leafNodeInfoUpdateOmittedEncoder, encodeLeafNodeInfoUpdateOmitted, leafNodeInfoCommitOmittedEncoder, encodeLeafNodeInfoCommitOmitted, leafNodeInfoOmittedEncoder, encodeLeafNodeInfoOmitted, decodeLeafNodeInfoKeyPackage, decodeLeafNodeInfoUpdateOmitted, decodeLeafNodeInfoCommitOmitted, decodeLeafNodeInfoOmitted, leafNodeInfoUpdateEncoder, encodeLeafNodeInfoUpdate, leafNodeInfoCommitEncoder, encodeLeafNodeInfoCommit, leafNodeInfoEncoder, encodeLeafNodeInfo, decodeLeafNodeInfoUpdate, decodeLeafNodeInfoCommit, decodeLeafNodeInfo, leafNodeTBSEncoder, encodeLeafNodeTBS, leafNodeEncoder, encodeLeafNode, decodeLeafNode, decodeLeafNodeKeyPackage, decodeLeafNodeCommit, decodeLeafNodeUpdate, init_leafNode, keyPackageTBSEncoder, encodeKeyPackageTBS, decodeKeyPackageTBS, keyPackageEncoder, encodeKeyPackage, decodeKeyPackage, init_keyPackage, init_kdf, pskTypes, pskTypeEncoder, encodePskType, decodePskType, resumptionPSKUsages, resumptionPSKUsageEncoder, encodeResumptionPSKUsage, decodeResumptionPSKUsage, encodePskInfoExternal, encodePskInfoResumption, decodePskInfoResumption, pskInfoEncoder, encodePskInfo, decodePskInfo, pskIdEncoder, encodePskId, decodePskId, pskLabelEncoder, encodePskLabel, decodePskLabel, init_presharedkey, addEncoder, encodeAdd, decodeAdd, updateEncoder, encodeUpdate, decodeUpdate, removeEncoder, encodeRemove, decodeRemove, pskEncoder, encodePSK, decodePSK, reinitEncoder, encodeReinit, decodeReinit, externalInitEncoder, encodeExternalInit, decodeExternalInit, groupContextExtensionsEncoder, encodeGroupContextExtensions, decodeGroupContextExtensions, proposalAddEncoder, encodeProposalAdd, proposalUpdateEncoder, encodeProposalUpdate, proposalRemoveEncoder, encodeProposalRemove, proposalPSKEncoder, encodeProposalPSK, proposalReinitEncoder, encodeProposalReinit, proposalExternalInitEncoder, encodeProposalExternalInit, proposalGroupContextExtensionsEncoder, encodeProposalGroupContextExtensions, proposalCustomEncoder, encodeProposalCustom, proposalEncoder, encodeProposal, decodeProposalAdd, decodeProposalUpdate, decodeProposalRemove, decodeProposalPSK, decodeProposalReinit, decodeProposalExternalInit, decodeProposalGroupContextExtensions, decodeProposal, init_proposal, proposalOrRefTypes, proposalOrRefTypeEncoder, encodeProposalOrRefType, decodeProposalOrRefType, proposalOrRefProposalEncoder, encodeProposalOrRefProposal, proposalOrRefProposalRefEncoder, encodeProposalOrRefProposalRef, proposalOrRefEncoder, encodeProposalOrRef, decodeProposalOrRef, init_proposalOrRefType, init_hpke, groupContextEncoder, encodeGroupContext, decodeGroupContext, init_groupContext, nodeTypes, nodeTypeEncoder, encodeNodeType, decodeNodeType, init_nodeType, parentNodeEncoder, encodeParentNode, decodeParentNode, init_parentNode, init_treemath, nodeEncoder, encodeNode, decodeNode, ratchetTreeEncoder, encodeRatchetTree, decodeRatchetTree, init_ratchetTree, leafNodeHashInputEncoder, encodeLeafNodeHashInput, decodeLeafNodeHashInput, parentNodeHashInputEncoder, encodeParentNodeHashInput, decodeParentNodeHashInput, treeHashInputEncoder, encodeTreeHashInput, decodeTreeHashInput, init_treeHash, parentHashInputEncoder, encodeParentHashInput, decodeParentHashInput, init_parentHash, hpkeCiphertextEncoder, encodeHpkeCiphertext, decodeHpkeCiphertext, init_hpkeCiphertext, updatePathNodeEncoder, encodeUpdatePathNode, decodeUpdatePathNode, updatePathEncoder, encodeUpdatePath, decodeUpdatePath, init_updatePath, commitEncoder, encodeCommit, decodeCommit, init_commit, contentTypes, contentTypeEncoder, encodeContentType, decodeContentType, init_contentType, wireformats, wireformatEncoder, encodeWireformat, decodeWireformat, init_wireformat, senderTypes, senderTypeEncoder, encodeSenderType, decodeSenderType, senderEncoder, encodeSender, decodeSender, reuseGuardEncoder, encodeReuseGuard, decodeReuseGuard, senderDataEncoder, encodeSenderData, decodeSenderData, senderDataAADEncoder, encodeSenderDataAAD, decodeSenderDataAAD, init_sender, framedContentApplicationDataEncoder, encodeFramedContentApplicationData, framedContentProposalDataEncoder, encodeFramedContentProposalData, framedContentCommitDataEncoder, encodeFramedContentCommitData, framedContentInfoEncoder, encodeFramedContentInfo, decodeFramedContentApplicationData, decodeFramedContentProposalData, decodeFramedContentCommitData, decodeFramedContentInfo, framedContentEncoder, encodeFramedContent, decodeFramedContent, senderInfoEncoder, encodeSenderInfo, framedContentTBSEncoder, encodeFramedContentTBS, encodeFramedContentAuthDataContent, encodeFramedContentAuthDataCommit, framedContentAuthDataEncoder, encodeFramedContentAuthData, decodeFramedContentAuthDataCommit, init_framedContent, authenticatedContentEncoder, encodeAuthenticatedContent, decodeAuthenticatedContent, authenticatedContentTBMEncoder, encodeAuthenticatedContentTBM, init_authenticatedContent, publicMessageInfoEncoder, encodePublicMessageInfo, publicMessageEncoder, encodePublicMessage, decodePublicMessage, init_publicMessage, init_messageProtectionPublic, init_externalProposal, requiredCapabilitiesEncoder, encodeRequiredCapabilities, decodeRequiredCapabilities, init_requiredCapabilities, defaultAuthenticationService, init_authenticationService, defaultPaddingConfig, init_paddingConfig, defaultKeyPackageEqualityConfig, init_keyPackageEqualityConfig, defaultLifetimeConfig, init_lifetimeConfig, defaultKeyRetentionConfig, init_keyRetentionConfig, groupInfoTBSEncoder, encodeGroupInfoTBS, decodeGroupInfoTBS, groupInfoEncoder, encodeGroupInfo, decodeGroupInfo, init_groupInfo, keyScheduleEncoder, encodeKeySchedule, decodeKeySchedule, init_keySchedule, generationSecretEncoder, decodeGenerationSecret, secretTreeNodeEncoder, decodeSecretTreeNode, secretTreeEncoder, decodeSecretTree, init_secretTree, confirmedTranscriptHashInputEncoder, encodeConfirmedTranscriptHashInput, decodeConfirmedTranscriptHashInput, init_transcriptHash, groupSecretsEncoder, encodeGroupSecrets, decodeGroupSecrets, init_groupSecrets, encryptedGroupSecretsEncoder, encodeEncryptedGroupSecrets, decodeEncryptedGroupSecrets, welcomeEncoder, encodeWelcome, decodeWelcome, init_welcome, init_pathSecrets, privateKeyPathEncoder, decodePrivateKeyPath, init_privateKeyPath, proposalWithSenderEncoder, decodeProposalWithSender, unappliedProposalsEncoder, decodeUnappliedProposals, init_unappliedProposals, emptyPskIndex, init_pskIndex, init_addToMap, defaultClientConfig, init_clientConfig, init_array, stringEncoder, encodeString, decodeString, init_string, activeEncoder, suspendedPendingReinitEncoder, removedFromGroupEncoder, groupActiveStateEncoder, decodeGroupActiveState, init_groupActiveState, epochReceiverDataEncoder, decodeEpochReceiverData, init_epochReceiverData, groupStateEncoder, encodeGroupState, decodeGroupState, groupStateEncoderWithoutTree, encodeGroupStateWithoutTree, emptyProposals, init_clientState, privateMessageEncoder, encodePrivateMessage, decodePrivateMessage, privateContentAADEncoder, encodePrivateContentAAD, decodePrivateContentAAD, init_privateMessage, init_messageProtection, init_createMessage, init_createCommit, init_processMessages, init_makeHashImpl, HpkeError, InvalidParamError, SerializeError, DeserializeError, EncapError, DecapError, ExportError, SealError, OpenError, MessageLimitReachedError, DeriveKeyPairError, NotSupportedError, init_errors, dntGlobals, dntGlobalThis, init_dnt_shims, NativeAlgorithm, init_algorithm, Mode, KemId, KdfId, AeadId, init_identifiers, INPUT_LENGTH_LIMIT, INFO_LENGTH_LIMIT, MINIMUM_PSK_LENGTH, EMPTY, BYTE_TO_BIGINT_256, init_consts, SUITE_ID_HEADER_KEM, init_kemInterface, HPKE_VERSION, HkdfNative, HkdfSha256Native, HkdfSha384Native, HkdfSha512Native, init_hkdf, isCryptoKeyPair, init_misc, LABEL_EAE_PRK, LABEL_SHARED_SECRET, Dhkem, init_dhkem, KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, init_dhkemPrimitives, Bignum, init_bignum, LABEL_CANDIDATE, ORDER_P_256, ORDER_P_384, ORDER_P_521, PKCS8_ALG_ID_P_256, PKCS8_ALG_ID_P_384, PKCS8_ALG_ID_P_521, EC_P_256_PARAMS, EC_P_384_PARAMS, EC_P_521_PARAMS, Ec, init_ec, init_xCryptoKey, init_xCurve, init_hybridkem, AEAD_USAGES, init_aeadEncryptionContext, _endianTestBuffer, _endianTestBytes, isLE2, init_noble, init_hash2, _HMAC, hmac, init_hmac, init_md2, U32_MASK642, _32n2, init_u642, init_sha2, _0n, _1n, _2n, _7n, _256n, _0x71n, SHA3_PI, SHA3_ROTL, _SHA3_IOTA, IOTAS, SHA3_IOTA_H, SHA3_IOTA_L, init_sha3, init_modular, init_curve, init_montgomery, init_mod, AesGcmContext, Aes128Gcm, Aes256Gcm, init_aesGcm, init_exportOnly, init_emitNotSupported, LABEL_SEC, ExporterContextImpl, RecipientExporterContextImpl, SenderExporterContextImpl, init_exporterContext, EncryptionContextImpl, init_encryptionContext, __classPrivateFieldGet, __classPrivateFieldSet, _Mutex_locked, Mutex, init_mutex, __classPrivateFieldGet2, __classPrivateFieldSet2, _RecipientContextImpl_mutex, RecipientContextImpl, init_recipientContext, __classPrivateFieldGet3, __classPrivateFieldSet3, _SenderContextImpl_mutex, SenderContextImpl, init_senderContext, LABEL_BASE_NONCE, LABEL_EXP, LABEL_INFO_HASH, LABEL_KEY, LABEL_PSK_ID_HASH, LABEL_SECRET, SUITE_ID_HEADER_HPKE, CipherSuiteNative, init_cipherSuiteNative, DhkemP256HkdfSha256Native, DhkemP384HkdfSha384Native, DhkemP521HkdfSha512Native, init_dhkemNative, CipherSuite, DhkemP256HkdfSha256, DhkemP384HkdfSha384, DhkemP521HkdfSha512, HkdfSha256, HkdfSha384, HkdfSha512, init_native, ALG_NAME, PKCS8_ALG_ID_X25519, BASE_POINT_X25519, X25519, init_x25519, DhkemX25519HkdfSha256, init_dhkemX25519, PKCS8_ALG_ID_X448, init_x448, init_dhkemX448, init_mod2, init_hpke2, isLE3, wrapCipher, init_utils2, encodeStr, sigma16, sigma32, sigma16_32, sigma32_32, BLOCK_LEN, BLOCK_LEN32, MAX_COUNTER, U32_EMPTY, _XorStreamPRG, createPRG, init_arx, Poly1305, poly1305, init_poly1305, chacha_exports, chacha20orig, chacha20, xchacha20, chacha8, chacha12, ZEROS16, updatePadded, ZEROS32, _poly1305_aead, chacha20poly1305, xchacha20poly1305, rngChacha20, rngChacha8, init_chacha, init_makeAead, init_makeKdfImpl, init_makeDhKem, init_makeHpke, defaultRng, init_rng, crypto3, init_cryptoNode, isLE4, swap32IfBE3, hasHexBuiltin2, hexes2, asciis, Hash, init_utils3, HashMD3, SHA256_IV3, SHA384_IV3, SHA512_IV3, init_md3, U32_MASK643, _32n3, shrSH3, shrSL3, rotrSH3, rotrSL3, rotrBH3, rotrBL3, rotlSH2, rotlSL2, rotlBH2, rotlBL2, add3L3, add3H3, add4L3, add4H3, add5L3, add5H3, init_u643, SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384, sha2563, sha5122, sha3842, init_sha22, _0n2, _1n2, isPosBig, bitMask, notImplemented, init_utils4, _0n3, _1n3, _2n2, _3n, _4n, _5n, _7n2, _8n, _9n, _16n, isNegativeLE, FIELD_FIELDS, init_modular2, _0n4, _1n4, pointPrecomputes, pointWindowSizes, wNAF, init_curve2, _0n5, _1n5, _2n3, _8n2, PrimeEdwardsPoint, init_edwards, os2ip, _DST_scalar, init_hash_to_curve, _0n6, _1n6, _2n4, init_montgomery2, ed25519_exports, _0n7, _1n7, _2n5, _3n2, _5n2, _8n3, ed25519_CURVE_p, ed25519_CURVE, ED25519_SQRT_M1, Fp, Fn, ed25519Defaults, ed25519, ed25519ctx, ed25519ph, x25519, ELL2_C1, ELL2_C2, ELL2_C3, ELL2_C1_EDWARDS, ed25519_hasher, SQRT_M1, SQRT_AD_MINUS_ONE, INVSQRT_A_MINUS_D, ONE_MINUS_D_SQ, D_MINUS_ONE_SQ, invertSqrt, MAX_255B, bytes255ToNumberLE, _RistrettoPoint, ristretto255, ristretto255_hasher, ED25519_TORSION_SUBGROUP, edwardsToMontgomery, RistrettoPoint, hashToCurve, encodeToCurve, hashToRistretto255, hash_to_ristretto255, init_ed25519, _0n8, _1n8, _2n6, _7n3, _256n2, _0x71n2, SHA3_PI2, SHA3_ROTL2, _SHA3_IOTA2, IOTAS2, SHA3_IOTA_H2, SHA3_IOTA_L2, rotlH, rotlL, Keccak, genShake, shake2562, init_sha32, ed448_exports, ed448_CURVE, E448_CURVE, shake256_114, shake256_64, _1n9, _2n7, _3n3, _4n2, _11n, _22n, _44n, _88n, _223n, Fp2, Fn2, Fp448, Fn448, ED448_DEF, ed448, ed448ph, E448, x448, ELL2_C12, ELL2_J, ed448_hasher, ONE_MINUS_D, ONE_MINUS_TWO_D, SQRT_MINUS_D, INVSQRT_MINUS_D, invertSqrt2, _DecafPoint, decaf448, decaf448_hasher, ED448_TORSION_SUBGROUP, DecafPoint, hashToCurve2, encodeToCurve2, hashToDecaf448, hash_to_decaf448, edwardsToMontgomery2, init_ed448, HMAC, hmac2, init_hmac2, divNearest, DERErr, DER, _0n9, _1n10, _2n8, _3n4, _4n3, init_weierstrass, init_shortw_utils, nist_exports, p256_CURVE, p384_CURVE, p521_CURVE, Fp256, Fp384, Fp521, p256, p256_hasher, p384, p384_hasher, p521, secp256r1, secp384r1, secp521r1, p521_hasher, init_nist, init_makeNobleSignatureImpl, defaultCryptoProvider, init_provider, init_getCiphersuiteImpl, init_resumption, SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384, sha2564, sha5123, sha3843, init_sha23, _HMAC2, hmac3, init_hmac3, init_makeHashImpl2, init_makeNobleSignatureImpl2, BLOCK_SIZE, ZEROS162, ZEROS322, POLY, mul2, swapLE, estimateWindow, GHASH, Polyval, ghash, polyval, init_polyval, BLOCK_SIZE2, BLOCK_SIZE32, EMPTY_BLOCK, POLY2, sbox, rotr32_8, rotl32_8, tableEncoding, xPowers, gcm, _CMAC, cmac, init_aes, init_makeAead2, init_makeKdfImpl2, init_makeDhKem2, init_makeHpke2, init_rng2, nobleCryptoProvider, init_provider2, mlsPublicMessageEncoder, encodeMlsPublicMessage, mlsWelcomeEncoder, encodeMlsWelcome, mlsPrivateMessageEncoder, encodeMlsPrivateMessage, mlsGroupInfoEncoder, encodeMlsGroupInfo, mlsKeyPackageEncoder, encodeMlsKeyPackage, mlsMessageContentEncoder, encodeMlsMessageContent, decodeMlsMessageContent, mlsMessageEncoder, encodeMlsMessage, decodeMlsMessage, init_message, greaseValues, defaultGreaseConfig, init_grease, init_defaultCapabilities, init_src, DEFAULT_CIPHERSUITE, MLSGroupManager, init_mls_group, DOMAIN, NONCE_BYTES3, init_owner_sync, init_mls_delivery_order, init_mls_presend_epoch, dist_exports, init_dist2, DIR_MODE, FILE_MODE, init_secure_file, SYNC_LOCK_STALE_MS, pendingKpPath, init_mls_state, init_mls_kp_pool, PACKAGE, FALLBACK, MAX_LEN, DISALLOWED, init_client_version, CredentialStore, init_credential_store, init_crypto_helpers, STATE_FILE, LEGACY_STATE_FILE, init_state, ACTIVATION_DOMAIN, UUID_RE2, init_transport2, A2ALogGate, init_a2a_log_gate, init_mls_membership_probe, FIRST_DIRTY_DELAY_MS, RETRY_BASE_DELAYS_MS, MAX_RETRY_DELAY_MS, JITTER_FRACTION, HistoryBackupScheduler, init_history_backup_scheduler, FILE_MODE2, init_history_recovery_file, TENANT_ID_PATTERN, DIR_MODE2, FILE_MODE3, HISTORY_RECOVERY_VERIFY_TIMEOUT_MS, VERIFY_TIMEOUT_MESSAGE, HistoryRecoveryVerificationTimeoutError, init_history_recovery_code, ACTIONS, init_decision_reply, history_backup_client_exports, HISTORY_RESTORE_TIMEOUT_MS, HISTORY_RESTORE_RESPONSE_MAX_BYTES, HISTORY_ENVELOPE_MIN_BYTES, HISTORY_AAD_PREFIX, UUID_RE3, GENERATION_RESPONSE_KEYS, utf8Encoder, utf8Decoder, HistoryBackupClient, init_history_backup_client, openclaw_compat_exports, defaultImporter, HEARTBEAT_CANDIDATES, AGENT_EVENT_CANDIDATES, TRANSCRIPT_CANDIDATES, _heartbeatFn, _agentEventFn, _transcriptFn, init_openclaw_compat, http_handlers_exports, init_http_handlers, mcp_proxy_helpers_exports, init_mcp_proxy_helpers, workspace_handlers_exports, MAX_FILE_SIZE, init_workspace_handlers, ROOM_AGENT_TYPES, CREDENTIAL_MESSAGE_TYPES, CATCHUP_MESSAGE_TYPES, POLL_INTERVAL_MS, RECONNECT_BASE_MS, UUID_RE4, RECONNECT_MAX_MS, PENDING_POLL_INTERVAL_MS, HISTORY_RESTORE_TIMEOUT_MS2, HISTORY_UPLOAD_TIMEOUT_MS, CANONICAL_TIMESTAMP_RE, OUTBOUND_DEDUPE_WINDOW_MS, OUTBOUND_DEDUPE_MAX_SUPPRESS_MS, OUTBOUND_DEDUPE_MAX, OUTBOUND_DEDUPE_TYPES, RETRY_CANDIDATE_TTL_MS, RETRY_CANDIDATE_MAX, TOPIC_ID_RE, ROOM_FULFIL_COOLDOWN_MS, SecureChannel, init_channel, init_types, DEFAULT_API_URL, DEFAULT_HTTP_PORT, init_account_config, init_lifecycle, _ocRuntime, _channels, agentVaultPlugin, init_openclaw_plugin, init_gateway_send, init_llm_response_parser, OPENROUTER_PRICING, init_llm_pricing_openrouter, LEGACY_PRICING, PRICING, init_llm_cost, traceStore, init_fetch_interceptor, init_tool_audit, init_harness_compat, managedRoutesRequested, init_openclaw_entry, util, objectUtil, ZodParsedType, getParsedType, init_util, ZodIssueCode, ZodError, init_ZodError, errorMap, en_default, init_en, overrideErrorMap, init_errors2, makeIssue, ParseStatus, INVALID, DIRTY, OK, isAborted, isDirty, isValid, isAsync, init_parseUtil, init_typeAliases, errorUtil, init_errorUtil, ParseInputLazyPath, handleResult, ZodType, cuidRegex, cuid2Regex, ulidRegex, uuidRegex, nanoidRegex, jwtRegex, durationRegex, emailRegex, _emojiRegex, emojiRegex, ipv4Regex, ipv4CidrRegex, ipv6Regex, ipv6CidrRegex, base64Regex, base64urlRegex, dateRegexSource, dateRegex, ZodString, ZodNumber, ZodBigInt, ZodBoolean, ZodDate, ZodSymbol, ZodUndefined, ZodNull, ZodAny, ZodUnknown, ZodNever, ZodVoid, ZodArray, ZodObject, ZodUnion, getDiscriminator, ZodDiscriminatedUnion, ZodIntersection, ZodTuple, ZodRecord, ZodMap, ZodSet, ZodFunction, ZodLazy, ZodLiteral, ZodEnum, ZodNativeEnum, ZodPromise, ZodEffects, ZodOptional, ZodNullable, ZodDefault, ZodCatch, ZodNaN, ZodBranded, ZodPipeline, ZodReadonly, late, ZodFirstPartyTypeKind, stringType, numberType, nanType, bigIntType, booleanType, dateType, symbolType, undefinedType, nullType, anyType, unknownType, neverType, voidType, arrayType, objectType, strictObjectType, unionType, discriminatedUnionType, intersectionType, tupleType, recordType, mapType, setType, functionType, lazyType, literalType, enumType, nativeEnumType, promiseType, effectsType, optionalType, nullableType, preprocessType, pipelineType, init_types2, init_external, init_v3, util_exports, Cached, EVALUATING, captureStackTrace, allowsEval, getParsedType2, propertyKeyTypes, primitiveTypes, NUMBER_FORMAT_RANGES, BIGINT_FORMAT_RANGES, highSurrogate, Class, installing, broke, breaker, CONSTANT_CATCH, init_util2, _a2, _zodDesc, _E, $ZodAsyncError, $ZodEncodeError, globalConfig, init_core, _messageDesc, _issuesDesc, _installedToString, initializer, $ZodError, $ZodRealError, init_errors3, _parse, parse, _parseAsync, parseAsync, _safeParse, safeParse, _safeParseAsync, safeParseAsync, COMPILE_INVALID, COMPILE_FALLBACK, validate, validateAsync, _encode, _decode, _encodeAsync, _decodeAsync, _safeEncode, _safeDecode, _safeEncodeAsync, _safeDecodeAsync, init_parse, cuid, cuid2, ulid, xid, ksuid, nanoid, duration, guid, uuid, email, _emoji, ipv4, ipv6, cidrv4, cidrv6, base64, base64url, httpProtocol, e164, dateSource, date, anyString, integer, number, boolean, _null, lowercase, uppercase, init_regexes, $ZodCheck, _whenHasLength, numericOriginMap, $ZodCheckLessThan, $ZodCheckGreaterThan, $ZodCheckMultipleOf, $ZodCheckNumberFormat, $ZodCheckMaxLength, $ZodCheckMinLength, $ZodCheckLengthEquals, $ZodCheckStringFormat, $ZodCheckRegex, $ZodCheckLowerCase, $ZodCheckUpperCase, $ZodCheckIncludes, $ZodCheckStartsWith, $ZodCheckEndsWith, $ZodCheckOverwrite, init_checks, Doc, init_doc, version, init_versions, $ZodType, toStandardResult, $ZodString, $ZodStringFormat, $ZodGUID, $ZodUUID, $ZodEmail, URL_BAD_FORMAT, URL_UNPARSEABLE, asciiTabOrNewline, $ZodURL, $ZodEmoji, $ZodNanoID, $ZodCUID, $ZodCUID2, $ZodULID, $ZodXID, $ZodKSUID, $ZodISODateTime, $ZodISODate, $ZodISOTime, $ZodISODuration, $ZodIPv4, ipv6Alphabet, $ZodIPv6, $ZodCIDRv4, $ZodCIDRv6, base64Charset, $ZodBase64, base64urlCharset, $ZodBase64URL, $ZodE164, $ZodJWT, $ZodNumber, $ZodNumberFormat, $ZodBoolean, $ZodNull, $ZodUnknown, $ZodNever, arraySize, $ZodArray, NO_SYMBOL_KEYS, $ZodObject, $ZodObjectJIT, $ZodUnion, $ZodDiscriminatedUnion, $ZodIntersection, $ZodRecord, $ZodEnum, $ZodLiteral, $ZodTransform, $ZodOptional, $ZodExactOptional, $ZodNullable, $ZodDefault, $ZodPrefault, $ZodNonOptional, $ZodCatch, $ZodPipe, $ZodPreprocess, $ZodReadonly, $ZodCustom, init_schemas, $ZodCyclicError, STATE, NO_ISSUES, recursive, NONE, ASSUMED, PROVEN, handoff, open4, memo, init_memoizer, error, init_en2, init_locales, _a3, $ZodRegistry, globalRegistry, init_registries, init_compile, init_api, FOLDABLE_KEYS, UNION_KEYS, createToJSONSchemaMethod, createStandardJSONSchemaMethod, init_to_json_schema, narrowMin, narrowMax, narrowBoth, addDivisor, addPattern, intersectMime, setFormat, minContributor, maxContributor, formatContributor, contributors, formatMap, exactPatterns, exactPattern, stringProcessor, numberProcessor, booleanProcessor, bigintProcessor, symbolProcessor, nullProcessor, undefinedProcessor, voidProcessor, neverProcessor, anyProcessor, unknownProcessor, dateProcessor, enumProcessor, literalProcessor, nanProcessor, templateLiteralProcessor, fileProcessor, successProcessor, customProcessor, functionProcessor, transformProcessor, mapProcessor, setProcessor, arrayProcessor, objectProcessor, unionProcessor, intersectionProcessor, tupleProcessor, pendingRecords, recordProcessor, nullableProcessor, nonoptionalProcessor, UNREPRESENTABLE_DEFAULT, defaultProcessor, prefaultProcessor, catchProcessor, pipeProcessor, readonlyProcessor, promiseProcessor, optionalProcessor, lazyProcessor, allProcessors, init_json_schema_processors, init_json_schema, init_core2, init_parse2, ZodMiniType, ZodMiniObject, init_schemas2, init_checks2, init_iso, init_coerce, init_external2, init_v4_mini, init_zod_compat, init_checks3, _installedErrorProtos, initializer2, ZodRealError, init_errors4, parse2, parseAsync2, safeParse3, safeParseAsync3, encode3, decode2, encodeAsync2, decodeAsync2, safeEncode2, safeDecode2, safeEncodeAsync2, safeDecodeAsync2, init_parse3, ZodType2, _ZodString, ZodString2, ZodStringFormat, ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration, ZodEmail, ZodGUID, ZodUUID, ZodURL, ZodEmoji, ZodNanoID, ZodCUID, ZodCUID2, ZodULID, ZodXID, ZodKSUID, ZodIPv4, ZodIPv6, ZodCIDRv4, ZodCIDRv6, ZodBase64, ZodBase64URL, ZodE164, ZodJWT, ZodNumber2, ZodNumberFormat, ZodBoolean2, ZodNull2, ZodUnknown2, ZodNever2, ZodArray2, ZodObject2, ZodUnion2, ZodDiscriminatedUnion2, ZodIntersection2, ZodRecord2, ZodEnum2, ZodLiteral2, ZodTransform, ZodOptional2, ZodExactOptional, ZodNullable2, ZodDefault2, ZodPrefault, ZodNonOptional, ZodCatch2, ZodPipe, ZodPreprocess, ZodReadonly2, ZodCustom, init_schemas3, ZodFirstPartyTypeKind2, init_compat, iso_exports2, init_iso2, init_coerce2, init_external3, init_classic, init_v4, LATEST_PROTOCOL_VERSION, DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY, JSONRPC_VERSION, AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams, RequestSchema, NotificationsParamsSchema, NotificationSchema, ResultSchema, RequestIdSchema, JSONRPCRequestSchema, isJSONRPCRequest, JSONRPCNotificationSchema, isJSONRPCNotification, JSONRPCResultResponseSchema, isJSONRPCResultResponse, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse, JSONRPCMessageSchema, JSONRPCResponseSchema, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, isInitializeRequest, ServerCapabilitiesSchema, InitializeResultSchema, InitializedNotificationSchema, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema, TextResourceContentsSchema, Base64Schema, BlobResourceContentsSchema, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema, ImageContentSchema, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError, init_types3, init_interfaces, ignoreOverride, defaultOptions, getDefaultOptions, init_Options, getRefs, init_Refs, init_errorMessages, getRelativePath, init_getRelativePath, init_any, init_array2, init_bigint, init_boolean, init_branded, parseCatchDef, init_catch, integerDateParser, init_date, init_default, init_effects, init_enum, isJsonSchema7AllOfType, init_intersection, init_literal, emojiRegex2, zodPatterns, ALPHA_NUMERIC, init_string2, init_record, init_map, init_nativeEnum, init_never, init_null, primitiveMappings, asAnyOf, init_union, init_nullable, init_number2, init_object, parseOptionalDef, init_optional2, parsePipelineDef, init_pipeline, init_promise, init_set, init_tuple, init_undefined, init_unknown, parseReadonlyDef, init_readonly, selectParser, init_selectParser, get$ref, addMeta, init_parseDef, init_parseTypes, zodToJsonSchema, init_zodToJsonSchema, init_esm, init_zod_json_schema_compat, DEFAULT_REQUEST_TIMEOUT_MSEC, Protocol, init_protocol, require_code, require_scope, require_codegen, require_util, require_names, require_errors, require_boolSchema, require_rules, require_applicability, require_dataType, require_defaults, require_code2, require_keyword, require_subschema, require_fast_deep_equal, require_json_schema_traverse, require_resolve, require_validate, require_validation_error, require_ref_error, require_compile, require_data, require_utils, require_schemes, require_fast_uri, require_uri, require_core, require_id, require_ref, require_core2, require_limitNumber, require_multipleOf, require_ucs2length, require_limitLength, require_pattern, require_limitProperties, require_required, require_limitItems, require_equal, require_uniqueItems, require_const, require_enum, require_validation, require_additionalItems, require_items, require_prefixItems, require_items2020, require_contains, require_dependencies, require_propertyNames, require_additionalProperties, require_properties, require_patternProperties, require_not, require_anyOf, require_oneOf, require_allOf, require_if, require_thenElse, require_applicator, require_format, require_format2, require_metadata, require_draft7, require_types, require_discriminator, require_json_schema_draft_07, require_ajv, require_formats, require_limit, require_dist, import_ajv, import_ajv_formats, AjvJsonSchemaValidator, init_ajv_provider, ExperimentalServerTasks, init_server, init_helpers, Server, init_server2, COMPLETABLE_SYMBOL, McpZodTypeKind, init_completable, init_uriTemplate, TOOL_NAME_REGEX, init_toolNameValidation, ExperimentalMcpServerTasks, init_mcp_server, init_zod, McpServer, EMPTY_OBJECT_JSON_SCHEMA, EMPTY_COMPLETION_RESULT, init_mcp, RequestError, toRequestError, GlobalRequest, Request2, newHeadersFromIncoming, wrapBodyStream, newRequestFromIncoming, getRequestCache, requestCache, incomingKey, urlKey, headersKey, abortControllerKey, getAbortController, requestPrototype, newRequest, responseCache, getResponseCache, cacheKey, GlobalResponse, Response2, buildOutgoingHttpHeaders, X_ALREADY_SENT, outgoingEnded, handleRequestError, handleFetchError, handleResponseError, flushHeaders, responseViaCache, isPromise, responseViaResponseObject, getRequestListener, init_dist22, require_content_type, import_content_type, init_mediaType, DEFAULT_MAX_REQUEST_BODY_SIZE, MAX_BATCH_SIZE, init_requestBody, DEFAULT_SSE_KEEP_ALIVE_MS, MAX_TIMER_DELAY_MS, init_sseKeepAlive, WebStandardStreamableHTTPServerTransport, init_webStandardStreamableHttp, StreamableHTTPServerTransport, init_streamableHttp, AgentVaultMcpServer, init_mcp_server2, init_mcp_handlers, init_skill_manifest, init_skill_invoker, spanBuffer, init_skill_telemetry, PolicyEnforcer, init_policy_enforcer, VERSION, init_index;
17684
+ var __create, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf, __hasOwnProp, __esm2, __commonJS, __export2, __copyProps, __toESM, SENTINEL, WRAPPERS, INSTRUCTION, init_abstention, AMBIGUOUS_OWNER_ERROR, init_owner_routing, init_envelope_text, init_mls_commit_classify, MENTION_RE, BROADCAST_NAMES, init_room_protocol, __filename, __dirname, url, path, Module, Module, root, window_, crypto_, randomValuesStandard, crypto2, randomValueNodeJS, _Module, libsodium_sumo_default, init_libsodium_sumo, a, r, t, c, libsodium_wrappers_default, init_libsodium_wrappers, init_keys, init_x3dh, MAX_SKIP, CHAIN_KEY_SEED, MSG_KEY_SEED, HEADER_KEY_SEED, DoubleRatchet, init_ratchet, init_file_crypto, DOMAIN_DID_DOCUMENT, DOMAIN_TRANSFER_INTENT, DOMAIN_TRANSFER_ACCEPT, BASE58_ALPHABET, init_did, BUILTIN_PATTERNS, ScanEngine, init_scan_engine, init_merkle, VC_CONTEXT_V2, AV_CREDENTIAL_CONTEXT, CRYPTOSUITE, BASE58_ALPHABET2, init_vc, init_transport, init_telemetry, TelemetryReporter, init_telemetry_reporter, CROCKFORD, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, BACKUP_VERSION, MAX_BACKUP_SIZE, init_backup, atitle, aobject, aopts, isLE, swap8IfBE, swap32IfBE, hasHexBuiltin, hexes, oidNist, init_utils, BSIGMA, init_blake, U32_MASK64, _32n, fromNumH, fromNumL, shrSH, shrSL, rotrSH, rotrSL, rotrBH, rotrBL, rotr32H, rotr32L, add3L, add3H, add4L, add4H, add5L, add5H, init_u64, HashMD, SHA256_IV, SHA384_IV, SHA512_IV, init_md, B2B_IV, BBUF, _BLAKE2, _BLAKE2b, blake2b, init_blake2, CROCKFORD2, SALT_BYTES2, NONCE_BYTES2, KEY_BYTES2, TAG_BYTES, ENVELOPE_OVERHEAD, AAD_PREFIX, UUID_RE, UUID_V4_RE, DIGEST_ID_RE, TIMESTAMP_RE, encoder, decoder, HISTORY_MAGIC, HISTORY_ARCHIVE_VERSION, HISTORY_MAX_ENTRIES, HISTORY_MAX_BLOB_BYTES, HISTORY_KDF_OPSLIMIT, HISTORY_KDF_MEMLIMIT, HistoryEntryTooLargeError, init_history_backup, init_approval, encVoid, init_tlsEncoder, uint8Encoder, encodeUint8, decodeUint8, uint16Encoder, encodeUint16, decodeUint16, uint32Encoder, encodeUint32, decodeUint32, uint64Encoder, encodeUint64, decodeUint64, init_number, init_tlsDecoder, init_enumHelpers, defaultProposalTypes, defaultProposalTypeEncoder, encodeDefaultProposalType, decodeDefaultProposalType, init_defaultProposalType, defaultExtensionTypes, defaultExtensionTypeEncoder, encodeDefaultExtensionType, decodeDefaultExtensionType, init_defaultExtensionType, acceptAll, init_incomingMessageAction, MlsError, ValidationError, CodecError, UsageError, DependencyError, CryptoVerificationError, CryptoError, InternalError, init_mlsError, init_byteArray, varLenDataEncoder, decodeVarLenData, init_variableLength, init_constantTimeCompare, extensionTypeEncoder, encodeExtensionType, decodeExtensionType, extensionEncoder, encodeExtension, decodeExtension, init_extension, credentialTypes, credentialTypeEncoder, encodeCredentialType, decodeCredentialType, init_credentialType, credentialBasicEncoder, encodeCredentialBasic, credentialX509Encoder, encodeCredentialX509, credentialCustomEncoder, encodeCredentialCustom, credentialEncoder, encodeCredential, decodeCredentialBasic, decodeCredentialX509, decodeCredential, init_credential, externalSenderEncoder, encodeExternalSender, decodeExternalSender, init_externalSender, init_hash, init_optional, ciphersuites, ciphersuiteEncoder, encodeCiphersuite, decodeCiphersuite, ciphersuiteValues, init_ciphersuite, init_signature, protocolVersions, protocolVersionEncoder, encodeProtocolVersion, decodeProtocolVersion, init_protocolVersion, capabilitiesEncoder, encodeCapabilities, decodeCapabilities, init_capabilities, leafNodeSources, leafNodeSourceEncoder, encodeLeafNodeSource, decodeLeafNodeSource, init_leafNodeSource, lifetimeEncoder, encodeLifetime, decodeLifetime, defaultLifetime, init_lifetime, leafNodeDataEncoder, encodeLeafNodeData, decodeLeafNodeData, leafNodeInfoKeyPackageEncoder, encodeLeafNodeInfoKeyPackage, leafNodeInfoUpdateOmittedEncoder, encodeLeafNodeInfoUpdateOmitted, leafNodeInfoCommitOmittedEncoder, encodeLeafNodeInfoCommitOmitted, leafNodeInfoOmittedEncoder, encodeLeafNodeInfoOmitted, decodeLeafNodeInfoKeyPackage, decodeLeafNodeInfoUpdateOmitted, decodeLeafNodeInfoCommitOmitted, decodeLeafNodeInfoOmitted, leafNodeInfoUpdateEncoder, encodeLeafNodeInfoUpdate, leafNodeInfoCommitEncoder, encodeLeafNodeInfoCommit, leafNodeInfoEncoder, encodeLeafNodeInfo, decodeLeafNodeInfoUpdate, decodeLeafNodeInfoCommit, decodeLeafNodeInfo, leafNodeTBSEncoder, encodeLeafNodeTBS, leafNodeEncoder, encodeLeafNode, decodeLeafNode, decodeLeafNodeKeyPackage, decodeLeafNodeCommit, decodeLeafNodeUpdate, init_leafNode, keyPackageTBSEncoder, encodeKeyPackageTBS, decodeKeyPackageTBS, keyPackageEncoder, encodeKeyPackage, decodeKeyPackage, init_keyPackage, init_kdf, pskTypes, pskTypeEncoder, encodePskType, decodePskType, resumptionPSKUsages, resumptionPSKUsageEncoder, encodeResumptionPSKUsage, decodeResumptionPSKUsage, encodePskInfoExternal, encodePskInfoResumption, decodePskInfoResumption, pskInfoEncoder, encodePskInfo, decodePskInfo, pskIdEncoder, encodePskId, decodePskId, pskLabelEncoder, encodePskLabel, decodePskLabel, init_presharedkey, addEncoder, encodeAdd, decodeAdd, updateEncoder, encodeUpdate, decodeUpdate, removeEncoder, encodeRemove, decodeRemove, pskEncoder, encodePSK, decodePSK, reinitEncoder, encodeReinit, decodeReinit, externalInitEncoder, encodeExternalInit, decodeExternalInit, groupContextExtensionsEncoder, encodeGroupContextExtensions, decodeGroupContextExtensions, proposalAddEncoder, encodeProposalAdd, proposalUpdateEncoder, encodeProposalUpdate, proposalRemoveEncoder, encodeProposalRemove, proposalPSKEncoder, encodeProposalPSK, proposalReinitEncoder, encodeProposalReinit, proposalExternalInitEncoder, encodeProposalExternalInit, proposalGroupContextExtensionsEncoder, encodeProposalGroupContextExtensions, proposalCustomEncoder, encodeProposalCustom, proposalEncoder, encodeProposal, decodeProposalAdd, decodeProposalUpdate, decodeProposalRemove, decodeProposalPSK, decodeProposalReinit, decodeProposalExternalInit, decodeProposalGroupContextExtensions, decodeProposal, init_proposal, proposalOrRefTypes, proposalOrRefTypeEncoder, encodeProposalOrRefType, decodeProposalOrRefType, proposalOrRefProposalEncoder, encodeProposalOrRefProposal, proposalOrRefProposalRefEncoder, encodeProposalOrRefProposalRef, proposalOrRefEncoder, encodeProposalOrRef, decodeProposalOrRef, init_proposalOrRefType, init_hpke, groupContextEncoder, encodeGroupContext, decodeGroupContext, init_groupContext, nodeTypes, nodeTypeEncoder, encodeNodeType, decodeNodeType, init_nodeType, parentNodeEncoder, encodeParentNode, decodeParentNode, init_parentNode, init_treemath, nodeEncoder, encodeNode, decodeNode, ratchetTreeEncoder, encodeRatchetTree, decodeRatchetTree, init_ratchetTree, leafNodeHashInputEncoder, encodeLeafNodeHashInput, decodeLeafNodeHashInput, parentNodeHashInputEncoder, encodeParentNodeHashInput, decodeParentNodeHashInput, treeHashInputEncoder, encodeTreeHashInput, decodeTreeHashInput, init_treeHash, parentHashInputEncoder, encodeParentHashInput, decodeParentHashInput, init_parentHash, hpkeCiphertextEncoder, encodeHpkeCiphertext, decodeHpkeCiphertext, init_hpkeCiphertext, updatePathNodeEncoder, encodeUpdatePathNode, decodeUpdatePathNode, updatePathEncoder, encodeUpdatePath, decodeUpdatePath, init_updatePath, commitEncoder, encodeCommit, decodeCommit, init_commit, contentTypes, contentTypeEncoder, encodeContentType, decodeContentType, init_contentType, wireformats, wireformatEncoder, encodeWireformat, decodeWireformat, init_wireformat, senderTypes, senderTypeEncoder, encodeSenderType, decodeSenderType, senderEncoder, encodeSender, decodeSender, reuseGuardEncoder, encodeReuseGuard, decodeReuseGuard, senderDataEncoder, encodeSenderData, decodeSenderData, senderDataAADEncoder, encodeSenderDataAAD, decodeSenderDataAAD, init_sender, framedContentApplicationDataEncoder, encodeFramedContentApplicationData, framedContentProposalDataEncoder, encodeFramedContentProposalData, framedContentCommitDataEncoder, encodeFramedContentCommitData, framedContentInfoEncoder, encodeFramedContentInfo, decodeFramedContentApplicationData, decodeFramedContentProposalData, decodeFramedContentCommitData, decodeFramedContentInfo, framedContentEncoder, encodeFramedContent, decodeFramedContent, senderInfoEncoder, encodeSenderInfo, framedContentTBSEncoder, encodeFramedContentTBS, encodeFramedContentAuthDataContent, encodeFramedContentAuthDataCommit, framedContentAuthDataEncoder, encodeFramedContentAuthData, decodeFramedContentAuthDataCommit, init_framedContent, authenticatedContentEncoder, encodeAuthenticatedContent, decodeAuthenticatedContent, authenticatedContentTBMEncoder, encodeAuthenticatedContentTBM, init_authenticatedContent, publicMessageInfoEncoder, encodePublicMessageInfo, publicMessageEncoder, encodePublicMessage, decodePublicMessage, init_publicMessage, init_messageProtectionPublic, init_externalProposal, requiredCapabilitiesEncoder, encodeRequiredCapabilities, decodeRequiredCapabilities, init_requiredCapabilities, defaultAuthenticationService, init_authenticationService, defaultPaddingConfig, init_paddingConfig, defaultKeyPackageEqualityConfig, init_keyPackageEqualityConfig, defaultLifetimeConfig, init_lifetimeConfig, defaultKeyRetentionConfig, init_keyRetentionConfig, groupInfoTBSEncoder, encodeGroupInfoTBS, decodeGroupInfoTBS, groupInfoEncoder, encodeGroupInfo, decodeGroupInfo, init_groupInfo, keyScheduleEncoder, encodeKeySchedule, decodeKeySchedule, init_keySchedule, generationSecretEncoder, decodeGenerationSecret, secretTreeNodeEncoder, decodeSecretTreeNode, secretTreeEncoder, decodeSecretTree, init_secretTree, confirmedTranscriptHashInputEncoder, encodeConfirmedTranscriptHashInput, decodeConfirmedTranscriptHashInput, init_transcriptHash, groupSecretsEncoder, encodeGroupSecrets, decodeGroupSecrets, init_groupSecrets, encryptedGroupSecretsEncoder, encodeEncryptedGroupSecrets, decodeEncryptedGroupSecrets, welcomeEncoder, encodeWelcome, decodeWelcome, init_welcome, init_pathSecrets, privateKeyPathEncoder, decodePrivateKeyPath, init_privateKeyPath, proposalWithSenderEncoder, decodeProposalWithSender, unappliedProposalsEncoder, decodeUnappliedProposals, init_unappliedProposals, emptyPskIndex, init_pskIndex, init_addToMap, defaultClientConfig, init_clientConfig, init_array, stringEncoder, encodeString, decodeString, init_string, activeEncoder, suspendedPendingReinitEncoder, removedFromGroupEncoder, groupActiveStateEncoder, decodeGroupActiveState, init_groupActiveState, epochReceiverDataEncoder, decodeEpochReceiverData, init_epochReceiverData, groupStateEncoder, encodeGroupState, decodeGroupState, groupStateEncoderWithoutTree, encodeGroupStateWithoutTree, emptyProposals, init_clientState, privateMessageEncoder, encodePrivateMessage, decodePrivateMessage, privateContentAADEncoder, encodePrivateContentAAD, decodePrivateContentAAD, init_privateMessage, init_messageProtection, init_createMessage, init_createCommit, init_processMessages, init_makeHashImpl, HpkeError, InvalidParamError, SerializeError, DeserializeError, EncapError, DecapError, ExportError, SealError, OpenError, MessageLimitReachedError, DeriveKeyPairError, NotSupportedError, init_errors, dntGlobals, dntGlobalThis, init_dnt_shims, NativeAlgorithm, init_algorithm, Mode, KemId, KdfId, AeadId, init_identifiers, INPUT_LENGTH_LIMIT, INFO_LENGTH_LIMIT, MINIMUM_PSK_LENGTH, EMPTY, BYTE_TO_BIGINT_256, init_consts, SUITE_ID_HEADER_KEM, init_kemInterface, HPKE_VERSION, HkdfNative, HkdfSha256Native, HkdfSha384Native, HkdfSha512Native, init_hkdf, isCryptoKeyPair, init_misc, LABEL_EAE_PRK, LABEL_SHARED_SECRET, Dhkem, init_dhkem, KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, init_dhkemPrimitives, Bignum, init_bignum, LABEL_CANDIDATE, ORDER_P_256, ORDER_P_384, ORDER_P_521, PKCS8_ALG_ID_P_256, PKCS8_ALG_ID_P_384, PKCS8_ALG_ID_P_521, EC_P_256_PARAMS, EC_P_384_PARAMS, EC_P_521_PARAMS, Ec, init_ec, init_xCryptoKey, init_xCurve, init_hybridkem, AEAD_USAGES, init_aeadEncryptionContext, _endianTestBuffer, _endianTestBytes, isLE2, init_noble, init_hash2, _HMAC, hmac, init_hmac, init_md2, U32_MASK642, _32n2, init_u642, init_sha2, _0n, _1n, _2n, _7n, _256n, _0x71n, SHA3_PI, SHA3_ROTL, _SHA3_IOTA, IOTAS, SHA3_IOTA_H, SHA3_IOTA_L, init_sha3, init_modular, init_curve, init_montgomery, init_mod, AesGcmContext, Aes128Gcm, Aes256Gcm, init_aesGcm, init_exportOnly, init_emitNotSupported, LABEL_SEC, ExporterContextImpl, RecipientExporterContextImpl, SenderExporterContextImpl, init_exporterContext, EncryptionContextImpl, init_encryptionContext, __classPrivateFieldGet, __classPrivateFieldSet, _Mutex_locked, Mutex, init_mutex, __classPrivateFieldGet2, __classPrivateFieldSet2, _RecipientContextImpl_mutex, RecipientContextImpl, init_recipientContext, __classPrivateFieldGet3, __classPrivateFieldSet3, _SenderContextImpl_mutex, SenderContextImpl, init_senderContext, LABEL_BASE_NONCE, LABEL_EXP, LABEL_INFO_HASH, LABEL_KEY, LABEL_PSK_ID_HASH, LABEL_SECRET, SUITE_ID_HEADER_HPKE, CipherSuiteNative, init_cipherSuiteNative, DhkemP256HkdfSha256Native, DhkemP384HkdfSha384Native, DhkemP521HkdfSha512Native, init_dhkemNative, CipherSuite, DhkemP256HkdfSha256, DhkemP384HkdfSha384, DhkemP521HkdfSha512, HkdfSha256, HkdfSha384, HkdfSha512, init_native, ALG_NAME, PKCS8_ALG_ID_X25519, BASE_POINT_X25519, X25519, init_x25519, DhkemX25519HkdfSha256, init_dhkemX25519, PKCS8_ALG_ID_X448, init_x448, init_dhkemX448, init_mod2, init_hpke2, isLE3, wrapCipher, init_utils2, encodeStr, sigma16, sigma32, sigma16_32, sigma32_32, BLOCK_LEN, BLOCK_LEN32, MAX_COUNTER, U32_EMPTY, _XorStreamPRG, createPRG, init_arx, Poly1305, poly1305, init_poly1305, chacha_exports, chacha20orig, chacha20, xchacha20, chacha8, chacha12, ZEROS16, updatePadded, ZEROS32, _poly1305_aead, chacha20poly1305, xchacha20poly1305, rngChacha20, rngChacha8, init_chacha, init_makeAead, init_makeKdfImpl, init_makeDhKem, init_makeHpke, defaultRng, init_rng, crypto3, init_cryptoNode, isLE4, swap32IfBE3, hasHexBuiltin2, hexes2, asciis, Hash, init_utils3, HashMD3, SHA256_IV3, SHA384_IV3, SHA512_IV3, init_md3, U32_MASK643, _32n3, shrSH3, shrSL3, rotrSH3, rotrSL3, rotrBH3, rotrBL3, rotlSH2, rotlSL2, rotlBH2, rotlBL2, add3L3, add3H3, add4L3, add4H3, add5L3, add5H3, init_u643, SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384, sha2563, sha5122, sha3842, init_sha22, _0n2, _1n2, isPosBig, bitMask, notImplemented, init_utils4, _0n3, _1n3, _2n2, _3n, _4n, _5n, _7n2, _8n, _9n, _16n, isNegativeLE, FIELD_FIELDS, init_modular2, _0n4, _1n4, pointPrecomputes, pointWindowSizes, wNAF, init_curve2, _0n5, _1n5, _2n3, _8n2, PrimeEdwardsPoint, init_edwards, os2ip, _DST_scalar, init_hash_to_curve, _0n6, _1n6, _2n4, init_montgomery2, ed25519_exports, _0n7, _1n7, _2n5, _3n2, _5n2, _8n3, ed25519_CURVE_p, ed25519_CURVE, ED25519_SQRT_M1, Fp, Fn, ed25519Defaults, ed25519, ed25519ctx, ed25519ph, x25519, ELL2_C1, ELL2_C2, ELL2_C3, ELL2_C1_EDWARDS, ed25519_hasher, SQRT_M1, SQRT_AD_MINUS_ONE, INVSQRT_A_MINUS_D, ONE_MINUS_D_SQ, D_MINUS_ONE_SQ, invertSqrt, MAX_255B, bytes255ToNumberLE, _RistrettoPoint, ristretto255, ristretto255_hasher, ED25519_TORSION_SUBGROUP, edwardsToMontgomery, RistrettoPoint, hashToCurve, encodeToCurve, hashToRistretto255, hash_to_ristretto255, init_ed25519, _0n8, _1n8, _2n6, _7n3, _256n2, _0x71n2, SHA3_PI2, SHA3_ROTL2, _SHA3_IOTA2, IOTAS2, SHA3_IOTA_H2, SHA3_IOTA_L2, rotlH, rotlL, Keccak, genShake, shake2562, init_sha32, ed448_exports, ed448_CURVE, E448_CURVE, shake256_114, shake256_64, _1n9, _2n7, _3n3, _4n2, _11n, _22n, _44n, _88n, _223n, Fp2, Fn2, Fp448, Fn448, ED448_DEF, ed448, ed448ph, E448, x448, ELL2_C12, ELL2_J, ed448_hasher, ONE_MINUS_D, ONE_MINUS_TWO_D, SQRT_MINUS_D, INVSQRT_MINUS_D, invertSqrt2, _DecafPoint, decaf448, decaf448_hasher, ED448_TORSION_SUBGROUP, DecafPoint, hashToCurve2, encodeToCurve2, hashToDecaf448, hash_to_decaf448, edwardsToMontgomery2, init_ed448, HMAC, hmac2, init_hmac2, divNearest, DERErr, DER, _0n9, _1n10, _2n8, _3n4, _4n3, init_weierstrass, init_shortw_utils, nist_exports, p256_CURVE, p384_CURVE, p521_CURVE, Fp256, Fp384, Fp521, p256, p256_hasher, p384, p384_hasher, p521, secp256r1, secp384r1, secp521r1, p521_hasher, init_nist, init_makeNobleSignatureImpl, defaultCryptoProvider, init_provider, init_getCiphersuiteImpl, init_resumption, SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384, sha2564, sha5123, sha3843, init_sha23, _HMAC2, hmac3, init_hmac3, init_makeHashImpl2, init_makeNobleSignatureImpl2, BLOCK_SIZE, ZEROS162, ZEROS322, POLY, mul2, swapLE, estimateWindow, GHASH, Polyval, ghash, polyval, init_polyval, BLOCK_SIZE2, BLOCK_SIZE32, EMPTY_BLOCK, POLY2, sbox, rotr32_8, rotl32_8, tableEncoding, xPowers, gcm, _CMAC, cmac, init_aes, init_makeAead2, init_makeKdfImpl2, init_makeDhKem2, init_makeHpke2, init_rng2, nobleCryptoProvider, init_provider2, mlsPublicMessageEncoder, encodeMlsPublicMessage, mlsWelcomeEncoder, encodeMlsWelcome, mlsPrivateMessageEncoder, encodeMlsPrivateMessage, mlsGroupInfoEncoder, encodeMlsGroupInfo, mlsKeyPackageEncoder, encodeMlsKeyPackage, mlsMessageContentEncoder, encodeMlsMessageContent, decodeMlsMessageContent, mlsMessageEncoder, encodeMlsMessage, decodeMlsMessage, init_message, greaseValues, defaultGreaseConfig, init_grease, init_defaultCapabilities, init_src, DEFAULT_CIPHERSUITE, MLSGroupManager, init_mls_group, DOMAIN, NONCE_BYTES3, init_owner_sync, init_mls_delivery_order, init_mls_presend_epoch, dist_exports, init_dist2, DIR_MODE, FILE_MODE, init_secure_file, SYNC_LOCK_STALE_MS, pendingKpPath, init_mls_state, init_mls_kp_pool, PACKAGE, FALLBACK, MAX_LEN, DISALLOWED, init_client_version, CredentialStore, init_credential_store, init_crypto_helpers, STATE_FILE, LEGACY_STATE_FILE, init_state, ACTIVATION_DOMAIN, UUID_RE2, init_transport2, A2ALogGate, init_a2a_log_gate, init_mls_membership_probe, FIRST_DIRTY_DELAY_MS, RETRY_BASE_DELAYS_MS, MAX_RETRY_DELAY_MS, JITTER_FRACTION, HistoryBackupScheduler, init_history_backup_scheduler, FILE_MODE2, init_history_recovery_file, TENANT_ID_PATTERN, DIR_MODE2, FILE_MODE3, HISTORY_RECOVERY_VERIFY_TIMEOUT_MS, VERIFY_TIMEOUT_MESSAGE, HistoryRecoveryVerificationTimeoutError, init_history_recovery_code, ACTIONS, init_decision_reply, KP_BACKOFF_INITIAL_MS, KP_BACKOFF_MAX_MS, KP_RACE_RETRY_MS, KP_RACE_RETRY_LIMIT, consoleLogger, short, WelcomeKeyPackageBackoff, init_welcome_kp_backoff, history_backup_client_exports, HISTORY_RESTORE_TIMEOUT_MS, HISTORY_RESTORE_RESPONSE_MAX_BYTES, HISTORY_ENVELOPE_MIN_BYTES, HISTORY_AAD_PREFIX, UUID_RE3, GENERATION_RESPONSE_KEYS, utf8Encoder, utf8Decoder, HistoryBackupClient, init_history_backup_client, openclaw_compat_exports, defaultImporter, HEARTBEAT_CANDIDATES, AGENT_EVENT_CANDIDATES, TRANSCRIPT_CANDIDATES, _heartbeatFn, _agentEventFn, _transcriptFn, init_openclaw_compat, http_handlers_exports, init_http_handlers, mcp_proxy_helpers_exports, init_mcp_proxy_helpers, workspace_handlers_exports, MAX_FILE_SIZE, init_workspace_handlers, ROOM_AGENT_TYPES, CREDENTIAL_MESSAGE_TYPES, CATCHUP_MESSAGE_TYPES, POLL_INTERVAL_MS, RECONNECT_BASE_MS, UUID_RE4, RECONNECT_MAX_MS, PENDING_POLL_INTERVAL_MS, HISTORY_RESTORE_TIMEOUT_MS2, HISTORY_UPLOAD_TIMEOUT_MS, CANONICAL_TIMESTAMP_RE, OUTBOUND_DEDUPE_WINDOW_MS, OUTBOUND_DEDUPE_MAX_SUPPRESS_MS, OUTBOUND_DEDUPE_MAX, OUTBOUND_DEDUPE_TYPES, RETRY_CANDIDATE_TTL_MS, RETRY_CANDIDATE_MAX, _turnConversation, PERSON_INVOLVED_WINDOW_MS, ATTESTED_INBOUND_MAX, UNMAPPED_RECONCILE_COOLDOWN_MS, TOPIC_ID_RE, ROOM_FULFIL_COOLDOWN_MS, SecureChannel, init_channel, init_types, DEFAULT_API_URL, DEFAULT_HTTP_PORT, init_account_config, init_lifecycle, _ocRuntime, _channels, agentVaultPlugin, init_openclaw_plugin, init_gateway_send, init_llm_response_parser, OPENROUTER_PRICING, init_llm_pricing_openrouter, LEGACY_PRICING, PRICING, init_llm_cost, traceStore, init_fetch_interceptor, init_tool_audit, init_harness_compat, managedRoutesRequested, init_openclaw_entry, util, objectUtil, ZodParsedType, getParsedType, init_util, ZodIssueCode, ZodError, init_ZodError, errorMap, en_default, init_en, overrideErrorMap, init_errors2, makeIssue, ParseStatus, INVALID, DIRTY, OK, isAborted, isDirty, isValid, isAsync, init_parseUtil, init_typeAliases, errorUtil, init_errorUtil, ParseInputLazyPath, handleResult, ZodType, cuidRegex, cuid2Regex, ulidRegex, uuidRegex, nanoidRegex, jwtRegex, durationRegex, emailRegex, _emojiRegex, emojiRegex, ipv4Regex, ipv4CidrRegex, ipv6Regex, ipv6CidrRegex, base64Regex, base64urlRegex, dateRegexSource, dateRegex, ZodString, ZodNumber, ZodBigInt, ZodBoolean, ZodDate, ZodSymbol, ZodUndefined, ZodNull, ZodAny, ZodUnknown, ZodNever, ZodVoid, ZodArray, ZodObject, ZodUnion, getDiscriminator, ZodDiscriminatedUnion, ZodIntersection, ZodTuple, ZodRecord, ZodMap, ZodSet, ZodFunction, ZodLazy, ZodLiteral, ZodEnum, ZodNativeEnum, ZodPromise, ZodEffects, ZodOptional, ZodNullable, ZodDefault, ZodCatch, ZodNaN, ZodBranded, ZodPipeline, ZodReadonly, late, ZodFirstPartyTypeKind, stringType, numberType, nanType, bigIntType, booleanType, dateType, symbolType, undefinedType, nullType, anyType, unknownType, neverType, voidType, arrayType, objectType, strictObjectType, unionType, discriminatedUnionType, intersectionType, tupleType, recordType, mapType, setType, functionType, lazyType, literalType, enumType, nativeEnumType, promiseType, effectsType, optionalType, nullableType, preprocessType, pipelineType, init_types2, init_external, init_v3, util_exports, Cached, EVALUATING, captureStackTrace, allowsEval, getParsedType2, propertyKeyTypes, primitiveTypes, NUMBER_FORMAT_RANGES, BIGINT_FORMAT_RANGES, highSurrogate, Class, installing, broke, breaker, CONSTANT_CATCH, init_util2, _a2, _zodDesc, _E, $ZodAsyncError, $ZodEncodeError, globalConfig, init_core, _messageDesc, _issuesDesc, _installedToString, initializer, $ZodError, $ZodRealError, init_errors3, _parse, parse, _parseAsync, parseAsync, _safeParse, safeParse, _safeParseAsync, safeParseAsync, COMPILE_INVALID, COMPILE_FALLBACK, validate, validateAsync, _encode, _decode, _encodeAsync, _decodeAsync, _safeEncode, _safeDecode, _safeEncodeAsync, _safeDecodeAsync, init_parse, cuid, cuid2, ulid, xid, ksuid, nanoid, duration, guid, uuid, email, _emoji, ipv4, ipv6, cidrv4, cidrv6, base64, base64url, httpProtocol, e164, dateSource, date, anyString, integer, number, boolean, _null, lowercase, uppercase, init_regexes, $ZodCheck, _whenHasLength, numericOriginMap, $ZodCheckLessThan, $ZodCheckGreaterThan, $ZodCheckMultipleOf, $ZodCheckNumberFormat, $ZodCheckMaxLength, $ZodCheckMinLength, $ZodCheckLengthEquals, $ZodCheckStringFormat, $ZodCheckRegex, $ZodCheckLowerCase, $ZodCheckUpperCase, $ZodCheckIncludes, $ZodCheckStartsWith, $ZodCheckEndsWith, $ZodCheckOverwrite, init_checks, Doc, init_doc, version, init_versions, $ZodType, toStandardResult, $ZodString, $ZodStringFormat, $ZodGUID, $ZodUUID, $ZodEmail, URL_BAD_FORMAT, URL_UNPARSEABLE, asciiTabOrNewline, $ZodURL, $ZodEmoji, $ZodNanoID, $ZodCUID, $ZodCUID2, $ZodULID, $ZodXID, $ZodKSUID, $ZodISODateTime, $ZodISODate, $ZodISOTime, $ZodISODuration, $ZodIPv4, ipv6Alphabet, $ZodIPv6, $ZodCIDRv4, $ZodCIDRv6, base64Charset, $ZodBase64, base64urlCharset, $ZodBase64URL, $ZodE164, $ZodJWT, $ZodNumber, $ZodNumberFormat, $ZodBoolean, $ZodNull, $ZodUnknown, $ZodNever, arraySize, $ZodArray, NO_SYMBOL_KEYS, $ZodObject, $ZodObjectJIT, $ZodUnion, $ZodDiscriminatedUnion, $ZodIntersection, $ZodRecord, $ZodEnum, $ZodLiteral, $ZodTransform, $ZodOptional, $ZodExactOptional, $ZodNullable, $ZodDefault, $ZodPrefault, $ZodNonOptional, $ZodCatch, $ZodPipe, $ZodPreprocess, $ZodReadonly, $ZodCustom, init_schemas, $ZodCyclicError, STATE, NO_ISSUES, recursive, NONE, ASSUMED, PROVEN, handoff, open4, memo, init_memoizer, error, init_en2, init_locales, _a3, $ZodRegistry, globalRegistry, init_registries, init_compile, init_api, FOLDABLE_KEYS, UNION_KEYS, createToJSONSchemaMethod, createStandardJSONSchemaMethod, init_to_json_schema, narrowMin, narrowMax, narrowBoth, addDivisor, addPattern, intersectMime, setFormat, minContributor, maxContributor, formatContributor, contributors, formatMap, exactPatterns, exactPattern, stringProcessor, numberProcessor, booleanProcessor, bigintProcessor, symbolProcessor, nullProcessor, undefinedProcessor, voidProcessor, neverProcessor, anyProcessor, unknownProcessor, dateProcessor, enumProcessor, literalProcessor, nanProcessor, templateLiteralProcessor, fileProcessor, successProcessor, customProcessor, functionProcessor, transformProcessor, mapProcessor, setProcessor, arrayProcessor, objectProcessor, unionProcessor, intersectionProcessor, tupleProcessor, pendingRecords, recordProcessor, nullableProcessor, nonoptionalProcessor, UNREPRESENTABLE_DEFAULT, defaultProcessor, prefaultProcessor, catchProcessor, pipeProcessor, readonlyProcessor, promiseProcessor, optionalProcessor, lazyProcessor, allProcessors, init_json_schema_processors, init_json_schema, init_core2, init_parse2, ZodMiniType, ZodMiniObject, init_schemas2, init_checks2, init_iso, init_coerce, init_external2, init_v4_mini, init_zod_compat, init_checks3, _installedErrorProtos, initializer2, ZodRealError, init_errors4, parse2, parseAsync2, safeParse3, safeParseAsync3, encode3, decode2, encodeAsync2, decodeAsync2, safeEncode2, safeDecode2, safeEncodeAsync2, safeDecodeAsync2, init_parse3, ZodType2, _ZodString, ZodString2, ZodStringFormat, ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration, ZodEmail, ZodGUID, ZodUUID, ZodURL, ZodEmoji, ZodNanoID, ZodCUID, ZodCUID2, ZodULID, ZodXID, ZodKSUID, ZodIPv4, ZodIPv6, ZodCIDRv4, ZodCIDRv6, ZodBase64, ZodBase64URL, ZodE164, ZodJWT, ZodNumber2, ZodNumberFormat, ZodBoolean2, ZodNull2, ZodUnknown2, ZodNever2, ZodArray2, ZodObject2, ZodUnion2, ZodDiscriminatedUnion2, ZodIntersection2, ZodRecord2, ZodEnum2, ZodLiteral2, ZodTransform, ZodOptional2, ZodExactOptional, ZodNullable2, ZodDefault2, ZodPrefault, ZodNonOptional, ZodCatch2, ZodPipe, ZodPreprocess, ZodReadonly2, ZodCustom, init_schemas3, ZodFirstPartyTypeKind2, init_compat, iso_exports2, init_iso2, init_coerce2, init_external3, init_classic, init_v4, LATEST_PROTOCOL_VERSION, DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY, JSONRPC_VERSION, AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams, RequestSchema, NotificationsParamsSchema, NotificationSchema, ResultSchema, RequestIdSchema, JSONRPCRequestSchema, isJSONRPCRequest, JSONRPCNotificationSchema, isJSONRPCNotification, JSONRPCResultResponseSchema, isJSONRPCResultResponse, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse, JSONRPCMessageSchema, JSONRPCResponseSchema, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, isInitializeRequest, ServerCapabilitiesSchema, InitializeResultSchema, InitializedNotificationSchema, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema, TextResourceContentsSchema, Base64Schema, BlobResourceContentsSchema, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema, ImageContentSchema, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError, init_types3, init_interfaces, ignoreOverride, defaultOptions, getDefaultOptions, init_Options, getRefs, init_Refs, init_errorMessages, getRelativePath, init_getRelativePath, init_any, init_array2, init_bigint, init_boolean, init_branded, parseCatchDef, init_catch, integerDateParser, init_date, init_default, init_effects, init_enum, isJsonSchema7AllOfType, init_intersection, init_literal, emojiRegex2, zodPatterns, ALPHA_NUMERIC, init_string2, init_record, init_map, init_nativeEnum, init_never, init_null, primitiveMappings, asAnyOf, init_union, init_nullable, init_number2, init_object, parseOptionalDef, init_optional2, parsePipelineDef, init_pipeline, init_promise, init_set, init_tuple, init_undefined, init_unknown, parseReadonlyDef, init_readonly, selectParser, init_selectParser, get$ref, addMeta, init_parseDef, init_parseTypes, zodToJsonSchema, init_zodToJsonSchema, init_esm, init_zod_json_schema_compat, DEFAULT_REQUEST_TIMEOUT_MSEC, Protocol, init_protocol, require_code, require_scope, require_codegen, require_util, require_names, require_errors, require_boolSchema, require_rules, require_applicability, require_dataType, require_defaults, require_code2, require_keyword, require_subschema, require_fast_deep_equal, require_json_schema_traverse, require_resolve, require_validate, require_validation_error, require_ref_error, require_compile, require_data, require_utils, require_schemes, require_fast_uri, require_uri, require_core, require_id, require_ref, require_core2, require_limitNumber, require_multipleOf, require_ucs2length, require_limitLength, require_pattern, require_limitProperties, require_required, require_limitItems, require_equal, require_uniqueItems, require_const, require_enum, require_validation, require_additionalItems, require_items, require_prefixItems, require_items2020, require_contains, require_dependencies, require_propertyNames, require_additionalProperties, require_properties, require_patternProperties, require_not, require_anyOf, require_oneOf, require_allOf, require_if, require_thenElse, require_applicator, require_format, require_format2, require_metadata, require_draft7, require_types, require_discriminator, require_json_schema_draft_07, require_ajv, require_formats, require_limit, require_dist, import_ajv, import_ajv_formats, AjvJsonSchemaValidator, init_ajv_provider, ExperimentalServerTasks, init_server, init_helpers, Server, init_server2, COMPLETABLE_SYMBOL, McpZodTypeKind, init_completable, init_uriTemplate, TOOL_NAME_REGEX, init_toolNameValidation, ExperimentalMcpServerTasks, init_mcp_server, init_zod, McpServer, EMPTY_OBJECT_JSON_SCHEMA, EMPTY_COMPLETION_RESULT, init_mcp, RequestError, toRequestError, GlobalRequest, Request2, newHeadersFromIncoming, wrapBodyStream, newRequestFromIncoming, getRequestCache, requestCache, incomingKey, urlKey, headersKey, abortControllerKey, getAbortController, requestPrototype, newRequest, responseCache, getResponseCache, cacheKey, GlobalResponse, Response2, buildOutgoingHttpHeaders, X_ALREADY_SENT, outgoingEnded, handleRequestError, handleFetchError, handleResponseError, flushHeaders, responseViaCache, isPromise, responseViaResponseObject, getRequestListener, init_dist22, require_content_type, import_content_type, init_mediaType, DEFAULT_MAX_REQUEST_BODY_SIZE, MAX_BATCH_SIZE, init_requestBody, DEFAULT_SSE_KEEP_ALIVE_MS, MAX_TIMER_DELAY_MS, init_sseKeepAlive, WebStandardStreamableHTTPServerTransport, init_webStandardStreamableHttp, StreamableHTTPServerTransport, init_streamableHttp, AgentVaultMcpServer, init_mcp_server2, init_mcp_handlers, init_skill_manifest, init_skill_invoker, spanBuffer, init_skill_telemetry, PolicyEnforcer, init_policy_enforcer, VERSION, init_index;
17647
17685
  var init_dist = __esm({
17648
17686
  async "../plugin/dist/index.js"() {
17649
17687
  "use strict";
@@ -17696,6 +17734,12 @@ var init_dist = __esm({
17696
17734
  INSTRUCTION = "not every message needs an answer from you: if this one is not addressed to you and asks nothing of you, reply with exactly " + SENTINEL + " and nothing else \u2014 that is discarded, not posted, and is how you stay quiet; never post a message SAYING that you are staying quiet";
17697
17735
  }
17698
17736
  });
17737
+ init_owner_routing = __esm2({
17738
+ "src/owner-routing.ts"() {
17739
+ "use strict";
17740
+ AMBIGUOUS_OWNER_ERROR = `More than one person is talking to this agent right now, so it can't tell who this is for. Add 'conversation_id' to say which conversation, or send audience "everyone" to reach them all.`;
17741
+ }
17742
+ });
17699
17743
  init_envelope_text = __esm2({
17700
17744
  "src/envelope-text.ts"() {
17701
17745
  "use strict";
@@ -70227,6 +70271,119 @@ var init_dist = __esm({
70227
70271
  ACTIONS = /* @__PURE__ */ new Set(["approve", "deny", "defer", "cancel"]);
70228
70272
  }
70229
70273
  });
70274
+ init_welcome_kp_backoff = __esm2({
70275
+ "src/welcome-kp-backoff.ts"() {
70276
+ "use strict";
70277
+ KP_BACKOFF_INITIAL_MS = 10 * 6e4;
70278
+ KP_BACKOFF_MAX_MS = 60 * 6e4;
70279
+ KP_RACE_RETRY_MS = 6e4;
70280
+ KP_RACE_RETRY_LIMIT = 3;
70281
+ consoleLogger = {
70282
+ warn: (m2) => console.warn(m2),
70283
+ info: (m2) => console.log(m2)
70284
+ };
70285
+ short = (id) => id.slice(0, 8);
70286
+ WelcomeKeyPackageBackoff = class {
70287
+ constructor(log = consoleLogger) {
70288
+ this.log = log;
70289
+ }
70290
+ log;
70291
+ entries = /* @__PURE__ */ new Map();
70292
+ pendingSig = /* @__PURE__ */ new Map();
70293
+ failing = /* @__PURE__ */ new Set();
70294
+ key(groupId, deviceId) {
70295
+ return `${groupId}:${deviceId}`;
70296
+ }
70297
+ /**
70298
+ * Record this pull's pending list for a group. Returns true when the set of
70299
+ * requests differs from the previous pull's — the caller logs its "N pending"
70300
+ * line only then. Backoffs for devices whose request is gone are dropped.
70301
+ */
70302
+ observePending(groupId, pending) {
70303
+ const sig = pending.map((r2) => r2.id).sort().join(",");
70304
+ const changed = this.pendingSig.get(groupId) !== sig;
70305
+ if (pending.length === 0) this.pendingSig.delete(groupId);
70306
+ else this.pendingSig.set(groupId, sig);
70307
+ const live = new Set(pending.map((r2) => r2.requesting_device_id));
70308
+ const prefix = `${groupId}:`;
70309
+ for (const k2 of [...this.entries.keys()]) {
70310
+ if (k2.startsWith(prefix) && !live.has(k2.slice(prefix.length))) this.entries.delete(k2);
70311
+ }
70312
+ return changed && pending.length > 0;
70313
+ }
70314
+ /** Should this pull ask the batch for this device's KeyPackage? */
70315
+ shouldAsk(groupId, deviceId, available, label, now = Date.now()) {
70316
+ const k2 = this.key(groupId, deviceId);
70317
+ const entry = this.entries.get(k2);
70318
+ if (available === false) {
70319
+ if (!entry) {
70320
+ this.entries.set(k2, { untilMs: now + KP_BACKOFF_INITIAL_MS, delayMs: KP_BACKOFF_INITIAL_MS, lastAvailable: false, raceRetries: 0 });
70321
+ this.log.warn(
70322
+ `[SecureChannel] No KeyPackage for ${short(deviceId)} in ${label} \u2014 waiting for the device to come back online; not asking again until it publishes one`
70323
+ );
70324
+ } else {
70325
+ entry.lastAvailable = false;
70326
+ }
70327
+ return false;
70328
+ }
70329
+ if (!entry) return true;
70330
+ if (available === true && entry.lastAvailable === false) return true;
70331
+ return now >= entry.untilMs;
70332
+ }
70333
+ /** The outcome of an ask. `found` = the batch returned a KeyPackage. */
70334
+ recordKeyPackage(groupId, deviceId, found, available, label, now = Date.now()) {
70335
+ const k2 = this.key(groupId, deviceId);
70336
+ const entry = this.entries.get(k2);
70337
+ if (found) {
70338
+ if (entry) {
70339
+ this.entries.delete(k2);
70340
+ this.log.info(`[SecureChannel] KeyPackage for ${short(deviceId)} is available again in ${label} \u2014 admitting`);
70341
+ }
70342
+ return;
70343
+ }
70344
+ const raced = available === true && (entry?.raceRetries ?? 0) < KP_RACE_RETRY_LIMIT;
70345
+ if (!entry) {
70346
+ if (raced) {
70347
+ this.entries.set(k2, { untilMs: now + KP_RACE_RETRY_MS, delayMs: 0, lastAvailable: available, raceRetries: 1 });
70348
+ this.log.warn(
70349
+ `[SecureChannel] No KeyPackage for ${short(deviceId)} in ${label} although the server listed one (claimed elsewhere?) \u2014 retrying in ${KP_RACE_RETRY_MS / 1e3} s`
70350
+ );
70351
+ return;
70352
+ }
70353
+ this.entries.set(k2, { untilMs: now + KP_BACKOFF_INITIAL_MS, delayMs: KP_BACKOFF_INITIAL_MS, lastAvailable: available, raceRetries: 0 });
70354
+ this.log.warn(
70355
+ `[SecureChannel] No KeyPackage for ${short(deviceId)} in ${label}, skipping \u2014 not asking again for ${KP_BACKOFF_INITIAL_MS / 6e4} min (the device has to come back online)`
70356
+ );
70357
+ return;
70358
+ }
70359
+ entry.lastAvailable = available;
70360
+ if (raced) {
70361
+ entry.raceRetries += 1;
70362
+ entry.untilMs = now + KP_RACE_RETRY_MS;
70363
+ return;
70364
+ }
70365
+ entry.raceRetries = available === true ? entry.raceRetries : 0;
70366
+ entry.delayMs = entry.delayMs === 0 ? KP_BACKOFF_INITIAL_MS : Math.min(entry.delayMs * 2, KP_BACKOFF_MAX_MS);
70367
+ entry.untilMs = now + entry.delayMs;
70368
+ }
70369
+ /** A non-OK response for `scope`: warn once until it recovers. */
70370
+ noteFetchFailure(scope, status) {
70371
+ if (this.failing.has(scope)) return;
70372
+ this.failing.add(scope);
70373
+ this.log.warn(`[SecureChannel] ${scope} failed (${status}) \u2014 will retry each pull; logging once until it recovers`);
70374
+ }
70375
+ noteFetchOk(scope) {
70376
+ if (!this.failing.delete(scope)) return;
70377
+ this.log.info(`[SecureChannel] ${scope} recovered`);
70378
+ }
70379
+ /** Test/diagnostic view. */
70380
+ backoffFor(groupId, deviceId) {
70381
+ const e = this.entries.get(this.key(groupId, deviceId));
70382
+ return e ? { untilMs: e.untilMs, delayMs: e.delayMs } : void 0;
70383
+ }
70384
+ };
70385
+ }
70386
+ });
70230
70387
  history_backup_client_exports = {};
70231
70388
  __export2(history_backup_client_exports, {
70232
70389
  HISTORY_RESTORE_RESPONSE_MAX_BYTES: () => HISTORY_RESTORE_RESPONSE_MAX_BYTES,
@@ -70527,6 +70684,7 @@ var init_dist = __esm({
70527
70684
  init_http_handlers = __esm2({
70528
70685
  "src/http-handlers.ts"() {
70529
70686
  "use strict";
70687
+ init_owner_routing();
70530
70688
  }
70531
70689
  });
70532
70690
  mcp_proxy_helpers_exports = {};
@@ -70556,6 +70714,7 @@ var init_dist = __esm({
70556
70714
  async "src/channel.ts"() {
70557
70715
  "use strict";
70558
70716
  init_abstention();
70717
+ init_owner_routing();
70559
70718
  init_envelope_text();
70560
70719
  init_mls_commit_classify();
70561
70720
  init_room_protocol();
@@ -70575,6 +70734,7 @@ var init_dist = __esm({
70575
70734
  init_history_backup_scheduler();
70576
70735
  await init_history_recovery_code();
70577
70736
  init_decision_reply();
70737
+ init_welcome_kp_backoff();
70578
70738
  ROOM_AGENT_TYPES = /* @__PURE__ */ new Set([
70579
70739
  "message",
70580
70740
  "text",
@@ -70605,6 +70765,10 @@ var init_dist = __esm({
70605
70765
  OUTBOUND_DEDUPE_TYPES = /* @__PURE__ */ new Set(["text", "status_alert", "artifact", "attachment"]);
70606
70766
  RETRY_CANDIDATE_TTL_MS = 6e4;
70607
70767
  RETRY_CANDIDATE_MAX = 32;
70768
+ _turnConversation = new AsyncLocalStorage();
70769
+ PERSON_INVOLVED_WINDOW_MS = 5 * 6e4;
70770
+ ATTESTED_INBOUND_MAX = 64;
70771
+ UNMAPPED_RECONCILE_COOLDOWN_MS = 6e4;
70608
70772
  TOPIC_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
70609
70773
  ROOM_FULFIL_COOLDOWN_MS = 6e4;
70610
70774
  SecureChannel = class _SecureChannel extends EventEmitter {
@@ -70681,6 +70845,8 @@ var init_dist = __esm({
70681
70845
  _mlsGroups = /* @__PURE__ */ new Map();
70682
70846
  /** `${mlsGroupId}:${deviceId}` -> last re-admit ms (#1171). */
70683
70847
  _roomFulfilCooldown = /* @__PURE__ */ new Map();
70848
+ /** #1428: per (group, device) KeyPackage backoff for the pending-Welcome pulls. */
70849
+ _welcomeKpBackoff = new WelcomeKeyPackageBackoff();
70684
70850
  /** Maps conversationId -> conversation_group_id for shared 1:1 MLS groups */
70685
70851
  _sessionGroupIds = /* @__PURE__ */ new Map();
70686
70852
  /** Consecutive MLS decrypt failure count per group key for epoch recovery. */
@@ -70843,6 +71009,31 @@ ${text}`;
70843
71009
  _lastIncomingTopics = /* @__PURE__ */ new Map();
70844
71010
  /** Room ID from the most recent inbound room message — used as fallback for HTTP /send replies. */
70845
71011
  _lastInboundRoomId;
71012
+ /**
71013
+ * #1418: the most recent owner 1:1 message that reached the agent — the
71014
+ * person involved in whatever the agent says next without naming a
71015
+ * conversation (see `_involvedPerson`). In memory only: after a restart
71016
+ * there is no trigger, so untargeted content goes to the primary person.
71017
+ */
71018
+ _lastInboundDm;
71019
+ /** #1418: turns in progress (`runForConversation`). */
71020
+ _activeTurns = /* @__PURE__ */ new Set();
71021
+ /**
71022
+ * #1418: recent owner 1:1 messages that decrypted, keyed by
71023
+ * conversation|group — evidence of which conversation, group and browser
71024
+ * belong together (one person). In memory only, bounded.
71025
+ */
71026
+ _attestedInbound = /* @__PURE__ */ new Map();
71027
+ /** #1418: per UNMAPPED group (or conversation), the last time it asked for a reconcile. */
71028
+ _unmappedReconcileAt = /* @__PURE__ */ new Map();
71029
+ /**
71030
+ * #1418: 1:1 groups joined by a Welcome IN THIS PROCESS while no
71031
+ * conversation mapped them — a person who has not been learned yet, counted
71032
+ * as one until the next successful reconcile. Persisted husks never are.
71033
+ */
71034
+ _welcomedUnmapped = /* @__PURE__ */ new Map();
71035
+ /** #1418: what the last SUCCESSFUL reconcile reported live, and when it started. */
71036
+ _lastReconcile;
70846
71037
  /** Rate-limit: last resync_request timestamp per conversation (5-min cooldown). */
70847
71038
  _lastResyncRequest = /* @__PURE__ */ new Map();
70848
71039
  /** Dedup: last room/group welcome self-heal request timestamp per group (30s window). */
@@ -71448,6 +71639,379 @@ ${text}`;
71448
71639
  if (this._persisted?.groupId) known.add(this._persisted.groupId);
71449
71640
  return known;
71450
71641
  }
71642
+ // --- #1418: only the person involved ----------------------------------
71643
+ /**
71644
+ * Run `fn` as the work an inbound 1:1 message from `conversationId`
71645
+ * triggered. Untargeted owner content sent while it runs — from inside its
71646
+ * async call chain, or from anywhere while it is the only turn in progress —
71647
+ * goes to that conversation's person only.
71648
+ *
71649
+ * `opts.groupId` is the group that message DECRYPTED under
71650
+ * (`metadata.conversationGroupId`). Pass it: it outranks the local
71651
+ * conversation→group map, which can be stale, and it is all there is for a
71652
+ * frame whose conversation is not mapped yet. With neither an id nor a
71653
+ * group, `fn` runs unchanged.
71654
+ */
71655
+ async runForConversation(conversationId, fn, opts) {
71656
+ const groupId = typeof opts?.groupId === "string" && opts.groupId ? opts.groupId : void 0;
71657
+ if (!conversationId && !groupId) return fn();
71658
+ const store = { convId: conversationId || void 0, groupId, ended: false };
71659
+ this._activeTurns.add(store);
71660
+ try {
71661
+ return await _turnConversation.run(store, fn);
71662
+ } finally {
71663
+ store.ended = true;
71664
+ store.endedAt = Date.now();
71665
+ this._activeTurns.delete(store);
71666
+ }
71667
+ }
71668
+ /**
71669
+ * The turn this call chain belongs to (#1418) — running, or ended but
71670
+ * still within the window in which work it left behind is for its person.
71671
+ * `"expired"` once that window is over: the work is proactive now.
71672
+ */
71673
+ _currentTurn() {
71674
+ const store = _turnConversation.getStore();
71675
+ if (!store) return void 0;
71676
+ if (!store.ended) return store;
71677
+ return Date.now() - (store.endedAt ?? 0) < PERSON_INVOLVED_WINDOW_MS ? store : "expired";
71678
+ }
71679
+ /**
71680
+ * Record an owner 1:1 message that just decrypted (#1418).
71681
+ *
71682
+ * Always kept as evidence of which conversation, group and browser belong
71683
+ * together (see `_dmPeople`). It makes its person "the person involved" only
71684
+ * when it is RECENT by the server's `createdAt`: a frame replayed from
71685
+ * backlog on reconnect is not something anyone is waiting on an answer to.
71686
+ */
71687
+ _noteInboundDm(convId, groupId, opts = {}) {
71688
+ if (!convId && !groupId) return;
71689
+ const now = Date.now();
71690
+ const sentAt = opts.createdAt ? Date.parse(opts.createdAt) : NaN;
71691
+ const at = Number.isFinite(sentAt) ? Math.min(now, sentAt) : now;
71692
+ const sender = opts.senderDeviceId && opts.senderDeviceId !== this._deviceId ? opts.senderDeviceId : void 0;
71693
+ const key = `${convId ?? ""}|${groupId ?? ""}|${sender ?? ""}`;
71694
+ const prior = this._attestedInbound.get(key);
71695
+ this._attestedInbound.delete(key);
71696
+ this._attestedInbound.set(key, { convId, groupId, senderDeviceId: sender, at: Math.max(prior?.at ?? 0, at) });
71697
+ while (this._attestedInbound.size > ATTESTED_INBOUND_MAX) {
71698
+ const oldest = this._attestedInbound.keys().next().value;
71699
+ if (oldest === void 0) break;
71700
+ this._attestedInbound.delete(oldest);
71701
+ }
71702
+ if (this._lastInboundDm && this._lastInboundDm.at > at) return;
71703
+ this._lastInboundDm = {
71704
+ convId,
71705
+ groupId: groupId ?? (convId ? this._sessionGroupIds.get(convId) : void 0),
71706
+ at
71707
+ };
71708
+ }
71709
+ /** The group `convId`'s most recent inbound decrypted under, if any. */
71710
+ _attestedGroupOf(convId) {
71711
+ if (!convId) return void 0;
71712
+ let gid;
71713
+ for (const a2 of this._attestedInbound.values()) {
71714
+ if (a2.convId === convId && a2.groupId) gid = a2.groupId;
71715
+ }
71716
+ return gid;
71717
+ }
71718
+ /** Does some mapped conversation point at `groupId`? */
71719
+ _isMappedGroup(groupId) {
71720
+ for (const gid of this._sessionGroupIds.values()) if (gid === groupId) return true;
71721
+ return false;
71722
+ }
71723
+ /**
71724
+ * An owner message decrypted under a group no mapped conversation points at
71725
+ * (#1418): the map is stale — a Welcome landed before its conversation was
71726
+ * learned, or a conversation was recreated. Re-resolve it from the server.
71727
+ * Fire-and-forget and rate-limited per group: never awaited on the receive
71728
+ * or Welcome path, so it can never hold up MLS processing.
71729
+ */
71730
+ _reconcileForUnmappedGroup(groupId) {
71731
+ if (!groupId || this._isMappedGroup(groupId)) return;
71732
+ this._reconcileSoon(`g:${groupId}`);
71733
+ }
71734
+ /** The same for a Double Ratchet message on a conversation the map does not know. */
71735
+ _reconcileForUnmappedConversation(convId) {
71736
+ if (!convId || this._sessionGroupIds.size === 0 || this._sessionGroupIds.has(convId)) return;
71737
+ this._reconcileSoon(`c:${convId}`);
71738
+ }
71739
+ _reconcileSoon(key) {
71740
+ const now = Date.now();
71741
+ if (now - (this._unmappedReconcileAt.get(key) ?? 0) < UNMAPPED_RECONCILE_COOLDOWN_MS) return;
71742
+ this._unmappedReconcileAt.set(key, now);
71743
+ void Promise.resolve().then(() => this._reconcileConversationGroups()).catch((err) => console.warn("[SecureChannel] Conversation-group reconcile (unmapped group) failed:", err));
71744
+ }
71745
+ /** A conversation of `groupId`, for an MLS frame that named only its group. */
71746
+ _conversationOfGroup(groupId) {
71747
+ if (!groupId) return void 0;
71748
+ if (this._primaryConversationId && this._sessionGroupIds.get(this._primaryConversationId) === groupId) {
71749
+ return this._primaryConversationId;
71750
+ }
71751
+ for (const [convId, gid] of this._sessionGroupIds) {
71752
+ if (gid === groupId) return convId;
71753
+ }
71754
+ return void 0;
71755
+ }
71756
+ /** Is `convId` one of this agent's own 1:1 conversations (never a room's or an A2A channel's)? */
71757
+ _isOwnDmConversation(convId) {
71758
+ if (this._isNonDmConversation(convId)) return false;
71759
+ return this._sessions.has(convId) || this._sessionGroupIds.has(convId) || !!this._persisted?.mlsConversations?.[convId] || convId === this._primaryConversationId;
71760
+ }
71761
+ /**
71762
+ * #1418 — the PEOPLE this agent has a 1:1 with, or `undefined` when it
71763
+ * cannot tell (no conversation is mapped: then it behaves as before #1418).
71764
+ *
71765
+ * People, not groups. Since #1399 one person has one group, but an agent
71766
+ * also keeps joined groups that are nobody's any more — husks of deleted or
71767
+ * recreated conversations. Measured 2026-10-24: wren held 13 joined groups
71768
+ * for 1 mapped, loopita 2 for 1, wowzer 2 for 1. Counting joined groups made
71769
+ * all three single-person agents look like several people, and their
71770
+ * replies could go only to a dead group.
71771
+ *
71772
+ * So a person is built from the conversations the server mapped, joined by
71773
+ * evidence that two things are the same person:
71774
+ * - the same group (a legacy group shared by several people cannot be told
71775
+ * apart, so it stays one — exactly the pre-#1418 behaviour);
71776
+ * - the same owner browser (a browser belongs to exactly one person);
71777
+ * - a message that decrypted under a group, from a conversation and browser.
71778
+ * A joined group nothing maps and nobody has spoken in is not a person. A
71779
+ * message on an unmapped group from a browser nobody knows IS someone —
71780
+ * that fails closed, toward "only them".
71781
+ */
71782
+ _dmPeople() {
71783
+ if (this._sessionGroupIds.size === 0) return void 0;
71784
+ const parent2 = /* @__PURE__ */ new Map();
71785
+ const add4 = (x2) => {
71786
+ if (!parent2.has(x2)) parent2.set(x2, x2);
71787
+ };
71788
+ const find = (x2) => {
71789
+ let root3 = x2;
71790
+ while (parent2.get(root3) !== root3) root3 = parent2.get(root3);
71791
+ return root3;
71792
+ };
71793
+ const union2 = (a2, b2) => {
71794
+ if (!a2 || !b2) return;
71795
+ add4(a2);
71796
+ add4(b2);
71797
+ const ra2 = find(a2), rb = find(b2);
71798
+ if (ra2 !== rb) parent2.set(ra2, rb);
71799
+ };
71800
+ const ownerOf = (convId) => {
71801
+ const owner = this._sessions.get(convId)?.ownerDeviceId ?? this._persisted?.sessions?.[convId]?.ownerDeviceId;
71802
+ return owner ? `d:${owner}` : void 0;
71803
+ };
71804
+ for (const [convId, gid] of this._sessionGroupIds) {
71805
+ add4(`c:${convId}`);
71806
+ union2(`c:${convId}`, `g:${gid}`);
71807
+ union2(`c:${convId}`, ownerOf(convId));
71808
+ }
71809
+ const primary = this._primaryConversationId || this._persisted?.primaryConversationId;
71810
+ const primaryGid = this._persisted?.groupId;
71811
+ if (primary && primaryGid && (parent2.has(`c:${primary}`) || parent2.has(`g:${primaryGid}`))) {
71812
+ union2(`c:${primary}`, `g:${primaryGid}`);
71813
+ }
71814
+ for (const gid of this._welcomedUnmapped.keys()) add4(`g:${gid}`);
71815
+ const records = [...this._attestedInbound.values()].map((a2) => ({
71816
+ a: a2,
71817
+ nodes: [
71818
+ a2.convId ? `c:${a2.convId}` : void 0,
71819
+ a2.groupId ? `g:${a2.groupId}` : void 0,
71820
+ a2.senderDeviceId ? `d:${a2.senderDeviceId}` : void 0
71821
+ ].filter((n2) => !!n2)
71822
+ }));
71823
+ const placed = /* @__PURE__ */ new Set();
71824
+ const place = (i2) => {
71825
+ const { a: a2, nodes } = records[i2];
71826
+ for (const n2 of nodes) add4(n2);
71827
+ for (const n2 of nodes.slice(1)) union2(nodes[0], n2);
71828
+ if (a2.convId && this._sessionGroupIds.has(a2.convId)) union2(`c:${a2.convId}`, ownerOf(a2.convId));
71829
+ placed.add(i2);
71830
+ };
71831
+ const linkKnown = () => {
71832
+ for (let progress = true; progress; ) {
71833
+ progress = false;
71834
+ records.forEach((r2, i2) => {
71835
+ if (!placed.has(i2) && r2.nodes.some((n2) => parent2.has(n2))) {
71836
+ place(i2);
71837
+ progress = true;
71838
+ }
71839
+ });
71840
+ }
71841
+ };
71842
+ linkKnown();
71843
+ records.forEach((r2, i2) => {
71844
+ if (!placed.has(i2) && this._mayBeNewPerson(r2.a)) place(i2);
71845
+ });
71846
+ linkKnown();
71847
+ const roots = /* @__PURE__ */ new Set();
71848
+ for (const node2 of parent2.keys()) {
71849
+ if (!node2.startsWith("d:")) roots.add(find(node2));
71850
+ }
71851
+ return {
71852
+ count: roots.size,
71853
+ keyOf: (convId, groupId) => {
71854
+ if (convId && parent2.has(`c:${convId}`)) return find(`c:${convId}`);
71855
+ if (groupId && parent2.has(`g:${groupId}`)) return find(`g:${groupId}`);
71856
+ return void 0;
71857
+ }
71858
+ };
71859
+ }
71860
+ /**
71861
+ * May this inbound evidence stand for a person nobody knows yet (#1418)?
71862
+ * Only if it was sent recently, and the last successful reconcile — when it
71863
+ * started after the message was sent — listed its conversation or group.
71864
+ */
71865
+ _mayBeNewPerson(a2) {
71866
+ if (Date.now() - a2.at >= PERSON_INVOLVED_WINDOW_MS) return false;
71867
+ const r2 = this._lastReconcile;
71868
+ if (r2 && a2.at <= r2.at && !(a2.convId && r2.convs.has(a2.convId)) && !(a2.groupId && r2.groups.has(a2.groupId))) return false;
71869
+ return true;
71870
+ }
71871
+ /** More than one person has a 1:1 with this agent (#1418). Unknown counts as one: the old behaviour. */
71872
+ _isMultiPerson() {
71873
+ return (this._dmPeople()?.count ?? 0) > 1;
71874
+ }
71875
+ /**
71876
+ * The group a turn's message decrypted under, for placing the turn when its
71877
+ * conversation is not mapped (a mapped conversation already names its person).
71878
+ */
71879
+ _turnGroup(turn) {
71880
+ return turn.groupId ?? this._attestedGroupOf(turn.convId);
71881
+ }
71882
+ /** The people with a 1:1 turn in progress, one turn each (#1418). */
71883
+ _activeTurnPeople() {
71884
+ const people = this._dmPeople();
71885
+ const out = /* @__PURE__ */ new Map();
71886
+ for (const turn of this._activeTurns) {
71887
+ if (turn.convId && (turn.groupId ? this._isNonDmConversation(turn.convId) : !this._isOwnDmConversation(turn.convId))) continue;
71888
+ const gid = this._turnGroup(turn);
71889
+ const key = people?.keyOf(turn.convId, gid) ?? (gid ? `g:${gid}` : `c:${turn.convId}`);
71890
+ if (!out.has(key)) out.set(key, turn);
71891
+ }
71892
+ return out;
71893
+ }
71894
+ /**
71895
+ * The person an untargeted owner message is for (#1418), in order:
71896
+ *
71897
+ * 1. the turn this call chain belongs to — always, and only, that
71898
+ * conversation, reached on the group its message decrypted under. A turn
71899
+ * never borrows another conversation's turn: one it cannot place fails
71900
+ * closed to its own conversation. Work the turn left running (a timer, a
71901
+ * dispatch orphaned by the turn budget) stays with that person for
71902
+ * `PERSON_INVOLVED_WINDOW_MS` after the turn, then is proactive (4);
71903
+ * 2. with no turn context (a skill's HTTP call), the one person with a turn
71904
+ * in progress;
71905
+ * 3. the last inbound 1:1 message, if it is recent — a reply produced in
71906
+ * response to it;
71907
+ * 4. otherwise the content is proactive: the PRIMARY conversation's person.
71908
+ */
71909
+ _involvedPerson() {
71910
+ const person = (convId, groupId, reason) => ({
71911
+ convId,
71912
+ groupId: groupId ?? this._attestedGroupOf(convId) ?? (convId ? this._sessionGroupIds.get(convId) : void 0),
71913
+ reason
71914
+ });
71915
+ const turn = this._currentTurn();
71916
+ if (turn && turn !== "expired") {
71917
+ return person(turn.convId ?? this._conversationOfGroup(turn.groupId), turn.groupId, turn.ended ? "outlived-turn" : "turn");
71918
+ }
71919
+ if (turn === "expired") return this._primaryPerson();
71920
+ const active = this._activeTurnPeople();
71921
+ if (active.size === 1) {
71922
+ const [only] = active.values();
71923
+ return person(only.convId ?? this._conversationOfGroup(only.groupId), only.groupId, "active-turn");
71924
+ }
71925
+ const last = this._lastInboundDm;
71926
+ if (active.size === 0 && last && Date.now() - last.at < PERSON_INVOLVED_WINDOW_MS) {
71927
+ return person(last.convId ?? this._conversationOfGroup(last.groupId), last.groupId, "last-inbound");
71928
+ }
71929
+ return this._primaryPerson();
71930
+ }
71931
+ /** The PRIMARY conversation's person — where proactive content goes. */
71932
+ _primaryPerson() {
71933
+ const primary = this._primaryConversationId || this._persisted?.primaryConversationId || void 0;
71934
+ const primaryGroup = (primary ? this._sessionGroupIds.get(primary) : void 0) ?? this._persisted?.groupId;
71935
+ return {
71936
+ convId: primary,
71937
+ groupId: primaryGroup ?? this._attestedGroupOf(primary),
71938
+ reason: "primary"
71939
+ };
71940
+ }
71941
+ /**
71942
+ * #1418 — would an untargeted owner send right now have to GUESS between
71943
+ * people? True only with no turn context while two or more people have a
71944
+ * turn in progress. The local HTTP API refuses such a request (409) and
71945
+ * asks for a conversation instead of picking one.
71946
+ */
71947
+ isUntargetedOwnerAmbiguous(options) {
71948
+ if (options?.conversationId !== void 0 || options?.audience === "everyone") return false;
71949
+ if (this._currentTurn()) return false;
71950
+ if (!this._isMultiPerson()) return false;
71951
+ return this._activeTurnPeople().size > 1;
71952
+ }
71953
+ /**
71954
+ * Who an UNTARGETED owner send reaches, or `null` for "every session, as
71955
+ * before". `null` when the caller chose `audience: "everyone"`, and when the
71956
+ * agent has one person (or cannot tell how many) — nothing to choose
71957
+ * between, so its recipients are exactly what they always were.
71958
+ */
71959
+ _untargetedAudience(options) {
71960
+ if (options?.conversationId !== void 0) return null;
71961
+ if (options?.audience === "everyone") return null;
71962
+ if (!this._isMultiPerson()) return null;
71963
+ return this._involvedPerson();
71964
+ }
71965
+ /** A stable name for who an untargeted owner send reaches right now, or undefined when that is "everyone, as before". */
71966
+ _audienceTag(options) {
71967
+ if (options?.audience === "everyone") return "everyone";
71968
+ const person = this._untargetedAudience(options);
71969
+ return person ? `person:${person.groupId ?? person.convId ?? ""}` : void 0;
71970
+ }
71971
+ /** Does conversation `convId` belong to `person`? A conversation nothing ties to them fails closed. */
71972
+ _isPersonsConversation(person, convId) {
71973
+ if (convId === person.convId) return true;
71974
+ const gid = this._sessionGroupIds.get(convId);
71975
+ if (gid !== void 0 && gid === person.groupId) return true;
71976
+ const people = this._dmPeople();
71977
+ const theirs = people?.keyOf(person.convId, person.groupId);
71978
+ return theirs !== void 0 && people.keyOf(convId, gid) === theirs;
71979
+ }
71980
+ /**
71981
+ * #1418: the Double Ratchet sessions an owner-bound FILE (attachment or
71982
+ * artifact) goes to, bucketed by the conversation its blob is uploaded
71983
+ * under. The blob is uploaded under a conversation of the person who gets
71984
+ * it — the backend only lets that conversation's participants download it —
71985
+ * so an explicit "everyone" uploads once per person.
71986
+ */
71987
+ _ownerFileRecipients(routing) {
71988
+ const roomConvIds = /* @__PURE__ */ new Set();
71989
+ for (const room of Object.values(this._persisted?.rooms ?? {})) {
71990
+ for (const cid of room.conversationIds ?? []) roomConvIds.add(cid);
71991
+ }
71992
+ const live = [...this._sessions].filter(([convId, session2]) => session2.activated && !roomConvIds.has(convId)).map(([convId]) => convId);
71993
+ const person = routing?.conversationId !== void 0 ? { convId: routing.conversationId, groupId: this._sessionGroupIds.get(routing.conversationId), reason: "target" } : this._untargetedAudience(routing);
71994
+ if (person) {
71995
+ const convIds = live.filter((convId) => this._isPersonsConversation(person, convId));
71996
+ const uploadConvId = person.convId ?? convIds[0];
71997
+ return uploadConvId && convIds.length > 0 ? [{ uploadConvId, convIds }] : [];
71998
+ }
71999
+ if (live.length === 0) return [];
72000
+ if (!this._isMultiPerson()) {
72001
+ return [{ uploadConvId: this._primaryConversationId, convIds: live }];
72002
+ }
72003
+ const people = this._dmPeople();
72004
+ const buckets = /* @__PURE__ */ new Map();
72005
+ for (const convId of live) {
72006
+ const gid = this._sessionGroupIds.get(convId);
72007
+ const key = people?.keyOf(convId, gid) ?? gid ?? `c:${convId}`;
72008
+ buckets.set(key, [...buckets.get(key) ?? [], convId]);
72009
+ }
72010
+ return [...buckets.values()].map((convIds) => ({
72011
+ uploadConvId: convIds.includes(this._primaryConversationId) ? this._primaryConversationId : convIds[0],
72012
+ convIds
72013
+ }));
72014
+ }
71451
72015
  /** The group a DM history entry belongs to (see the forms above). */
71452
72016
  _dmEntryScope(entry, known) {
71453
72017
  const t2 = entry.topicId ?? "";
@@ -72019,6 +72583,7 @@ ${text}`;
72019
72583
  Promise.resolve().then(() => (init_openclaw_compat(), openclaw_compat_exports)).then(({ requestHeartbeatNow: requestHeartbeatNow2 }) => requestHeartbeatNow2({ reason: "channel-send" })).catch(() => {
72020
72584
  });
72021
72585
  const targetConvId = options?.conversationId;
72586
+ const audience = this._untargetedAudience(options);
72022
72587
  const explicitTopicId = options?.topicId;
72023
72588
  const targeted = targetConvId !== void 0;
72024
72589
  const frameHistoryContexts = [];
@@ -72057,7 +72622,7 @@ ${text}`;
72057
72622
  if (this._persisted?.mlsGroups && this._state === "ready" && this._ws) {
72058
72623
  const targetSharedGid = targetConvId ? this._sessionGroupIds?.get(targetConvId) : void 0;
72059
72624
  console.log(
72060
- `[SecureChannel] send(): considering ${Object.keys(this._persisted.mlsGroups).length} shared group(s); targetConvId=${targetConvId ? targetConvId.slice(0, 8) : "(none \u2014 broadcast)"} targetSharedGid=${targetSharedGid ? targetSharedGid.slice(0, 8) : "(none)"}`
72625
+ `[SecureChannel] send(): considering ${Object.keys(this._persisted.mlsGroups).length} shared group(s); targetConvId=${targetConvId ? targetConvId.slice(0, 8) : audience ? `(none \u2014 person involved: ${audience.reason})` : "(none \u2014 everyone)"} targetSharedGid=${targetSharedGid ? targetSharedGid.slice(0, 8) : audience?.groupId ? audience.groupId.slice(0, 8) : "(none)"}`
72061
72626
  );
72062
72627
  const skipped = [];
72063
72628
  for (const [gid, entry] of Object.entries(this._persisted.mlsGroups)) {
@@ -72065,6 +72630,10 @@ ${text}`;
72065
72630
  skipped.push(`${gid.slice(0, 8)}:not-target`);
72066
72631
  continue;
72067
72632
  }
72633
+ if (audience && gid !== audience.groupId) {
72634
+ skipped.push(`${gid.slice(0, 8)}:not-involved`);
72635
+ continue;
72636
+ }
72068
72637
  if (!entry.mlsGroupId) {
72069
72638
  skipped.push(`${gid.slice(0, 8)}:no-mlsGroupId`);
72070
72639
  continue;
@@ -72121,6 +72690,7 @@ ${text}`;
72121
72690
  if (!session2.activated) continue;
72122
72691
  if (roomConvIds.has(convId)) continue;
72123
72692
  if (targetConvId && convId !== targetConvId) continue;
72693
+ if (audience && !this._isPersonsConversation(audience, convId)) continue;
72124
72694
  const convGroupId = this._sessionGroupIds?.get(convId);
72125
72695
  if (convGroupId && sentSharedGroupIds.has(convGroupId)) {
72126
72696
  sentCount++;
@@ -72239,6 +72809,7 @@ ${text}`;
72239
72809
  if (this._persisted?.mlsConversations && this._state === "ready" && this._ws) {
72240
72810
  for (const [mlsConvId, entry] of Object.entries(this._persisted.mlsConversations)) {
72241
72811
  if (targetConvId && mlsConvId !== targetConvId) continue;
72812
+ if (audience && !this._isPersonsConversation(audience, mlsConvId)) continue;
72242
72813
  if (this._sessions.has(mlsConvId)) continue;
72243
72814
  if (roomConvIds.has(mlsConvId)) continue;
72244
72815
  const mlsOnlyConvGroupId = this._sessionGroupIds?.get(mlsConvId);
@@ -72362,7 +72933,7 @@ ${text}`;
72362
72933
  */
72363
72934
  sendActivitySpan(spanData) {
72364
72935
  if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
72365
- const pluginVersion = true ? "0.23.51" : "0.0.0-dev";
72936
+ const pluginVersion = true ? "0.23.53" : "0.0.0-dev";
72366
72937
  const agentName = this.config.agentName ?? "Agent";
72367
72938
  const resource = {
72368
72939
  "service.name": "agentvault-agent",
@@ -72414,7 +72985,7 @@ ${text}`;
72414
72985
  * Builds a structured envelope with decision metadata and sends it
72415
72986
  * as a high-priority message. Returns the generated decision_id.
72416
72987
  */
72417
- async sendDecisionRequest(request) {
72988
+ async sendDecisionRequest(request, routing) {
72418
72989
  const decision_id = `dec_${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
72419
72990
  const payload = JSON.stringify({
72420
72991
  type: "message",
@@ -72425,6 +72996,8 @@ ${text}`;
72425
72996
  }
72426
72997
  });
72427
72998
  await this.send(payload, {
72999
+ conversationId: routing?.conversationId,
73000
+ audience: routing?.audience,
72428
73001
  messageType: "decision_request",
72429
73002
  priority: "high",
72430
73003
  metadata: {
@@ -72831,6 +73404,7 @@ ${text}`;
72831
73404
  const jwt = this._deviceJwt ?? this._persisted?.deviceJwt;
72832
73405
  if (!jwt || !this._persisted) return false;
72833
73406
  let rows;
73407
+ const reconcileStartedAt = Date.now();
72834
73408
  try {
72835
73409
  const res = await fetch(`${this.config.apiUrl}/api/v1/conversations`, {
72836
73410
  headers: { Authorization: `Bearer ${jwt}` }
@@ -72859,6 +73433,19 @@ ${text}`;
72859
73433
  }
72860
73434
  this._sessionGroupIds = new Map(mine.map((r2) => [r2.id, r2.group_id]));
72861
73435
  this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
73436
+ {
73437
+ const convs = new Set(mine.map((r2) => r2.id));
73438
+ const groups = new Set(mine.map((r2) => r2.group_id));
73439
+ this._lastReconcile = { at: reconcileStartedAt, convs, groups };
73440
+ for (const [key, a2] of this._attestedInbound) {
73441
+ if (a2.at > reconcileStartedAt) continue;
73442
+ if (a2.convId && convs.has(a2.convId) || a2.groupId && groups.has(a2.groupId)) continue;
73443
+ this._attestedInbound.delete(key);
73444
+ }
73445
+ for (const [gid, at] of this._welcomedUnmapped) {
73446
+ if (at <= reconcileStartedAt) this._welcomedUnmapped.delete(gid);
73447
+ }
73448
+ }
72862
73449
  const joined = mine.find((r2) => this._persisted.mlsGroups?.[r2.group_id]);
72863
73450
  const primary = mine.find((r2) => r2.id === this._persisted.primaryConversationId) ?? joined ?? mine[0];
72864
73451
  if (!mine.some((r2) => r2.id === this._persisted.primaryConversationId)) {
@@ -73052,7 +73639,7 @@ ${text}`;
73052
73639
  }
73053
73640
  this._heartbeatCallback = null;
73054
73641
  }
73055
- async sendStatusAlert(alert) {
73642
+ async sendStatusAlert(alert, routing) {
73056
73643
  const priority = alert.severity === "error" || alert.severity === "critical" ? "high" : "normal";
73057
73644
  const envelope = {
73058
73645
  title: alert.title,
@@ -73066,52 +73653,61 @@ ${text}`;
73066
73653
  await this.send(
73067
73654
  JSON.stringify(envelope),
73068
73655
  {
73656
+ conversationId: routing?.conversationId,
73657
+ audience: routing?.audience,
73069
73658
  messageType: "status_alert",
73070
73659
  priority,
73071
73660
  metadata: { severity: alert.severity }
73072
73661
  }
73073
73662
  );
73074
73663
  }
73075
- async sendArtifact(artifact) {
73664
+ async sendArtifact(artifact, routing) {
73076
73665
  if (this._state !== "ready" || this._sessions.size === 0 || !this._ws) {
73077
73666
  throw new Error("Channel is not ready");
73078
73667
  }
73079
- const attachMeta = await this._uploadAttachment(artifact.filePath, this._primaryConversationId);
73080
- const envelope = JSON.stringify({
73081
- type: "artifact",
73082
- blob_id: attachMeta.blobId,
73083
- blob_url: attachMeta.blobUrl,
73084
- filename: artifact.filename,
73085
- mime_type: artifact.mimeType,
73086
- size_bytes: attachMeta.size,
73087
- description: artifact.description,
73088
- attachment: attachMeta
73089
- });
73090
73668
  const messageGroupId = randomUUID4();
73091
73669
  const pendingWsSends = [];
73092
- for (const [convId, session2] of this._sessions) {
73093
- if (!session2.activated) continue;
73094
- const encrypted = session2.ratchet.encrypt(envelope);
73095
- const transport = encryptedMessageToTransport(encrypted);
73096
- pendingWsSends.push(
73097
- JSON.stringify({
73098
- event: "message",
73099
- data: {
73100
- conversation_id: convId,
73101
- header_blob: transport.header_blob,
73102
- ciphertext: transport.ciphertext,
73103
- message_group_id: messageGroupId,
73104
- message_type: "artifact_share"
73105
- }
73106
- })
73107
- );
73670
+ const buckets = this._ownerFileRecipients(routing);
73671
+ if (buckets.length === 0) {
73672
+ console.warn("[SecureChannel] sendArtifact(): no live session for the person involved \u2014 nothing sent");
73673
+ throw new Error("No conversation is ready to receive this file");
73674
+ }
73675
+ for (const bucket of buckets) {
73676
+ const attachMeta = await this._uploadAttachment(artifact.filePath, bucket.uploadConvId);
73677
+ const envelope = JSON.stringify({
73678
+ type: "artifact",
73679
+ blob_id: attachMeta.blobId,
73680
+ blob_url: attachMeta.blobUrl,
73681
+ filename: artifact.filename,
73682
+ mime_type: artifact.mimeType,
73683
+ size_bytes: attachMeta.size,
73684
+ description: artifact.description,
73685
+ attachment: attachMeta
73686
+ });
73687
+ for (const convId of bucket.convIds) {
73688
+ const session2 = this._sessions.get(convId);
73689
+ const encrypted = session2.ratchet.encrypt(envelope);
73690
+ const transport = encryptedMessageToTransport(encrypted);
73691
+ pendingWsSends.push(
73692
+ JSON.stringify({
73693
+ event: "message",
73694
+ data: {
73695
+ conversation_id: convId,
73696
+ header_blob: transport.header_blob,
73697
+ ciphertext: transport.ciphertext,
73698
+ message_group_id: messageGroupId,
73699
+ message_type: "artifact_share"
73700
+ }
73701
+ })
73702
+ );
73703
+ }
73108
73704
  }
73109
73705
  await this._persistState();
73110
73706
  for (const frame of pendingWsSends) {
73111
73707
  this._ws.send(frame);
73112
73708
  }
73113
73709
  }
73114
- async sendActionConfirmation(confirmation) {
73710
+ async sendActionConfirmation(confirmation, routing) {
73115
73711
  const envelope = {
73116
73712
  type: "action_confirmation",
73117
73713
  action: confirmation.action,
@@ -73122,6 +73718,8 @@ ${text}`;
73122
73718
  await this.send(
73123
73719
  JSON.stringify(envelope),
73124
73720
  {
73721
+ conversationId: routing?.conversationId,
73722
+ audience: routing?.audience,
73125
73723
  messageType: "action_confirmation",
73126
73724
  metadata: { status: confirmation.status }
73127
73725
  }
@@ -73227,9 +73825,23 @@ ${text}`;
73227
73825
  } else {
73228
73826
  return { ok: false, destination: { kind: "owner" }, error: "Unknown target kind", timestamp: ts };
73229
73827
  }
73828
+ if (resolved.kind === "owner" && options?.refuseIfAmbiguous && this.isUntargetedOwnerAmbiguous(options)) {
73829
+ console.log(`[deliver] target=owner content=${content.type} result=REFUSED: ambiguous (several people mid-turn)`);
73830
+ return { ok: false, ambiguous: true, destination: resolved, error: AMBIGUOUS_OWNER_ERROR, timestamp: ts };
73831
+ }
73230
73832
  let dedupeKey = null;
73231
73833
  try {
73232
- dedupeKey = outboundDedupeKey(resolved, content, options);
73834
+ let audienceTag;
73835
+ try {
73836
+ audienceTag = resolved.kind === "owner" && options?.conversationId === void 0 ? this._audienceTag(options) : void 0;
73837
+ } catch {
73838
+ audienceTag = void 0;
73839
+ }
73840
+ dedupeKey = outboundDedupeKey(
73841
+ resolved,
73842
+ content,
73843
+ audienceTag ? { ...options, conversationId: audienceTag } : options
73844
+ );
73233
73845
  if (dedupeKey) {
73234
73846
  const now = Date.now();
73235
73847
  const recent = this._recentDeliveries ??= /* @__PURE__ */ new Map();
@@ -73249,6 +73861,10 @@ ${text}`;
73249
73861
  }
73250
73862
  try {
73251
73863
  let decisionId;
73864
+ const ownerRouting = {
73865
+ conversationId: options?.conversationId,
73866
+ audience: options?.audience
73867
+ };
73252
73868
  if (content.type === "text") {
73253
73869
  if (resolved.kind === "room") {
73254
73870
  await this.sendToRoom(resolved.id, content.text, {
@@ -73267,6 +73883,7 @@ ${text}`;
73267
73883
  } else {
73268
73884
  await this.send(content.text, {
73269
73885
  conversationId: options?.conversationId,
73886
+ audience: options?.audience,
73270
73887
  topicId: options?.topicId,
73271
73888
  messageType: options?.metadata?.message_type,
73272
73889
  priority: options?.priority,
@@ -73279,7 +73896,7 @@ ${text}`;
73279
73896
  console.log(`[deliver] target=${resolved.kind}:${resolved.id} content=decision_request result=FAIL: ${err}`);
73280
73897
  return { ok: false, destination: resolved, error: err, timestamp: ts };
73281
73898
  }
73282
- decisionId = await this.sendDecisionRequest(content.request);
73899
+ decisionId = await this.sendDecisionRequest(content.request, ownerRouting);
73283
73900
  } else if (content.type === "status_alert") {
73284
73901
  if (resolved.kind === "room") {
73285
73902
  const envelope = {
@@ -73297,7 +73914,7 @@ ${text}`;
73297
73914
  metadata: { severity: content.alert.severity }
73298
73915
  });
73299
73916
  } else if (resolved.kind === "owner") {
73300
- await this.sendStatusAlert(content.alert);
73917
+ await this.sendStatusAlert(content.alert, ownerRouting);
73301
73918
  } else {
73302
73919
  return { ok: false, destination: resolved, error: "Status alerts cannot be sent to A2A targets", timestamp: ts };
73303
73920
  }
@@ -73305,7 +73922,7 @@ ${text}`;
73305
73922
  if (resolved.kind === "room") {
73306
73923
  await this.sendActionConfirmationToRoom(resolved.id, content.confirmation);
73307
73924
  } else if (resolved.kind === "owner") {
73308
- await this.sendActionConfirmation(content.confirmation);
73925
+ await this.sendActionConfirmation(content.confirmation, ownerRouting);
73309
73926
  } else {
73310
73927
  return { ok: false, destination: resolved, error: "Action confirmations cannot be sent to A2A targets", timestamp: ts };
73311
73928
  }
@@ -73313,13 +73930,14 @@ ${text}`;
73313
73930
  if (resolved.kind !== "owner") {
73314
73931
  return { ok: false, destination: resolved, error: "Artifacts can only be sent to owner", timestamp: ts };
73315
73932
  }
73316
- await this.sendArtifact(content.artifact);
73933
+ await this.sendArtifact(content.artifact, ownerRouting);
73317
73934
  } else if (content.type === "attachment") {
73318
73935
  if (resolved.kind !== "owner") {
73319
73936
  return { ok: false, destination: resolved, error: "Attachments can only be sent to owner", timestamp: ts };
73320
73937
  }
73321
73938
  await this.sendWithAttachment(content.text, content.filePath, {
73322
- topicId: options?.topicId
73939
+ topicId: options?.topicId,
73940
+ ...ownerRouting
73323
73941
  });
73324
73942
  }
73325
73943
  const targetLabel = resolved.kind === "owner" ? "owner" : `${resolved.kind}:${resolved.id?.slice(0, 8)}...`;
@@ -74492,7 +75110,7 @@ ${text}`;
74492
75110
  agentVersion: this.config.agentVersion ?? "0.0.0",
74493
75111
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
74494
75112
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
74495
- pluginVersion: true ? "0.23.51" : "0.0.0-dev"
75113
+ pluginVersion: true ? "0.23.53" : "0.0.0-dev"
74496
75114
  });
74497
75115
  this._telemetryReporter.startAutoFlush(3e4);
74498
75116
  }
@@ -74820,7 +75438,7 @@ ${text}`;
74820
75438
  agentVersion: this.config.agentVersion ?? "0.0.0",
74821
75439
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
74822
75440
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
74823
- pluginVersion: true ? "0.23.51" : "0.0.0-dev"
75441
+ pluginVersion: true ? "0.23.53" : "0.0.0-dev"
74824
75442
  });
74825
75443
  this._telemetryReporter.startAutoFlush(3e4);
74826
75444
  }
@@ -75361,9 +75979,18 @@ ${text}`;
75361
75979
  messageType,
75362
75980
  { groupId: dmGroupId, conversationId: convId }
75363
75981
  );
75982
+ const dmConvId = convId ?? this._conversationOfGroup(dmGroupId);
75983
+ this._noteInboundDm(dmConvId, dmGroupId, { createdAt: data.created_at, senderDeviceId });
75984
+ this._reconcileForUnmappedGroup(dmGroupId);
75364
75985
  const metadata = {
75365
75986
  messageId: data.message_id ?? `mls_${Date.now()}`,
75366
- conversationId: convId ?? this._primaryConversationId,
75987
+ // A frame on a KNOWN group that no conversation maps yet is not the
75988
+ // primary person's: leave the conversation unnamed rather than hand
75989
+ // the reply to someone else; `conversationGroupId` still places it.
75990
+ conversationId: dmConvId ?? (dmGroupId ? void 0 : this._primaryConversationId),
75991
+ // #1418: the group this message decrypted under — attested, so a turn
75992
+ // answers here even when the local map is stale.
75993
+ conversationGroupId: dmGroupId,
75367
75994
  timestamp: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
75368
75995
  topicId,
75369
75996
  // #621: positive attestation that this decrypted under the OWNER'S 1:1
@@ -75618,6 +76245,13 @@ ${messageText}`;
75618
76245
  // envelope text before the fold; `emitText` is the folded copy.
75619
76246
  caption: messageText
75620
76247
  };
76248
+ if (!roomId) {
76249
+ this._noteInboundDm(convId, void 0, {
76250
+ createdAt: msgData.created_at,
76251
+ senderDeviceId: msgData.sender_device_id
76252
+ });
76253
+ this._reconcileForUnmappedConversation(convId);
76254
+ }
75621
76255
  this.emit("message", emitText, metadata);
75622
76256
  Promise.resolve(this.config.onMessage?.(emitText, metadata)).catch((err) => {
75623
76257
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -75766,34 +76400,41 @@ ${baseText}`;
75766
76400
  if (this._state !== "ready" || this._sessions.size === 0 || !this._ws) {
75767
76401
  throw new Error("Channel is not ready");
75768
76402
  }
75769
- const attachMeta = await this._uploadAttachment(filePath, this._primaryConversationId);
75770
76403
  const messageGroupId = randomUUID4();
75771
76404
  const pendingWsSends = [];
75772
76405
  const frameHistoryContexts = [];
75773
- for (const [convId, session2] of this._sessions) {
75774
- if (!session2.activated) continue;
75775
- const topicId = this._topicForFrame(void 0, convId, options?.topicId, false, false);
75776
- const envelope = JSON.stringify({
75777
- type: "message",
75778
- text: plaintext,
75779
- topicId,
75780
- attachment: attachMeta
75781
- });
75782
- const encrypted = session2.ratchet.encrypt(envelope);
75783
- const transport = encryptedMessageToTransport(encrypted);
75784
- pendingWsSends.push(
75785
- JSON.stringify({
75786
- event: "message",
75787
- data: {
75788
- conversation_id: convId,
75789
- header_blob: transport.header_blob,
75790
- ciphertext: transport.ciphertext,
75791
- message_group_id: messageGroupId,
75792
- topic_id: topicId
75793
- }
75794
- })
75795
- );
75796
- frameHistoryContexts.push(this._dmHistoryContext(topicId, void 0, convId));
76406
+ const buckets = this._ownerFileRecipients(options);
76407
+ if (buckets.length === 0) {
76408
+ console.warn("[SecureChannel] sendWithAttachment(): no live session for the person involved \u2014 nothing sent");
76409
+ throw new Error("No conversation is ready to receive this file");
76410
+ }
76411
+ for (const bucket of buckets) {
76412
+ const attachMeta = await this._uploadAttachment(filePath, bucket.uploadConvId);
76413
+ for (const convId of bucket.convIds) {
76414
+ const session2 = this._sessions.get(convId);
76415
+ const topicId = this._topicForFrame(void 0, convId, options?.topicId, false, false);
76416
+ const envelope = JSON.stringify({
76417
+ type: "message",
76418
+ text: plaintext,
76419
+ topicId,
76420
+ attachment: attachMeta
76421
+ });
76422
+ const encrypted = session2.ratchet.encrypt(envelope);
76423
+ const transport = encryptedMessageToTransport(encrypted);
76424
+ pendingWsSends.push(
76425
+ JSON.stringify({
76426
+ event: "message",
76427
+ data: {
76428
+ conversation_id: convId,
76429
+ header_blob: transport.header_blob,
76430
+ ciphertext: transport.ciphertext,
76431
+ message_group_id: messageGroupId,
76432
+ topic_id: topicId
76433
+ }
76434
+ })
76435
+ );
76436
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, void 0, convId));
76437
+ }
75797
76438
  }
75798
76439
  await this._persistState();
75799
76440
  let deliveredFrames = 0;
@@ -75953,10 +76594,15 @@ ${baseText}`;
75953
76594
  `[SecureChannel] New owner device linked: ${event.owner_device_id.slice(0, 8)}...`
75954
76595
  );
75955
76596
  try {
76597
+ if (event.group_id && !this._sessionGroupIds.has(event.conversation_id)) {
76598
+ this._sessionGroupIds.set(event.conversation_id, event.group_id);
76599
+ this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
76600
+ }
75956
76601
  if (!event.owner_identity_public_key) {
75957
76602
  console.error(
75958
76603
  `[SecureChannel] device_linked event missing owner keys for conv ${event.conversation_id.slice(0, 8)}...`
75959
76604
  );
76605
+ await this._persistState();
75960
76606
  return;
75961
76607
  }
75962
76608
  const identity = this._persisted.identityKeypair;
@@ -75991,10 +76637,6 @@ ${baseText}`;
75991
76637
  if (event.owner_hub_id) {
75992
76638
  this._persisted.ownerHubId = event.owner_hub_id;
75993
76639
  }
75994
- if (event.group_id && !this._sessionGroupIds.has(event.conversation_id)) {
75995
- this._sessionGroupIds.set(event.conversation_id, event.group_id);
75996
- this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
75997
- }
75998
76640
  await this._persistState();
75999
76641
  console.log(
76000
76642
  `[SecureChannel] Session initialized for device ${event.owner_device_id.slice(0, 8)}... (conv ${event.conversation_id.slice(0, 8)}...)`
@@ -76732,7 +77374,7 @@ ${baseText}`;
76732
77374
  return 0;
76733
77375
  }
76734
77376
  const snapshot = mlsGroup.exportState();
76735
- const preHead = await this._readGroupHead(mlsGroupId);
77377
+ const preHead = opts.preHead ?? await this._readGroupHead(mlsGroupId);
76736
77378
  if (preHead.ok && preHead.epoch !== Number(mlsGroup.epoch)) {
76737
77379
  console.warn(
76738
77380
  `[SecureChannel] ${label}: server head is at epoch ${preHead.epoch}, we are at ${Number(mlsGroup.epoch)} \u2014 NOT committing (it would be refused, #1184); ${targets.length} request(s) stay pending`
@@ -76919,6 +77561,40 @@ ${baseText}`;
76919
77561
  _wsIsOpen() {
76920
77562
  return this._ws?.readyState === 1;
76921
77563
  }
77564
+ /**
77565
+ * #1429 review: the cheap checks `_fulfilWelcomeRequests` makes, run BEFORE a
77566
+ * pending-Welcome site claims KeyPackages — the order #1225 S4 gave the A2A
77567
+ * path. `GET /key-packages/batch` CONSUMES; the room, shared-1:1 and conv
77568
+ * sites used to claim one per pending device and only then find the socket
77569
+ * closed, another commit in flight, or the server head elsewhere — burning a
77570
+ * package per device per failed pull (and the shared/conv sites have no
77571
+ * cooldown). `_fulfilWelcomeRequests` keeps its own checks: this is a gate on
77572
+ * spending, not a replacement for the guard at the point of commit.
77573
+ */
77574
+ /**
77575
+ * Returns the head it read (handed on to `_fulfilWelcomeRequests` as its
77576
+ * pre-flight, so a pull still reads the head once before committing), or
77577
+ * `null` when nothing should be claimed this pull.
77578
+ */
77579
+ async _welcomeCommitPreflight(mlsGroupId, mlsGroup, label) {
77580
+ if (!this._wsIsOpen()) {
77581
+ console.warn(`[SecureChannel] ${label}: socket is not OPEN \u2014 not claiming KeyPackages; requests stay pending for the next pull`);
77582
+ return null;
77583
+ }
77584
+ if (this._commitInFlight.has(mlsGroupId)) {
77585
+ console.warn(`[SecureChannel] ${label}: another commit for this group is in flight \u2014 not claiming KeyPackages this pull`);
77586
+ return null;
77587
+ }
77588
+ const head = await this._readGroupHead(mlsGroupId);
77589
+ if (head.ok && head.epoch !== Number(mlsGroup.epoch)) {
77590
+ console.warn(
77591
+ `[SecureChannel] ${label}: server head is at epoch ${head.epoch}, we are at ${Number(mlsGroup.epoch)} \u2014 not claiming KeyPackages (the commit would be refused, #1184); requests stay pending`
77592
+ );
77593
+ await this._catchUpAfterPreflightSkip(mlsGroupId, head.epoch, Number(mlsGroup.epoch), label);
77594
+ return null;
77595
+ }
77596
+ return head;
77597
+ }
76922
77598
  /** SHA-256 hex of a commit's bytes — its identity on the server (#1175/#1177). */
76923
77599
  /**
76924
77600
  * #1225: send ONE commit over the socket and wait for the server's verdict,
@@ -77664,6 +78340,10 @@ ${baseText}`;
77664
78340
  await this._persistState();
77665
78341
  }
77666
78342
  console.log(`[SecureChannel] Joined shared 1:1 MLS group for group ${conversationGroupId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
78343
+ if (!this._isMappedGroup(conversationGroupId)) {
78344
+ this._welcomedUnmapped.set(conversationGroupId, Date.now());
78345
+ }
78346
+ this._reconcileForUnmappedGroup(conversationGroupId);
77667
78347
  await this._flushMlsHold(conversationGroupId);
77668
78348
  return;
77669
78349
  }
@@ -77940,14 +78620,27 @@ ${baseText}`;
77940
78620
  const roomState = this._persisted?.rooms?.[roomId];
77941
78621
  if (!roomState?.mlsGroupId) continue;
77942
78622
  try {
78623
+ const roomLabel = `room ${roomId.slice(0, 8)}`;
77943
78624
  const pendingRes = await fetch(
77944
78625
  `${this.config.apiUrl}/api/v1/mls/groups/${roomState.mlsGroupId}/pending-welcomes`,
77945
78626
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
77946
78627
  );
77947
- if (!pendingRes.ok) continue;
78628
+ if (!pendingRes.ok) {
78629
+ this._welcomeKpBackoff.noteFetchFailure(`pending-welcomes for ${roomLabel}`, pendingRes.status);
78630
+ continue;
78631
+ }
78632
+ this._welcomeKpBackoff.noteFetchOk(`pending-welcomes for ${roomLabel}`);
77948
78633
  let pending = await pendingRes.json();
78634
+ if (this._welcomeKpBackoff.observePending(roomState.mlsGroupId, pending)) {
78635
+ console.log(`[SecureChannel] ${pending.length} pending Welcome requests for room ${roomId.slice(0, 8)}`);
78636
+ }
78637
+ if (pending.length === 0) continue;
78638
+ const nowKp = Date.now();
78639
+ const roomMlsGroupId = roomState.mlsGroupId;
78640
+ pending = pending.filter(
78641
+ (r2) => this._welcomeKpBackoff.shouldAsk(roomMlsGroupId, r2.requesting_device_id, r2.key_package_available, roomLabel, nowKp)
78642
+ );
77949
78643
  if (pending.length === 0) continue;
77950
- console.log(`[SecureChannel] ${pending.length} pending Welcome requests for room ${roomId.slice(0, 8)}`);
77951
78644
  const nowMs = Date.now();
77952
78645
  const fresh = pending.filter((r2) => {
77953
78646
  const key = `${roomState.mlsGroupId}:${r2.requesting_device_id}`;
@@ -77961,6 +78654,8 @@ ${baseText}`;
77961
78654
  return true;
77962
78655
  });
77963
78656
  if (fresh.length === 0) continue;
78657
+ const roomPreHead = await this._welcomeCommitPreflight(roomState.mlsGroupId, mlsGroup, roomLabel);
78658
+ if (!roomPreHead) continue;
77964
78659
  for (const r2 of fresh) {
77965
78660
  this._roomFulfilCooldown.set(`${roomState.mlsGroupId}:${r2.requesting_device_id}`, nowMs);
77966
78661
  }
@@ -77970,13 +78665,23 @@ ${baseText}`;
77970
78665
  `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${deviceIds.join(",")}`,
77971
78666
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
77972
78667
  );
77973
- if (!kpRes.ok) continue;
78668
+ if (!kpRes.ok) {
78669
+ this._welcomeKpBackoff.noteFetchFailure(`KeyPackage batch for ${roomLabel}`, kpRes.status);
78670
+ continue;
78671
+ }
78672
+ this._welcomeKpBackoff.noteFetchOk(`KeyPackage batch for ${roomLabel}`);
77974
78673
  const kpData = await kpRes.json();
77975
78674
  const roomTargets = [];
77976
78675
  for (const req of pending) {
77977
78676
  const kpHex = kpData[req.requesting_device_id];
78677
+ this._welcomeKpBackoff.recordKeyPackage(
78678
+ roomState.mlsGroupId,
78679
+ req.requesting_device_id,
78680
+ Boolean(kpHex),
78681
+ req.key_package_available,
78682
+ roomLabel
78683
+ );
77978
78684
  if (!kpHex) {
77979
- console.warn(`[SecureChannel] No KeyPackage for ${req.requesting_device_id.slice(0, 8)}, skipping`);
77980
78685
  continue;
77981
78686
  }
77982
78687
  const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
@@ -77994,8 +78699,10 @@ ${baseText}`;
77994
78699
  label: `room ${roomId.slice(0, 8)}`,
77995
78700
  welcomeFields: { room_id: roomId },
77996
78701
  targets: roomTargets,
77997
- memberDeviceIds: (roomState.members ?? []).map((m2) => m2.deviceId)
78702
+ memberDeviceIds: (roomState.members ?? []).map((m2) => m2.deviceId),
77998
78703
  // #1226
78704
+ preHead: roomPreHead
78705
+ // #1429
77999
78706
  });
78000
78707
  if (done > 0) {
78001
78708
  console.log(
@@ -78013,28 +78720,49 @@ ${baseText}`;
78013
78720
  const mlsGroup = this._mlsGroups.get(`1to1-group:${gid}`);
78014
78721
  if (!mlsGroup?.isInitialized) continue;
78015
78722
  try {
78723
+ const sharedLabel = `shared group ${gid.slice(0, 8)}`;
78016
78724
  const pendingRes = await fetch(
78017
78725
  `${this.config.apiUrl}/api/v1/mls/groups/${entry.mlsGroupId}/pending-welcomes`,
78018
78726
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78019
78727
  );
78020
- if (!pendingRes.ok) continue;
78021
- const pending = await pendingRes.json();
78728
+ if (!pendingRes.ok) {
78729
+ this._welcomeKpBackoff.noteFetchFailure(`pending-welcomes for ${sharedLabel}`, pendingRes.status);
78730
+ continue;
78731
+ }
78732
+ this._welcomeKpBackoff.noteFetchOk(`pending-welcomes for ${sharedLabel}`);
78733
+ const allPending = await pendingRes.json();
78734
+ if (this._welcomeKpBackoff.observePending(entry.mlsGroupId, allPending)) {
78735
+ console.log(`[SecureChannel] ${allPending.length} pending Welcome requests for shared group ${gid.slice(0, 8)}`);
78736
+ }
78737
+ const nowKp = Date.now();
78738
+ const pending = allPending.filter(
78739
+ (r2) => this._welcomeKpBackoff.shouldAsk(entry.mlsGroupId, r2.requesting_device_id, r2.key_package_available, sharedLabel, nowKp)
78740
+ );
78022
78741
  if (pending.length === 0) continue;
78023
- console.log(`[SecureChannel] ${pending.length} pending Welcome requests for shared group ${gid.slice(0, 8)}`);
78742
+ const sharedPreHead = await this._welcomeCommitPreflight(entry.mlsGroupId, mlsGroup, sharedLabel);
78743
+ if (!sharedPreHead) continue;
78024
78744
  const deviceIds = pending.map((r2) => r2.requesting_device_id);
78025
78745
  const kpRes = await fetch(
78026
78746
  `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${deviceIds.join(",")}`,
78027
78747
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78028
78748
  );
78029
- if (!kpRes.ok) continue;
78749
+ if (!kpRes.ok) {
78750
+ this._welcomeKpBackoff.noteFetchFailure(`KeyPackage batch for ${sharedLabel}`, kpRes.status);
78751
+ continue;
78752
+ }
78753
+ this._welcomeKpBackoff.noteFetchOk(`KeyPackage batch for ${sharedLabel}`);
78030
78754
  const kpData = await kpRes.json();
78031
78755
  const validReqs = [];
78032
78756
  for (const req of pending) {
78033
78757
  const kpHex = kpData[req.requesting_device_id];
78034
- if (!kpHex) {
78035
- console.warn(`[SecureChannel] No KeyPackage for ${req.requesting_device_id.slice(0, 8)}, skipping`);
78036
- continue;
78037
- }
78758
+ this._welcomeKpBackoff.recordKeyPackage(
78759
+ entry.mlsGroupId,
78760
+ req.requesting_device_id,
78761
+ Boolean(kpHex),
78762
+ req.key_package_available,
78763
+ sharedLabel
78764
+ );
78765
+ if (!kpHex) continue;
78038
78766
  const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
78039
78767
  validReqs.push({ req, kp: MLSGroupManager.deserializeKeyPackage(kpBytes) });
78040
78768
  }
@@ -78051,8 +78779,10 @@ ${baseText}`;
78051
78779
  label: `shared group ${gid.slice(0, 8)}`,
78052
78780
  welcomeFields: { conversation_group_id: gid },
78053
78781
  targets: sharedTargets,
78054
- memberDeviceIds: entry.memberDeviceIds ?? []
78782
+ memberDeviceIds: entry.memberDeviceIds ?? [],
78055
78783
  // #1226
78784
+ preHead: sharedPreHead
78785
+ // #1429
78056
78786
  });
78057
78787
  if (done > 0) {
78058
78788
  console.log(`[SecureChannel] Batched Welcome for ${done}/${validReqs.length} devices in shared group ${gid.slice(0, 8)} (epoch=${mlsGroup.epoch})`);
@@ -78086,23 +78816,49 @@ ${baseText}`;
78086
78816
  const mlsGroup = this._mlsGroups.get(`conv:${convId}`);
78087
78817
  if (!mlsGroup?.isInitialized) continue;
78088
78818
  try {
78819
+ const convLabel = `conv ${convId.slice(0, 8)}`;
78089
78820
  const pendingRes = await fetch(
78090
78821
  `${this.config.apiUrl}/api/v1/mls/groups/${convEntry.mlsGroupId}/pending-welcomes`,
78091
78822
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78092
78823
  );
78093
- if (!pendingRes.ok) continue;
78824
+ if (!pendingRes.ok) {
78825
+ this._welcomeKpBackoff.noteFetchFailure(`pending-welcomes for ${convLabel}`, pendingRes.status);
78826
+ continue;
78827
+ }
78828
+ this._welcomeKpBackoff.noteFetchOk(`pending-welcomes for ${convLabel}`);
78094
78829
  const pending = await pendingRes.json();
78830
+ if (this._welcomeKpBackoff.observePending(convEntry.mlsGroupId, pending)) {
78831
+ console.log(`[SecureChannel] ${pending.length} pending Welcome requests for conv ${convId.slice(0, 8)}`);
78832
+ }
78095
78833
  if (pending.length === 0) continue;
78096
- console.log(`[SecureChannel] ${pending.length} pending Welcome requests for conv ${convId.slice(0, 8)}`);
78097
78834
  for (const req of pending) {
78098
78835
  try {
78836
+ if (!this._welcomeKpBackoff.shouldAsk(
78837
+ convEntry.mlsGroupId,
78838
+ req.requesting_device_id,
78839
+ req.key_package_available,
78840
+ convLabel
78841
+ )) continue;
78842
+ const convPreHead = await this._welcomeCommitPreflight(convEntry.mlsGroupId, mlsGroup, convLabel);
78843
+ if (!convPreHead) break;
78099
78844
  const kpRes = await fetch(
78100
78845
  `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${req.requesting_device_id}`,
78101
78846
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78102
78847
  );
78103
- if (!kpRes.ok) continue;
78848
+ if (!kpRes.ok) {
78849
+ this._welcomeKpBackoff.noteFetchFailure(`KeyPackage batch for ${convLabel}`, kpRes.status);
78850
+ continue;
78851
+ }
78852
+ this._welcomeKpBackoff.noteFetchOk(`KeyPackage batch for ${convLabel}`);
78104
78853
  const kpData = await kpRes.json();
78105
78854
  const kpHex = kpData[req.requesting_device_id];
78855
+ this._welcomeKpBackoff.recordKeyPackage(
78856
+ convEntry.mlsGroupId,
78857
+ req.requesting_device_id,
78858
+ Boolean(kpHex),
78859
+ req.key_package_available,
78860
+ convLabel
78861
+ );
78106
78862
  if (!kpHex) continue;
78107
78863
  const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
78108
78864
  const memberKp = MLSGroupManager.deserializeKeyPackage(kpBytes);
@@ -78119,7 +78875,9 @@ ${baseText}`;
78119
78875
  // #1226: a 1:1 roster is [self, owner] — the web's shape too.
78120
78876
  memberDeviceIds: [this._persisted?.sessions?.[convId]?.ownerDeviceId].filter(
78121
78877
  (d2) => typeof d2 === "string"
78122
- )
78878
+ ),
78879
+ preHead: convPreHead
78880
+ // #1429
78123
78881
  });
78124
78882
  if (done > 0) {
78125
78883
  console.log(`[SecureChannel] Fulfilled Welcome for ${req.requesting_device_id.slice(0, 8)} in conv ${convId.slice(0, 8)}`);
@@ -78167,15 +78925,28 @@ ${baseText}`;
78167
78925
  if (!mlsGroup?.isInitialized) continue;
78168
78926
  if (chState.role !== "creator") continue;
78169
78927
  try {
78928
+ const a2aPendingLabel = `A2A ${chId.slice(0, 8)}`;
78170
78929
  const pendingRes = await fetch(
78171
78930
  `${this.config.apiUrl}/api/v1/mls/groups/${chState.mlsGroupId}/pending-welcomes`,
78172
78931
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78173
78932
  );
78174
- if (!pendingRes.ok) continue;
78933
+ if (!pendingRes.ok) {
78934
+ this._welcomeKpBackoff.noteFetchFailure(`pending-welcomes for ${a2aPendingLabel}`, pendingRes.status);
78935
+ continue;
78936
+ }
78937
+ this._welcomeKpBackoff.noteFetchOk(`pending-welcomes for ${a2aPendingLabel}`);
78175
78938
  const pending = await pendingRes.json();
78939
+ if (this._welcomeKpBackoff.observePending(chState.mlsGroupId, pending)) {
78940
+ console.log(`[SecureChannel] ${pending.length} pending A2A Welcome requests for channel ${chId.slice(0, 8)}`);
78941
+ }
78176
78942
  if (pending.length === 0) continue;
78177
- console.log(`[SecureChannel] ${pending.length} pending A2A Welcome requests for channel ${chId.slice(0, 8)}`);
78178
78943
  for (const req of pending) {
78944
+ if (!this._welcomeKpBackoff.shouldAsk(
78945
+ chState.mlsGroupId,
78946
+ req.requesting_device_id,
78947
+ req.key_package_available,
78948
+ a2aPendingLabel
78949
+ )) continue;
78179
78950
  try {
78180
78951
  const next = await this._fulfilA2AWelcome(chId, chState, mlsGroup, req);
78181
78952
  if (next === "stop") break;
@@ -78305,6 +79076,7 @@ ${baseText}`;
78305
79076
  ownerDm1to1: true,
78306
79077
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
78307
79078
  };
79079
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
78308
79080
  this.emit("message", messageText, metadata);
78309
79081
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
78310
79082
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -78486,9 +79258,20 @@ ${baseText}`;
78486
79258
  `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${req.requesting_device_id}`,
78487
79259
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78488
79260
  );
78489
- if (!kpRes.ok) return "next";
79261
+ if (!kpRes.ok) {
79262
+ this._welcomeKpBackoff.noteFetchFailure(`KeyPackage batch for ${a2aLabel}`, kpRes.status);
79263
+ return "next";
79264
+ }
79265
+ this._welcomeKpBackoff.noteFetchOk(`KeyPackage batch for ${a2aLabel}`);
78490
79266
  const kpData = await kpRes.json();
78491
79267
  const kpHex = kpData[req.requesting_device_id];
79268
+ this._welcomeKpBackoff.recordKeyPackage(
79269
+ chState.mlsGroupId,
79270
+ req.requesting_device_id,
79271
+ Boolean(kpHex),
79272
+ req.key_package_available,
79273
+ a2aLabel
79274
+ );
78492
79275
  if (!kpHex) return "next";
78493
79276
  const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
78494
79277
  const memberKp = MLSGroupManager.deserializeKeyPackage(kpBytes);
@@ -78911,6 +79694,7 @@ ${baseText}`;
78911
79694
  ownerDm1to1: true,
78912
79695
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
78913
79696
  };
79697
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
78914
79698
  this.emit("message", messageText, metadata);
78915
79699
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
78916
79700
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -79231,6 +80015,7 @@ ${baseText}`;
79231
80015
  ownerDm1to1: true,
79232
80016
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
79233
80017
  };
80018
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
79234
80019
  this.emit("message", messageText, metadata);
79235
80020
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
79236
80021
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -80251,7 +81036,7 @@ ${actionsText}`);
80251
81036
  "use strict";
80252
81037
  init_llm_response_parser();
80253
81038
  init_llm_cost();
80254
- traceStore = new AsyncLocalStorage();
81039
+ traceStore = new AsyncLocalStorage2();
80255
81040
  }
80256
81041
  });
80257
81042
  init_tool_audit = __esm2({
@@ -100999,7 +101784,7 @@ data:
100999
101784
  await init_skill_telemetry();
101000
101785
  await init_policy_enforcer();
101001
101786
  init_room_protocol();
101002
- VERSION = true ? "0.23.51" : "0.0.0-dev";
101787
+ VERSION = true ? "0.23.53" : "0.0.0-dev";
101003
101788
  }
101004
101789
  });
101005
101790
  await init_index();
@@ -102860,13 +103645,28 @@ var RoomHushState = class {
102860
103645
  return t2 !== void 0 && now < t2;
102861
103646
  }
102862
103647
  };
103648
+ async function sendDm(channel, t2, text) {
103649
+ if ((t2.conversationId || t2.groupId) && typeof channel.runForConversation === "function") {
103650
+ await channel.runForConversation(
103651
+ t2.conversationId,
103652
+ () => channel.send(text),
103653
+ t2.groupId ? { groupId: t2.groupId } : void 0
103654
+ );
103655
+ } else {
103656
+ await channel.send(text);
103657
+ }
103658
+ }
102863
103659
  var ActiveTarget = class {
102864
103660
  target = null;
102865
103661
  setRoom(roomId) {
102866
103662
  this.target = { kind: "room", roomId };
102867
103663
  }
102868
- setDm() {
102869
- this.target = { kind: "dm" };
103664
+ setDm(conversationId, groupId) {
103665
+ this.target = {
103666
+ kind: "dm",
103667
+ ...conversationId ? { conversationId } : {},
103668
+ ...groupId ? { groupId } : {}
103669
+ };
102870
103670
  }
102871
103671
  get current() {
102872
103672
  return this.target;
@@ -102886,7 +103686,7 @@ var ActiveTarget = class {
102886
103686
  if (!t2) return;
102887
103687
  try {
102888
103688
  if (t2.kind === "room") await channel.sendToRoom(t2.roomId, text);
102889
- else await channel.send(text);
103689
+ else await sendDm(channel, t2, text);
102890
103690
  log(`said to ${where}`);
102891
103691
  } catch (err) {
102892
103692
  log(`send failed to ${where}: ${err instanceof Error ? err.message : String(err)}`);
@@ -102995,7 +103795,7 @@ function wireBridge(channel, session2, target, opts = {}) {
102995
103795
  } else {
102996
103796
  log("inbound 1:1 DM from owner");
102997
103797
  }
102998
- target.setDm();
103798
+ target.setDm(metadata?.conversationId, metadata?.conversationGroupId);
102999
103799
  session2.push(text, target.snapshotReply(channel, log), { autoReplyOnText: ownerAttested });
103000
103800
  });
103001
103801
  }
@@ -103100,7 +103900,7 @@ async function main() {
103100
103900
  const info = parseInfoFlags(process.argv.slice(2));
103101
103901
  if (info.showVersion || info.showHelp) {
103102
103902
  const version2 = buildClientVersion2(
103103
- true ? "0.4.22" : void 0
103903
+ true ? "0.4.24" : void 0
103104
103904
  );
103105
103905
  if (info.showVersion) printLine(version2);
103106
103906
  if (info.showHelp) {
@@ -103139,7 +103939,7 @@ async function main() {
103139
103939
  process.exit(0);
103140
103940
  }
103141
103941
  const cfg = loadConfig(process.env, process.argv.slice(2));
103142
- logLine(`[grok-bridge] version: ${true ? "0.4.22" : "dev"}`);
103942
+ logLine(`[grok-bridge] version: ${true ? "0.4.24" : "dev"}`);
103143
103943
  mkdirSync7(cfg.workspaceDir, { recursive: true });
103144
103944
  mkdirSync7(cfg.fenceHome, { recursive: true });
103145
103945
  seedFenceCredential({
@@ -103154,7 +103954,7 @@ async function main() {
103154
103954
  agentName: cfg.agentName,
103155
103955
  platform: "node",
103156
103956
  clientVersion: buildClientVersion2(
103157
- true ? "0.4.22" : void 0
103957
+ true ? "0.4.24" : void 0
103158
103958
  )
103159
103959
  });
103160
103960
  channelRef = channel;