@agentvault/openai-bridge 0.1.5 → 0.1.7

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.50" : FALLBACK;
11791
+ const v2 = true ? "0.23.52" : FALLBACK;
11791
11792
  return `${PACKAGE}@${v2}`;
11792
11793
  }
11793
11794
  function buildSha() {
11794
- const raw = true ? "c8f1371" : "";
11795
+ const raw = true ? "d7143c3" : "";
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) } };
@@ -12992,14 +13030,27 @@ function migrateHistoryEntries(history) {
12992
13030
  return { id, ...legacyEntry };
12993
13031
  });
12994
13032
  }
13033
+ function isTopicId(value) {
13034
+ return typeof value === "string" && TOPIC_ID_RE.test(value);
13035
+ }
13036
+ function migrateDefaultTopics(state) {
13037
+ if (!state.defaultTopicId || !state.groupId) return state;
13038
+ if (state.defaultTopicIds?.[state.groupId]) return state;
13039
+ return {
13040
+ ...state,
13041
+ defaultTopicIds: { ...state.defaultTopicIds ?? {}, [state.groupId]: state.defaultTopicId }
13042
+ };
13043
+ }
12995
13044
  function migratePersistedState(raw) {
12996
13045
  if (raw.sessions && raw.primaryConversationId) {
12997
13046
  const history = raw.messageHistory;
12998
- if (!history?.some((entry) => typeof entry.id !== "string")) return raw;
12999
- return {
13047
+ if (!history?.some((entry) => typeof entry.id !== "string")) {
13048
+ return migrateDefaultTopics(raw);
13049
+ }
13050
+ return migrateDefaultTopics({
13000
13051
  ...raw,
13001
13052
  messageHistory: migrateHistoryEntries(history)
13002
- };
13053
+ });
13003
13054
  }
13004
13055
  const legacy = raw;
13005
13056
  return {
@@ -13227,7 +13278,7 @@ async function _handleInbound(params) {
13227
13278
  core.error?.(`[AgentVault] session record failed: ${String(err)}`);
13228
13279
  }
13229
13280
  });
13230
- await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
13281
+ await channel.runForConversation(metadata.conversationId, () => core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
13231
13282
  ctx: ctxPayload,
13232
13283
  cfg,
13233
13284
  dispatcherOptions: {
@@ -13244,7 +13295,7 @@ async function _handleInbound(params) {
13244
13295
  }
13245
13296
  },
13246
13297
  replyOptions: {}
13247
- });
13298
+ }), { groupId: metadata.conversationGroupId });
13248
13299
  }
