@agentvault/muse-bridge 0.1.26 → 0.1.28

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
@@ -94,6 +94,7 @@ import { readdir as readdir2, readFile as readFile4, writeFile as writeFile2, re
94
94
  import { join as join5 } from "node:path";
95
95
  import { randomUUID as randomUUID3 } from "node:crypto";
96
96
  import { EventEmitter } from "node:events";
97
+ import { AsyncLocalStorage } from "node:async_hooks";
97
98
  import { createServer } from "node:http";
98
99
  import { randomUUID as randomUUID4, createHash } from "node:crypto";
99
100
  import { readFileSync } from "node:fs";
@@ -103,7 +104,7 @@ import { join as join6 } from "node:path";
103
104
  import { readFile as readFile5 } from "node:fs/promises";
104
105
  import WebSocket from "ws";
105
106
  import { resolve as resolve2 } from "node:path";
106
- import { AsyncLocalStorage } from "node:async_hooks";
107
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
107
108
  import { Http2ServerRequest as Http2ServerRequest2 } from "http2";
108
109
  import { Http2ServerRequest } from "http2";
109
110
  import { Readable as Readable2 } from "stream";
@@ -11787,11 +11788,11 @@ async function joinWithFirstMatchingKp(welcomeBytes, candidates) {
11787
11788
  return null;
11788
11789
  }
11789
11790
  function ownIdentity() {
11790
- const v2 = true ? "0.23.51" : FALLBACK;
11791
+ const v2 = true ? "0.23.53" : FALLBACK;
11791
11792
  return `${PACKAGE}@${v2}`;
11792
11793
  }
11793
11794
  function buildSha() {
11794
- const raw = true ? "753de79" : "";
11795
+ const raw = true ? "3f2a933" : "";
11795
11796
  const cleaned = (raw ?? "").trim();
11796
11797
  return !cleaned || cleaned === "unknown" ? null : cleaned;
11797
11798
  }
@@ -12595,11 +12596,38 @@ function _resetCompatCacheForTest() {
12595
12596
  _agentEventFn = null;
12596
12597
  _transcriptFn = null;
12597
12598
  }
12599
+ function ownerRoutingFrom(parsed) {
12600
+ const out = {};
12601
+ if (parsed.conversation_id !== void 0) {
12602
+ if (typeof parsed.conversation_id !== "string" || !parsed.conversation_id) return "'conversation_id' must be a string";
12603
+ out.conversationId = parsed.conversation_id;
12604
+ }
12605
+ if (parsed.audience !== void 0) {
12606
+ if (parsed.audience !== "person" && parsed.audience !== "everyone") {
12607
+ return `'audience' must be "person" or "everyone"`;
12608
+ }
12609
+ out.audience = parsed.audience;
12610
+ }
12611
+ return out;
12612
+ }
12613
+ function ambiguousOwnerRequest(channel, routing) {
12614
+ const check = channel.isUntargetedOwnerAmbiguous;
12615
+ if (typeof check !== "function" || !check.call(channel, routing)) return null;
12616
+ return { status: 409, body: { ok: false, error: AMBIGUOUS_OWNER_ERROR } };
12617
+ }
12618
+ function statusOf(receipt) {
12619
+ if (receipt.ambiguous) return 409;
12620
+ return receipt.ok ? 200 : 500;
12621
+ }
12598
12622
  async function handleSendRequest(parsed, channel) {
12599
12623
  const text = parsed.text;
12600
12624
  if (!text || typeof text !== "string") {
12601
12625
  return { status: 400, body: { ok: false, error: "Missing 'text' field" } };
12602
12626
  }
12627
+ const routing = ownerRoutingFrom(parsed);
12628
+ if (typeof routing === "string") {
12629
+ return { status: 400, body: { ok: false, error: routing } };
12630
+ }
12603
12631
  try {
12604
12632
  let target;
12605
12633
  let a2aTarget = parsed.hub_address ?? parsed.a2a_address ?? parsed.a2aAddress;
@@ -12617,10 +12645,10 @@ async function handleSendRequest(parsed, channel) {
12617
12645
  const receipt2 = await channel.deliver(
12618
12646
  { kind: "owner" },
12619
12647
  { type: "attachment", text, filePath: parsed.file_path },
12620
- { topicId: parsed.topicId }
12648
+ { topicId: parsed.topicId, ...routing, refuseIfAmbiguous: true }
12621
12649
  );
12622
12650
  return {
12623
- status: receipt2.ok ? 200 : 500,
12651
+ status: statusOf(receipt2),
12624
12652
  body: {
12625
12653
  ok: receipt2.ok,
12626
12654
  destination: receipt2.destination,
@@ -12634,6 +12662,8 @@ async function handleSendRequest(parsed, channel) {
12634
12662
  target,
12635
12663
  { type: "text", text },
12636
12664
  {
12665
+ ...routing,
12666
+ refuseIfAmbiguous: true,
12637
12667
  topicId: parsed.topicId,
12638
12668
  priority: parsed.priority,
12639
12669
  metadata: {
@@ -12643,7 +12673,7 @@ async function handleSendRequest(parsed, channel) {
12643
12673
  }
12644
12674
  );
12645
12675
  return {
12646
- status: receipt.ok ? 200 : 500,
12676
+ status: statusOf(receipt),
12647
12677
  body: {
12648
12678
  ok: receipt.ok,
12649
12679
  destination: receipt.destination,
@@ -12658,6 +12688,10 @@ async function handleActionRequest(parsed, channel) {
12658
12688
  if (!parsed.action || typeof parsed.action !== "string") {
12659
12689
  return { status: 400, body: { ok: false, error: "Missing 'action' field" } };
12660
12690
  }
12691
+ const routing = ownerRoutingFrom(parsed);
12692
+ if (typeof routing === "string") {
12693
+ return { status: 400, body: { ok: false, error: routing } };
12694
+ }
12661
12695
  try {
12662
12696
  const confirmation = {
12663
12697
  action: parsed.action,
@@ -12667,12 +12701,10 @@ async function handleActionRequest(parsed, channel) {
12667
12701
  estimated_cost: parsed.estimated_cost
12668
12702
  };
12669
12703
  const target = parsed.room_id && typeof parsed.room_id === "string" ? { kind: "room", roomId: parsed.room_id } : { kind: "owner" };
12670
- const receipt = await channel.deliver(
12671
- target,
12672
- { type: "action_confirmation", confirmation }
12673
- );
12704
+ const content = { type: "action_confirmation", confirmation };
12705
+ const receipt = await channel.deliver(target, content, { ...routing, refuseIfAmbiguous: true });
12674
12706
  return {
12675
- status: receipt.ok ? 200 : 500,
12707
+ status: statusOf(receipt),
12676
12708
  body: {
12677
12709
  ok: receipt.ok,
12678
12710
  destination: receipt.destination,
@@ -12697,6 +12729,12 @@ async function handleDecisionRequest(parsed, channel) {
12697
12729
  return { status: 400, body: { ok: false, error: "Each option must have 'option_id' and 'label'" } };
12698
12730
  }
12699
12731
  }
12732
+ const routing = ownerRoutingFrom(parsed);
12733
+ if (typeof routing === "string") {
12734
+ return { status: 400, body: { ok: false, error: routing } };
12735
+ }
12736
+ const ambiguous = ambiguousOwnerRequest(channel, routing);
12737
+ if (ambiguous) return ambiguous;
12700
12738
  try {
12701
12739
  const decision_id = await channel.sendDecisionRequest({
12702
12740
  title,
@@ -12705,7 +12743,7 @@ async function handleDecisionRequest(parsed, channel) {
12705
12743
  context_refs: parsed.context_refs,
12706
12744
  deadline: parsed.deadline,
12707
12745
  auto_action: parsed.auto_action
12708
- });
12746
+ }, routing);
12709
12747
  return { status: 200, body: { ok: true, decision_id } };
12710
12748
  } catch (err) {
12711
12749
  return { status: 500, body: { ok: false, error: String(err) } };
@@ -13240,7 +13278,7 @@ async function _handleInbound(params) {
13240
13278
  core.error?.(`[AgentVault] session record failed: ${String(err)}`);
13241
13279
  }
13242
13280
  });
13243
- await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
13281
+ await channel.runForConversation(metadata.conversationId, () => core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
13244
13282
  ctx: ctxPayload,
13245
13283
  cfg,
13246
13284
  dispatcherOptions: {
@@ -13257,7 +13295,7 @@ async function _handleInbound(params) {
13257
13295
  }
13258
13296
  },
13259
13297
  replyOptions: {}
13260
- });
13298
+ }), { groupId: metadata.conversationGroupId });
13261
13299
  }
13262
13300
  function resolveBaseUrl(options) {
13263
13301
  const host = options?.host ?? "127.0.0.1";
@@ -18333,7 +18371,7 @@ function reportSkillInvocation(opts) {
18333
18371
  spanBuffer.push(span);
18334
18372
  return span;
18335
18373
  }
18336
- 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_exports2, 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;
18374
+ 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_exports2, 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;
18337
18375
  var init_dist = __esm({
18338
18376
  async "../plugin/dist/index.js"() {
18339
18377
  "use strict";
@@ -18386,6 +18424,12 @@ var init_dist = __esm({
18386
18424
  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";
18387
18425
  }
18388
18426
  });
18427
+ init_owner_routing = __esm2({
18428
+ "src/owner-routing.ts"() {
18429
+ "use strict";
18430
+ 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.`;
18431
+ }
18432
+ });
18389
18433
  init_envelope_text = __esm2({
18390
18434
  "src/envelope-text.ts"() {
18391
18435
  "use strict";
@@ -70917,6 +70961,119 @@ var init_dist = __esm({
70917
70961
  ACTIONS = /* @__PURE__ */ new Set(["approve", "deny", "defer", "cancel"]);
70918
70962
  }
70919
70963
  });
70964
+ init_welcome_kp_backoff = __esm2({
70965
+ "src/welcome-kp-backoff.ts"() {
70966
+ "use strict";
70967
+ KP_BACKOFF_INITIAL_MS = 10 * 6e4;
70968
+ KP_BACKOFF_MAX_MS = 60 * 6e4;
70969
+ KP_RACE_RETRY_MS = 6e4;
70970
+ KP_RACE_RETRY_LIMIT = 3;
70971
+ consoleLogger = {
70972
+ warn: (m2) => console.warn(m2),
70973
+ info: (m2) => console.log(m2)
70974
+ };
70975
+ short = (id) => id.slice(0, 8);
70976
+ WelcomeKeyPackageBackoff = class {
70977
+ constructor(log = consoleLogger) {
70978
+ this.log = log;
70979
+ }
70980
+ log;
70981
+ entries = /* @__PURE__ */ new Map();
70982
+ pendingSig = /* @__PURE__ */ new Map();
70983
+ failing = /* @__PURE__ */ new Set();
70984
+ key(groupId, deviceId) {
70985
+ return `${groupId}:${deviceId}`;
70986
+ }
70987
+ /**
70988
+ * Record this pull's pending list for a group. Returns true when the set of
70989
+ * requests differs from the previous pull's — the caller logs its "N pending"
70990
+ * line only then. Backoffs for devices whose request is gone are dropped.
70991
+ */
70992
+ observePending(groupId, pending) {
70993
+ const sig = pending.map((r2) => r2.id).sort().join(",");
70994
+ const changed = this.pendingSig.get(groupId) !== sig;
70995
+ if (pending.length === 0) this.pendingSig.delete(groupId);
70996
+ else this.pendingSig.set(groupId, sig);
70997
+ const live = new Set(pending.map((r2) => r2.requesting_device_id));
70998
+ const prefix = `${groupId}:`;
70999
+ for (const k2 of [...this.entries.keys()]) {
71000
+ if (k2.startsWith(prefix) && !live.has(k2.slice(prefix.length))) this.entries.delete(k2);
71001
+ }
71002
+ return changed && pending.length > 0;
71003
+ }
71004
+ /** Should this pull ask the batch for this device's KeyPackage? */
71005
+ shouldAsk(groupId, deviceId, available, label, now = Date.now()) {
71006
+ const k2 = this.key(groupId, deviceId);
71007
+ const entry = this.entries.get(k2);
71008
+ if (available === false) {
71009
+ if (!entry) {
71010
+ this.entries.set(k2, { untilMs: now + KP_BACKOFF_INITIAL_MS, delayMs: KP_BACKOFF_INITIAL_MS, lastAvailable: false, raceRetries: 0 });
71011
+ this.log.warn(
71012
+ `[SecureChannel] No KeyPackage for ${short(deviceId)} in ${label} \u2014 waiting for the device to come back online; not asking again until it publishes one`
71013
+ );
71014
+ } else {
71015
+ entry.lastAvailable = false;
71016
+ }
71017
+ return false;
71018
+ }
71019
+ if (!entry) return true;
71020
+ if (available === true && entry.lastAvailable === false) return true;
71021
+ return now >= entry.untilMs;
71022
+ }
71023
+ /** The outcome of an ask. `found` = the batch returned a KeyPackage. */
71024
+ recordKeyPackage(groupId, deviceId, found, available, label, now = Date.now()) {
71025
+ const k2 = this.key(groupId, deviceId);
71026
+ const entry = this.entries.get(k2);
71027
+ if (found) {
71028
+ if (entry) {
71029
+ this.entries.delete(k2);
71030
+ this.log.info(`[SecureChannel] KeyPackage for ${short(deviceId)} is available again in ${label} \u2014 admitting`);
71031
+ }
71032
+ return;
71033
+ }
71034
+ const raced = available === true && (entry?.raceRetries ?? 0) < KP_RACE_RETRY_LIMIT;
71035
+ if (!entry) {
71036
+ if (raced) {
71037
+ this.entries.set(k2, { untilMs: now + KP_RACE_RETRY_MS, delayMs: 0, lastAvailable: available, raceRetries: 1 });
71038
+ this.log.warn(
71039
+ `[SecureChannel] No KeyPackage for ${short(deviceId)} in ${label} although the server listed one (claimed elsewhere?) \u2014 retrying in ${KP_RACE_RETRY_MS / 1e3} s`
71040
+ );
71041
+ return;
71042
+ }
71043
+ this.entries.set(k2, { untilMs: now + KP_BACKOFF_INITIAL_MS, delayMs: KP_BACKOFF_INITIAL_MS, lastAvailable: available, raceRetries: 0 });
71044
+ this.log.warn(
71045
+ `[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)`
71046
+ );
71047
+ return;
71048
+ }
71049
+ entry.lastAvailable = available;
71050
+ if (raced) {
71051
+ entry.raceRetries += 1;
71052
+ entry.untilMs = now + KP_RACE_RETRY_MS;
71053
+ return;
71054
+ }
71055
+ entry.raceRetries = available === true ? entry.raceRetries : 0;
71056
+ entry.delayMs = entry.delayMs === 0 ? KP_BACKOFF_INITIAL_MS : Math.min(entry.delayMs * 2, KP_BACKOFF_MAX_MS);
71057
+ entry.untilMs = now + entry.delayMs;
71058
+ }
71059
+ /** A non-OK response for `scope`: warn once until it recovers. */
71060
+ noteFetchFailure(scope, status) {
71061
+ if (this.failing.has(scope)) return;
71062
+ this.failing.add(scope);
71063
+ this.log.warn(`[SecureChannel] ${scope} failed (${status}) \u2014 will retry each pull; logging once until it recovers`);
71064
+ }
71065
+ noteFetchOk(scope) {
71066
+ if (!this.failing.delete(scope)) return;
71067
+ this.log.info(`[SecureChannel] ${scope} recovered`);
71068
+ }
71069
+ /** Test/diagnostic view. */
71070
+ backoffFor(groupId, deviceId) {
71071
+ const e = this.entries.get(this.key(groupId, deviceId));
71072
+ return e ? { untilMs: e.untilMs, delayMs: e.delayMs } : void 0;
71073
+ }
71074
+ };
71075
+ }
71076
+ });
70920
71077
  history_backup_client_exports = {};
70921
71078
  __export2(history_backup_client_exports, {
70922
71079
  HISTORY_RESTORE_RESPONSE_MAX_BYTES: () => HISTORY_RESTORE_RESPONSE_MAX_BYTES,
@@ -71217,6 +71374,7 @@ var init_dist = __esm({
71217
71374
  init_http_handlers = __esm2({
71218
71375
  "src/http-handlers.ts"() {
71219
71376
  "use strict";
71377
+ init_owner_routing();
71220
71378
  }
71221
71379
  });
71222
71380
  mcp_proxy_helpers_exports = {};
@@ -71246,6 +71404,7 @@ var init_dist = __esm({
71246
71404
  async "src/channel.ts"() {
71247
71405
  "use strict";
71248
71406
  init_abstention();
71407
+ init_owner_routing();
71249
71408
  init_envelope_text();
71250
71409
  init_mls_commit_classify();
71251
71410
  init_room_protocol();
@@ -71265,6 +71424,7 @@ var init_dist = __esm({
71265
71424
  init_history_backup_scheduler();
71266
71425
  await init_history_recovery_code();
71267
71426
  init_decision_reply();
71427
+ init_welcome_kp_backoff();
71268
71428
  ROOM_AGENT_TYPES = /* @__PURE__ */ new Set([
71269
71429
  "message",
71270
71430
  "text",
@@ -71295,6 +71455,10 @@ var init_dist = __esm({
71295
71455
  OUTBOUND_DEDUPE_TYPES = /* @__PURE__ */ new Set(["text", "status_alert", "artifact", "attachment"]);
71296
71456
  RETRY_CANDIDATE_TTL_MS = 6e4;
71297
71457
  RETRY_CANDIDATE_MAX = 32;
71458
+ _turnConversation = new AsyncLocalStorage();
71459
+ PERSON_INVOLVED_WINDOW_MS = 5 * 6e4;
71460
+ ATTESTED_INBOUND_MAX = 64;
71461
+ UNMAPPED_RECONCILE_COOLDOWN_MS = 6e4;
71298
71462
  TOPIC_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
71299
71463
  ROOM_FULFIL_COOLDOWN_MS = 6e4;
71300
71464
  SecureChannel = class _SecureChannel extends EventEmitter {
@@ -71371,6 +71535,8 @@ var init_dist = __esm({
71371
71535
  _mlsGroups = /* @__PURE__ */ new Map();
71372
71536
  /** `${mlsGroupId}:${deviceId}` -> last re-admit ms (#1171). */
71373
71537
  _roomFulfilCooldown = /* @__PURE__ */ new Map();
71538
+ /** #1428: per (group, device) KeyPackage backoff for the pending-Welcome pulls. */
71539
+ _welcomeKpBackoff = new WelcomeKeyPackageBackoff();
71374
71540
  /** Maps conversationId -> conversation_group_id for shared 1:1 MLS groups */
71375
71541
  _sessionGroupIds = /* @__PURE__ */ new Map();
71376
71542
  /** Consecutive MLS decrypt failure count per group key for epoch recovery. */
@@ -71533,6 +71699,31 @@ ${text}`;
71533
71699
  _lastIncomingTopics = /* @__PURE__ */ new Map();
71534
71700
  /** Room ID from the most recent inbound room message — used as fallback for HTTP /send replies. */
71535
71701
  _lastInboundRoomId;
71702
+ /**
71703
+ * #1418: the most recent owner 1:1 message that reached the agent — the
71704
+ * person involved in whatever the agent says next without naming a
71705
+ * conversation (see `_involvedPerson`). In memory only: after a restart
71706
+ * there is no trigger, so untargeted content goes to the primary person.
71707
+ */
71708
+ _lastInboundDm;
71709
+ /** #1418: turns in progress (`runForConversation`). */
71710
+ _activeTurns = /* @__PURE__ */ new Set();
71711
+ /**
71712
+ * #1418: recent owner 1:1 messages that decrypted, keyed by
71713
+ * conversation|group — evidence of which conversation, group and browser
71714
+ * belong together (one person). In memory only, bounded.
71715
+ */
71716
+ _attestedInbound = /* @__PURE__ */ new Map();
71717
+ /** #1418: per UNMAPPED group (or conversation), the last time it asked for a reconcile. */
71718
+ _unmappedReconcileAt = /* @__PURE__ */ new Map();
71719
+ /**
71720
+ * #1418: 1:1 groups joined by a Welcome IN THIS PROCESS while no
71721
+ * conversation mapped them — a person who has not been learned yet, counted
71722
+ * as one until the next successful reconcile. Persisted husks never are.
71723
+ */
71724
+ _welcomedUnmapped = /* @__PURE__ */ new Map();
71725
+ /** #1418: what the last SUCCESSFUL reconcile reported live, and when it started. */
71726
+ _lastReconcile;
71536
71727
  /** Rate-limit: last resync_request timestamp per conversation (5-min cooldown). */
71537
71728
  _lastResyncRequest = /* @__PURE__ */ new Map();
71538
71729
  /** Dedup: last room/group welcome self-heal request timestamp per group (30s window). */
@@ -72138,6 +72329,379 @@ ${text}`;
72138
72329
  if (this._persisted?.groupId) known.add(this._persisted.groupId);
72139
72330
  return known;
72140
72331
  }
72332
+ // --- #1418: only the person involved ----------------------------------
72333
+ /**
72334
+ * Run `fn` as the work an inbound 1:1 message from `conversationId`
72335
+ * triggered. Untargeted owner content sent while it runs — from inside its
72336
+ * async call chain, or from anywhere while it is the only turn in progress —
72337
+ * goes to that conversation's person only.
72338
+ *
72339
+ * `opts.groupId` is the group that message DECRYPTED under
72340
+ * (`metadata.conversationGroupId`). Pass it: it outranks the local
72341
+ * conversation→group map, which can be stale, and it is all there is for a
72342
+ * frame whose conversation is not mapped yet. With neither an id nor a
72343
+ * group, `fn` runs unchanged.
72344
+ */
72345
+ async runForConversation(conversationId, fn, opts) {
72346
+ const groupId = typeof opts?.groupId === "string" && opts.groupId ? opts.groupId : void 0;
72347
+ if (!conversationId && !groupId) return fn();
72348
+ const store = { convId: conversationId || void 0, groupId, ended: false };
72349
+ this._activeTurns.add(store);
72350
+ try {
72351
+ return await _turnConversation.run(store, fn);
72352
+ } finally {
72353
+ store.ended = true;
72354
+ store.endedAt = Date.now();
72355
+ this._activeTurns.delete(store);
72356
+ }
72357
+ }
72358
+ /**
72359
+ * The turn this call chain belongs to (#1418) — running, or ended but
72360
+ * still within the window in which work it left behind is for its person.
72361
+ * `"expired"` once that window is over: the work is proactive now.
72362
+ */
72363
+ _currentTurn() {
72364
+ const store = _turnConversation.getStore();
72365
+ if (!store) return void 0;
72366
+ if (!store.ended) return store;
72367
+ return Date.now() - (store.endedAt ?? 0) < PERSON_INVOLVED_WINDOW_MS ? store : "expired";
72368
+ }
72369
+ /**
72370
+ * Record an owner 1:1 message that just decrypted (#1418).
72371
+ *
72372
+ * Always kept as evidence of which conversation, group and browser belong
72373
+ * together (see `_dmPeople`). It makes its person "the person involved" only
72374
+ * when it is RECENT by the server's `createdAt`: a frame replayed from
72375
+ * backlog on reconnect is not something anyone is waiting on an answer to.
72376
+ */
72377
+ _noteInboundDm(convId, groupId, opts = {}) {
72378
+ if (!convId && !groupId) return;
72379
+ const now = Date.now();
72380
+ const sentAt = opts.createdAt ? Date.parse(opts.createdAt) : NaN;
72381
+ const at = Number.isFinite(sentAt) ? Math.min(now, sentAt) : now;
72382
+ const sender = opts.senderDeviceId && opts.senderDeviceId !== this._deviceId ? opts.senderDeviceId : void 0;
72383
+ const key = `${convId ?? ""}|${groupId ?? ""}|${sender ?? ""}`;
72384
+ const prior = this._attestedInbound.get(key);
72385
+ this._attestedInbound.delete(key);
72386
+ this._attestedInbound.set(key, { convId, groupId, senderDeviceId: sender, at: Math.max(prior?.at ?? 0, at) });
72387
+ while (this._attestedInbound.size > ATTESTED_INBOUND_MAX) {
72388
+ const oldest = this._attestedInbound.keys().next().value;
72389
+ if (oldest === void 0) break;
72390
+ this._attestedInbound.delete(oldest);
72391
+ }
72392
+ if (this._lastInboundDm && this._lastInboundDm.at > at) return;
72393
+ this._lastInboundDm = {
72394
+ convId,
72395
+ groupId: groupId ?? (convId ? this._sessionGroupIds.get(convId) : void 0),
72396
+ at
72397
+ };
72398
+ }
72399
+ /** The group `convId`'s most recent inbound decrypted under, if any. */
72400
+ _attestedGroupOf(convId) {
72401
+ if (!convId) return void 0;
72402
+ let gid;
72403
+ for (const a2 of this._attestedInbound.values()) {
72404
+ if (a2.convId === convId && a2.groupId) gid = a2.groupId;
72405
+ }
72406
+ return gid;
72407
+ }
72408
+ /** Does some mapped conversation point at `groupId`? */
72409
+ _isMappedGroup(groupId) {
72410
+ for (const gid of this._sessionGroupIds.values()) if (gid === groupId) return true;
72411
+ return false;
72412
+ }
72413
+ /**
72414
+ * An owner message decrypted under a group no mapped conversation points at
72415
+ * (#1418): the map is stale — a Welcome landed before its conversation was
72416
+ * learned, or a conversation was recreated. Re-resolve it from the server.
72417
+ * Fire-and-forget and rate-limited per group: never awaited on the receive
72418
+ * or Welcome path, so it can never hold up MLS processing.
72419
+ */
72420
+ _reconcileForUnmappedGroup(groupId) {
72421
+ if (!groupId || this._isMappedGroup(groupId)) return;
72422
+ this._reconcileSoon(`g:${groupId}`);
72423
+ }
72424
+ /** The same for a Double Ratchet message on a conversation the map does not know. */
72425
+ _reconcileForUnmappedConversation(convId) {
72426
+ if (!convId || this._sessionGroupIds.size === 0 || this._sessionGroupIds.has(convId)) return;
72427
+ this._reconcileSoon(`c:${convId}`);
72428
+ }
72429
+ _reconcileSoon(key) {
72430
+ const now = Date.now();
72431
+ if (now - (this._unmappedReconcileAt.get(key) ?? 0) < UNMAPPED_RECONCILE_COOLDOWN_MS) return;
72432
+ this._unmappedReconcileAt.set(key, now);
72433
+ void Promise.resolve().then(() => this._reconcileConversationGroups()).catch((err) => console.warn("[SecureChannel] Conversation-group reconcile (unmapped group) failed:", err));
72434
+ }
72435
+ /** A conversation of `groupId`, for an MLS frame that named only its group. */
72436
+ _conversationOfGroup(groupId) {
72437
+ if (!groupId) return void 0;
72438
+ if (this._primaryConversationId && this._sessionGroupIds.get(this._primaryConversationId) === groupId) {
72439
+ return this._primaryConversationId;
72440
+ }
72441
+ for (const [convId, gid] of this._sessionGroupIds) {
72442
+ if (gid === groupId) return convId;
72443
+ }
72444
+ return void 0;
72445
+ }
72446
+ /** Is `convId` one of this agent's own 1:1 conversations (never a room's or an A2A channel's)? */
72447
+ _isOwnDmConversation(convId) {
72448
+ if (this._isNonDmConversation(convId)) return false;
72449
+ return this._sessions.has(convId) || this._sessionGroupIds.has(convId) || !!this._persisted?.mlsConversations?.[convId] || convId === this._primaryConversationId;
72450
+ }
72451
+ /**
72452
+ * #1418 — the PEOPLE this agent has a 1:1 with, or `undefined` when it
72453
+ * cannot tell (no conversation is mapped: then it behaves as before #1418).
72454
+ *
72455
+ * People, not groups. Since #1399 one person has one group, but an agent
72456
+ * also keeps joined groups that are nobody's any more — husks of deleted or
72457
+ * recreated conversations. Measured 2026-10-24: wren held 13 joined groups
72458
+ * for 1 mapped, loopita 2 for 1, wowzer 2 for 1. Counting joined groups made
72459
+ * all three single-person agents look like several people, and their
72460
+ * replies could go only to a dead group.
72461
+ *
72462
+ * So a person is built from the conversations the server mapped, joined by
72463
+ * evidence that two things are the same person:
72464
+ * - the same group (a legacy group shared by several people cannot be told
72465
+ * apart, so it stays one — exactly the pre-#1418 behaviour);
72466
+ * - the same owner browser (a browser belongs to exactly one person);
72467
+ * - a message that decrypted under a group, from a conversation and browser.
72468
+ * A joined group nothing maps and nobody has spoken in is not a person. A
72469
+ * message on an unmapped group from a browser nobody knows IS someone —
72470
+ * that fails closed, toward "only them".
72471
+ */
72472
+ _dmPeople() {
72473
+ if (this._sessionGroupIds.size === 0) return void 0;
72474
+ const parent2 = /* @__PURE__ */ new Map();
72475
+ const add4 = (x2) => {
72476
+ if (!parent2.has(x2)) parent2.set(x2, x2);
72477
+ };
72478
+ const find = (x2) => {
72479
+ let root3 = x2;
72480
+ while (parent2.get(root3) !== root3) root3 = parent2.get(root3);
72481
+ return root3;
72482
+ };
72483
+ const union2 = (a2, b2) => {
72484
+ if (!a2 || !b2) return;
72485
+ add4(a2);
72486
+ add4(b2);
72487
+ const ra2 = find(a2), rb = find(b2);
72488
+ if (ra2 !== rb) parent2.set(ra2, rb);
72489
+ };
72490
+ const ownerOf = (convId) => {
72491
+ const owner = this._sessions.get(convId)?.ownerDeviceId ?? this._persisted?.sessions?.[convId]?.ownerDeviceId;
72492
+ return owner ? `d:${owner}` : void 0;
72493
+ };
72494
+ for (const [convId, gid] of this._sessionGroupIds) {
72495
+ add4(`c:${convId}`);
72496
+ union2(`c:${convId}`, `g:${gid}`);
72497
+ union2(`c:${convId}`, ownerOf(convId));
72498
+ }
72499
+ const primary = this._primaryConversationId || this._persisted?.primaryConversationId;
72500
+ const primaryGid = this._persisted?.groupId;
72501
+ if (primary && primaryGid && (parent2.has(`c:${primary}`) || parent2.has(`g:${primaryGid}`))) {
72502
+ union2(`c:${primary}`, `g:${primaryGid}`);
72503
+ }
72504
+ for (const gid of this._welcomedUnmapped.keys()) add4(`g:${gid}`);
72505
+ const records = [...this._attestedInbound.values()].map((a2) => ({
72506
+ a: a2,
72507
+ nodes: [
72508
+ a2.convId ? `c:${a2.convId}` : void 0,
72509
+ a2.groupId ? `g:${a2.groupId}` : void 0,
72510
+ a2.senderDeviceId ? `d:${a2.senderDeviceId}` : void 0
72511
+ ].filter((n2) => !!n2)
72512
+ }));
72513
+ const placed = /* @__PURE__ */ new Set();
72514
+ const place = (i2) => {
72515
+ const { a: a2, nodes } = records[i2];
72516
+ for (const n2 of nodes) add4(n2);
72517
+ for (const n2 of nodes.slice(1)) union2(nodes[0], n2);
72518
+ if (a2.convId && this._sessionGroupIds.has(a2.convId)) union2(`c:${a2.convId}`, ownerOf(a2.convId));
72519
+ placed.add(i2);
72520
+ };
72521
+ const linkKnown = () => {
72522
+ for (let progress = true; progress; ) {
72523
+ progress = false;
72524
+ records.forEach((r2, i2) => {
72525
+ if (!placed.has(i2) && r2.nodes.some((n2) => parent2.has(n2))) {
72526
+ place(i2);
72527
+ progress = true;
72528
+ }
72529
+ });
72530
+ }
72531
+ };
72532
+ linkKnown();
72533
+ records.forEach((r2, i2) => {
72534
+ if (!placed.has(i2) && this._mayBeNewPerson(r2.a)) place(i2);
72535
+ });
72536
+ linkKnown();
72537
+ const roots = /* @__PURE__ */ new Set();
72538
+ for (const node2 of parent2.keys()) {
72539
+ if (!node2.startsWith("d:")) roots.add(find(node2));
72540
+ }
72541
+ return {
72542
+ count: roots.size,
72543
+ keyOf: (convId, groupId) => {
72544
+ if (convId && parent2.has(`c:${convId}`)) return find(`c:${convId}`);
72545
+ if (groupId && parent2.has(`g:${groupId}`)) return find(`g:${groupId}`);
72546
+ return void 0;
72547
+ }
72548
+ };
72549
+ }
72550
+ /**
72551
+ * May this inbound evidence stand for a person nobody knows yet (#1418)?
72552
+ * Only if it was sent recently, and the last successful reconcile — when it
72553
+ * started after the message was sent — listed its conversation or group.
72554
+ */
72555
+ _mayBeNewPerson(a2) {
72556
+ if (Date.now() - a2.at >= PERSON_INVOLVED_WINDOW_MS) return false;
72557
+ const r2 = this._lastReconcile;
72558
+ if (r2 && a2.at <= r2.at && !(a2.convId && r2.convs.has(a2.convId)) && !(a2.groupId && r2.groups.has(a2.groupId))) return false;
72559
+ return true;
72560
+ }
72561
+ /** More than one person has a 1:1 with this agent (#1418). Unknown counts as one: the old behaviour. */
72562
+ _isMultiPerson() {
72563
+ return (this._dmPeople()?.count ?? 0) > 1;
72564
+ }
72565
+ /**
72566
+ * The group a turn's message decrypted under, for placing the turn when its
72567
+ * conversation is not mapped (a mapped conversation already names its person).
72568
+ */
72569
+ _turnGroup(turn) {
72570
+ return turn.groupId ?? this._attestedGroupOf(turn.convId);
72571
+ }
72572
+ /** The people with a 1:1 turn in progress, one turn each (#1418). */
72573
+ _activeTurnPeople() {
72574
+ const people = this._dmPeople();
72575
+ const out = /* @__PURE__ */ new Map();
72576
+ for (const turn of this._activeTurns) {
72577
+ if (turn.convId && (turn.groupId ? this._isNonDmConversation(turn.convId) : !this._isOwnDmConversation(turn.convId))) continue;
72578
+ const gid = this._turnGroup(turn);
72579
+ const key = people?.keyOf(turn.convId, gid) ?? (gid ? `g:${gid}` : `c:${turn.convId}`);
72580
+ if (!out.has(key)) out.set(key, turn);
72581
+ }
72582
+ return out;
72583
+ }
72584
+ /**
72585
+ * The person an untargeted owner message is for (#1418), in order:
72586
+ *
72587
+ * 1. the turn this call chain belongs to — always, and only, that
72588
+ * conversation, reached on the group its message decrypted under. A turn
72589
+ * never borrows another conversation's turn: one it cannot place fails
72590
+ * closed to its own conversation. Work the turn left running (a timer, a
72591
+ * dispatch orphaned by the turn budget) stays with that person for
72592
+ * `PERSON_INVOLVED_WINDOW_MS` after the turn, then is proactive (4);
72593
+ * 2. with no turn context (a skill's HTTP call), the one person with a turn
72594
+ * in progress;
72595
+ * 3. the last inbound 1:1 message, if it is recent — a reply produced in
72596
+ * response to it;
72597
+ * 4. otherwise the content is proactive: the PRIMARY conversation's person.
72598
+ */
72599
+ _involvedPerson() {
72600
+ const person = (convId, groupId, reason) => ({
72601
+ convId,
72602
+ groupId: groupId ?? this._attestedGroupOf(convId) ?? (convId ? this._sessionGroupIds.get(convId) : void 0),
72603
+ reason
72604
+ });
72605
+ const turn = this._currentTurn();
72606
+ if (turn && turn !== "expired") {
72607
+ return person(turn.convId ?? this._conversationOfGroup(turn.groupId), turn.groupId, turn.ended ? "outlived-turn" : "turn");
72608
+ }
72609
+ if (turn === "expired") return this._primaryPerson();
72610
+ const active = this._activeTurnPeople();
72611
+ if (active.size === 1) {
72612
+ const [only] = active.values();
72613
+ return person(only.convId ?? this._conversationOfGroup(only.groupId), only.groupId, "active-turn");
72614
+ }
72615
+ const last = this._lastInboundDm;
72616
+ if (active.size === 0 && last && Date.now() - last.at < PERSON_INVOLVED_WINDOW_MS) {
72617
+ return person(last.convId ?? this._conversationOfGroup(last.groupId), last.groupId, "last-inbound");
72618
+ }
72619
+ return this._primaryPerson();
72620
+ }
72621
+ /** The PRIMARY conversation's person — where proactive content goes. */
72622
+ _primaryPerson() {
72623
+ const primary = this._primaryConversationId || this._persisted?.primaryConversationId || void 0;
72624
+ const primaryGroup = (primary ? this._sessionGroupIds.get(primary) : void 0) ?? this._persisted?.groupId;
72625
+ return {
72626
+ convId: primary,
72627
+ groupId: primaryGroup ?? this._attestedGroupOf(primary),
72628
+ reason: "primary"
72629
+ };
72630
+ }
72631
+ /**
72632
+ * #1418 — would an untargeted owner send right now have to GUESS between
72633
+ * people? True only with no turn context while two or more people have a
72634
+ * turn in progress. The local HTTP API refuses such a request (409) and
72635
+ * asks for a conversation instead of picking one.
72636
+ */
72637
+ isUntargetedOwnerAmbiguous(options) {
72638
+ if (options?.conversationId !== void 0 || options?.audience === "everyone") return false;
72639
+ if (this._currentTurn()) return false;
72640
+ if (!this._isMultiPerson()) return false;
72641
+ return this._activeTurnPeople().size > 1;
72642
+ }
72643
+ /**
72644
+ * Who an UNTARGETED owner send reaches, or `null` for "every session, as
72645
+ * before". `null` when the caller chose `audience: "everyone"`, and when the
72646
+ * agent has one person (or cannot tell how many) — nothing to choose
72647
+ * between, so its recipients are exactly what they always were.
72648
+ */
72649
+ _untargetedAudience(options) {
72650
+ if (options?.conversationId !== void 0) return null;
72651
+ if (options?.audience === "everyone") return null;
72652
+ if (!this._isMultiPerson()) return null;
72653
+ return this._involvedPerson();
72654
+ }
72655
+ /** A stable name for who an untargeted owner send reaches right now, or undefined when that is "everyone, as before". */
72656
+ _audienceTag(options) {
72657
+ if (options?.audience === "everyone") return "everyone";
72658
+ const person = this._untargetedAudience(options);
72659
+ return person ? `person:${person.groupId ?? person.convId ?? ""}` : void 0;
72660
+ }
72661
+ /** Does conversation `convId` belong to `person`? A conversation nothing ties to them fails closed. */
72662
+ _isPersonsConversation(person, convId) {
72663
+ if (convId === person.convId) return true;
72664
+ const gid = this._sessionGroupIds.get(convId);
72665
+ if (gid !== void 0 && gid === person.groupId) return true;
72666
+ const people = this._dmPeople();
72667
+ const theirs = people?.keyOf(person.convId, person.groupId);
72668
+ return theirs !== void 0 && people.keyOf(convId, gid) === theirs;
72669
+ }
72670
+ /**
72671
+ * #1418: the Double Ratchet sessions an owner-bound FILE (attachment or
72672
+ * artifact) goes to, bucketed by the conversation its blob is uploaded
72673
+ * under. The blob is uploaded under a conversation of the person who gets
72674
+ * it — the backend only lets that conversation's participants download it —
72675
+ * so an explicit "everyone" uploads once per person.
72676
+ */
72677
+ _ownerFileRecipients(routing) {
72678
+ const roomConvIds = /* @__PURE__ */ new Set();
72679
+ for (const room of Object.values(this._persisted?.rooms ?? {})) {
72680
+ for (const cid of room.conversationIds ?? []) roomConvIds.add(cid);
72681
+ }
72682
+ const live = [...this._sessions].filter(([convId, session]) => session.activated && !roomConvIds.has(convId)).map(([convId]) => convId);
72683
+ const person = routing?.conversationId !== void 0 ? { convId: routing.conversationId, groupId: this._sessionGroupIds.get(routing.conversationId), reason: "target" } : this._untargetedAudience(routing);
72684
+ if (person) {
72685
+ const convIds = live.filter((convId) => this._isPersonsConversation(person, convId));
72686
+ const uploadConvId = person.convId ?? convIds[0];
72687
+ return uploadConvId && convIds.length > 0 ? [{ uploadConvId, convIds }] : [];
72688
+ }
72689
+ if (live.length === 0) return [];
72690
+ if (!this._isMultiPerson()) {
72691
+ return [{ uploadConvId: this._primaryConversationId, convIds: live }];
72692
+ }
72693
+ const people = this._dmPeople();
72694
+ const buckets = /* @__PURE__ */ new Map();
72695
+ for (const convId of live) {
72696
+ const gid = this._sessionGroupIds.get(convId);
72697
+ const key = people?.keyOf(convId, gid) ?? gid ?? `c:${convId}`;
72698
+ buckets.set(key, [...buckets.get(key) ?? [], convId]);
72699
+ }
72700
+ return [...buckets.values()].map((convIds) => ({
72701
+ uploadConvId: convIds.includes(this._primaryConversationId) ? this._primaryConversationId : convIds[0],
72702
+ convIds
72703
+ }));
72704
+ }
72141
72705
  /** The group a DM history entry belongs to (see the forms above). */
72142
72706
  _dmEntryScope(entry, known) {
72143
72707
  const t2 = entry.topicId ?? "";
@@ -72709,6 +73273,7 @@ ${text}`;
72709
73273
  Promise.resolve().then(() => (init_openclaw_compat(), openclaw_compat_exports)).then(({ requestHeartbeatNow: requestHeartbeatNow2 }) => requestHeartbeatNow2({ reason: "channel-send" })).catch(() => {
72710
73274
  });
72711
73275
  const targetConvId = options?.conversationId;
73276
+ const audience = this._untargetedAudience(options);
72712
73277
  const explicitTopicId = options?.topicId;
72713
73278
  const targeted = targetConvId !== void 0;
72714
73279
  const frameHistoryContexts = [];
@@ -72747,7 +73312,7 @@ ${text}`;
72747
73312
  if (this._persisted?.mlsGroups && this._state === "ready" && this._ws) {
72748
73313
  const targetSharedGid = targetConvId ? this._sessionGroupIds?.get(targetConvId) : void 0;
72749
73314
  console.log(
72750
- `[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)"}`
73315
+ `[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)"}`
72751
73316
  );
72752
73317
  const skipped = [];
72753
73318
  for (const [gid, entry] of Object.entries(this._persisted.mlsGroups)) {
@@ -72755,6 +73320,10 @@ ${text}`;
72755
73320
  skipped.push(`${gid.slice(0, 8)}:not-target`);
72756
73321
  continue;
72757
73322
  }
73323
+ if (audience && gid !== audience.groupId) {
73324
+ skipped.push(`${gid.slice(0, 8)}:not-involved`);
73325
+ continue;
73326
+ }
72758
73327
  if (!entry.mlsGroupId) {
72759
73328
  skipped.push(`${gid.slice(0, 8)}:no-mlsGroupId`);
72760
73329
  continue;
@@ -72811,6 +73380,7 @@ ${text}`;
72811
73380
  if (!session.activated) continue;
72812
73381
  if (roomConvIds.has(convId)) continue;
72813
73382
  if (targetConvId && convId !== targetConvId) continue;
73383
+ if (audience && !this._isPersonsConversation(audience, convId)) continue;
72814
73384
  const convGroupId = this._sessionGroupIds?.get(convId);
72815
73385
  if (convGroupId && sentSharedGroupIds.has(convGroupId)) {
72816
73386
  sentCount++;
@@ -72929,6 +73499,7 @@ ${text}`;
72929
73499
  if (this._persisted?.mlsConversations && this._state === "ready" && this._ws) {
72930
73500
  for (const [mlsConvId, entry] of Object.entries(this._persisted.mlsConversations)) {
72931
73501
  if (targetConvId && mlsConvId !== targetConvId) continue;
73502
+ if (audience && !this._isPersonsConversation(audience, mlsConvId)) continue;
72932
73503
  if (this._sessions.has(mlsConvId)) continue;
72933
73504
  if (roomConvIds.has(mlsConvId)) continue;
72934
73505
  const mlsOnlyConvGroupId = this._sessionGroupIds?.get(mlsConvId);
@@ -73052,7 +73623,7 @@ ${text}`;
73052
73623
  */
73053
73624
  sendActivitySpan(spanData) {
73054
73625
  if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
73055
- const pluginVersion = true ? "0.23.51" : "0.0.0-dev";
73626
+ const pluginVersion = true ? "0.23.53" : "0.0.0-dev";
73056
73627
  const agentName = this.config.agentName ?? "Agent";
73057
73628
  const resource = {
73058
73629
  "service.name": "agentvault-agent",
@@ -73104,7 +73675,7 @@ ${text}`;
73104
73675
  * Builds a structured envelope with decision metadata and sends it
73105
73676
  * as a high-priority message. Returns the generated decision_id.
73106
73677
  */
73107
- async sendDecisionRequest(request) {
73678
+ async sendDecisionRequest(request, routing) {
73108
73679
  const decision_id = `dec_${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
73109
73680
  const payload = JSON.stringify({
73110
73681
  type: "message",
@@ -73115,6 +73686,8 @@ ${text}`;
73115
73686
  }
73116
73687
  });
73117
73688
  await this.send(payload, {
73689
+ conversationId: routing?.conversationId,
73690
+ audience: routing?.audience,
73118
73691
  messageType: "decision_request",
73119
73692
  priority: "high",
73120
73693
  metadata: {
@@ -73521,6 +74094,7 @@ ${text}`;
73521
74094
  const jwt = this._deviceJwt ?? this._persisted?.deviceJwt;
73522
74095
  if (!jwt || !this._persisted) return false;
73523
74096
  let rows;
74097
+ const reconcileStartedAt = Date.now();
73524
74098
  try {
73525
74099
  const res = await fetch(`${this.config.apiUrl}/api/v1/conversations`, {
73526
74100
  headers: { Authorization: `Bearer ${jwt}` }
@@ -73549,6 +74123,19 @@ ${text}`;
73549
74123
  }
73550
74124
  this._sessionGroupIds = new Map(mine.map((r2) => [r2.id, r2.group_id]));
73551
74125
  this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
74126
+ {
74127
+ const convs = new Set(mine.map((r2) => r2.id));
74128
+ const groups = new Set(mine.map((r2) => r2.group_id));
74129
+ this._lastReconcile = { at: reconcileStartedAt, convs, groups };
74130
+ for (const [key, a2] of this._attestedInbound) {
74131
+ if (a2.at > reconcileStartedAt) continue;
74132
+ if (a2.convId && convs.has(a2.convId) || a2.groupId && groups.has(a2.groupId)) continue;
74133
+ this._attestedInbound.delete(key);
74134
+ }
74135
+ for (const [gid, at] of this._welcomedUnmapped) {
74136
+ if (at <= reconcileStartedAt) this._welcomedUnmapped.delete(gid);
74137
+ }
74138
+ }
73552
74139
  const joined = mine.find((r2) => this._persisted.mlsGroups?.[r2.group_id]);
73553
74140
  const primary = mine.find((r2) => r2.id === this._persisted.primaryConversationId) ?? joined ?? mine[0];
73554
74141
  if (!mine.some((r2) => r2.id === this._persisted.primaryConversationId)) {
@@ -73742,7 +74329,7 @@ ${text}`;
73742
74329
  }
73743
74330
  this._heartbeatCallback = null;
73744
74331
  }
73745
- async sendStatusAlert(alert) {
74332
+ async sendStatusAlert(alert, routing) {
73746
74333
  const priority = alert.severity === "error" || alert.severity === "critical" ? "high" : "normal";
73747
74334
  const envelope = {
73748
74335
  title: alert.title,
@@ -73756,52 +74343,61 @@ ${text}`;
73756
74343
  await this.send(
73757
74344
  JSON.stringify(envelope),
73758
74345
  {
74346
+ conversationId: routing?.conversationId,
74347
+ audience: routing?.audience,
73759
74348
  messageType: "status_alert",
73760
74349
  priority,
73761
74350
  metadata: { severity: alert.severity }
73762
74351
  }
73763
74352
  );
73764
74353
  }
73765
- async sendArtifact(artifact) {
74354
+ async sendArtifact(artifact, routing) {
73766
74355
  if (this._state !== "ready" || this._sessions.size === 0 || !this._ws) {
73767
74356
  throw new Error("Channel is not ready");
73768
74357
  }
73769
- const attachMeta = await this._uploadAttachment(artifact.filePath, this._primaryConversationId);
73770
- const envelope = JSON.stringify({
73771
- type: "artifact",
73772
- blob_id: attachMeta.blobId,
73773
- blob_url: attachMeta.blobUrl,
73774
- filename: artifact.filename,
73775
- mime_type: artifact.mimeType,
73776
- size_bytes: attachMeta.size,
73777
- description: artifact.description,
73778
- attachment: attachMeta
73779
- });
73780
74358
  const messageGroupId = randomUUID4();
73781
74359
  const pendingWsSends = [];
73782
- for (const [convId, session] of this._sessions) {
73783
- if (!session.activated) continue;
73784
- const encrypted = session.ratchet.encrypt(envelope);
73785
- const transport = encryptedMessageToTransport(encrypted);
73786
- pendingWsSends.push(
73787
- JSON.stringify({
73788
- event: "message",
73789
- data: {
73790
- conversation_id: convId,
73791
- header_blob: transport.header_blob,
73792
- ciphertext: transport.ciphertext,
73793
- message_group_id: messageGroupId,
73794
- message_type: "artifact_share"
73795
- }
73796
- })
73797
- );
74360
+ const buckets = this._ownerFileRecipients(routing);
74361
+ if (buckets.length === 0) {
74362
+ console.warn("[SecureChannel] sendArtifact(): no live session for the person involved \u2014 nothing sent");
74363
+ throw new Error("No conversation is ready to receive this file");
74364
+ }
74365
+ for (const bucket of buckets) {
74366
+ const attachMeta = await this._uploadAttachment(artifact.filePath, bucket.uploadConvId);
74367
+ const envelope = JSON.stringify({
74368
+ type: "artifact",
74369
+ blob_id: attachMeta.blobId,
74370
+ blob_url: attachMeta.blobUrl,
74371
+ filename: artifact.filename,
74372
+ mime_type: artifact.mimeType,
74373
+ size_bytes: attachMeta.size,
74374
+ description: artifact.description,
74375
+ attachment: attachMeta
74376
+ });
74377
+ for (const convId of bucket.convIds) {
74378
+ const session = this._sessions.get(convId);
74379
+ const encrypted = session.ratchet.encrypt(envelope);
74380
+ const transport = encryptedMessageToTransport(encrypted);
74381
+ pendingWsSends.push(
74382
+ JSON.stringify({
74383
+ event: "message",
74384
+ data: {
74385
+ conversation_id: convId,
74386
+ header_blob: transport.header_blob,
74387
+ ciphertext: transport.ciphertext,
74388
+ message_group_id: messageGroupId,
74389
+ message_type: "artifact_share"
74390
+ }
74391
+ })
74392
+ );
74393
+ }
73798
74394
  }
73799
74395
  await this._persistState();
73800
74396
  for (const frame of pendingWsSends) {
73801
74397
  this._ws.send(frame);
73802
74398
  }
73803
74399
  }
73804
- async sendActionConfirmation(confirmation) {
74400
+ async sendActionConfirmation(confirmation, routing) {
73805
74401
  const envelope = {
73806
74402
  type: "action_confirmation",
73807
74403
  action: confirmation.action,
@@ -73812,6 +74408,8 @@ ${text}`;
73812
74408
  await this.send(
73813
74409
  JSON.stringify(envelope),
73814
74410
  {
74411
+ conversationId: routing?.conversationId,
74412
+ audience: routing?.audience,
73815
74413
  messageType: "action_confirmation",
73816
74414
  metadata: { status: confirmation.status }
73817
74415
  }
@@ -73917,9 +74515,23 @@ ${text}`;
73917
74515
  } else {
73918
74516
  return { ok: false, destination: { kind: "owner" }, error: "Unknown target kind", timestamp: ts };
73919
74517
  }
74518
+ if (resolved.kind === "owner" && options?.refuseIfAmbiguous && this.isUntargetedOwnerAmbiguous(options)) {
74519
+ console.log(`[deliver] target=owner content=${content.type} result=REFUSED: ambiguous (several people mid-turn)`);
74520
+ return { ok: false, ambiguous: true, destination: resolved, error: AMBIGUOUS_OWNER_ERROR, timestamp: ts };
74521
+ }
73920
74522
  let dedupeKey = null;
73921
74523
  try {
73922
- dedupeKey = outboundDedupeKey(resolved, content, options);
74524
+ let audienceTag;
74525
+ try {
74526
+ audienceTag = resolved.kind === "owner" && options?.conversationId === void 0 ? this._audienceTag(options) : void 0;
74527
+ } catch {
74528
+ audienceTag = void 0;
74529
+ }
74530
+ dedupeKey = outboundDedupeKey(
74531
+ resolved,
74532
+ content,
74533
+ audienceTag ? { ...options, conversationId: audienceTag } : options
74534
+ );
73923
74535
  if (dedupeKey) {
73924
74536
  const now = Date.now();
73925
74537
  const recent = this._recentDeliveries ??= /* @__PURE__ */ new Map();
@@ -73939,6 +74551,10 @@ ${text}`;
73939
74551
  }
73940
74552
  try {
73941
74553
  let decisionId;
74554
+ const ownerRouting = {
74555
+ conversationId: options?.conversationId,
74556
+ audience: options?.audience
74557
+ };
73942
74558
  if (content.type === "text") {
73943
74559
  if (resolved.kind === "room") {
73944
74560
  await this.sendToRoom(resolved.id, content.text, {
@@ -73957,6 +74573,7 @@ ${text}`;
73957
74573
  } else {
73958
74574
  await this.send(content.text, {
73959
74575
  conversationId: options?.conversationId,
74576
+ audience: options?.audience,
73960
74577
  topicId: options?.topicId,
73961
74578
  messageType: options?.metadata?.message_type,
73962
74579
  priority: options?.priority,
@@ -73969,7 +74586,7 @@ ${text}`;
73969
74586
  console.log(`[deliver] target=${resolved.kind}:${resolved.id} content=decision_request result=FAIL: ${err}`);
73970
74587
  return { ok: false, destination: resolved, error: err, timestamp: ts };
73971
74588
  }
73972
- decisionId = await this.sendDecisionRequest(content.request);
74589
+ decisionId = await this.sendDecisionRequest(content.request, ownerRouting);
73973
74590
  } else if (content.type === "status_alert") {
73974
74591
  if (resolved.kind === "room") {
73975
74592
  const envelope = {
@@ -73987,7 +74604,7 @@ ${text}`;
73987
74604
  metadata: { severity: content.alert.severity }
73988
74605
  });
73989
74606
  } else if (resolved.kind === "owner") {
73990
- await this.sendStatusAlert(content.alert);
74607
+ await this.sendStatusAlert(content.alert, ownerRouting);
73991
74608
  } else {
73992
74609
  return { ok: false, destination: resolved, error: "Status alerts cannot be sent to A2A targets", timestamp: ts };
73993
74610
  }
@@ -73995,7 +74612,7 @@ ${text}`;
73995
74612
  if (resolved.kind === "room") {
73996
74613
  await this.sendActionConfirmationToRoom(resolved.id, content.confirmation);
73997
74614
  } else if (resolved.kind === "owner") {
73998
- await this.sendActionConfirmation(content.confirmation);
74615
+ await this.sendActionConfirmation(content.confirmation, ownerRouting);
73999
74616
  } else {
74000
74617
  return { ok: false, destination: resolved, error: "Action confirmations cannot be sent to A2A targets", timestamp: ts };
74001
74618
  }
@@ -74003,13 +74620,14 @@ ${text}`;
74003
74620
  if (resolved.kind !== "owner") {
74004
74621
  return { ok: false, destination: resolved, error: "Artifacts can only be sent to owner", timestamp: ts };
74005
74622
  }
74006
- await this.sendArtifact(content.artifact);
74623
+ await this.sendArtifact(content.artifact, ownerRouting);
74007
74624
  } else if (content.type === "attachment") {
74008
74625
  if (resolved.kind !== "owner") {
74009
74626
  return { ok: false, destination: resolved, error: "Attachments can only be sent to owner", timestamp: ts };
74010
74627
  }
74011
74628
  await this.sendWithAttachment(content.text, content.filePath, {
74012
- topicId: options?.topicId
74629
+ topicId: options?.topicId,
74630
+ ...ownerRouting
74013
74631
  });
74014
74632
  }
74015
74633
  const targetLabel = resolved.kind === "owner" ? "owner" : `${resolved.kind}:${resolved.id?.slice(0, 8)}...`;
@@ -75182,7 +75800,7 @@ ${text}`;
75182
75800
  agentVersion: this.config.agentVersion ?? "0.0.0",
75183
75801
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
75184
75802
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
75185
- pluginVersion: true ? "0.23.51" : "0.0.0-dev"
75803
+ pluginVersion: true ? "0.23.53" : "0.0.0-dev"
75186
75804
  });
75187
75805
  this._telemetryReporter.startAutoFlush(3e4);
75188
75806
  }
@@ -75510,7 +76128,7 @@ ${text}`;
75510
76128
  agentVersion: this.config.agentVersion ?? "0.0.0",
75511
76129
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
75512
76130
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
75513
- pluginVersion: true ? "0.23.51" : "0.0.0-dev"
76131
+ pluginVersion: true ? "0.23.53" : "0.0.0-dev"
75514
76132
  });
75515
76133
  this._telemetryReporter.startAutoFlush(3e4);
75516
76134
  }
@@ -76051,9 +76669,18 @@ ${text}`;
76051
76669
  messageType,
76052
76670
  { groupId: dmGroupId, conversationId: convId }
76053
76671
  );
76672
+ const dmConvId = convId ?? this._conversationOfGroup(dmGroupId);
76673
+ this._noteInboundDm(dmConvId, dmGroupId, { createdAt: data.created_at, senderDeviceId });
76674
+ this._reconcileForUnmappedGroup(dmGroupId);
76054
76675
  const metadata = {
76055
76676
  messageId: data.message_id ?? `mls_${Date.now()}`,
76056
- conversationId: convId ?? this._primaryConversationId,
76677
+ // A frame on a KNOWN group that no conversation maps yet is not the
76678
+ // primary person's: leave the conversation unnamed rather than hand
76679
+ // the reply to someone else; `conversationGroupId` still places it.
76680
+ conversationId: dmConvId ?? (dmGroupId ? void 0 : this._primaryConversationId),
76681
+ // #1418: the group this message decrypted under — attested, so a turn
76682
+ // answers here even when the local map is stale.
76683
+ conversationGroupId: dmGroupId,
76057
76684
  timestamp: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
76058
76685
  topicId,
76059
76686
  // #621: positive attestation that this decrypted under the OWNER'S 1:1
@@ -76308,6 +76935,13 @@ ${messageText}`;
76308
76935
  // envelope text before the fold; `emitText` is the folded copy.
76309
76936
  caption: messageText
76310
76937
  };
76938
+ if (!roomId) {
76939
+ this._noteInboundDm(convId, void 0, {
76940
+ createdAt: msgData.created_at,
76941
+ senderDeviceId: msgData.sender_device_id
76942
+ });
76943
+ this._reconcileForUnmappedConversation(convId);
76944
+ }
76311
76945
  this.emit("message", emitText, metadata);
76312
76946
  Promise.resolve(this.config.onMessage?.(emitText, metadata)).catch((err) => {
76313
76947
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -76456,34 +77090,41 @@ ${baseText}`;
76456
77090
  if (this._state !== "ready" || this._sessions.size === 0 || !this._ws) {
76457
77091
  throw new Error("Channel is not ready");
76458
77092
  }
76459
- const attachMeta = await this._uploadAttachment(filePath, this._primaryConversationId);
76460
77093
  const messageGroupId = randomUUID4();
76461
77094
  const pendingWsSends = [];
76462
77095
  const frameHistoryContexts = [];
76463
- for (const [convId, session] of this._sessions) {
76464
- if (!session.activated) continue;
76465
- const topicId = this._topicForFrame(void 0, convId, options?.topicId, false, false);
76466
- const envelope = JSON.stringify({
76467
- type: "message",
76468
- text: plaintext,
76469
- topicId,
76470
- attachment: attachMeta
76471
- });
76472
- const encrypted = session.ratchet.encrypt(envelope);
76473
- const transport = encryptedMessageToTransport(encrypted);
76474
- pendingWsSends.push(
76475
- JSON.stringify({
76476
- event: "message",
76477
- data: {
76478
- conversation_id: convId,
76479
- header_blob: transport.header_blob,
76480
- ciphertext: transport.ciphertext,
76481
- message_group_id: messageGroupId,
76482
- topic_id: topicId
76483
- }
76484
- })
76485
- );
76486
- frameHistoryContexts.push(this._dmHistoryContext(topicId, void 0, convId));
77096
+ const buckets = this._ownerFileRecipients(options);
77097
+ if (buckets.length === 0) {
77098
+ console.warn("[SecureChannel] sendWithAttachment(): no live session for the person involved \u2014 nothing sent");
77099
+ throw new Error("No conversation is ready to receive this file");
77100
+ }
77101
+ for (const bucket of buckets) {
77102
+ const attachMeta = await this._uploadAttachment(filePath, bucket.uploadConvId);
77103
+ for (const convId of bucket.convIds) {
77104
+ const session = this._sessions.get(convId);
77105
+ const topicId = this._topicForFrame(void 0, convId, options?.topicId, false, false);
77106
+ const envelope = JSON.stringify({
77107
+ type: "message",
77108
+ text: plaintext,
77109
+ topicId,
77110
+ attachment: attachMeta
77111
+ });
77112
+ const encrypted = session.ratchet.encrypt(envelope);
77113
+ const transport = encryptedMessageToTransport(encrypted);
77114
+ pendingWsSends.push(
77115
+ JSON.stringify({
77116
+ event: "message",
77117
+ data: {
77118
+ conversation_id: convId,
77119
+ header_blob: transport.header_blob,
77120
+ ciphertext: transport.ciphertext,
77121
+ message_group_id: messageGroupId,
77122
+ topic_id: topicId
77123
+ }
77124
+ })
77125
+ );
77126
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, void 0, convId));
77127
+ }
76487
77128
  }
76488
77129
  await this._persistState();
76489
77130
  let deliveredFrames = 0;
@@ -76643,10 +77284,15 @@ ${baseText}`;
76643
77284
  `[SecureChannel] New owner device linked: ${event.owner_device_id.slice(0, 8)}...`
76644
77285
  );
76645
77286
  try {
77287
+ if (event.group_id && !this._sessionGroupIds.has(event.conversation_id)) {
77288
+ this._sessionGroupIds.set(event.conversation_id, event.group_id);
77289
+ this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
77290
+ }
76646
77291
  if (!event.owner_identity_public_key) {
76647
77292
  console.error(
76648
77293
  `[SecureChannel] device_linked event missing owner keys for conv ${event.conversation_id.slice(0, 8)}...`
76649
77294
  );
77295
+ await this._persistState();
76650
77296
  return;
76651
77297
  }
76652
77298
  const identity = this._persisted.identityKeypair;
@@ -76681,10 +77327,6 @@ ${baseText}`;
76681
77327
  if (event.owner_hub_id) {
76682
77328
  this._persisted.ownerHubId = event.owner_hub_id;
76683
77329
  }
76684
- if (event.group_id && !this._sessionGroupIds.has(event.conversation_id)) {
76685
- this._sessionGroupIds.set(event.conversation_id, event.group_id);
76686
- this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
76687
- }
76688
77330
  await this._persistState();
76689
77331
  console.log(
76690
77332
  `[SecureChannel] Session initialized for device ${event.owner_device_id.slice(0, 8)}... (conv ${event.conversation_id.slice(0, 8)}...)`
@@ -77422,7 +78064,7 @@ ${baseText}`;
77422
78064
  return 0;
77423
78065
  }
77424
78066
  const snapshot = mlsGroup.exportState();
77425
- const preHead = await this._readGroupHead(mlsGroupId);
78067
+ const preHead = opts.preHead ?? await this._readGroupHead(mlsGroupId);
77426
78068
  if (preHead.ok && preHead.epoch !== Number(mlsGroup.epoch)) {
77427
78069
  console.warn(
77428
78070
  `[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`
@@ -77609,6 +78251,40 @@ ${baseText}`;
77609
78251
  _wsIsOpen() {
77610
78252
  return this._ws?.readyState === 1;
77611
78253
  }
78254
+ /**
78255
+ * #1429 review: the cheap checks `_fulfilWelcomeRequests` makes, run BEFORE a
78256
+ * pending-Welcome site claims KeyPackages — the order #1225 S4 gave the A2A
78257
+ * path. `GET /key-packages/batch` CONSUMES; the room, shared-1:1 and conv
78258
+ * sites used to claim one per pending device and only then find the socket
78259
+ * closed, another commit in flight, or the server head elsewhere — burning a
78260
+ * package per device per failed pull (and the shared/conv sites have no
78261
+ * cooldown). `_fulfilWelcomeRequests` keeps its own checks: this is a gate on
78262
+ * spending, not a replacement for the guard at the point of commit.
78263
+ */
78264
+ /**
78265
+ * Returns the head it read (handed on to `_fulfilWelcomeRequests` as its
78266
+ * pre-flight, so a pull still reads the head once before committing), or
78267
+ * `null` when nothing should be claimed this pull.
78268
+ */
78269
+ async _welcomeCommitPreflight(mlsGroupId, mlsGroup, label) {
78270
+ if (!this._wsIsOpen()) {
78271
+ console.warn(`[SecureChannel] ${label}: socket is not OPEN \u2014 not claiming KeyPackages; requests stay pending for the next pull`);
78272
+ return null;
78273
+ }
78274
+ if (this._commitInFlight.has(mlsGroupId)) {
78275
+ console.warn(`[SecureChannel] ${label}: another commit for this group is in flight \u2014 not claiming KeyPackages this pull`);
78276
+ return null;
78277
+ }
78278
+ const head = await this._readGroupHead(mlsGroupId);
78279
+ if (head.ok && head.epoch !== Number(mlsGroup.epoch)) {
78280
+ console.warn(
78281
+ `[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`
78282
+ );
78283
+ await this._catchUpAfterPreflightSkip(mlsGroupId, head.epoch, Number(mlsGroup.epoch), label);
78284
+ return null;
78285
+ }
78286
+ return head;
78287
+ }
77612
78288
  /** SHA-256 hex of a commit's bytes — its identity on the server (#1175/#1177). */
77613
78289
  /**
77614
78290
  * #1225: send ONE commit over the socket and wait for the server's verdict,
@@ -78354,6 +79030,10 @@ ${baseText}`;
78354
79030
  await this._persistState();
78355
79031
  }
78356
79032
  console.log(`[SecureChannel] Joined shared 1:1 MLS group for group ${conversationGroupId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
79033
+ if (!this._isMappedGroup(conversationGroupId)) {
79034
+ this._welcomedUnmapped.set(conversationGroupId, Date.now());
79035
+ }
79036
+ this._reconcileForUnmappedGroup(conversationGroupId);
78357
79037
  await this._flushMlsHold(conversationGroupId);
78358
79038
  return;
78359
79039
  }
@@ -78630,14 +79310,27 @@ ${baseText}`;
78630
79310
  const roomState = this._persisted?.rooms?.[roomId];
78631
79311
  if (!roomState?.mlsGroupId) continue;
78632
79312
  try {
79313
+ const roomLabel = `room ${roomId.slice(0, 8)}`;
78633
79314
  const pendingRes = await fetch(
78634
79315
  `${this.config.apiUrl}/api/v1/mls/groups/${roomState.mlsGroupId}/pending-welcomes`,
78635
79316
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78636
79317
  );
78637
- if (!pendingRes.ok) continue;
79318
+ if (!pendingRes.ok) {
79319
+ this._welcomeKpBackoff.noteFetchFailure(`pending-welcomes for ${roomLabel}`, pendingRes.status);
79320
+ continue;
79321
+ }
79322
+ this._welcomeKpBackoff.noteFetchOk(`pending-welcomes for ${roomLabel}`);
78638
79323
  let pending = await pendingRes.json();
79324
+ if (this._welcomeKpBackoff.observePending(roomState.mlsGroupId, pending)) {
79325
+ console.log(`[SecureChannel] ${pending.length} pending Welcome requests for room ${roomId.slice(0, 8)}`);
79326
+ }
79327
+ if (pending.length === 0) continue;
79328
+ const nowKp = Date.now();
79329
+ const roomMlsGroupId = roomState.mlsGroupId;
79330
+ pending = pending.filter(
79331
+ (r2) => this._welcomeKpBackoff.shouldAsk(roomMlsGroupId, r2.requesting_device_id, r2.key_package_available, roomLabel, nowKp)
79332
+ );
78639
79333
  if (pending.length === 0) continue;
78640
- console.log(`[SecureChannel] ${pending.length} pending Welcome requests for room ${roomId.slice(0, 8)}`);
78641
79334
  const nowMs = Date.now();
78642
79335
  const fresh = pending.filter((r2) => {
78643
79336
  const key = `${roomState.mlsGroupId}:${r2.requesting_device_id}`;
@@ -78651,6 +79344,8 @@ ${baseText}`;
78651
79344
  return true;
78652
79345
  });
78653
79346
  if (fresh.length === 0) continue;
79347
+ const roomPreHead = await this._welcomeCommitPreflight(roomState.mlsGroupId, mlsGroup, roomLabel);
79348
+ if (!roomPreHead) continue;
78654
79349
  for (const r2 of fresh) {
78655
79350
  this._roomFulfilCooldown.set(`${roomState.mlsGroupId}:${r2.requesting_device_id}`, nowMs);
78656
79351
  }
@@ -78660,13 +79355,23 @@ ${baseText}`;
78660
79355
  `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${deviceIds.join(",")}`,
78661
79356
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78662
79357
  );
78663
- if (!kpRes.ok) continue;
79358
+ if (!kpRes.ok) {
79359
+ this._welcomeKpBackoff.noteFetchFailure(`KeyPackage batch for ${roomLabel}`, kpRes.status);
79360
+ continue;
79361
+ }
79362
+ this._welcomeKpBackoff.noteFetchOk(`KeyPackage batch for ${roomLabel}`);
78664
79363
  const kpData = await kpRes.json();
78665
79364
  const roomTargets = [];
78666
79365
  for (const req of pending) {
78667
79366
  const kpHex = kpData[req.requesting_device_id];
79367
+ this._welcomeKpBackoff.recordKeyPackage(
79368
+ roomState.mlsGroupId,
79369
+ req.requesting_device_id,
79370
+ Boolean(kpHex),
79371
+ req.key_package_available,
79372
+ roomLabel
79373
+ );
78668
79374
  if (!kpHex) {
78669
- console.warn(`[SecureChannel] No KeyPackage for ${req.requesting_device_id.slice(0, 8)}, skipping`);
78670
79375
  continue;
78671
79376
  }
78672
79377
  const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
@@ -78684,8 +79389,10 @@ ${baseText}`;
78684
79389
  label: `room ${roomId.slice(0, 8)}`,
78685
79390
  welcomeFields: { room_id: roomId },
78686
79391
  targets: roomTargets,
78687
- memberDeviceIds: (roomState.members ?? []).map((m2) => m2.deviceId)
79392
+ memberDeviceIds: (roomState.members ?? []).map((m2) => m2.deviceId),
78688
79393
  // #1226
79394
+ preHead: roomPreHead
79395
+ // #1429
78689
79396
  });
78690
79397
  if (done > 0) {
78691
79398
  console.log(
@@ -78703,28 +79410,49 @@ ${baseText}`;
78703
79410
  const mlsGroup = this._mlsGroups.get(`1to1-group:${gid}`);
78704
79411
  if (!mlsGroup?.isInitialized) continue;
78705
79412
  try {
79413
+ const sharedLabel = `shared group ${gid.slice(0, 8)}`;
78706
79414
  const pendingRes = await fetch(
78707
79415
  `${this.config.apiUrl}/api/v1/mls/groups/${entry.mlsGroupId}/pending-welcomes`,
78708
79416
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78709
79417
  );
78710
- if (!pendingRes.ok) continue;
78711
- const pending = await pendingRes.json();
79418
+ if (!pendingRes.ok) {
79419
+ this._welcomeKpBackoff.noteFetchFailure(`pending-welcomes for ${sharedLabel}`, pendingRes.status);
79420
+ continue;
79421
+ }
79422
+ this._welcomeKpBackoff.noteFetchOk(`pending-welcomes for ${sharedLabel}`);
79423
+ const allPending = await pendingRes.json();
79424
+ if (this._welcomeKpBackoff.observePending(entry.mlsGroupId, allPending)) {
79425
+ console.log(`[SecureChannel] ${allPending.length} pending Welcome requests for shared group ${gid.slice(0, 8)}`);
79426
+ }
79427
+ const nowKp = Date.now();
79428
+ const pending = allPending.filter(
79429
+ (r2) => this._welcomeKpBackoff.shouldAsk(entry.mlsGroupId, r2.requesting_device_id, r2.key_package_available, sharedLabel, nowKp)
79430
+ );
78712
79431
  if (pending.length === 0) continue;
78713
- console.log(`[SecureChannel] ${pending.length} pending Welcome requests for shared group ${gid.slice(0, 8)}`);
79432
+ const sharedPreHead = await this._welcomeCommitPreflight(entry.mlsGroupId, mlsGroup, sharedLabel);
79433
+ if (!sharedPreHead) continue;
78714
79434
  const deviceIds = pending.map((r2) => r2.requesting_device_id);
78715
79435
  const kpRes = await fetch(
78716
79436
  `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${deviceIds.join(",")}`,
78717
79437
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78718
79438
  );
78719
- if (!kpRes.ok) continue;
79439
+ if (!kpRes.ok) {
79440
+ this._welcomeKpBackoff.noteFetchFailure(`KeyPackage batch for ${sharedLabel}`, kpRes.status);
79441
+ continue;
79442
+ }
79443
+ this._welcomeKpBackoff.noteFetchOk(`KeyPackage batch for ${sharedLabel}`);
78720
79444
  const kpData = await kpRes.json();
78721
79445
  const validReqs = [];
78722
79446
  for (const req of pending) {
78723
79447
  const kpHex = kpData[req.requesting_device_id];
78724
- if (!kpHex) {
78725
- console.warn(`[SecureChannel] No KeyPackage for ${req.requesting_device_id.slice(0, 8)}, skipping`);
78726
- continue;
78727
- }
79448
+ this._welcomeKpBackoff.recordKeyPackage(
79449
+ entry.mlsGroupId,
79450
+ req.requesting_device_id,
79451
+ Boolean(kpHex),
79452
+ req.key_package_available,
79453
+ sharedLabel
79454
+ );
79455
+ if (!kpHex) continue;
78728
79456
  const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
78729
79457
  validReqs.push({ req, kp: MLSGroupManager.deserializeKeyPackage(kpBytes) });
78730
79458
  }
@@ -78741,8 +79469,10 @@ ${baseText}`;
78741
79469
  label: `shared group ${gid.slice(0, 8)}`,
78742
79470
  welcomeFields: { conversation_group_id: gid },
78743
79471
  targets: sharedTargets,
78744
- memberDeviceIds: entry.memberDeviceIds ?? []
79472
+ memberDeviceIds: entry.memberDeviceIds ?? [],
78745
79473
  // #1226
79474
+ preHead: sharedPreHead
79475
+ // #1429
78746
79476
  });
78747
79477
  if (done > 0) {
78748
79478
  console.log(`[SecureChannel] Batched Welcome for ${done}/${validReqs.length} devices in shared group ${gid.slice(0, 8)} (epoch=${mlsGroup.epoch})`);
@@ -78776,23 +79506,49 @@ ${baseText}`;
78776
79506
  const mlsGroup = this._mlsGroups.get(`conv:${convId}`);
78777
79507
  if (!mlsGroup?.isInitialized) continue;
78778
79508
  try {
79509
+ const convLabel = `conv ${convId.slice(0, 8)}`;
78779
79510
  const pendingRes = await fetch(
78780
79511
  `${this.config.apiUrl}/api/v1/mls/groups/${convEntry.mlsGroupId}/pending-welcomes`,
78781
79512
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78782
79513
  );
78783
- if (!pendingRes.ok) continue;
79514
+ if (!pendingRes.ok) {
79515
+ this._welcomeKpBackoff.noteFetchFailure(`pending-welcomes for ${convLabel}`, pendingRes.status);
79516
+ continue;
79517
+ }
79518
+ this._welcomeKpBackoff.noteFetchOk(`pending-welcomes for ${convLabel}`);
78784
79519
  const pending = await pendingRes.json();
79520
+ if (this._welcomeKpBackoff.observePending(convEntry.mlsGroupId, pending)) {
79521
+ console.log(`[SecureChannel] ${pending.length} pending Welcome requests for conv ${convId.slice(0, 8)}`);
79522
+ }
78785
79523
  if (pending.length === 0) continue;
78786
- console.log(`[SecureChannel] ${pending.length} pending Welcome requests for conv ${convId.slice(0, 8)}`);
78787
79524
  for (const req of pending) {
78788
79525
  try {
79526
+ if (!this._welcomeKpBackoff.shouldAsk(
79527
+ convEntry.mlsGroupId,
79528
+ req.requesting_device_id,
79529
+ req.key_package_available,
79530
+ convLabel
79531
+ )) continue;
79532
+ const convPreHead = await this._welcomeCommitPreflight(convEntry.mlsGroupId, mlsGroup, convLabel);
79533
+ if (!convPreHead) break;
78789
79534
  const kpRes = await fetch(
78790
79535
  `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${req.requesting_device_id}`,
78791
79536
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78792
79537
  );
78793
- if (!kpRes.ok) continue;
79538
+ if (!kpRes.ok) {
79539
+ this._welcomeKpBackoff.noteFetchFailure(`KeyPackage batch for ${convLabel}`, kpRes.status);
79540
+ continue;
79541
+ }
79542
+ this._welcomeKpBackoff.noteFetchOk(`KeyPackage batch for ${convLabel}`);
78794
79543
  const kpData = await kpRes.json();
78795
79544
  const kpHex = kpData[req.requesting_device_id];
79545
+ this._welcomeKpBackoff.recordKeyPackage(
79546
+ convEntry.mlsGroupId,
79547
+ req.requesting_device_id,
79548
+ Boolean(kpHex),
79549
+ req.key_package_available,
79550
+ convLabel
79551
+ );
78796
79552
  if (!kpHex) continue;
78797
79553
  const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
78798
79554
  const memberKp = MLSGroupManager.deserializeKeyPackage(kpBytes);
@@ -78809,7 +79565,9 @@ ${baseText}`;
78809
79565
  // #1226: a 1:1 roster is [self, owner] — the web's shape too.
78810
79566
  memberDeviceIds: [this._persisted?.sessions?.[convId]?.ownerDeviceId].filter(
78811
79567
  (d2) => typeof d2 === "string"
78812
- )
79568
+ ),
79569
+ preHead: convPreHead
79570
+ // #1429
78813
79571
  });
78814
79572
  if (done > 0) {
78815
79573
  console.log(`[SecureChannel] Fulfilled Welcome for ${req.requesting_device_id.slice(0, 8)} in conv ${convId.slice(0, 8)}`);
@@ -78857,15 +79615,28 @@ ${baseText}`;
78857
79615
  if (!mlsGroup?.isInitialized) continue;
78858
79616
  if (chState.role !== "creator") continue;
78859
79617
  try {
79618
+ const a2aPendingLabel = `A2A ${chId.slice(0, 8)}`;
78860
79619
  const pendingRes = await fetch(
78861
79620
  `${this.config.apiUrl}/api/v1/mls/groups/${chState.mlsGroupId}/pending-welcomes`,
78862
79621
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
78863
79622
  );
78864
- if (!pendingRes.ok) continue;
79623
+ if (!pendingRes.ok) {
79624
+ this._welcomeKpBackoff.noteFetchFailure(`pending-welcomes for ${a2aPendingLabel}`, pendingRes.status);
79625
+ continue;
79626
+ }
79627
+ this._welcomeKpBackoff.noteFetchOk(`pending-welcomes for ${a2aPendingLabel}`);
78865
79628
  const pending = await pendingRes.json();
79629
+ if (this._welcomeKpBackoff.observePending(chState.mlsGroupId, pending)) {
79630
+ console.log(`[SecureChannel] ${pending.length} pending A2A Welcome requests for channel ${chId.slice(0, 8)}`);
79631
+ }
78866
79632
  if (pending.length === 0) continue;
78867
- console.log(`[SecureChannel] ${pending.length} pending A2A Welcome requests for channel ${chId.slice(0, 8)}`);
78868
79633
  for (const req of pending) {
79634
+ if (!this._welcomeKpBackoff.shouldAsk(
79635
+ chState.mlsGroupId,
79636
+ req.requesting_device_id,
79637
+ req.key_package_available,
79638
+ a2aPendingLabel
79639
+ )) continue;
78869
79640
  try {
78870
79641
  const next = await this._fulfilA2AWelcome(chId, chState, mlsGroup, req);
78871
79642
  if (next === "stop") break;
@@ -78995,6 +79766,7 @@ ${baseText}`;
78995
79766
  ownerDm1to1: true,
78996
79767
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
78997
79768
  };
79769
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
78998
79770
  this.emit("message", messageText, metadata);
78999
79771
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
79000
79772
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -79176,9 +79948,20 @@ ${baseText}`;
79176
79948
  `${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${req.requesting_device_id}`,
79177
79949
  { headers: { Authorization: `Bearer ${this._deviceJwt}` } }
79178
79950
  );
79179
- if (!kpRes.ok) return "next";
79951
+ if (!kpRes.ok) {
79952
+ this._welcomeKpBackoff.noteFetchFailure(`KeyPackage batch for ${a2aLabel}`, kpRes.status);
79953
+ return "next";
79954
+ }
79955
+ this._welcomeKpBackoff.noteFetchOk(`KeyPackage batch for ${a2aLabel}`);
79180
79956
  const kpData = await kpRes.json();
79181
79957
  const kpHex = kpData[req.requesting_device_id];
79958
+ this._welcomeKpBackoff.recordKeyPackage(
79959
+ chState.mlsGroupId,
79960
+ req.requesting_device_id,
79961
+ Boolean(kpHex),
79962
+ req.key_package_available,
79963
+ a2aLabel
79964
+ );
79182
79965
  if (!kpHex) return "next";
79183
79966
  const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
79184
79967
  const memberKp = MLSGroupManager.deserializeKeyPackage(kpBytes);
@@ -79601,6 +80384,7 @@ ${baseText}`;
79601
80384
  ownerDm1to1: true,
79602
80385
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
79603
80386
  };
80387
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
79604
80388
  this.emit("message", messageText, metadata);
79605
80389
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
79606
80390
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -79921,6 +80705,7 @@ ${baseText}`;
79921
80705
  ownerDm1to1: true,
79922
80706
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
79923
80707
  };
80708
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
79924
80709
  this.emit("message", messageText, metadata);
79925
80710
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
79926
80711
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -80941,7 +81726,7 @@ ${actionsText}`);
80941
81726
  "use strict";
80942
81727
  init_llm_response_parser();
80943
81728
  init_llm_cost();
80944
- traceStore = new AsyncLocalStorage();
81729
+ traceStore = new AsyncLocalStorage2();
80945
81730
  }
80946
81731
  });
80947
81732
  init_tool_audit = __esm2({
@@ -101689,7 +102474,7 @@ data:
101689
102474
  await init_skill_telemetry();
101690
102475
  await init_policy_enforcer();
101691
102476
  init_room_protocol();
101692
- VERSION = true ? "0.23.51" : "0.0.0-dev";
102477
+ VERSION = true ? "0.23.53" : "0.0.0-dev";
101693
102478
  }
101694
102479
  });
101695
102480
  await init_index();
@@ -103448,13 +104233,28 @@ var RoomHushState = class {
103448
104233
  return t2 !== void 0 && now < t2;
103449
104234
  }
103450
104235
  };
104236
+ async function sendDm(channel, t2, text) {
104237
+ if ((t2.conversationId || t2.groupId) && typeof channel.runForConversation === "function") {
104238
+ await channel.runForConversation(
104239
+ t2.conversationId,
104240
+ () => channel.send(text),
104241
+ t2.groupId ? { groupId: t2.groupId } : void 0
104242
+ );
104243
+ } else {
104244
+ await channel.send(text);
104245
+ }
104246
+ }
103451
104247
  var ActiveTarget = class {
103452
104248
  target = null;
103453
104249
  setRoom(roomId) {
103454
104250
  this.target = { kind: "room", roomId };
103455
104251
  }
103456
- setDm() {
103457
- this.target = { kind: "dm" };
104252
+ setDm(conversationId, groupId) {
104253
+ this.target = {
104254
+ kind: "dm",
104255
+ ...conversationId ? { conversationId } : {},
104256
+ ...groupId ? { groupId } : {}
104257
+ };
103458
104258
  }
103459
104259
  get current() {
103460
104260
  return this.target;
@@ -103467,7 +104267,7 @@ var ActiveTarget = class {
103467
104267
  if (!t2) return;
103468
104268
  try {
103469
104269
  if (t2.kind === "room") await channel.sendToRoom(t2.roomId, text);
103470
- else await channel.send(text);
104270
+ else await sendDm(channel, t2, text);
103471
104271
  log(`said to ${where}`);
103472
104272
  } catch (err) {
103473
104273
  log(`send failed to ${where}: ${err instanceof Error ? err.message : String(err)}`);
@@ -103583,7 +104383,7 @@ function wireBridge(channel, session, target, opts = {}) {
103583
104383
  } else {
103584
104384
  log("inbound 1:1 DM from owner");
103585
104385
  }
103586
- target.setDm();
104386
+ target.setDm(metadata?.conversationId, metadata?.conversationGroupId);
103587
104387
  session.push(text, target.snapshotReply(channel, log), { autoReplyOnText: ownerAttested });
103588
104388
  });
103589
104389
  }
@@ -103634,7 +104434,7 @@ function mkdir700(path2) {
103634
104434
  chmodSync5(path2, 448);
103635
104435
  }
103636
104436
  function packageVersion() {
103637
- return true ? "0.1.26" : void 0;
104437
+ return true ? "0.1.28" : void 0;
103638
104438
  }
103639
104439
  function helpText(version2) {
103640
104440
  return [