13249
13300
  function resolveBaseUrl(options) {
13250
13301
  const host = options?.host ?? "127.0.0.1";
@@ -18320,7 +18371,7 @@ function reportSkillInvocation(opts) {
18320
18371
  spanBuffer.push(span);
18321
18372
  return span;
18322
18373
  }
18323
- 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, 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, 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;
18324
18375
  var init_dist = __esm({
18325
18376
  async "../plugin/dist/index.js"() {
18326
18377
  "use strict";
@@ -18373,6 +18424,12 @@ var init_dist = __esm({
18373
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";
18374
18425
  }
18375
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
+ });
18376
18433
  init_envelope_text = __esm2({
18377
18434
  "src/envelope-text.ts"() {
18378
18435
  "use strict";
@@ -71204,6 +71261,7 @@ var init_dist = __esm({
71204
71261
  init_http_handlers = __esm2({
71205
71262
  "src/http-handlers.ts"() {
71206
71263
  "use strict";
71264
+ init_owner_routing();
71207
71265
  }
71208
71266
  });
71209
71267
  mcp_proxy_helpers_exports = {};
@@ -71233,6 +71291,7 @@ var init_dist = __esm({
71233
71291
  async "src/channel.ts"() {
71234
71292
  "use strict";
71235
71293
  init_abstention();
71294
+ init_owner_routing();
71236
71295
  init_envelope_text();
71237
71296
  init_mls_commit_classify();
71238
71297
  init_room_protocol();
@@ -71282,6 +71341,11 @@ var init_dist = __esm({
71282
71341
  OUTBOUND_DEDUPE_TYPES = /* @__PURE__ */ new Set(["text", "status_alert", "artifact", "attachment"]);
71283
71342
  RETRY_CANDIDATE_TTL_MS = 6e4;
71284
71343
  RETRY_CANDIDATE_MAX = 32;
71344
+ _turnConversation = new AsyncLocalStorage();
71345
+ PERSON_INVOLVED_WINDOW_MS = 5 * 6e4;
71346
+ ATTESTED_INBOUND_MAX = 64;
71347
+ UNMAPPED_RECONCILE_COOLDOWN_MS = 6e4;
71348
+ TOPIC_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
71285
71349
  ROOM_FULFIL_COOLDOWN_MS = 6e4;
71286
71350
  SecureChannel = class _SecureChannel extends EventEmitter {
71287
71351
  constructor(config2) {
@@ -71508,10 +71572,42 @@ ${text}`;
71508
71572
  _scanEngine = null;
71509
71573
  _scanRuleSetVersion = 0;
71510
71574
  _telemetryReporter = null;
71511
- /** Topic ID from the most recent inbound message — used as fallback for replies. */
71512
- _lastIncomingTopicId;
71575
+ /**
71576
+ * #1416: topic of the most recent inbound message, PER conversation group —
71577
+ * the fallback for a reply that names no topic. Keyed by `_topicScope()`:
71578
+ * `g:<group>` normally, `c:<conversation>` for a conversation whose group is
71579
+ * not known yet, `*` for a legacy agent that knows no groups at all. It used
71580
+ * to be one value for the whole agent, so a broadcast into person B's group
71581
+ * carried the topic of person A's last message. In memory only, as before.
71582
+ */
71583
+ _lastIncomingTopics = /* @__PURE__ */ new Map();
71513
71584
  /** Room ID from the most recent inbound room message — used as fallback for HTTP /send replies. */
71514
71585
  _lastInboundRoomId;
71586
+ /**
71587
+ * #1418: the most recent owner 1:1 message that reached the agent — the
71588
+ * person involved in whatever the agent says next without naming a
71589
+ * conversation (see `_involvedPerson`). In memory only: after a restart
71590
+ * there is no trigger, so untargeted content goes to the primary person.
71591
+ */
71592
+ _lastInboundDm;
71593
+ /** #1418: turns in progress (`runForConversation`). */
71594
+ _activeTurns = /* @__PURE__ */ new Set();
71595
+ /**
71596
+ * #1418: recent owner 1:1 messages that decrypted, keyed by
71597
+ * conversation|group — evidence of which conversation, group and browser
71598
+ * belong together (one person). In memory only, bounded.
71599
+ */
71600
+ _attestedInbound = /* @__PURE__ */ new Map();
71601
+ /** #1418: per UNMAPPED group (or conversation), the last time it asked for a reconcile. */
71602
+ _unmappedReconcileAt = /* @__PURE__ */ new Map();
71603
+ /**
71604
+ * #1418: 1:1 groups joined by a Welcome IN THIS PROCESS while no
71605
+ * conversation mapped them — a person who has not been learned yet, counted
71606
+ * as one until the next successful reconcile. Persisted husks never are.
71607
+ */
71608
+ _welcomedUnmapped = /* @__PURE__ */ new Map();
71609
+ /** #1418: what the last SUCCESSFUL reconcile reported live, and when it started. */
71610
+ _lastReconcile;
71515
71611
  /** Rate-limit: last resync_request timestamp per conversation (5-min cooldown). */
71516
71612
  _lastResyncRequest = /* @__PURE__ */ new Map();
71517
71613
  /** Dedup: last room/group welcome self-heal request timestamp per group (30s window). */
@@ -72087,13 +72183,449 @@ ${text}`;
72087
72183
  }
72088
72184
  return `${kind}:${id ?? ""}`;
72089
72185
  }
72186
+ /*
72187
+ * #1416 — DM history is partitioned by conversation GROUP.
72188
+ *
72189
+ * Since #1399 every person has their own 1:1 group with the agent, but the
72190
+ * agent kept one DM history pool: a catch-up request or a session_init
72191
+ * replay from person B's group was answered with person A's plaintext too.
72192
+ * A DM entry's context now names its group:
72193
+ *
72194
+ * dm:g:<groupId>:<topicId> — the group is known
72195
+ * dm:c:<convId>:<topicId> — the conversation's group is not known yet
72196
+ * dm:<topicId> — legacy (pre-#1416): the PRIMARY group's
72197
+ *
72198
+ * Every form keeps the `dm:` prefix the archive, the web client and Hermes
72199
+ * test for, and the archive format (`topicId` is a free string) is unchanged.
72200
+ * An agent that knows at most one group selects exactly what it did before.
72201
+ */
72202
+ /** The DM history context for a message in `gid` (or `convId`'s group). */
72203
+ _dmHistoryContext(topicId, gid, convId) {
72204
+ const g2 = gid ?? (convId ? this._sessionGroupIds.get(convId) : void 0);
72205
+ if (g2) return `dm:g:${g2}:${topicId ?? ""}`;
72206
+ if (convId && this._knownDmGroups().size > 0) return `dm:c:${convId}:${topicId ?? ""}`;
72207
+ const legacyTopic = topicId && /^[gc]:/.test(topicId) ? "" : topicId;
72208
+ return this._historyContext("dm", legacyTopic);
72209
+ }
72210
+ /** Every conversation group this agent knows of. */
72211
+ _knownDmGroups() {
72212
+ const known = new Set(this._sessionGroupIds.values());
72213
+ if (this._persisted?.groupId) known.add(this._persisted.groupId);
72214
+ return known;
72215
+ }
72216
+ // --- #1418: only the person involved ----------------------------------
72217
+ /**
72218
+ * Run `fn` as the work an inbound 1:1 message from `conversationId`
72219
+ * triggered. Untargeted owner content sent while it runs — from inside its
72220
+ * async call chain, or from anywhere while it is the only turn in progress —
72221
+ * goes to that conversation's person only.
72222
+ *
72223
+ * `opts.groupId` is the group that message DECRYPTED under
72224
+ * (`metadata.conversationGroupId`). Pass it: it outranks the local
72225
+ * conversation→group map, which can be stale, and it is all there is for a
72226
+ * frame whose conversation is not mapped yet. With neither an id nor a
72227
+ * group, `fn` runs unchanged.
72228
+ */
72229
+ async runForConversation(conversationId, fn, opts) {
72230
+ const groupId = typeof opts?.groupId === "string" && opts.groupId ? opts.groupId : void 0;
72231
+ if (!conversationId && !groupId) return fn();
72232
+ const store = { convId: conversationId || void 0, groupId, ended: false };
72233
+ this._activeTurns.add(store);
72234
+ try {
72235
+ return await _turnConversation.run(store, fn);
72236
+ } finally {
72237
+ store.ended = true;
72238
+ store.endedAt = Date.now();
72239
+ this._activeTurns.delete(store);
72240
+ }
72241
+ }
72242
+ /**
72243
+ * The turn this call chain belongs to (#1418) — running, or ended but
72244
+ * still within the window in which work it left behind is for its person.
72245
+ * `"expired"` once that window is over: the work is proactive now.
72246
+ */
72247
+ _currentTurn() {
72248
+ const store = _turnConversation.getStore();
72249
+ if (!store) return void 0;
72250
+ if (!store.ended) return store;
72251
+ return Date.now() - (store.endedAt ?? 0) < PERSON_INVOLVED_WINDOW_MS ? store : "expired";
72252
+ }
72253
+ /**
72254
+ * Record an owner 1:1 message that just decrypted (#1418).
72255
+ *
72256
+ * Always kept as evidence of which conversation, group and browser belong
72257
+ * together (see `_dmPeople`). It makes its person "the person involved" only
72258
+ * when it is RECENT by the server's `createdAt`: a frame replayed from
72259
+ * backlog on reconnect is not something anyone is waiting on an answer to.
72260
+ */
72261
+ _noteInboundDm(convId, groupId, opts = {}) {
72262
+ if (!convId && !groupId) return;
72263
+ const now = Date.now();
72264
+ const sentAt = opts.createdAt ? Date.parse(opts.createdAt) : NaN;
72265
+ const at = Number.isFinite(sentAt) ? Math.min(now, sentAt) : now;
72266
+ const sender = opts.senderDeviceId && opts.senderDeviceId !== this._deviceId ? opts.senderDeviceId : void 0;
72267
+ const key = `${convId ?? ""}|${groupId ?? ""}|${sender ?? ""}`;
72268
+ const prior = this._attestedInbound.get(key);
72269
+ this._attestedInbound.delete(key);
72270
+ this._attestedInbound.set(key, { convId, groupId, senderDeviceId: sender, at: Math.max(prior?.at ?? 0, at) });
72271
+ while (this._attestedInbound.size > ATTESTED_INBOUND_MAX) {
72272
+ const oldest = this._attestedInbound.keys().next().value;
72273
+ if (oldest === void 0) break;
72274
+ this._attestedInbound.delete(oldest);
72275
+ }
72276
+ if (this._lastInboundDm && this._lastInboundDm.at > at) return;
72277
+ this._lastInboundDm = {
72278
+ convId,
72279
+ groupId: groupId ?? (convId ? this._sessionGroupIds.get(convId) : void 0),
72280
+ at
72281
+ };
72282
+ }
72283
+ /** The group `convId`'s most recent inbound decrypted under, if any. */
72284
+ _attestedGroupOf(convId) {
72285
+ if (!convId) return void 0;
72286
+ let gid;
72287
+ for (const a2 of this._attestedInbound.values()) {
72288
+ if (a2.convId === convId && a2.groupId) gid = a2.groupId;
72289
+ }
72290
+ return gid;
72291
+ }
72292
+ /** Does some mapped conversation point at `groupId`? */
72293
+ _isMappedGroup(groupId) {
72294
+ for (const gid of this._sessionGroupIds.values()) if (gid === groupId) return true;
72295
+ return false;
72296
+ }
72297
+ /**
72298
+ * An owner message decrypted under a group no mapped conversation points at
72299
+ * (#1418): the map is stale — a Welcome landed before its conversation was
72300
+ * learned, or a conversation was recreated. Re-resolve it from the server.
72301
+ * Fire-and-forget and rate-limited per group: never awaited on the receive
72302
+ * or Welcome path, so it can never hold up MLS processing.
72303
+ */
72304
+ _reconcileForUnmappedGroup(groupId) {
72305
+ if (!groupId || this._isMappedGroup(groupId)) return;
72306
+ this._reconcileSoon(`g:${groupId}`);
72307
+ }
72308
+ /** The same for a Double Ratchet message on a conversation the map does not know. */
72309
+ _reconcileForUnmappedConversation(convId) {
72310
+ if (!convId || this._sessionGroupIds.size === 0 || this._sessionGroupIds.has(convId)) return;
72311
+ this._reconcileSoon(`c:${convId}`);
72312
+ }
72313
+ _reconcileSoon(key) {
72314
+ const now = Date.now();
72315
+ if (now - (this._unmappedReconcileAt.get(key) ?? 0) < UNMAPPED_RECONCILE_COOLDOWN_MS) return;
72316
+ this._unmappedReconcileAt.set(key, now);
72317
+ void Promise.resolve().then(() => this._reconcileConversationGroups()).catch((err) => console.warn("[SecureChannel] Conversation-group reconcile (unmapped group) failed:", err));
72318
+ }
72319
+ /** A conversation of `groupId`, for an MLS frame that named only its group. */
72320
+ _conversationOfGroup(groupId) {
72321
+ if (!groupId) return void 0;
72322
+ if (this._primaryConversationId && this._sessionGroupIds.get(this._primaryConversationId) === groupId) {
72323
+ return this._primaryConversationId;
72324
+ }
72325
+ for (const [convId, gid] of this._sessionGroupIds) {
72326
+ if (gid === groupId) return convId;
72327
+ }
72328
+ return void 0;
72329
+ }
72330
+ /** Is `convId` one of this agent's own 1:1 conversations (never a room's or an A2A channel's)? */
72331
+ _isOwnDmConversation(convId) {
72332
+ if (this._isNonDmConversation(convId)) return false;
72333
+ return this._sessions.has(convId) || this._sessionGroupIds.has(convId) || !!this._persisted?.mlsConversations?.[convId] || convId === this._primaryConversationId;
72334
+ }
72335
+ /**
72336
+ * #1418 — the PEOPLE this agent has a 1:1 with, or `undefined` when it
72337
+ * cannot tell (no conversation is mapped: then it behaves as before #1418).
72338
+ *
72339
+ * People, not groups. Since #1399 one person has one group, but an agent
72340
+ * also keeps joined groups that are nobody's any more — husks of deleted or
72341
+ * recreated conversations. Measured 2026-10-24: wren held 13 joined groups
72342
+ * for 1 mapped, loopita 2 for 1, wowzer 2 for 1. Counting joined groups made
72343
+ * all three single-person agents look like several people, and their
72344
+ * replies could go only to a dead group.
72345
+ *
72346
+ * So a person is built from the conversations the server mapped, joined by
72347
+ * evidence that two things are the same person:
72348
+ * - the same group (a legacy group shared by several people cannot be told
72349
+ * apart, so it stays one — exactly the pre-#1418 behaviour);
72350
+ * - the same owner browser (a browser belongs to exactly one person);
72351
+ * - a message that decrypted under a group, from a conversation and browser.
72352
+ * A joined group nothing maps and nobody has spoken in is not a person. A
72353
+ * message on an unmapped group from a browser nobody knows IS someone —
72354
+ * that fails closed, toward "only them".
72355
+ */
72356
+ _dmPeople() {
72357
+ if (this._sessionGroupIds.size === 0) return void 0;
72358
+ const parent2 = /* @__PURE__ */ new Map();
72359
+ const add4 = (x2) => {
72360
+ if (!parent2.has(x2)) parent2.set(x2, x2);
72361
+ };
72362
+ const find = (x2) => {
72363
+ let root3 = x2;
72364
+ while (parent2.get(root3) !== root3) root3 = parent2.get(root3);
72365
+ return root3;
72366
+ };
72367
+ const union2 = (a2, b2) => {
72368
+ if (!a2 || !b2) return;
72369
+ add4(a2);
72370
+ add4(b2);
72371
+ const ra2 = find(a2), rb = find(b2);
72372
+ if (ra2 !== rb) parent2.set(ra2, rb);
72373
+ };
72374
+ const ownerOf = (convId) => {
72375
+ const owner = this._sessions.get(convId)?.ownerDeviceId ?? this._persisted?.sessions?.[convId]?.ownerDeviceId;
72376
+ return owner ? `d:${owner}` : void 0;
72377
+ };
72378
+ for (const [convId, gid] of this._sessionGroupIds) {
72379
+ add4(`c:${convId}`);
72380
+ union2(`c:${convId}`, `g:${gid}`);
72381
+ union2(`c:${convId}`, ownerOf(convId));
72382
+ }
72383
+ const primary = this._primaryConversationId || this._persisted?.primaryConversationId;
72384
+ const primaryGid = this._persisted?.groupId;
72385
+ if (primary && primaryGid && (parent2.has(`c:${primary}`) || parent2.has(`g:${primaryGid}`))) {
72386
+ union2(`c:${primary}`, `g:${primaryGid}`);
72387
+ }
72388
+ for (const gid of this._welcomedUnmapped.keys()) add4(`g:${gid}`);
72389
+ const records = [...this._attestedInbound.values()].map((a2) => ({
72390
+ a: a2,
72391
+ nodes: [
72392
+ a2.convId ? `c:${a2.convId}` : void 0,
72393
+ a2.groupId ? `g:${a2.groupId}` : void 0,
72394
+ a2.senderDeviceId ? `d:${a2.senderDeviceId}` : void 0
72395
+ ].filter((n2) => !!n2)
72396
+ }));
72397
+ const placed = /* @__PURE__ */ new Set();
72398
+ const place = (i2) => {
72399
+ const { a: a2, nodes } = records[i2];
72400
+ for (const n2 of nodes) add4(n2);
72401
+ for (const n2 of nodes.slice(1)) union2(nodes[0], n2);
72402
+ if (a2.convId && this._sessionGroupIds.has(a2.convId)) union2(`c:${a2.convId}`, ownerOf(a2.convId));
72403
+ placed.add(i2);
72404
+ };
72405
+ const linkKnown = () => {
72406
+ for (let progress = true; progress; ) {
72407
+ progress = false;
72408
+ records.forEach((r2, i2) => {
72409
+ if (!placed.has(i2) && r2.nodes.some((n2) => parent2.has(n2))) {
72410
+ place(i2);
72411
+ progress = true;
72412
+ }
72413
+ });
72414
+ }
72415
+ };
72416
+ linkKnown();
72417
+ records.forEach((r2, i2) => {
72418
+ if (!placed.has(i2) && this._mayBeNewPerson(r2.a)) place(i2);
72419
+ });
72420
+ linkKnown();
72421
+ const roots = /* @__PURE__ */ new Set();
72422
+ for (const node2 of parent2.keys()) {
72423
+ if (!node2.startsWith("d:")) roots.add(find(node2));
72424
+ }
72425
+ return {
72426
+ count: roots.size,
72427
+ keyOf: (convId, groupId) => {
72428
+ if (convId && parent2.has(`c:${convId}`)) return find(`c:${convId}`);
72429
+ if (groupId && parent2.has(`g:${groupId}`)) return find(`g:${groupId}`);
72430
+ return void 0;
72431
+ }
72432
+ };
72433
+ }
72434
+ /**
72435
+ * May this inbound evidence stand for a person nobody knows yet (#1418)?
72436
+ * Only if it was sent recently, and the last successful reconcile — when it
72437
+ * started after the message was sent — listed its conversation or group.
72438
+ */
72439
+ _mayBeNewPerson(a2) {
72440
+ if (Date.now() - a2.at >= PERSON_INVOLVED_WINDOW_MS) return false;
72441
+ const r2 = this._lastReconcile;
72442
+ if (r2 && a2.at <= r2.at && !(a2.convId && r2.convs.has(a2.convId)) && !(a2.groupId && r2.groups.has(a2.groupId))) return false;
72443
+ return true;
72444
+ }
72445
+ /** More than one person has a 1:1 with this agent (#1418). Unknown counts as one: the old behaviour. */
72446
+ _isMultiPerson() {
72447
+ return (this._dmPeople()?.count ?? 0) > 1;
72448
+ }
72449
+ /**
72450
+ * The group a turn's message decrypted under, for placing the turn when its
72451
+ * conversation is not mapped (a mapped conversation already names its person).
72452
+ */
72453
+ _turnGroup(turn) {
72454
+ return turn.groupId ?? this._attestedGroupOf(turn.convId);
72455
+ }
72456
+ /** The people with a 1:1 turn in progress, one turn each (#1418). */
72457
+ _activeTurnPeople() {
72458
+ const people = this._dmPeople();
72459
+ const out = /* @__PURE__ */ new Map();
72460
+ for (const turn of this._activeTurns) {
72461
+ if (turn.convId && (turn.groupId ? this._isNonDmConversation(turn.convId) : !this._isOwnDmConversation(turn.convId))) continue;
72462
+ const gid = this._turnGroup(turn);
72463
+ const key = people?.keyOf(turn.convId, gid) ?? (gid ? `g:${gid}` : `c:${turn.convId}`);
72464
+ if (!out.has(key)) out.set(key, turn);
72465
+ }
72466
+ return out;
72467
+ }
72468
+ /**
72469
+ * The person an untargeted owner message is for (#1418), in order:
72470
+ *
72471
+ * 1. the turn this call chain belongs to — always, and only, that
72472
+ * conversation, reached on the group its message decrypted under. A turn
72473
+ * never borrows another conversation's turn: one it cannot place fails
72474
+ * closed to its own conversation. Work the turn left running (a timer, a
72475
+ * dispatch orphaned by the turn budget) stays with that person for
72476
+ * `PERSON_INVOLVED_WINDOW_MS` after the turn, then is proactive (4);
72477
+ * 2. with no turn context (a skill's HTTP call), the one person with a turn
72478
+ * in progress;
72479
+ * 3. the last inbound 1:1 message, if it is recent — a reply produced in
72480
+ * response to it;
72481
+ * 4. otherwise the content is proactive: the PRIMARY conversation's person.
72482
+ */
72483
+ _involvedPerson() {
72484
+ const person = (convId, groupId, reason) => ({
72485
+ convId,
72486
+ groupId: groupId ?? this._attestedGroupOf(convId) ?? (convId ? this._sessionGroupIds.get(convId) : void 0),
72487
+ reason
72488
+ });
72489
+ const turn = this._currentTurn();
72490
+ if (turn && turn !== "expired") {
72491
+ return person(turn.convId ?? this._conversationOfGroup(turn.groupId), turn.groupId, turn.ended ? "outlived-turn" : "turn");
72492
+ }
72493
+ if (turn === "expired") return this._primaryPerson();
72494
+ const active = this._activeTurnPeople();
72495
+ if (active.size === 1) {
72496
+ const [only] = active.values();
72497
+ return person(only.convId ?? this._conversationOfGroup(only.groupId), only.groupId, "active-turn");
72498
+ }
72499
+ const last = this._lastInboundDm;
72500
+ if (active.size === 0 && last && Date.now() - last.at < PERSON_INVOLVED_WINDOW_MS) {
72501
+ return person(last.convId ?? this._conversationOfGroup(last.groupId), last.groupId, "last-inbound");
72502
+ }
72503
+ return this._primaryPerson();
72504
+ }
72505
+ /** The PRIMARY conversation's person — where proactive content goes. */
72506
+ _primaryPerson() {
72507
+ const primary = this._primaryConversationId || this._persisted?.primaryConversationId || void 0;
72508
+ const primaryGroup = (primary ? this._sessionGroupIds.get(primary) : void 0) ?? this._persisted?.groupId;
72509
+ return {
72510
+ convId: primary,
72511
+ groupId: primaryGroup ?? this._attestedGroupOf(primary),
72512
+ reason: "primary"
72513
+ };
72514
+ }
72515
+ /**
72516
+ * #1418 — would an untargeted owner send right now have to GUESS between
72517
+ * people? True only with no turn context while two or more people have a
72518
+ * turn in progress. The local HTTP API refuses such a request (409) and
72519
+ * asks for a conversation instead of picking one.
72520
+ */
72521
+ isUntargetedOwnerAmbiguous(options) {
72522
+ if (options?.conversationId !== void 0 || options?.audience === "everyone") return false;
72523
+ if (this._currentTurn()) return false;
72524
+ if (!this._isMultiPerson()) return false;
72525
+ return this._activeTurnPeople().size > 1;
72526
+ }
72527
+ /**
72528
+ * Who an UNTARGETED owner send reaches, or `null` for "every session, as
72529
+ * before". `null` when the caller chose `audience: "everyone"`, and when the
72530
+ * agent has one person (or cannot tell how many) — nothing to choose
72531
+ * between, so its recipients are exactly what they always were.
72532
+ */
72533
+ _untargetedAudience(options) {
72534
+ if (options?.conversationId !== void 0) return null;
72535
+ if (options?.audience === "everyone") return null;
72536
+ if (!this._isMultiPerson()) return null;
72537
+ return this._involvedPerson();
72538
+ }
72539
+ /** A stable name for who an untargeted owner send reaches right now, or undefined when that is "everyone, as before". */
72540
+ _audienceTag(options) {
72541
+ if (options?.audience === "everyone") return "everyone";
72542
+ const person = this._untargetedAudience(options);
72543
+ return person ? `person:${person.groupId ?? person.convId ?? ""}` : void 0;
72544
+ }
72545
+ /** Does conversation `convId` belong to `person`? A conversation nothing ties to them fails closed. */
72546
+ _isPersonsConversation(person, convId) {
72547
+ if (convId === person.convId) return true;
72548
+ const gid = this._sessionGroupIds.get(convId);
72549
+ if (gid !== void 0 && gid === person.groupId) return true;
72550
+ const people = this._dmPeople();
72551
+ const theirs = people?.keyOf(person.convId, person.groupId);
72552
+ return theirs !== void 0 && people.keyOf(convId, gid) === theirs;
72553
+ }
72554
+ /**
72555
+ * #1418: the Double Ratchet sessions an owner-bound FILE (attachment or
72556
+ * artifact) goes to, bucketed by the conversation its blob is uploaded
72557
+ * under. The blob is uploaded under a conversation of the person who gets
72558
+ * it — the backend only lets that conversation's participants download it —
72559
+ * so an explicit "everyone" uploads once per person.
72560
+ */
72561
+ _ownerFileRecipients(routing) {
72562
+ const roomConvIds = /* @__PURE__ */ new Set();
72563
+ for (const room of Object.values(this._persisted?.rooms ?? {})) {
72564
+ for (const cid of room.conversationIds ?? []) roomConvIds.add(cid);
72565
+ }
72566
+ const live = [...this._sessions].filter(([convId, session]) => session.activated && !roomConvIds.has(convId)).map(([convId]) => convId);
72567
+ const person = routing?.conversationId !== void 0 ? { convId: routing.conversationId, groupId: this._sessionGroupIds.get(routing.conversationId), reason: "target" } : this._untargetedAudience(routing);
72568
+ if (person) {
72569
+ const convIds = live.filter((convId) => this._isPersonsConversation(person, convId));
72570
+ const uploadConvId = person.convId ?? convIds[0];
72571
+ return uploadConvId && convIds.length > 0 ? [{ uploadConvId, convIds }] : [];
72572
+ }
72573
+ if (live.length === 0) return [];
72574
+ if (!this._isMultiPerson()) {
72575
+ return [{ uploadConvId: this._primaryConversationId, convIds: live }];
72576
+ }
72577
+ const people = this._dmPeople();
72578
+ const buckets = /* @__PURE__ */ new Map();
72579
+ for (const convId of live) {
72580
+ const gid = this._sessionGroupIds.get(convId);
72581
+ const key = people?.keyOf(convId, gid) ?? gid ?? `c:${convId}`;
72582
+ buckets.set(key, [...buckets.get(key) ?? [], convId]);
72583
+ }
72584
+ return [...buckets.values()].map((convIds) => ({
72585
+ uploadConvId: convIds.includes(this._primaryConversationId) ? this._primaryConversationId : convIds[0],
72586
+ convIds
72587
+ }));
72588
+ }
72589
+ /** The group a DM history entry belongs to (see the forms above). */
72590
+ _dmEntryScope(entry, known) {
72591
+ const t2 = entry.topicId ?? "";
72592
+ let scope;
72593
+ if (t2.startsWith("dm:g:")) {
72594
+ scope = t2.slice("dm:g:".length).split(":")[0];
72595
+ } else if (t2.startsWith("dm:c:")) {
72596
+ const conv = t2.slice("dm:c:".length).split(":")[0];
72597
+ scope = this._sessionGroupIds.get(conv) ?? `c:${conv}`;
72598
+ } else {
72599
+ scope = this._persisted?.groupId;
72600
+ }
72601
+ if ((scope === void 0 || scope.startsWith("c:")) && known.size === 1) {
72602
+ return [...known][0];
72603
+ }
72604
+ return scope;
72605
+ }
72606
+ /**
72607
+ * The group a DM history request is answered from, or `null` for "every DM
72608
+ * entry" (an agent that knows no groups at all — the old behaviour). A
72609
+ * request whose group cannot be told fails closed to its own conversation.
72610
+ */
72611
+ _dmRequestScope(gid, convId, known) {
72612
+ if (known.size === 0) return null;
72613
+ const g2 = gid ?? (convId ? this._sessionGroupIds.get(convId) : void 0);
72614
+ if (g2) return g2;
72615
+ const isPrimaryConv = convId === void 0 || convId === this._primaryConversationId;
72616
+ if (known.size === 1 && isPrimaryConv) return [...known][0];
72617
+ if (convId && convId === this._primaryConversationId && this._persisted?.groupId) {
72618
+ return this._persisted.groupId;
72619
+ }
72620
+ return `c:${convId ?? ""}`;
72621
+ }
72090
72622
  /**
72091
72623
  * Normalize one accepted application envelope before it enters plaintext
72092
72624
  * history. Protocol/control types and empty attachment-only envelopes are
72093
72625
  * never archived, and attachment key material can never become the fallback
72094
72626
  * text.
72095
72627
  */
72096
- async _captureHistoryApplication(sender, rawPlaintext, kind, id, transportTimestamp, declaredType = "message") {
72628
+ async _captureHistoryApplication(sender, rawPlaintext, kind, id, transportTimestamp, declaredType = "message", dmScope) {
72097
72629
  let messageType = declaredType;
72098
72630
  let text = rawPlaintext;
72099
72631
  try {
@@ -72108,14 +72640,14 @@ ${text}`;
72108
72640
  await this._appendHistory(
72109
72641
  sender,
72110
72642
  text,
72111
- this._historyContext(kind, id),
72643
+ kind === "dm" ? this._dmHistoryContext(id, dmScope?.groupId, dmScope?.conversationId) : this._historyContext(kind, id),
72112
72644
  transportTimestamp
72113
72645
  );
72114
72646
  return text;
72115
72647
  }
72116
72648
  /** Select a context before applying the optional lower bound and final cap. */
72117
- _historyForCatchup(kind, id, sinceTs) {
72118
- let filtered = this._selectHistoryContext(kind, id);
72649
+ _historyForCatchup(kind, id, sinceTs, dmScope) {
72650
+ let filtered = this._selectHistoryContext(kind, id, dmScope);
72119
72651
  if (sinceTs !== void 0 && sinceTs !== null) {
72120
72652
  if (typeof sinceTs !== "string" || !CANONICAL_TIMESTAMP_RE.test(sinceTs) || !Number.isFinite(Date.parse(sinceTs)) || new Date(Date.parse(sinceTs)).toISOString() !== sinceTs) {
72121
72653
  throw new Error("Invalid history catch-up timestamp");
@@ -72125,11 +72657,17 @@ ${text}`;
72125
72657
  return filtered.sort((a2, b2) => Date.parse(a2.ts) - Date.parse(b2.ts) || a2.id.localeCompare(b2.id)).slice(-100);
72126
72658
  }
72127
72659
  /** Shared exact routing selector for catch-up and legacy DR replay. */
72128
- _selectHistoryContext(kind, id) {
72660
+ _selectHistoryContext(kind, id, dmScope) {
72129
72661
  const history = this._persisted?.messageHistory ?? [];
72130
- return kind === "room" ? history.filter((entry) => entry.topicId === this._historyContext("room", id)) : history.filter(
72662
+ if (kind === "room") {
72663
+ return history.filter((entry) => entry.topicId === this._historyContext("room", id));
72664
+ }
72665
+ const dm = history.filter(
72131
72666
  (entry) => entry.topicId?.startsWith("dm:") === true || !entry.topicId?.startsWith("room:") && !entry.topicId?.startsWith("a2a:")
72132
72667
  );
72668
+ const known = this._knownDmGroups();
72669
+ const want = this._dmRequestScope(dmScope?.groupId, dmScope?.conversationId, known);
72670
+ return want === null ? dm : dm.filter((entry) => this._dmEntryScope(entry, known) === want);
72133
72671
  }
72134
72672
  _markHistoryDirty() {
72135
72673
  this._historyBackupScheduler.markDirty();
@@ -72619,7 +73157,10 @@ ${text}`;
72619
73157
  Promise.resolve().then(() => (init_openclaw_compat(), openclaw_compat_exports)).then(({ requestHeartbeatNow: requestHeartbeatNow2 }) => requestHeartbeatNow2({ reason: "channel-send" })).catch(() => {
72620
73158
  });
72621
73159
  const targetConvId = options?.conversationId;
72622
- const topicId = options?.topicId ?? this._lastIncomingTopicId ?? this._persisted?.defaultTopicId;
73160
+ const audience = this._untargetedAudience(options);
73161
+ const explicitTopicId = options?.topicId;
73162
+ const targeted = targetConvId !== void 0;
73163
+ const frameHistoryContexts = [];
72623
73164
  const messageType = options?.messageType ?? "text";
72624
73165
  const priority = options?.priority ?? "normal";
72625
73166
  const parentSpanId = options?.parentSpanId;
@@ -72655,7 +73196,7 @@ ${text}`;
72655
73196
  if (this._persisted?.mlsGroups && this._state === "ready" && this._ws) {
72656
73197
  const targetSharedGid = targetConvId ? this._sessionGroupIds?.get(targetConvId) : void 0;
72657
73198
  console.log(
72658
- `[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)"}`
73199
+ `[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)"}`
72659
73200
  );
72660
73201
  const skipped = [];
72661
73202
  for (const [gid, entry] of Object.entries(this._persisted.mlsGroups)) {
@@ -72663,6 +73204,10 @@ ${text}`;
72663
73204
  skipped.push(`${gid.slice(0, 8)}:not-target`);
72664
73205
  continue;
72665
73206
  }
73207
+ if (audience && gid !== audience.groupId) {
73208
+ skipped.push(`${gid.slice(0, 8)}:not-involved`);
73209
+ continue;
73210
+ }
72666
73211
  if (!entry.mlsGroupId) {
72667
73212
  skipped.push(`${gid.slice(0, 8)}:no-mlsGroupId`);
72668
73213
  continue;
@@ -72686,11 +73231,12 @@ ${text}`;
72686
73231
  plaintextBytes
72687
73232
  );
72688
73233
  await saveMlsState(this.config.dataDir, entry.mlsGroupId, JSON.stringify(mlsGroup.exportState()));
73234
+ const frameTopicId = this._topicForFrame(gid, targetConvId, explicitTopicId, targeted);
72689
73235
  const payload = {
72690
73236
  group_id: entry.mlsGroupId,
72691
73237
  epoch: Number(mlsGroup.epoch),
72692
73238
  payload: Buffer.from(cipherBytes).toString("hex"),
72693
- topic_id: topicId,
73239
+ topic_id: frameTopicId,
72694
73240
  client_message_id: clientMessageId,
72695
73241
  message_type: messageType,
72696
73242
  priority,
@@ -72700,6 +73246,7 @@ ${text}`;
72700
73246
  if (this._persisted?.hubAddress) payload.hub_address = this._persisted.hubAddress;
72701
73247
  if (this._persisted?.hubId) payload.sender_hub_id = this._persisted.hubId;
72702
73248
  pendingWsSends.push(JSON.stringify({ event: "message_mls", data: payload }));
73249
+ frameHistoryContexts.push(this._dmHistoryContext(frameTopicId, gid, targetConvId));
72703
73250
  addressedMlsGroupIds.push(entry.mlsGroupId);
72704
73251
  sentSharedGroupIds.add(gid);
72705
73252
  sentCount++;
@@ -72717,12 +73264,14 @@ ${text}`;
72717
73264
  if (!session.activated) continue;
72718
73265
  if (roomConvIds.has(convId)) continue;
72719
73266
  if (targetConvId && convId !== targetConvId) continue;
73267
+ if (audience && !this._isPersonsConversation(audience, convId)) continue;
72720
73268
  const convGroupId = this._sessionGroupIds?.get(convId);
72721
73269
  if (convGroupId && sentSharedGroupIds.has(convGroupId)) {
72722
73270
  sentCount++;
72723
73271
  continue;
72724
73272
  }
72725
73273
  try {
73274
+ const topicId = this._topicForFrame(convGroupId, convId, explicitTopicId, targeted);
72726
73275
  const mlsGroup = (convGroupId ? this._mlsGroups.get(`1to1-group:${convGroupId}`) : null) ?? this._mlsGroups.get(`conv:${convId}`);
72727
73276
  const mlsGroupId = (convGroupId ? this._persisted?.mlsGroups?.[convGroupId]?.mlsGroupId : null) ?? this._persisted?.mlsConversations?.[convId]?.mlsGroupId;
72728
73277
  if (convGroupId && mlsGroupId && sentSharedGroupIds.has(convGroupId)) {
@@ -72764,6 +73313,7 @@ ${text}`;
72764
73313
  data: payload
72765
73314
  })
72766
73315
  );
73316
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, convGroupId, convId));
72767
73317
  addressedMlsGroupIds.push(mlsGroupId);
72768
73318
  if (convGroupId) sentSharedGroupIds.add(convGroupId);
72769
73319
  } else if (!options?.bypassMlsHold && this._shouldHoldForMls(convGroupId, mlsGroup, mlsGroupId)) {
@@ -72783,7 +73333,7 @@ ${text}`;
72783
73333
  history: {
72784
73334
  id: clientMessageId,
72785
73335
  text: plaintext,
72786
- topicId: this._historyContext("dm", topicId)
73336
+ topicId: this._dmHistoryContext(topicId, convGroupId, convId)
72787
73337
  }
72788
73338
  } : {}
72789
73339
  };
@@ -72812,6 +73362,7 @@ ${text}`;
72812
73362
  data: payload
72813
73363
  })
72814
73364
  );
73365
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, convGroupId, convId));
72815
73366
  } else {
72816
73367
  if (!this._persisted.outboundQueue) {
72817
73368
  this._persisted.outboundQueue = [];
@@ -72832,6 +73383,7 @@ ${text}`;
72832
73383
  if (this._persisted?.mlsConversations && this._state === "ready" && this._ws) {
72833
73384
  for (const [mlsConvId, entry] of Object.entries(this._persisted.mlsConversations)) {
72834
73385
  if (targetConvId && mlsConvId !== targetConvId) continue;
73386
+ if (audience && !this._isPersonsConversation(audience, mlsConvId)) continue;
72835
73387
  if (this._sessions.has(mlsConvId)) continue;
72836
73388
  if (roomConvIds.has(mlsConvId)) continue;
72837
73389
  const mlsOnlyConvGroupId = this._sessionGroupIds?.get(mlsConvId);
@@ -72843,6 +73395,7 @@ ${text}`;
72843
73395
  continue;
72844
73396
  }
72845
73397
  try {
73398
+ const topicId = this._topicForFrame(mlsOnlyConvGroupId, mlsConvId, explicitTopicId, targeted);
72846
73399
  const plaintextBytes = new TextEncoder().encode(plaintext);
72847
73400
  const mlsOnlyGroupKey = mlsOnlyConvGroupId && this._mlsGroups.has(`1to1-group:${mlsOnlyConvGroupId}`) ? `1to1-group:${mlsOnlyConvGroupId}` : `conv:${mlsConvId}`;
72848
73401
  const cipherBytes = await this._encryptWithCatchUp(
@@ -72868,6 +73421,7 @@ ${text}`;
72868
73421
  if (this._persisted?.hubAddress) payload.hub_address = this._persisted.hubAddress;
72869
73422
  if (this._persisted?.hubId) payload.sender_hub_id = this._persisted.hubId;
72870
73423
  pendingWsSends.push(JSON.stringify({ event: "message_mls", data: payload }));
73424
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, mlsOnlyConvGroupId, mlsConvId));
72871
73425
  addressedMlsGroupIds.push(resolvedMlsGroupId);
72872
73426
  sentCount++;
72873
73427
  if (mlsOnlyConvGroupId) sentSharedGroupIds.add(mlsOnlyConvGroupId);
@@ -72889,11 +73443,15 @@ ${text}`;
72889
73443
  );
72890
73444
  }
72891
73445
  let writtenFrames = 0;
72892
- for (const frame of pendingWsSends) {
72893
- if (this._sendApplicationFrame(frame)) writtenFrames += 1;
73446
+ let historyContext;
73447
+ for (const [i2, frame] of pendingWsSends.entries()) {
73448
+ if (this._sendApplicationFrame(frame)) {
73449
+ if (writtenFrames === 0) historyContext = frameHistoryContexts[i2];
73450
+ writtenFrames += 1;
73451
+ }
72894
73452
  }
72895
73453
  if (!options?.isResend && messageType === "text" && writtenFrames > 0) {
72896
- await this._appendHistory("agent", plaintext, this._historyContext("dm", topicId), void 0, clientMessageId);
73454
+ await this._appendHistory("agent", plaintext, historyContext ?? this._historyContext("dm"), void 0, clientMessageId);
72897
73455
  }
72898
73456
  if (writtenFrames > 0) {
72899
73457
  console.log(
@@ -72949,7 +73507,7 @@ ${text}`;
72949
73507
  */
72950
73508
  sendActivitySpan(spanData) {
72951
73509
  if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
72952
- const pluginVersion = true ? "0.23.50" : "0.0.0-dev";
73510
+ const pluginVersion = true ? "0.23.52" : "0.0.0-dev";
72953
73511
  const agentName = this.config.agentName ?? "Agent";
72954
73512
  const resource = {
72955
73513
  "service.name": "agentvault-agent",
@@ -73001,7 +73559,7 @@ ${text}`;
73001
73559
  * Builds a structured envelope with decision metadata and sends it
73002
73560
  * as a high-priority message. Returns the generated decision_id.
73003
73561
  */
73004
- async sendDecisionRequest(request) {
73562
+ async sendDecisionRequest(request, routing) {
73005
73563
  const decision_id = `dec_${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
73006
73564
  const payload = JSON.stringify({
73007
73565
  type: "message",
@@ -73012,6 +73570,8 @@ ${text}`;
73012
73570
  }
73013
73571
  });
73014
73572
  await this.send(payload, {
73573
+ conversationId: routing?.conversationId,
73574
+ audience: routing?.audience,
73015
73575
  messageType: "decision_request",
73016
73576
  priority: "high",
73017
73577
  metadata: {
@@ -73418,6 +73978,7 @@ ${text}`;
73418
73978
  const jwt = this._deviceJwt ?? this._persisted?.deviceJwt;
73419
73979
  if (!jwt || !this._persisted) return false;
73420
73980
  let rows;
73981
+ const reconcileStartedAt = Date.now();
73421
73982
  try {
73422
73983
  const res = await fetch(`${this.config.apiUrl}/api/v1/conversations`, {
73423
73984
  headers: { Authorization: `Bearer ${jwt}` }
@@ -73434,8 +73995,31 @@ ${text}`;
73434
73995
  );
73435
73996
  if (mine.length === 0) return false;
73436
73997
  const before = this._persisted.groupId;
73998
+ const primaryBefore = this._persisted.primaryConversationId;
73999
+ const knownBefore = this._knownDmGroups();
74000
+ const ownersBefore = /* @__PURE__ */ new Set();
74001
+ if (before) {
74002
+ for (const [convId, gid] of this._sessionGroupIds) {
74003
+ if (gid !== before) continue;
74004
+ const owner = this._sessions.get(convId)?.ownerDeviceId ?? this._persisted.sessions?.[convId]?.ownerDeviceId;
74005
+ if (owner) ownersBefore.add(owner);
74006
+ }
74007
+ }
73437
74008
  this._sessionGroupIds = new Map(mine.map((r2) => [r2.id, r2.group_id]));
73438
74009
  this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
74010
+ {
74011
+ const convs = new Set(mine.map((r2) => r2.id));
74012
+ const groups = new Set(mine.map((r2) => r2.group_id));
74013
+ this._lastReconcile = { at: reconcileStartedAt, convs, groups };
74014
+ for (const [key, a2] of this._attestedInbound) {
74015
+ if (a2.at > reconcileStartedAt) continue;
74016
+ if (a2.convId && convs.has(a2.convId) || a2.groupId && groups.has(a2.groupId)) continue;
74017
+ this._attestedInbound.delete(key);
74018
+ }
74019
+ for (const [gid, at] of this._welcomedUnmapped) {
74020
+ if (at <= reconcileStartedAt) this._welcomedUnmapped.delete(gid);
74021
+ }
74022
+ }
73439
74023
  const joined = mine.find((r2) => this._persisted.mlsGroups?.[r2.group_id]);
73440
74024
  const primary = mine.find((r2) => r2.id === this._persisted.primaryConversationId) ?? joined ?? mine[0];
73441
74025
  if (!mine.some((r2) => r2.id === this._persisted.primaryConversationId)) {
@@ -73445,6 +74029,23 @@ ${text}`;
73445
74029
  }
73446
74030
  this._persisted.groupId = primary.group_id;
73447
74031
  this._persisted.primaryConversationId = primary.id;
74032
+ for (const r2 of mine) {
74033
+ if (typeof r2.default_topic_id === "string") this._recordDefaultTopic(r2.group_id, r2.default_topic_id);
74034
+ }
74035
+ const primaryDefault = this._persisted.defaultTopicIds?.[primary.group_id];
74036
+ if (primaryDefault) this._persisted.defaultTopicId = primaryDefault;
74037
+ const primaryOwner = primary.owner_device_id;
74038
+ const samePerson = primary.id === primaryBefore || typeof primaryOwner === "string" && ownersBefore.has(primaryOwner);
74039
+ let retagged = false;
74040
+ if (before && primary.group_id !== before && knownBefore.size === 1 && knownBefore.has(before) && samePerson) {
74041
+ const oldPrefix = `dm:g:${before}:`;
74042
+ for (const entry of this._persisted.messageHistory ?? []) {
74043
+ if (entry.topicId?.startsWith(oldPrefix)) {
74044
+ entry.topicId = `dm:g:${primary.group_id}:${entry.topicId.slice(oldPrefix.length)}`;
74045
+ retagged = true;
74046
+ }
74047
+ }
74048
+ }
73448
74049
  const liveGroupIds = new Set(mine.map((r2) => r2.group_id));
73449
74050
  if (staleGid && staleMlsGroupId && !liveGroupIds.has(staleGid)) {
73450
74051
  try {
@@ -73459,6 +74060,10 @@ ${text}`;
73459
74060
  });
73460
74061
  }
73461
74062
  await this._persistState();
74063
+ if (retagged) {
74064
+ this._markHistoryDirty();
74065
+ await this._saveHistoryState();
74066
+ }
73462
74067
  console.log(
73463
74068
  `[SecureChannel] Re-resolved conversation groups ${staleMlsGroupId ? `after 'unknown group' ${staleMlsGroupId.slice(0, 8)}` : "on connect (#1034)"}: primary group ${String(before).slice(0, 8)} \u2192 ${this._persisted.groupId.slice(0, 8)} (${mine.length} active conversation(s))`
73464
74069
  );
@@ -73608,7 +74213,7 @@ ${text}`;
73608
74213
  }
73609
74214
  this._heartbeatCallback = null;
73610
74215
  }
73611
- async sendStatusAlert(alert) {
74216
+ async sendStatusAlert(alert, routing) {
73612
74217
  const priority = alert.severity === "error" || alert.severity === "critical" ? "high" : "normal";
73613
74218
  const envelope = {
73614
74219
  title: alert.title,
@@ -73622,52 +74227,61 @@ ${text}`;
73622
74227
  await this.send(
73623
74228
  JSON.stringify(envelope),
73624
74229
  {
74230
+ conversationId: routing?.conversationId,
74231
+ audience: routing?.audience,
73625
74232
  messageType: "status_alert",
73626
74233
  priority,
73627
74234
  metadata: { severity: alert.severity }
73628
74235
  }
73629
74236
  );
73630
74237
  }
73631
- async sendArtifact(artifact) {
74238
+ async sendArtifact(artifact, routing) {
73632
74239
  if (this._state !== "ready" || this._sessions.size === 0 || !this._ws) {
73633
74240
  throw new Error("Channel is not ready");
73634
74241
  }
73635
- const attachMeta = await this._uploadAttachment(artifact.filePath, this._primaryConversationId);
73636
- const envelope = JSON.stringify({
73637
- type: "artifact",
73638
- blob_id: attachMeta.blobId,
73639
- blob_url: attachMeta.blobUrl,
73640
- filename: artifact.filename,
73641
- mime_type: artifact.mimeType,
73642
- size_bytes: attachMeta.size,
73643
- description: artifact.description,
73644
- attachment: attachMeta
73645
- });
73646
74242
  const messageGroupId = randomUUID4();
73647
74243
  const pendingWsSends = [];
73648
- for (const [convId, session] of this._sessions) {
73649
- if (!session.activated) continue;
73650
- const encrypted = session.ratchet.encrypt(envelope);
73651
- const transport = encryptedMessageToTransport(encrypted);
73652
- pendingWsSends.push(
73653
- JSON.stringify({
73654
- event: "message",
73655
- data: {
73656
- conversation_id: convId,
73657
- header_blob: transport.header_blob,
73658
- ciphertext: transport.ciphertext,
73659
- message_group_id: messageGroupId,
73660
- message_type: "artifact_share"
73661
- }
73662
- })
73663
- );
74244
+ const buckets = this._ownerFileRecipients(routing);
74245
+ if (buckets.length === 0) {
74246
+ console.warn("[SecureChannel] sendArtifact(): no live session for the person involved \u2014 nothing sent");
74247
+ throw new Error("No conversation is ready to receive this file");
74248
+ }
74249
+ for (const bucket of buckets) {
74250
+ const attachMeta = await this._uploadAttachment(artifact.filePath, bucket.uploadConvId);
74251
+ const envelope = JSON.stringify({
74252
+ type: "artifact",
74253
+ blob_id: attachMeta.blobId,
74254
+ blob_url: attachMeta.blobUrl,
74255
+ filename: artifact.filename,
74256
+ mime_type: artifact.mimeType,
74257
+ size_bytes: attachMeta.size,
74258
+ description: artifact.description,
74259
+ attachment: attachMeta
74260
+ });
74261
+ for (const convId of bucket.convIds) {
74262
+ const session = this._sessions.get(convId);
74263
+ const encrypted = session.ratchet.encrypt(envelope);
74264
+ const transport = encryptedMessageToTransport(encrypted);
74265
+ pendingWsSends.push(
74266
+ JSON.stringify({
74267
+ event: "message",
74268
+ data: {
74269
+ conversation_id: convId,
74270
+ header_blob: transport.header_blob,
74271
+ ciphertext: transport.ciphertext,
74272
+ message_group_id: messageGroupId,
74273
+ message_type: "artifact_share"
74274
+ }
74275
+ })
74276
+ );
74277
+ }
73664
74278
  }
73665
74279
  await this._persistState();
73666
74280
  for (const frame of pendingWsSends) {
73667
74281
  this._ws.send(frame);
73668
74282
  }
73669
74283
  }
73670
- async sendActionConfirmation(confirmation) {
74284
+ async sendActionConfirmation(confirmation, routing) {
73671
74285
  const envelope = {
73672
74286
  type: "action_confirmation",
73673
74287
  action: confirmation.action,
@@ -73678,6 +74292,8 @@ ${text}`;
73678
74292
  await this.send(
73679
74293
  JSON.stringify(envelope),
73680
74294
  {
74295
+ conversationId: routing?.conversationId,
74296
+ audience: routing?.audience,
73681
74297
  messageType: "action_confirmation",
73682
74298
  metadata: { status: confirmation.status }
73683
74299
  }
@@ -73783,9 +74399,23 @@ ${text}`;
73783
74399
  } else {
73784
74400
  return { ok: false, destination: { kind: "owner" }, error: "Unknown target kind", timestamp: ts };
73785
74401
  }
74402
+ if (resolved.kind === "owner" && options?.refuseIfAmbiguous && this.isUntargetedOwnerAmbiguous(options)) {
74403
+ console.log(`[deliver] target=owner content=${content.type} result=REFUSED: ambiguous (several people mid-turn)`);
74404
+ return { ok: false, ambiguous: true, destination: resolved, error: AMBIGUOUS_OWNER_ERROR, timestamp: ts };
74405
+ }
73786
74406
  let dedupeKey = null;
73787
74407
  try {
73788
- dedupeKey = outboundDedupeKey(resolved, content, options);
74408
+ let audienceTag;
74409
+ try {
74410
+ audienceTag = resolved.kind === "owner" && options?.conversationId === void 0 ? this._audienceTag(options) : void 0;
74411
+ } catch {
74412
+ audienceTag = void 0;
74413
+ }
74414
+ dedupeKey = outboundDedupeKey(
74415
+ resolved,
74416
+ content,
74417
+ audienceTag ? { ...options, conversationId: audienceTag } : options
74418
+ );
73789
74419
  if (dedupeKey) {
73790
74420
  const now = Date.now();
73791
74421
  const recent = this._recentDeliveries ??= /* @__PURE__ */ new Map();
@@ -73805,6 +74435,10 @@ ${text}`;
73805
74435
  }
73806
74436
  try {
73807
74437
  let decisionId;
74438
+ const ownerRouting = {
74439
+ conversationId: options?.conversationId,
74440
+ audience: options?.audience
74441
+ };
73808
74442
  if (content.type === "text") {
73809
74443
  if (resolved.kind === "room") {
73810
74444
  await this.sendToRoom(resolved.id, content.text, {
@@ -73823,6 +74457,7 @@ ${text}`;
73823
74457
  } else {
73824
74458
  await this.send(content.text, {
73825
74459
  conversationId: options?.conversationId,
74460
+ audience: options?.audience,
73826
74461
  topicId: options?.topicId,
73827
74462
  messageType: options?.metadata?.message_type,
73828
74463
  priority: options?.priority,
@@ -73835,7 +74470,7 @@ ${text}`;
73835
74470
  console.log(`[deliver] target=${resolved.kind}:${resolved.id} content=decision_request result=FAIL: ${err}`);
73836
74471
  return { ok: false, destination: resolved, error: err, timestamp: ts };
73837
74472
  }
73838
- decisionId = await this.sendDecisionRequest(content.request);
74473
+ decisionId = await this.sendDecisionRequest(content.request, ownerRouting);
73839
74474
  } else if (content.type === "status_alert") {
73840
74475
  if (resolved.kind === "room") {
73841
74476
  const envelope = {
@@ -73853,7 +74488,7 @@ ${text}`;
73853
74488
  metadata: { severity: content.alert.severity }
73854
74489
  });
73855
74490
  } else if (resolved.kind === "owner") {
73856
- await this.sendStatusAlert(content.alert);
74491
+ await this.sendStatusAlert(content.alert, ownerRouting);
73857
74492
  } else {
73858
74493
  return { ok: false, destination: resolved, error: "Status alerts cannot be sent to A2A targets", timestamp: ts };
73859
74494
  }
@@ -73861,7 +74496,7 @@ ${text}`;
73861
74496
  if (resolved.kind === "room") {
73862
74497
  await this.sendActionConfirmationToRoom(resolved.id, content.confirmation);
73863
74498
  } else if (resolved.kind === "owner") {
73864
- await this.sendActionConfirmation(content.confirmation);
74499
+ await this.sendActionConfirmation(content.confirmation, ownerRouting);
73865
74500
  } else {
73866
74501
  return { ok: false, destination: resolved, error: "Action confirmations cannot be sent to A2A targets", timestamp: ts };
73867
74502
  }
@@ -73869,13 +74504,14 @@ ${text}`;
73869
74504
  if (resolved.kind !== "owner") {
73870
74505
  return { ok: false, destination: resolved, error: "Artifacts can only be sent to owner", timestamp: ts };
73871
74506
  }
73872
- await this.sendArtifact(content.artifact);
74507
+ await this.sendArtifact(content.artifact, ownerRouting);
73873
74508
  } else if (content.type === "attachment") {
73874
74509
  if (resolved.kind !== "owner") {
73875
74510
  return { ok: false, destination: resolved, error: "Attachments can only be sent to owner", timestamp: ts };
73876
74511
  }
73877
74512
  await this.sendWithAttachment(content.text, content.filePath, {
73878
- topicId: options?.topicId
74513
+ topicId: options?.topicId,
74514
+ ...ownerRouting
73879
74515
  });
73880
74516
  }
73881
74517
  const targetLabel = resolved.kind === "owner" ? "owner" : `${resolved.kind}:${resolved.id?.slice(0, 8)}...`;
@@ -74192,15 +74828,105 @@ ${text}`;
74192
74828
  return this._mcpServer;
74193
74829
  }
74194
74830
  // --- Topic management ---
74831
+ /*
74832
+ * #1416 — topics are per conversation GROUP.
74833
+ *
74834
+ * Since #1399 every person has their own 1:1 group with the agent, and a
74835
+ * topic belongs to exactly one group (`topics.group_id`). The agent used to
74836
+ * keep ONE default topic (the primary group's) and ONE last-incoming topic,
74837
+ * and stamped both on every frame — so a reply into person B's group could
74838
+ * carry person A's topic, and B's web client (which filters live messages by
74839
+ * the topic it is viewing) dropped it until a reload.
74840
+ *
74841
+ * The rule now: a frame's topic comes from THAT frame's group. A group with
74842
+ * no known topic gets none — the server then files the message under that
74843
+ * conversation's own default topic (`ws.py`, lazily created) — rather than
74844
+ * borrowing another group's.
74845
+ */
74846
+ /** Scope key for per-group topic state; see `_lastIncomingTopics`. */
74847
+ _topicScope(gid, convId) {
74848
+ if (gid) return `g:${gid}`;
74849
+ if (!this._persisted?.groupId && this._sessionGroupIds.size === 0) return "*";
74850
+ return convId ? `c:${convId}` : void 0;
74851
+ }
74852
+ /** Record the topic of an inbound 1:1 message for its own group (#1416). */
74853
+ _rememberIncomingTopic(convId, gid, topicId) {
74854
+ const scope = this._topicScope(gid ?? (convId ? this._sessionGroupIds.get(convId) : void 0), convId);
74855
+ if (!scope) return;
74856
+ if (topicId && !isTopicId(topicId)) return;
74857
+ if (topicId) this._lastIncomingTopics.set(scope, topicId);
74858
+ else this._lastIncomingTopics.delete(scope);
74859
+ }
74195
74860
  /**
74196
- * Create a new topic within the conversation group.
74197
- * Requires the channel to be initialized with a groupId (from activation).
74861
+ * Record a group's default topic (#1416). The legacy `defaultTopicId` keeps
74862
+ * mirroring the PRIMARY group's entry, for older readers and backups.
74863
+ */
74864
+ _recordDefaultTopic(gid, topicId) {
74865
+ if (!gid || !topicId || !this._persisted) return;
74866
+ (this._persisted.defaultTopicIds ??= {})[gid] = topicId;
74867
+ if (gid === this._persisted.groupId) this._persisted.defaultTopicId = topicId;
74868
+ }
74869
+ /** The group a topic is known to belong to, if any. */
74870
+ _groupOfTopic(topicId) {
74871
+ const p2 = this._persisted;
74872
+ for (const [gid, tid] of Object.entries(p2?.defaultTopicIds ?? {})) {
74873
+ if (tid === topicId) return gid;
74874
+ }
74875
+ if (p2?.defaultTopicId === topicId && p2.groupId) return p2.groupId;
74876
+ for (const t2 of p2?.topics ?? []) {
74877
+ if (t2.id === topicId) return t2.groupId ?? p2?.groupId;
74878
+ }
74879
+ for (const [scope, tid] of this._lastIncomingTopics) {
74880
+ if (tid === topicId && scope.startsWith("g:")) return scope.slice(2);
74881
+ }
74882
+ return void 0;
74883
+ }
74884
+ /**
74885
+ * The topic one outgoing 1:1 frame carries (#1416), or `undefined` to send
74886
+ * none. `gid` is the frame's conversation group (looked up from `convId`
74887
+ * when not given); `explicit` is the caller's `topicId`; `targeted` is true
74888
+ * when the caller addressed one conversation.
74198
74889
  */
74199
- async createTopic(name) {
74890
+ _topicForFrame(gid, convId, explicit, targeted, useLastIncoming = true) {
74891
+ const p2 = this._persisted;
74892
+ const g2 = gid ?? (convId ? this._sessionGroupIds.get(convId) : void 0);
74893
+ const primaryScope = g2 !== void 0 ? g2 === p2?.groupId : convId === this._primaryConversationId || !p2?.groupId;
74894
+ if (isTopicId(explicit)) {
74895
+ const owner = this._groupOfTopic(explicit);
74896
+ if (owner !== void 0 ? owner === g2 : targeted || primaryScope) return explicit;
74897
+ }
74898
+ const scope = this._topicScope(g2, convId);
74899
+ const last = scope && useLastIncoming ? this._lastIncomingTopics.get(scope) : void 0;
74900
+ if (last) return last;
74901
+ if (g2 && p2?.defaultTopicIds?.[g2]) return p2.defaultTopicIds[g2];
74902
+ if (primaryScope && p2?.defaultTopicId) return p2.defaultTopicId;
74903
+ return void 0;
74904
+ }
74905
+ /**
74906
+ * The conversation group a topic call addresses (#1416): the named
74907
+ * conversation's own group, else the primary group. A named conversation
74908
+ * whose group is unknown is an error — falling back to the primary group
74909
+ * would create/list topics in somebody else's chat.
74910
+ */
74911
+ _topicGroupFor(conversationId) {
74912
+ if (conversationId) {
74913
+ const gid = this._sessionGroupIds.get(conversationId);
74914
+ if (!gid) throw new Error("Conversation group unknown for topic call");
74915
+ return gid;
74916
+ }
74200
74917
  if (!this._persisted?.groupId) {
74201
74918
  throw new Error("Channel not initialized or groupId unknown");
74202
74919
  }
74203
- if (!this._deviceJwt) {
74920
+ return this._persisted.groupId;
74921
+ }
74922
+ /**
74923
+ * Create a new topic within a conversation group — the given conversation's
74924
+ * own group (#1416), or the primary group when none is named.
74925
+ * Requires the channel to be initialized with a groupId (from activation).
74926
+ */
74927
+ async createTopic(name, options) {
74928
+ const groupId = this._topicGroupFor(options?.conversationId);
74929
+ if (!this._deviceJwt || !this._persisted) {
74204
74930
  throw new Error("Channel not authenticated");
74205
74931
  }
74206
74932
  const res = await fetch(`${this.config.apiUrl}/api/v1/topics`, {
@@ -74210,7 +74936,7 @@ ${text}`;
74210
74936
  Authorization: `Bearer ${this._deviceJwt}`
74211
74937
  },
74212
74938
  body: JSON.stringify({
74213
- group_id: this._persisted.groupId,
74939
+ group_id: groupId,
74214
74940
  name,
74215
74941
  creator_device_id: this._persisted.deviceId
74216
74942
  })
@@ -74224,23 +74950,23 @@ ${text}`;
74224
74950
  if (!this._persisted.topics) {
74225
74951
  this._persisted.topics = [];
74226
74952
  }
74227
- this._persisted.topics.push(topic);
74953
+ this._persisted.topics.push({ ...topic, groupId });
74954
+ if (topic.isDefault) this._recordDefaultTopic(groupId, topic.id);
74228
74955
  await this._persistState();
74229
74956
  return topic;
74230
74957
  }
74231
74958
  /**
74232
- * List all topics in the conversation group.
74959
+ * List all topics in a conversation group — the given conversation's own
74960
+ * group (#1416), or the primary group when none is named.
74233
74961
  * Requires the channel to be initialized with a groupId (from activation).
74234
74962
  */
74235
- async listTopics() {
74236
- if (!this._persisted?.groupId) {
74237
- throw new Error("Channel not initialized or groupId unknown");
74238
- }
74239
- if (!this._deviceJwt) {
74963
+ async listTopics(options) {
74964
+ const groupId = this._topicGroupFor(options?.conversationId);
74965
+ if (!this._deviceJwt || !this._persisted) {
74240
74966
  throw new Error("Channel not authenticated");
74241
74967
  }
74242
74968
  const res = await fetch(
74243
- `${this.config.apiUrl}/api/v1/topics?group_id=${encodeURIComponent(this._persisted.groupId)}`,
74969
+ `${this.config.apiUrl}/api/v1/topics?group_id=${encodeURIComponent(groupId)}`,
74244
74970
  {
74245
74971
  headers: {
74246
74972
  Authorization: `Bearer ${this._deviceJwt}`
@@ -74253,7 +74979,13 @@ ${text}`;
74253
74979
  }
74254
74980
  const resp = await res.json();
74255
74981
  const topics = resp.map((t2) => ({ id: t2.id, name: t2.name, isDefault: t2.is_default }));
74256
- this._persisted.topics = topics;
74982
+ const primaryGid = this._persisted.groupId;
74983
+ this._persisted.topics = [
74984
+ ...(this._persisted.topics ?? []).filter((t2) => (t2.groupId ?? primaryGid) !== groupId),
74985
+ ...topics.map((t2) => ({ ...t2, groupId }))
74986
+ ];
74987
+ const def = topics.find((t2) => t2.isDefault);
74988
+ if (def) this._recordDefaultTopic(groupId, def.id);
74257
74989
  await this._persistState();
74258
74990
  return topics;
74259
74991
  }
@@ -74837,6 +75569,9 @@ ${text}`;
74837
75569
  this._persisted.defaultTopicId = primary.default_topic_id;
74838
75570
  }
74839
75571
  }
75572
+ for (const conv of conversations) {
75573
+ this._recordDefaultTopic(conv.group_id, conv.default_topic_id);
75574
+ }
74840
75575
  this._sessionGroupIds = /* @__PURE__ */ new Map();
74841
75576
  for (const conv of conversations) {
74842
75577
  if (conv.group_id) {
@@ -74949,7 +75684,7 @@ ${text}`;
74949
75684
  agentVersion: this.config.agentVersion ?? "0.0.0",
74950
75685
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
74951
75686
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
74952
- pluginVersion: true ? "0.23.50" : "0.0.0-dev"
75687
+ pluginVersion: true ? "0.23.52" : "0.0.0-dev"
74953
75688
  });
74954
75689
  this._telemetryReporter.startAutoFlush(3e4);
74955
75690
  }
@@ -75277,7 +76012,7 @@ ${text}`;
75277
76012
  agentVersion: this.config.agentVersion ?? "0.0.0",
75278
76013
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
75279
76014
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
75280
- pluginVersion: true ? "0.23.50" : "0.0.0-dev"
76015
+ pluginVersion: true ? "0.23.52" : "0.0.0-dev"
75281
76016
  });
75282
76017
  this._telemetryReporter.startAutoFlush(3e4);
75283
76018
  }
@@ -75740,11 +76475,15 @@ ${text}`;
75740
76475
  if (decisionReply) messageType = "decision_response";
75741
76476
  } catch {
75742
76477
  }
76478
+ const dmGroupId = convGroupId ?? (mgrKey?.startsWith("1to1-group:") ? mgrKey.slice("1to1-group:".length) : void 0);
75743
76479
  if (messageType === "history_catchup_request") {
75744
76480
  try {
75745
76481
  const request = JSON.parse(plaintext);
75746
76482
  if (typeof request.requesting_device_id !== "string") return;
75747
- const filtered = this._historyForCatchup("dm", void 0, request.since_ts);
76483
+ const filtered = this._historyForCatchup("dm", void 0, request.since_ts, {
76484
+ groupId: dmGroupId,
76485
+ conversationId: convId
76486
+ });
75748
76487
  const responsePayload = JSON.stringify({
75749
76488
  type: "history_catchup_response",
75750
76489
  target_device_id: request.requesting_device_id,
@@ -75799,6 +76538,9 @@ ${text}`;
75799
76538
  console.log(`[SecureChannel] Session ${convId.slice(0, 8)} activated via MLS message`);
75800
76539
  }
75801
76540
  }
76541
+ if (topicId) {
76542
+ this._rememberIncomingTopic(convId, dmGroupId, topicId);
76543
+ }
75802
76544
  if (mlsAttachment) {
75803
76545
  text = await this._augmentWithAttachment(mlsAttachment, text);
75804
76546
  }
@@ -75808,11 +76550,21 @@ ${text}`;
75808
76550
  "dm",
75809
76551
  topicId,
75810
76552
  data.created_at,
75811
- messageType
76553
+ messageType,
76554
+ { groupId: dmGroupId, conversationId: convId }
75812
76555
  );
76556
+ const dmConvId = convId ?? this._conversationOfGroup(dmGroupId);
76557
+ this._noteInboundDm(dmConvId, dmGroupId, { createdAt: data.created_at, senderDeviceId });
76558
+ this._reconcileForUnmappedGroup(dmGroupId);
75813
76559
  const metadata = {
75814
76560
  messageId: data.message_id ?? `mls_${Date.now()}`,
75815
- conversationId: convId ?? this._primaryConversationId,
76561
+ // A frame on a KNOWN group that no conversation maps yet is not the
76562
+ // primary person's: leave the conversation unnamed rather than hand
76563
+ // the reply to someone else; `conversationGroupId` still places it.
76564
+ conversationId: dmConvId ?? (dmGroupId ? void 0 : this._primaryConversationId),
76565
+ // #1418: the group this message decrypted under — attested, so a turn
76566
+ // answers here even when the local map is stale.
76567
+ conversationGroupId: dmGroupId,
75816
76568
  timestamp: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
75817
76569
  topicId,
75818
76570
  // #621: positive attestation that this decrypted under the OWNER'S 1:1
@@ -75993,7 +76745,7 @@ ${text}`;
75993
76745
  }
75994
76746
  if (messageType === "message" || messageType === "decision_response" && decisionReply) {
75995
76747
  const topicId = msgData.topic_id;
75996
- this._lastIncomingTopicId = topicId;
76748
+ this._rememberIncomingTopic(convId, void 0, topicId);
75997
76749
  let attachData;
75998
76750
  if (attachmentInfo) {
75999
76751
  try {
@@ -76021,7 +76773,8 @@ ${text}`;
76021
76773
  "dm",
76022
76774
  topicId,
76023
76775
  msgData.created_at,
76024
- messageType
76776
+ messageType,
76777
+ { conversationId: convId }
76025
76778
  );
76026
76779
  let emitText = messageText;
76027
76780
  if (attachData) {
@@ -76066,6 +76819,13 @@ ${messageText}`;
76066
76819
  // envelope text before the fold; `emitText` is the folded copy.
76067
76820
  caption: messageText
76068
76821
  };
76822
+ if (!roomId) {
76823
+ this._noteInboundDm(convId, void 0, {
76824
+ createdAt: msgData.created_at,
76825
+ senderDeviceId: msgData.sender_device_id
76826
+ });
76827
+ this._reconcileForUnmappedConversation(convId);
76828
+ }
76069
76829
  this.emit("message", emitText, metadata);
76070
76830
  Promise.resolve(this.config.onMessage?.(emitText, metadata)).catch((err) => {
76071
76831
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -76214,40 +76974,53 @@ ${baseText}`;
76214
76974
  if (this._state !== "ready" || this._sessions.size === 0 || !this._ws) {
76215
76975
  throw new Error("Channel is not ready");
76216
76976
  }
76217
- const topicId = options?.topicId ?? this._persisted?.defaultTopicId;
76218
- const attachMeta = await this._uploadAttachment(filePath, this._primaryConversationId);
76219
- const envelope = JSON.stringify({
76220
- type: "message",
76221
- text: plaintext,
76222
- topicId,
76223
- attachment: attachMeta
76224
- });
76225
76977
  const messageGroupId = randomUUID4();
76226
76978
  const pendingWsSends = [];
76227
- for (const [convId, session] of this._sessions) {
76228
- if (!session.activated) continue;
76229
- const encrypted = session.ratchet.encrypt(envelope);
76230
- const transport = encryptedMessageToTransport(encrypted);
76231
- pendingWsSends.push(
76232
- JSON.stringify({
76233
- event: "message",
76234
- data: {
76235
- conversation_id: convId,
76236
- header_blob: transport.header_blob,
76237
- ciphertext: transport.ciphertext,
76238
- message_group_id: messageGroupId,
76239
- topic_id: topicId
76240
- }
76241
- })
76242
- );
76979
+ const frameHistoryContexts = [];
76980
+ const buckets = this._ownerFileRecipients(options);
76981
+ if (buckets.length === 0) {
76982
+ console.warn("[SecureChannel] sendWithAttachment(): no live session for the person involved \u2014 nothing sent");
76983
+ throw new Error("No conversation is ready to receive this file");
76984
+ }
76985
+ for (const bucket of buckets) {
76986
+ const attachMeta = await this._uploadAttachment(filePath, bucket.uploadConvId);
76987
+ for (const convId of bucket.convIds) {
76988
+ const session = this._sessions.get(convId);
76989
+ const topicId = this._topicForFrame(void 0, convId, options?.topicId, false, false);
76990
+ const envelope = JSON.stringify({
76991
+ type: "message",
76992
+ text: plaintext,
76993
+ topicId,
76994
+ attachment: attachMeta
76995
+ });
76996
+ const encrypted = session.ratchet.encrypt(envelope);
76997
+ const transport = encryptedMessageToTransport(encrypted);
76998
+ pendingWsSends.push(
76999
+ JSON.stringify({
77000
+ event: "message",
77001
+ data: {
77002
+ conversation_id: convId,
77003
+ header_blob: transport.header_blob,
77004
+ ciphertext: transport.ciphertext,
77005
+ message_group_id: messageGroupId,
77006
+ topic_id: topicId
77007
+ }
77008
+ })
77009
+ );
77010
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, void 0, convId));
77011
+ }
76243
77012
  }
76244
77013
  await this._persistState();
76245
77014
  let deliveredFrames = 0;
76246
- for (const frame of pendingWsSends) {
76247
- if (this._sendApplicationFrame(frame)) deliveredFrames += 1;
77015
+ let historyContext;
77016
+ for (const [i2, frame] of pendingWsSends.entries()) {
77017
+ if (this._sendApplicationFrame(frame)) {
77018
+ if (deliveredFrames === 0) historyContext = frameHistoryContexts[i2];
77019
+ deliveredFrames += 1;
77020
+ }
76248
77021
  }
76249
77022
  if (deliveredFrames > 0) {
76250
- await this._appendHistory("agent", plaintext, this._historyContext("dm", topicId), void 0, messageGroupId);
77023
+ await this._appendHistory("agent", plaintext, historyContext ?? this._historyContext("dm"), void 0, messageGroupId);
76251
77024
  }
76252
77025
  }
76253
77026
  /**
@@ -76272,9 +77045,13 @@ ${baseText}`;
76272
77045
  topicId
76273
77046
  });
76274
77047
  const pendingWsSends = [];
77048
+ const sourceGid = this._sessionGroupIds.get(sourceConvId);
77049
+ const knowsGroups = this._sessionGroupIds.size > 0;
76275
77050
  for (const [siblingConvId, siblingSession] of this._sessions) {
76276
77051
  if (siblingConvId === sourceConvId) continue;
76277
77052
  if (!siblingSession.activated) continue;
77053
+ const siblingGid = this._sessionGroupIds.get(siblingConvId);
77054
+ if (knowsGroups && !(sourceGid && siblingGid && siblingGid === sourceGid)) continue;
76278
77055
  if (roomConvIds.has(siblingConvId)) continue;
76279
77056
  const syncEncrypted = siblingSession.ratchet.encrypt(syncPayload);
76280
77057
  const syncTransport = encryptedMessageToTransport(syncEncrypted);
@@ -76355,7 +77132,7 @@ ${baseText}`;
76355
77132
  async _replayHistoryToSession(convId) {
76356
77133
  const session = this._sessions.get(convId);
76357
77134
  if (!session || !session.activated || !this._ws) return;
76358
- const history = this._selectHistoryContext("dm");
77135
+ const history = this._selectHistoryContext("dm", void 0, { conversationId: convId });
76359
77136
  if (history.length === 0) {
76360
77137
  console.log(`[SecureChannel] No history to replay for ${convId.slice(0, 8)}...`);
76361
77138
  return;
@@ -76391,10 +77168,15 @@ ${baseText}`;
76391
77168
  `[SecureChannel] New owner device linked: ${event.owner_device_id.slice(0, 8)}...`
76392
77169
  );
76393
77170
  try {
77171
+ if (event.group_id && !this._sessionGroupIds.has(event.conversation_id)) {
77172
+ this._sessionGroupIds.set(event.conversation_id, event.group_id);
77173
+ this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
77174
+ }
76394
77175
  if (!event.owner_identity_public_key) {
76395
77176
  console.error(
76396
77177
  `[SecureChannel] device_linked event missing owner keys for conv ${event.conversation_id.slice(0, 8)}...`
76397
77178
  );
77179
+ await this._persistState();
76398
77180
  return;
76399
77181
  }
76400
77182
  const identity = this._persisted.identityKeypair;
@@ -78098,6 +78880,10 @@ ${baseText}`;
78098
78880
  await this._persistState();
78099
78881
  }
78100
78882
  console.log(`[SecureChannel] Joined shared 1:1 MLS group for group ${conversationGroupId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
78883
+ if (!this._isMappedGroup(conversationGroupId)) {
78884
+ this._welcomedUnmapped.set(conversationGroupId, Date.now());
78885
+ }
78886
+ this._reconcileForUnmappedGroup(conversationGroupId);
78101
78887
  await this._flushMlsHold(conversationGroupId);
78102
78888
  return;
78103
78889
  }
@@ -78727,7 +79513,7 @@ ${baseText}`;
78727
79513
  }
78728
79514
  if (messageType === "message" || messageType === "decision_response" && decisionReply) {
78729
79515
  const topicId = msg.topic_id;
78730
- await this._appendHistory("owner", messageText, this._historyContext("dm", topicId), msg.created_at, msg.message_id);
79516
+ await this._appendHistory("owner", messageText, this._dmHistoryContext(topicId, void 0, msg.conversation_id), msg.created_at, msg.message_id);
78731
79517
  const metadata = {
78732
79518
  messageId: msg.message_id,
78733
79519
  conversationId: msg.conversation_id,
@@ -78739,6 +79525,7 @@ ${baseText}`;
78739
79525
  ownerDm1to1: true,
78740
79526
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
78741
79527
  };
79528
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
78742
79529
  this.emit("message", messageText, metadata);
78743
79530
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
78744
79531
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -79333,7 +80120,7 @@ ${baseText}`;
79333
80120
  }
79334
80121
  if (messageType === "message" || messageType === "decision_response" && decisionReply) {
79335
80122
  const topicId = msg.topic_id;
79336
- await this._appendHistory("owner", messageText, this._historyContext("dm", topicId), msg.created_at, msg.id);
80123
+ await this._appendHistory("owner", messageText, this._dmHistoryContext(topicId, void 0, msg.conversation_id), msg.created_at, msg.id);
79337
80124
  const metadata = {
79338
80125
  messageId: msg.id,
79339
80126
  conversationId: msg.conversation_id,
@@ -79345,6 +80132,7 @@ ${baseText}`;
79345
80132
  ownerDm1to1: true,
79346
80133
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
79347
80134
  };
80135
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
79348
80136
  this.emit("message", messageText, metadata);
79349
80137
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
79350
80138
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -79653,7 +80441,7 @@ ${baseText}`;
79653
80441
  }
79654
80442
  if (messageType === "message" || messageType === "decision_response" && decisionReply) {
79655
80443
  const topicId = msg.topic_id;
79656
- await this._appendHistory("owner", messageText, this._historyContext("dm", topicId), msg.created_at, msg.id);
80444
+ await this._appendHistory("owner", messageText, this._dmHistoryContext(topicId, void 0, msg.conversation_id), msg.created_at, msg.id);
79657
80445
  const metadata = {
79658
80446
  messageId: msg.id,
79659
80447
  conversationId: msg.conversation_id,
@@ -79665,6 +80453,7 @@ ${baseText}`;
79665
80453
  ownerDm1to1: true,
79666
80454
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
79667
80455
  };
80456
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
79668
80457
  this.emit("message", messageText, metadata);
79669
80458
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
79670
80459
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -80685,7 +81474,7 @@ ${actionsText}`);
80685
81474
  "use strict";
80686
81475
  init_llm_response_parser();
80687
81476
  init_llm_cost();
80688
- traceStore = new AsyncLocalStorage();
81477
+ traceStore = new AsyncLocalStorage2();
80689
81478
  }
80690
81479
  });
80691
81480
  init_tool_audit = __esm2({
@@ -101433,7 +102222,7 @@ data:
101433
102222
  await init_skill_telemetry();
101434
102223
  await init_policy_enforcer();
101435
102224
  init_room_protocol();
101436
- VERSION = true ? "0.23.50" : "0.0.0-dev";
102225
+ VERSION = true ? "0.23.52" : "0.0.0-dev";
101437
102226
  }
101438
102227
  });
101439
102228
  await init_index();
@@ -102085,7 +102874,7 @@ var init_cli = __esm({
102085
102874
  "use strict";
102086
102875
  await init_dist();
102087
102876
  init_driver();
102088
- VERSION2 = "0.1.5";
102877
+ VERSION2 = "0.1.7";
102089
102878
  HELP = `AgentVault OpenAI Bridge ${VERSION2}
102090
102879
  Usage: AV_AGENT_NAME=<name> agentvault-openai-bridge <command>
102091
102880