@agentvault/grok-bridge 0.4.21 → 0.4.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -43,6 +43,7 @@ import { readdir as readdir2, readFile as readFile4, writeFile as writeFile2, re
43
43
  import { join as join5 } from "node:path";
44
44
  import { randomUUID as randomUUID3 } from "node:crypto";
45
45
  import { EventEmitter } from "node:events";
46
+ import { AsyncLocalStorage } from "node:async_hooks";
46
47
  import { createServer } from "node:http";
47
48
  import { randomUUID as randomUUID4, createHash } from "node:crypto";
48
49
  import { readFileSync } from "node:fs";
@@ -52,7 +53,7 @@ import { join as join6 } from "node:path";
52
53
  import { readFile as readFile5 } from "node:fs/promises";
53
54
  import WebSocket from "ws";
54
55
  import { resolve as resolve2 } from "node:path";
55
- import { AsyncLocalStorage } from "node:async_hooks";
56
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
56
57
  import { Http2ServerRequest as Http2ServerRequest2 } from "http2";
57
58
  import { Http2ServerRequest } from "http2";
58
59
  import { Readable as Readable2 } from "stream";
@@ -11712,11 +11713,11 @@ async function joinWithFirstMatchingKp(welcomeBytes, candidates) {
11712
11713
  return null;
11713
11714
  }
11714
11715
  function ownIdentity() {
11715
- const v2 = true ? "0.23.50" : FALLBACK;
11716
+ const v2 = true ? "0.23.52" : FALLBACK;
11716
11717
  return `${PACKAGE}@${v2}`;
11717
11718
  }
11718
11719
  function buildSha() {
11719
- const raw = true ? "c8f1371" : "";
11720
+ const raw = true ? "d7143c3" : "";
11720
11721
  const cleaned = (raw ?? "").trim();
11721
11722
  return !cleaned || cleaned === "unknown" ? null : cleaned;
11722
11723
  }
@@ -12494,11 +12495,38 @@ function _resetCompatCacheForTest() {
12494
12495
  _agentEventFn = null;
12495
12496
  _transcriptFn = null;
12496
12497
  }
12498
+ function ownerRoutingFrom(parsed) {
12499
+ const out = {};
12500
+ if (parsed.conversation_id !== void 0) {
12501
+ if (typeof parsed.conversation_id !== "string" || !parsed.conversation_id) return "'conversation_id' must be a string";
12502
+ out.conversationId = parsed.conversation_id;
12503
+ }
12504
+ if (parsed.audience !== void 0) {
12505
+ if (parsed.audience !== "person" && parsed.audience !== "everyone") {
12506
+ return `'audience' must be "person" or "everyone"`;
12507
+ }
12508
+ out.audience = parsed.audience;
12509
+ }
12510
+ return out;
12511
+ }
12512
+ function ambiguousOwnerRequest(channel, routing) {
12513
+ const check = channel.isUntargetedOwnerAmbiguous;
12514
+ if (typeof check !== "function" || !check.call(channel, routing)) return null;
12515
+ return { status: 409, body: { ok: false, error: AMBIGUOUS_OWNER_ERROR } };
12516
+ }
12517
+ function statusOf(receipt) {
12518
+ if (receipt.ambiguous) return 409;
12519
+ return receipt.ok ? 200 : 500;
12520
+ }
12497
12521
  async function handleSendRequest(parsed, channel) {
12498
12522
  const text = parsed.text;
12499
12523
  if (!text || typeof text !== "string") {
12500
12524
  return { status: 400, body: { ok: false, error: "Missing 'text' field" } };
12501
12525
  }
12526
+ const routing = ownerRoutingFrom(parsed);
12527
+ if (typeof routing === "string") {
12528
+ return { status: 400, body: { ok: false, error: routing } };
12529
+ }
12502
12530
  try {
12503
12531
  let target;
12504
12532
  let a2aTarget = parsed.hub_address ?? parsed.a2a_address ?? parsed.a2aAddress;
@@ -12516,10 +12544,10 @@ async function handleSendRequest(parsed, channel) {
12516
12544
  const receipt2 = await channel.deliver(
12517
12545
  { kind: "owner" },
12518
12546
  { type: "attachment", text, filePath: parsed.file_path },
12519
- { topicId: parsed.topicId }
12547
+ { topicId: parsed.topicId, ...routing, refuseIfAmbiguous: true }
12520
12548
  );
12521
12549
  return {
12522
- status: receipt2.ok ? 200 : 500,
12550
+ status: statusOf(receipt2),
12523
12551
  body: {
12524
12552
  ok: receipt2.ok,
12525
12553
  destination: receipt2.destination,
@@ -12533,6 +12561,8 @@ async function handleSendRequest(parsed, channel) {
12533
12561
  target,
12534
12562
  { type: "text", text },
12535
12563
  {
12564
+ ...routing,
12565
+ refuseIfAmbiguous: true,
12536
12566
  topicId: parsed.topicId,
12537
12567
  priority: parsed.priority,
12538
12568
  metadata: {
@@ -12542,7 +12572,7 @@ async function handleSendRequest(parsed, channel) {
12542
12572
  }
12543
12573
  );
12544
12574
  return {
12545
- status: receipt.ok ? 200 : 500,
12575
+ status: statusOf(receipt),
12546
12576
  body: {
12547
12577
  ok: receipt.ok,
12548
12578
  destination: receipt.destination,
@@ -12557,6 +12587,10 @@ async function handleActionRequest(parsed, channel) {
12557
12587
  if (!parsed.action || typeof parsed.action !== "string") {
12558
12588
  return { status: 400, body: { ok: false, error: "Missing 'action' field" } };
12559
12589
  }
12590
+ const routing = ownerRoutingFrom(parsed);
12591
+ if (typeof routing === "string") {
12592
+ return { status: 400, body: { ok: false, error: routing } };
12593
+ }
12560
12594
  try {
12561
12595
  const confirmation = {
12562
12596
  action: parsed.action,
@@ -12566,12 +12600,10 @@ async function handleActionRequest(parsed, channel) {
12566
12600
  estimated_cost: parsed.estimated_cost
12567
12601
  };
12568
12602
  const target = parsed.room_id && typeof parsed.room_id === "string" ? { kind: "room", roomId: parsed.room_id } : { kind: "owner" };
12569
- const receipt = await channel.deliver(
12570
- target,
12571
- { type: "action_confirmation", confirmation }
12572
- );
12603
+ const content = { type: "action_confirmation", confirmation };
12604
+ const receipt = await channel.deliver(target, content, { ...routing, refuseIfAmbiguous: true });
12573
12605
  return {
12574
- status: receipt.ok ? 200 : 500,
12606
+ status: statusOf(receipt),
12575
12607
  body: {
12576
12608
  ok: receipt.ok,
12577
12609
  destination: receipt.destination,
@@ -12596,6 +12628,12 @@ async function handleDecisionRequest(parsed, channel) {
12596
12628
  return { status: 400, body: { ok: false, error: "Each option must have 'option_id' and 'label'" } };
12597
12629
  }
12598
12630
  }
12631
+ const routing = ownerRoutingFrom(parsed);
12632
+ if (typeof routing === "string") {
12633
+ return { status: 400, body: { ok: false, error: routing } };
12634
+ }
12635
+ const ambiguous = ambiguousOwnerRequest(channel, routing);
12636
+ if (ambiguous) return ambiguous;
12599
12637
  try {
12600
12638
  const decision_id = await channel.sendDecisionRequest({
12601
12639
  title,
@@ -12604,7 +12642,7 @@ async function handleDecisionRequest(parsed, channel) {
12604
12642
  context_refs: parsed.context_refs,
12605
12643
  deadline: parsed.deadline,
12606
12644
  auto_action: parsed.auto_action
12607
- });
12645
+ }, routing);
12608
12646
  return { status: 200, body: { ok: true, decision_id } };
12609
12647
  } catch (err) {
12610
12648
  return { status: 500, body: { ok: false, error: String(err) } };
@@ -12891,14 +12929,27 @@ function migrateHistoryEntries(history) {
12891
12929
  return { id, ...legacyEntry };
12892
12930
  });
12893
12931
  }
12932
+ function isTopicId(value) {
12933
+ return typeof value === "string" && TOPIC_ID_RE.test(value);
12934
+ }
12935
+ function migrateDefaultTopics(state) {
12936
+ if (!state.defaultTopicId || !state.groupId) return state;
12937
+ if (state.defaultTopicIds?.[state.groupId]) return state;
12938
+ return {
12939
+ ...state,
12940
+ defaultTopicIds: { ...state.defaultTopicIds ?? {}, [state.groupId]: state.defaultTopicId }
12941
+ };
12942
+ }
12894
12943
  function migratePersistedState(raw) {
12895
12944
  if (raw.sessions && raw.primaryConversationId) {
12896
12945
  const history = raw.messageHistory;
12897
- if (!history?.some((entry) => typeof entry.id !== "string")) return raw;
12898
- return {
12946
+ if (!history?.some((entry) => typeof entry.id !== "string")) {
12947
+ return migrateDefaultTopics(raw);
12948
+ }
12949
+ return migrateDefaultTopics({
12899
12950
  ...raw,
12900
12951
  messageHistory: migrateHistoryEntries(history)
12901
- };
12952
+ });
12902
12953
  }
12903
12954
  const legacy = raw;
12904
12955
  return {
@@ -13089,7 +13140,7 @@ async function _handleInbound(params) {
13089
13140
  core.error?.(`[AgentVault] session record failed: ${String(err)}`);
13090
13141
  }
13091
13142
  });
13092
- await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
13143
+ await channel.runForConversation(metadata.conversationId, () => core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
13093
13144
  ctx: ctxPayload,
13094
13145
  cfg,
13095
13146
  dispatcherOptions: {
@@ -13106,7 +13157,7 @@ async function _handleInbound(params) {
13106
13157
  }
13107
13158
  },
13108
13159
  replyOptions: {}
13109
- });
13160
+ }), { groupId: metadata.conversationGroupId });
13110
13161
  }
13111
13162
  function getErrorMap() {
13112
13163
  return overrideErrorMap;
@@ -17630,7 +17681,7 @@ function armSseKeepAlive(intervalMs, onTick) {
17630
17681
  timer.unref?.();
17631
17682
  return timer;
17632
17683
  }
17633
- var __create, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf, __hasOwnProp, __esm2, __commonJS, __export2, __copyProps, __toESM, SENTINEL, WRAPPERS, INSTRUCTION, init_abstention, init_envelope_text, init_mls_commit_classify, MENTION_RE, BROADCAST_NAMES, init_room_protocol, __filename, __dirname, url, path, Module, Module, root, window_, crypto_, randomValuesStandard, crypto2, randomValueNodeJS, _Module, libsodium_sumo_default, init_libsodium_sumo, a, r, t, c, libsodium_wrappers_default, init_libsodium_wrappers, init_keys, init_x3dh, MAX_SKIP, CHAIN_KEY_SEED, MSG_KEY_SEED, HEADER_KEY_SEED, DoubleRatchet, init_ratchet, init_file_crypto, DOMAIN_DID_DOCUMENT, DOMAIN_TRANSFER_INTENT, DOMAIN_TRANSFER_ACCEPT, BASE58_ALPHABET, init_did, BUILTIN_PATTERNS, ScanEngine, init_scan_engine, init_merkle, VC_CONTEXT_V2, AV_CREDENTIAL_CONTEXT, CRYPTOSUITE, BASE58_ALPHABET2, init_vc, init_transport, init_telemetry, TelemetryReporter, init_telemetry_reporter, CROCKFORD, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, BACKUP_VERSION, MAX_BACKUP_SIZE, init_backup, atitle, aobject, aopts, isLE, swap8IfBE, swap32IfBE, hasHexBuiltin, hexes, oidNist, init_utils, BSIGMA, init_blake, U32_MASK64, _32n, fromNumH, fromNumL, shrSH, shrSL, rotrSH, rotrSL, rotrBH, rotrBL, rotr32H, rotr32L, add3L, add3H, add4L, add4H, add5L, add5H, init_u64, HashMD, SHA256_IV, SHA384_IV, SHA512_IV, init_md, B2B_IV, BBUF, _BLAKE2, _BLAKE2b, blake2b, init_blake2, CROCKFORD2, SALT_BYTES2, NONCE_BYTES2, KEY_BYTES2, TAG_BYTES, ENVELOPE_OVERHEAD, AAD_PREFIX, UUID_RE, UUID_V4_RE, DIGEST_ID_RE, TIMESTAMP_RE, encoder, decoder, HISTORY_MAGIC, HISTORY_ARCHIVE_VERSION, HISTORY_MAX_ENTRIES, HISTORY_MAX_BLOB_BYTES, HISTORY_KDF_OPSLIMIT, HISTORY_KDF_MEMLIMIT, HistoryEntryTooLargeError, init_history_backup, init_approval, encVoid, init_tlsEncoder, uint8Encoder, encodeUint8, decodeUint8, uint16Encoder, encodeUint16, decodeUint16, uint32Encoder, encodeUint32, decodeUint32, uint64Encoder, encodeUint64, decodeUint64, init_number, init_tlsDecoder, init_enumHelpers, defaultProposalTypes, defaultProposalTypeEncoder, encodeDefaultProposalType, decodeDefaultProposalType, init_defaultProposalType, defaultExtensionTypes, defaultExtensionTypeEncoder, encodeDefaultExtensionType, decodeDefaultExtensionType, init_defaultExtensionType, acceptAll, init_incomingMessageAction, MlsError, ValidationError, CodecError, UsageError, DependencyError, CryptoVerificationError, CryptoError, InternalError, init_mlsError, init_byteArray, varLenDataEncoder, decodeVarLenData, init_variableLength, init_constantTimeCompare, extensionTypeEncoder, encodeExtensionType, decodeExtensionType, extensionEncoder, encodeExtension, decodeExtension, init_extension, credentialTypes, credentialTypeEncoder, encodeCredentialType, decodeCredentialType, init_credentialType, credentialBasicEncoder, encodeCredentialBasic, credentialX509Encoder, encodeCredentialX509, credentialCustomEncoder, encodeCredentialCustom, credentialEncoder, encodeCredential, decodeCredentialBasic, decodeCredentialX509, decodeCredential, init_credential, externalSenderEncoder, encodeExternalSender, decodeExternalSender, init_externalSender, init_hash, init_optional, ciphersuites, ciphersuiteEncoder, encodeCiphersuite, decodeCiphersuite, ciphersuiteValues, init_ciphersuite, init_signature, protocolVersions, protocolVersionEncoder, encodeProtocolVersion, decodeProtocolVersion, init_protocolVersion, capabilitiesEncoder, encodeCapabilities, decodeCapabilities, init_capabilities, leafNodeSources, leafNodeSourceEncoder, encodeLeafNodeSource, decodeLeafNodeSource, init_leafNodeSource, lifetimeEncoder, encodeLifetime, decodeLifetime, defaultLifetime, init_lifetime, leafNodeDataEncoder, encodeLeafNodeData, decodeLeafNodeData, leafNodeInfoKeyPackageEncoder, encodeLeafNodeInfoKeyPackage, leafNodeInfoUpdateOmittedEncoder, encodeLeafNodeInfoUpdateOmitted, leafNodeInfoCommitOmittedEncoder, encodeLeafNodeInfoCommitOmitted, leafNodeInfoOmittedEncoder, encodeLeafNodeInfoOmitted, decodeLeafNodeInfoKeyPackage, decodeLeafNodeInfoUpdateOmitted, decodeLeafNodeInfoCommitOmitted, decodeLeafNodeInfoOmitted, leafNodeInfoUpdateEncoder, encodeLeafNodeInfoUpdate, leafNodeInfoCommitEncoder, encodeLeafNodeInfoCommit, leafNodeInfoEncoder, encodeLeafNodeInfo, decodeLeafNodeInfoUpdate, decodeLeafNodeInfoCommit, decodeLeafNodeInfo, leafNodeTBSEncoder, encodeLeafNodeTBS, leafNodeEncoder, encodeLeafNode, decodeLeafNode, decodeLeafNodeKeyPackage, decodeLeafNodeCommit, decodeLeafNodeUpdate, init_leafNode, keyPackageTBSEncoder, encodeKeyPackageTBS, decodeKeyPackageTBS, keyPackageEncoder, encodeKeyPackage, decodeKeyPackage, init_keyPackage, init_kdf, pskTypes, pskTypeEncoder, encodePskType, decodePskType, resumptionPSKUsages, resumptionPSKUsageEncoder, encodeResumptionPSKUsage, decodeResumptionPSKUsage, encodePskInfoExternal, encodePskInfoResumption, decodePskInfoResumption, pskInfoEncoder, encodePskInfo, decodePskInfo, pskIdEncoder, encodePskId, decodePskId, pskLabelEncoder, encodePskLabel, decodePskLabel, init_presharedkey, addEncoder, encodeAdd, decodeAdd, updateEncoder, encodeUpdate, decodeUpdate, removeEncoder, encodeRemove, decodeRemove, pskEncoder, encodePSK, decodePSK, reinitEncoder, encodeReinit, decodeReinit, externalInitEncoder, encodeExternalInit, decodeExternalInit, groupContextExtensionsEncoder, encodeGroupContextExtensions, decodeGroupContextExtensions, proposalAddEncoder, encodeProposalAdd, proposalUpdateEncoder, encodeProposalUpdate, proposalRemoveEncoder, encodeProposalRemove, proposalPSKEncoder, encodeProposalPSK, proposalReinitEncoder, encodeProposalReinit, proposalExternalInitEncoder, encodeProposalExternalInit, proposalGroupContextExtensionsEncoder, encodeProposalGroupContextExtensions, proposalCustomEncoder, encodeProposalCustom, proposalEncoder, encodeProposal, decodeProposalAdd, decodeProposalUpdate, decodeProposalRemove, decodeProposalPSK, decodeProposalReinit, decodeProposalExternalInit, decodeProposalGroupContextExtensions, decodeProposal, init_proposal, proposalOrRefTypes, proposalOrRefTypeEncoder, encodeProposalOrRefType, decodeProposalOrRefType, proposalOrRefProposalEncoder, encodeProposalOrRefProposal, proposalOrRefProposalRefEncoder, encodeProposalOrRefProposalRef, proposalOrRefEncoder, encodeProposalOrRef, decodeProposalOrRef, init_proposalOrRefType, init_hpke, groupContextEncoder, encodeGroupContext, decodeGroupContext, init_groupContext, nodeTypes, nodeTypeEncoder, encodeNodeType, decodeNodeType, init_nodeType, parentNodeEncoder, encodeParentNode, decodeParentNode, init_parentNode, init_treemath, nodeEncoder, encodeNode, decodeNode, ratchetTreeEncoder, encodeRatchetTree, decodeRatchetTree, init_ratchetTree, leafNodeHashInputEncoder, encodeLeafNodeHashInput, decodeLeafNodeHashInput, parentNodeHashInputEncoder, encodeParentNodeHashInput, decodeParentNodeHashInput, treeHashInputEncoder, encodeTreeHashInput, decodeTreeHashInput, init_treeHash, parentHashInputEncoder, encodeParentHashInput, decodeParentHashInput, init_parentHash, hpkeCiphertextEncoder, encodeHpkeCiphertext, decodeHpkeCiphertext, init_hpkeCiphertext, updatePathNodeEncoder, encodeUpdatePathNode, decodeUpdatePathNode, updatePathEncoder, encodeUpdatePath, decodeUpdatePath, init_updatePath, commitEncoder, encodeCommit, decodeCommit, init_commit, contentTypes, contentTypeEncoder, encodeContentType, decodeContentType, init_contentType, wireformats, wireformatEncoder, encodeWireformat, decodeWireformat, init_wireformat, senderTypes, senderTypeEncoder, encodeSenderType, decodeSenderType, senderEncoder, encodeSender, decodeSender, reuseGuardEncoder, encodeReuseGuard, decodeReuseGuard, senderDataEncoder, encodeSenderData, decodeSenderData, senderDataAADEncoder, encodeSenderDataAAD, decodeSenderDataAAD, init_sender, framedContentApplicationDataEncoder, encodeFramedContentApplicationData, framedContentProposalDataEncoder, encodeFramedContentProposalData, framedContentCommitDataEncoder, encodeFramedContentCommitData, framedContentInfoEncoder, encodeFramedContentInfo, decodeFramedContentApplicationData, decodeFramedContentProposalData, decodeFramedContentCommitData, decodeFramedContentInfo, framedContentEncoder, encodeFramedContent, decodeFramedContent, senderInfoEncoder, encodeSenderInfo, framedContentTBSEncoder, encodeFramedContentTBS, encodeFramedContentAuthDataContent, encodeFramedContentAuthDataCommit, framedContentAuthDataEncoder, encodeFramedContentAuthData, decodeFramedContentAuthDataCommit, init_framedContent, authenticatedContentEncoder, encodeAuthenticatedContent, decodeAuthenticatedContent, authenticatedContentTBMEncoder, encodeAuthenticatedContentTBM, init_authenticatedContent, publicMessageInfoEncoder, encodePublicMessageInfo, publicMessageEncoder, encodePublicMessage, decodePublicMessage, init_publicMessage, init_messageProtectionPublic, init_externalProposal, requiredCapabilitiesEncoder, encodeRequiredCapabilities, decodeRequiredCapabilities, init_requiredCapabilities, defaultAuthenticationService, init_authenticationService, defaultPaddingConfig, init_paddingConfig, defaultKeyPackageEqualityConfig, init_keyPackageEqualityConfig, defaultLifetimeConfig, init_lifetimeConfig, defaultKeyRetentionConfig, init_keyRetentionConfig, groupInfoTBSEncoder, encodeGroupInfoTBS, decodeGroupInfoTBS, groupInfoEncoder, encodeGroupInfo, decodeGroupInfo, init_groupInfo, keyScheduleEncoder, encodeKeySchedule, decodeKeySchedule, init_keySchedule, generationSecretEncoder, decodeGenerationSecret, secretTreeNodeEncoder, decodeSecretTreeNode, secretTreeEncoder, decodeSecretTree, init_secretTree, confirmedTranscriptHashInputEncoder, encodeConfirmedTranscriptHashInput, decodeConfirmedTranscriptHashInput, init_transcriptHash, groupSecretsEncoder, encodeGroupSecrets, decodeGroupSecrets, init_groupSecrets, encryptedGroupSecretsEncoder, encodeEncryptedGroupSecrets, decodeEncryptedGroupSecrets, welcomeEncoder, encodeWelcome, decodeWelcome, init_welcome, init_pathSecrets, privateKeyPathEncoder, decodePrivateKeyPath, init_privateKeyPath, proposalWithSenderEncoder, decodeProposalWithSender, unappliedProposalsEncoder, decodeUnappliedProposals, init_unappliedProposals, emptyPskIndex, init_pskIndex, init_addToMap, defaultClientConfig, init_clientConfig, init_array, stringEncoder, encodeString, decodeString, init_string, activeEncoder, suspendedPendingReinitEncoder, removedFromGroupEncoder, groupActiveStateEncoder, decodeGroupActiveState, init_groupActiveState, epochReceiverDataEncoder, decodeEpochReceiverData, init_epochReceiverData, groupStateEncoder, encodeGroupState, decodeGroupState, groupStateEncoderWithoutTree, encodeGroupStateWithoutTree, emptyProposals, init_clientState, privateMessageEncoder, encodePrivateMessage, decodePrivateMessage, privateContentAADEncoder, encodePrivateContentAAD, decodePrivateContentAAD, init_privateMessage, init_messageProtection, init_createMessage, init_createCommit, init_processMessages, init_makeHashImpl, HpkeError, InvalidParamError, SerializeError, DeserializeError, EncapError, DecapError, ExportError, SealError, OpenError, MessageLimitReachedError, DeriveKeyPairError, NotSupportedError, init_errors, dntGlobals, dntGlobalThis, init_dnt_shims, NativeAlgorithm, init_algorithm, Mode, KemId, KdfId, AeadId, init_identifiers, INPUT_LENGTH_LIMIT, INFO_LENGTH_LIMIT, MINIMUM_PSK_LENGTH, EMPTY, BYTE_TO_BIGINT_256, init_consts, SUITE_ID_HEADER_KEM, init_kemInterface, HPKE_VERSION, HkdfNative, HkdfSha256Native, HkdfSha384Native, HkdfSha512Native, init_hkdf, isCryptoKeyPair, init_misc, LABEL_EAE_PRK, LABEL_SHARED_SECRET, Dhkem, init_dhkem, KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, init_dhkemPrimitives, Bignum, init_bignum, LABEL_CANDIDATE, ORDER_P_256, ORDER_P_384, ORDER_P_521, PKCS8_ALG_ID_P_256, PKCS8_ALG_ID_P_384, PKCS8_ALG_ID_P_521, EC_P_256_PARAMS, EC_P_384_PARAMS, EC_P_521_PARAMS, Ec, init_ec, init_xCryptoKey, init_xCurve, init_hybridkem, AEAD_USAGES, init_aeadEncryptionContext, _endianTestBuffer, _endianTestBytes, isLE2, init_noble, init_hash2, _HMAC, hmac, init_hmac, init_md2, U32_MASK642, _32n2, init_u642, init_sha2, _0n, _1n, _2n, _7n, _256n, _0x71n, SHA3_PI, SHA3_ROTL, _SHA3_IOTA, IOTAS, SHA3_IOTA_H, SHA3_IOTA_L, init_sha3, init_modular, init_curve, init_montgomery, init_mod, AesGcmContext, Aes128Gcm, Aes256Gcm, init_aesGcm, init_exportOnly, init_emitNotSupported, LABEL_SEC, ExporterContextImpl, RecipientExporterContextImpl, SenderExporterContextImpl, init_exporterContext, EncryptionContextImpl, init_encryptionContext, __classPrivateFieldGet, __classPrivateFieldSet, _Mutex_locked, Mutex, init_mutex, __classPrivateFieldGet2, __classPrivateFieldSet2, _RecipientContextImpl_mutex, RecipientContextImpl, init_recipientContext, __classPrivateFieldGet3, __classPrivateFieldSet3, _SenderContextImpl_mutex, SenderContextImpl, init_senderContext, LABEL_BASE_NONCE, LABEL_EXP, LABEL_INFO_HASH, LABEL_KEY, LABEL_PSK_ID_HASH, LABEL_SECRET, SUITE_ID_HEADER_HPKE, CipherSuiteNative, init_cipherSuiteNative, DhkemP256HkdfSha256Native, DhkemP384HkdfSha384Native, DhkemP521HkdfSha512Native, init_dhkemNative, CipherSuite, DhkemP256HkdfSha256, DhkemP384HkdfSha384, DhkemP521HkdfSha512, HkdfSha256, HkdfSha384, HkdfSha512, init_native, ALG_NAME, PKCS8_ALG_ID_X25519, BASE_POINT_X25519, X25519, init_x25519, DhkemX25519HkdfSha256, init_dhkemX25519, PKCS8_ALG_ID_X448, init_x448, init_dhkemX448, init_mod2, init_hpke2, isLE3, wrapCipher, init_utils2, encodeStr, sigma16, sigma32, sigma16_32, sigma32_32, BLOCK_LEN, BLOCK_LEN32, MAX_COUNTER, U32_EMPTY, _XorStreamPRG, createPRG, init_arx, Poly1305, poly1305, init_poly1305, chacha_exports, chacha20orig, chacha20, xchacha20, chacha8, chacha12, ZEROS16, updatePadded, ZEROS32, _poly1305_aead, chacha20poly1305, xchacha20poly1305, rngChacha20, rngChacha8, init_chacha, init_makeAead, init_makeKdfImpl, init_makeDhKem, init_makeHpke, defaultRng, init_rng, crypto3, init_cryptoNode, isLE4, swap32IfBE3, hasHexBuiltin2, hexes2, asciis, Hash, init_utils3, HashMD3, SHA256_IV3, SHA384_IV3, SHA512_IV3, init_md3, U32_MASK643, _32n3, shrSH3, shrSL3, rotrSH3, rotrSL3, rotrBH3, rotrBL3, rotlSH2, rotlSL2, rotlBH2, rotlBL2, add3L3, add3H3, add4L3, add4H3, add5L3, add5H3, init_u643, SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384, sha2563, sha5122, sha3842, init_sha22, _0n2, _1n2, isPosBig, bitMask, notImplemented, init_utils4, _0n3, _1n3, _2n2, _3n, _4n, _5n, _7n2, _8n, _9n, _16n, isNegativeLE, FIELD_FIELDS, init_modular2, _0n4, _1n4, pointPrecomputes, pointWindowSizes, wNAF, init_curve2, _0n5, _1n5, _2n3, _8n2, PrimeEdwardsPoint, init_edwards, os2ip, _DST_scalar, init_hash_to_curve, _0n6, _1n6, _2n4, init_montgomery2, ed25519_exports, _0n7, _1n7, _2n5, _3n2, _5n2, _8n3, ed25519_CURVE_p, ed25519_CURVE, ED25519_SQRT_M1, Fp, Fn, ed25519Defaults, ed25519, ed25519ctx, ed25519ph, x25519, ELL2_C1, ELL2_C2, ELL2_C3, ELL2_C1_EDWARDS, ed25519_hasher, SQRT_M1, SQRT_AD_MINUS_ONE, INVSQRT_A_MINUS_D, ONE_MINUS_D_SQ, D_MINUS_ONE_SQ, invertSqrt, MAX_255B, bytes255ToNumberLE, _RistrettoPoint, ristretto255, ristretto255_hasher, ED25519_TORSION_SUBGROUP, edwardsToMontgomery, RistrettoPoint, hashToCurve, encodeToCurve, hashToRistretto255, hash_to_ristretto255, init_ed25519, _0n8, _1n8, _2n6, _7n3, _256n2, _0x71n2, SHA3_PI2, SHA3_ROTL2, _SHA3_IOTA2, IOTAS2, SHA3_IOTA_H2, SHA3_IOTA_L2, rotlH, rotlL, Keccak, genShake, shake2562, init_sha32, ed448_exports, ed448_CURVE, E448_CURVE, shake256_114, shake256_64, _1n9, _2n7, _3n3, _4n2, _11n, _22n, _44n, _88n, _223n, Fp2, Fn2, Fp448, Fn448, ED448_DEF, ed448, ed448ph, E448, x448, ELL2_C12, ELL2_J, ed448_hasher, ONE_MINUS_D, ONE_MINUS_TWO_D, SQRT_MINUS_D, INVSQRT_MINUS_D, invertSqrt2, _DecafPoint, decaf448, decaf448_hasher, ED448_TORSION_SUBGROUP, DecafPoint, hashToCurve2, encodeToCurve2, hashToDecaf448, hash_to_decaf448, edwardsToMontgomery2, init_ed448, HMAC, hmac2, init_hmac2, divNearest, DERErr, DER, _0n9, _1n10, _2n8, _3n4, _4n3, init_weierstrass, init_shortw_utils, nist_exports, p256_CURVE, p384_CURVE, p521_CURVE, Fp256, Fp384, Fp521, p256, p256_hasher, p384, p384_hasher, p521, secp256r1, secp384r1, secp521r1, p521_hasher, init_nist, init_makeNobleSignatureImpl, defaultCryptoProvider, init_provider, init_getCiphersuiteImpl, init_resumption, SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384, sha2564, sha5123, sha3843, init_sha23, _HMAC2, hmac3, init_hmac3, init_makeHashImpl2, init_makeNobleSignatureImpl2, BLOCK_SIZE, ZEROS162, ZEROS322, POLY, mul2, swapLE, estimateWindow, GHASH, Polyval, ghash, polyval, init_polyval, BLOCK_SIZE2, BLOCK_SIZE32, EMPTY_BLOCK, POLY2, sbox, rotr32_8, rotl32_8, tableEncoding, xPowers, gcm, _CMAC, cmac, init_aes, init_makeAead2, init_makeKdfImpl2, init_makeDhKem2, init_makeHpke2, init_rng2, nobleCryptoProvider, init_provider2, mlsPublicMessageEncoder, encodeMlsPublicMessage, mlsWelcomeEncoder, encodeMlsWelcome, mlsPrivateMessageEncoder, encodeMlsPrivateMessage, mlsGroupInfoEncoder, encodeMlsGroupInfo, mlsKeyPackageEncoder, encodeMlsKeyPackage, mlsMessageContentEncoder, encodeMlsMessageContent, decodeMlsMessageContent, mlsMessageEncoder, encodeMlsMessage, decodeMlsMessage, init_message, greaseValues, defaultGreaseConfig, init_grease, init_defaultCapabilities, init_src, DEFAULT_CIPHERSUITE, MLSGroupManager, init_mls_group, DOMAIN, NONCE_BYTES3, init_owner_sync, init_mls_delivery_order, init_mls_presend_epoch, dist_exports, init_dist2, DIR_MODE, FILE_MODE, init_secure_file, SYNC_LOCK_STALE_MS, pendingKpPath, init_mls_state, init_mls_kp_pool, PACKAGE, FALLBACK, MAX_LEN, DISALLOWED, init_client_version, CredentialStore, init_credential_store, init_crypto_helpers, STATE_FILE, LEGACY_STATE_FILE, init_state, ACTIVATION_DOMAIN, UUID_RE2, init_transport2, A2ALogGate, init_a2a_log_gate, init_mls_membership_probe, FIRST_DIRTY_DELAY_MS, RETRY_BASE_DELAYS_MS, MAX_RETRY_DELAY_MS, JITTER_FRACTION, HistoryBackupScheduler, init_history_backup_scheduler, FILE_MODE2, init_history_recovery_file, TENANT_ID_PATTERN, DIR_MODE2, FILE_MODE3, HISTORY_RECOVERY_VERIFY_TIMEOUT_MS, VERIFY_TIMEOUT_MESSAGE, HistoryRecoveryVerificationTimeoutError, init_history_recovery_code, ACTIONS, init_decision_reply, history_backup_client_exports, HISTORY_RESTORE_TIMEOUT_MS, HISTORY_RESTORE_RESPONSE_MAX_BYTES, HISTORY_ENVELOPE_MIN_BYTES, HISTORY_AAD_PREFIX, UUID_RE3, GENERATION_RESPONSE_KEYS, utf8Encoder, utf8Decoder, HistoryBackupClient, init_history_backup_client, openclaw_compat_exports, defaultImporter, HEARTBEAT_CANDIDATES, AGENT_EVENT_CANDIDATES, TRANSCRIPT_CANDIDATES, _heartbeatFn, _agentEventFn, _transcriptFn, init_openclaw_compat, http_handlers_exports, init_http_handlers, mcp_proxy_helpers_exports, init_mcp_proxy_helpers, workspace_handlers_exports, MAX_FILE_SIZE, init_workspace_handlers, ROOM_AGENT_TYPES, CREDENTIAL_MESSAGE_TYPES, CATCHUP_MESSAGE_TYPES, POLL_INTERVAL_MS, RECONNECT_BASE_MS, UUID_RE4, RECONNECT_MAX_MS, PENDING_POLL_INTERVAL_MS, HISTORY_RESTORE_TIMEOUT_MS2, HISTORY_UPLOAD_TIMEOUT_MS, CANONICAL_TIMESTAMP_RE, OUTBOUND_DEDUPE_WINDOW_MS, OUTBOUND_DEDUPE_MAX_SUPPRESS_MS, OUTBOUND_DEDUPE_MAX, OUTBOUND_DEDUPE_TYPES, RETRY_CANDIDATE_TTL_MS, RETRY_CANDIDATE_MAX, ROOM_FULFIL_COOLDOWN_MS, SecureChannel, init_channel, init_types, DEFAULT_API_URL, DEFAULT_HTTP_PORT, init_account_config, init_lifecycle, _ocRuntime, _channels, agentVaultPlugin, init_openclaw_plugin, init_gateway_send, init_llm_response_parser, OPENROUTER_PRICING, init_llm_pricing_openrouter, LEGACY_PRICING, PRICING, init_llm_cost, traceStore, init_fetch_interceptor, init_tool_audit, init_harness_compat, managedRoutesRequested, init_openclaw_entry, util, objectUtil, ZodParsedType, getParsedType, init_util, ZodIssueCode, ZodError, init_ZodError, errorMap, en_default, init_en, overrideErrorMap, init_errors2, makeIssue, ParseStatus, INVALID, DIRTY, OK, isAborted, isDirty, isValid, isAsync, init_parseUtil, init_typeAliases, errorUtil, init_errorUtil, ParseInputLazyPath, handleResult, ZodType, cuidRegex, cuid2Regex, ulidRegex, uuidRegex, nanoidRegex, jwtRegex, durationRegex, emailRegex, _emojiRegex, emojiRegex, ipv4Regex, ipv4CidrRegex, ipv6Regex, ipv6CidrRegex, base64Regex, base64urlRegex, dateRegexSource, dateRegex, ZodString, ZodNumber, ZodBigInt, ZodBoolean, ZodDate, ZodSymbol, ZodUndefined, ZodNull, ZodAny, ZodUnknown, ZodNever, ZodVoid, ZodArray, ZodObject, ZodUnion, getDiscriminator, ZodDiscriminatedUnion, ZodIntersection, ZodTuple, ZodRecord, ZodMap, ZodSet, ZodFunction, ZodLazy, ZodLiteral, ZodEnum, ZodNativeEnum, ZodPromise, ZodEffects, ZodOptional, ZodNullable, ZodDefault, ZodCatch, ZodNaN, ZodBranded, ZodPipeline, ZodReadonly, late, ZodFirstPartyTypeKind, stringType, numberType, nanType, bigIntType, booleanType, dateType, symbolType, undefinedType, nullType, anyType, unknownType, neverType, voidType, arrayType, objectType, strictObjectType, unionType, discriminatedUnionType, intersectionType, tupleType, recordType, mapType, setType, functionType, lazyType, literalType, enumType, nativeEnumType, promiseType, effectsType, optionalType, nullableType, preprocessType, pipelineType, init_types2, init_external, init_v3, util_exports, Cached, EVALUATING, captureStackTrace, allowsEval, getParsedType2, propertyKeyTypes, primitiveTypes, NUMBER_FORMAT_RANGES, BIGINT_FORMAT_RANGES, highSurrogate, Class, installing, broke, breaker, CONSTANT_CATCH, init_util2, _a2, _zodDesc, _E, $ZodAsyncError, $ZodEncodeError, globalConfig, init_core, _messageDesc, _issuesDesc, _installedToString, initializer, $ZodError, $ZodRealError, init_errors3, _parse, parse, _parseAsync, parseAsync, _safeParse, safeParse, _safeParseAsync, safeParseAsync, COMPILE_INVALID, COMPILE_FALLBACK, validate, validateAsync, _encode, _decode, _encodeAsync, _decodeAsync, _safeEncode, _safeDecode, _safeEncodeAsync, _safeDecodeAsync, init_parse, cuid, cuid2, ulid, xid, ksuid, nanoid, duration, guid, uuid, email, _emoji, ipv4, ipv6, cidrv4, cidrv6, base64, base64url, httpProtocol, e164, dateSource, date, anyString, integer, number, boolean, _null, lowercase, uppercase, init_regexes, $ZodCheck, _whenHasLength, numericOriginMap, $ZodCheckLessThan, $ZodCheckGreaterThan, $ZodCheckMultipleOf, $ZodCheckNumberFormat, $ZodCheckMaxLength, $ZodCheckMinLength, $ZodCheckLengthEquals, $ZodCheckStringFormat, $ZodCheckRegex, $ZodCheckLowerCase, $ZodCheckUpperCase, $ZodCheckIncludes, $ZodCheckStartsWith, $ZodCheckEndsWith, $ZodCheckOverwrite, init_checks, Doc, init_doc, version, init_versions, $ZodType, toStandardResult, $ZodString, $ZodStringFormat, $ZodGUID, $ZodUUID, $ZodEmail, URL_BAD_FORMAT, URL_UNPARSEABLE, asciiTabOrNewline, $ZodURL, $ZodEmoji, $ZodNanoID, $ZodCUID, $ZodCUID2, $ZodULID, $ZodXID, $ZodKSUID, $ZodISODateTime, $ZodISODate, $ZodISOTime, $ZodISODuration, $ZodIPv4, ipv6Alphabet, $ZodIPv6, $ZodCIDRv4, $ZodCIDRv6, base64Charset, $ZodBase64, base64urlCharset, $ZodBase64URL, $ZodE164, $ZodJWT, $ZodNumber, $ZodNumberFormat, $ZodBoolean, $ZodNull, $ZodUnknown, $ZodNever, arraySize, $ZodArray, NO_SYMBOL_KEYS, $ZodObject, $ZodObjectJIT, $ZodUnion, $ZodDiscriminatedUnion, $ZodIntersection, $ZodRecord, $ZodEnum, $ZodLiteral, $ZodTransform, $ZodOptional, $ZodExactOptional, $ZodNullable, $ZodDefault, $ZodPrefault, $ZodNonOptional, $ZodCatch, $ZodPipe, $ZodPreprocess, $ZodReadonly, $ZodCustom, init_schemas, $ZodCyclicError, STATE, NO_ISSUES, recursive, NONE, ASSUMED, PROVEN, handoff, open4, memo, init_memoizer, error, init_en2, init_locales, _a3, $ZodRegistry, globalRegistry, init_registries, init_compile, init_api, FOLDABLE_KEYS, UNION_KEYS, createToJSONSchemaMethod, createStandardJSONSchemaMethod, init_to_json_schema, narrowMin, narrowMax, narrowBoth, addDivisor, addPattern, intersectMime, setFormat, minContributor, maxContributor, formatContributor, contributors, formatMap, exactPatterns, exactPattern, stringProcessor, numberProcessor, booleanProcessor, bigintProcessor, symbolProcessor, nullProcessor, undefinedProcessor, voidProcessor, neverProcessor, anyProcessor, unknownProcessor, dateProcessor, enumProcessor, literalProcessor, nanProcessor, templateLiteralProcessor, fileProcessor, successProcessor, customProcessor, functionProcessor, transformProcessor, mapProcessor, setProcessor, arrayProcessor, objectProcessor, unionProcessor, intersectionProcessor, tupleProcessor, pendingRecords, recordProcessor, nullableProcessor, nonoptionalProcessor, UNREPRESENTABLE_DEFAULT, defaultProcessor, prefaultProcessor, catchProcessor, pipeProcessor, readonlyProcessor, promiseProcessor, optionalProcessor, lazyProcessor, allProcessors, init_json_schema_processors, init_json_schema, init_core2, init_parse2, ZodMiniType, ZodMiniObject, init_schemas2, init_checks2, init_iso, init_coerce, init_external2, init_v4_mini, init_zod_compat, init_checks3, _installedErrorProtos, initializer2, ZodRealError, init_errors4, parse2, parseAsync2, safeParse3, safeParseAsync3, encode3, decode2, encodeAsync2, decodeAsync2, safeEncode2, safeDecode2, safeEncodeAsync2, safeDecodeAsync2, init_parse3, ZodType2, _ZodString, ZodString2, ZodStringFormat, ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration, ZodEmail, ZodGUID, ZodUUID, ZodURL, ZodEmoji, ZodNanoID, ZodCUID, ZodCUID2, ZodULID, ZodXID, ZodKSUID, ZodIPv4, ZodIPv6, ZodCIDRv4, ZodCIDRv6, ZodBase64, ZodBase64URL, ZodE164, ZodJWT, ZodNumber2, ZodNumberFormat, ZodBoolean2, ZodNull2, ZodUnknown2, ZodNever2, ZodArray2, ZodObject2, ZodUnion2, ZodDiscriminatedUnion2, ZodIntersection2, ZodRecord2, ZodEnum2, ZodLiteral2, ZodTransform, ZodOptional2, ZodExactOptional, ZodNullable2, ZodDefault2, ZodPrefault, ZodNonOptional, ZodCatch2, ZodPipe, ZodPreprocess, ZodReadonly2, ZodCustom, init_schemas3, ZodFirstPartyTypeKind2, init_compat, iso_exports2, init_iso2, init_coerce2, init_external3, init_classic, init_v4, LATEST_PROTOCOL_VERSION, DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY, JSONRPC_VERSION, AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams, RequestSchema, NotificationsParamsSchema, NotificationSchema, ResultSchema, RequestIdSchema, JSONRPCRequestSchema, isJSONRPCRequest, JSONRPCNotificationSchema, isJSONRPCNotification, JSONRPCResultResponseSchema, isJSONRPCResultResponse, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse, JSONRPCMessageSchema, JSONRPCResponseSchema, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, isInitializeRequest, ServerCapabilitiesSchema, InitializeResultSchema, InitializedNotificationSchema, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema, TextResourceContentsSchema, Base64Schema, BlobResourceContentsSchema, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema, ImageContentSchema, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError, init_types3, init_interfaces, ignoreOverride, defaultOptions, getDefaultOptions, init_Options, getRefs, init_Refs, init_errorMessages, getRelativePath, init_getRelativePath, init_any, init_array2, init_bigint, init_boolean, init_branded, parseCatchDef, init_catch, integerDateParser, init_date, init_default, init_effects, init_enum, isJsonSchema7AllOfType, init_intersection, init_literal, emojiRegex2, zodPatterns, ALPHA_NUMERIC, init_string2, init_record, init_map, init_nativeEnum, init_never, init_null, primitiveMappings, asAnyOf, init_union, init_nullable, init_number2, init_object, parseOptionalDef, init_optional2, parsePipelineDef, init_pipeline, init_promise, init_set, init_tuple, init_undefined, init_unknown, parseReadonlyDef, init_readonly, selectParser, init_selectParser, get$ref, addMeta, init_parseDef, init_parseTypes, zodToJsonSchema, init_zodToJsonSchema, init_esm, init_zod_json_schema_compat, DEFAULT_REQUEST_TIMEOUT_MSEC, Protocol, init_protocol, require_code, require_scope, require_codegen, require_util, require_names, require_errors, require_boolSchema, require_rules, require_applicability, require_dataType, require_defaults, require_code2, require_keyword, require_subschema, require_fast_deep_equal, require_json_schema_traverse, require_resolve, require_validate, require_validation_error, require_ref_error, require_compile, require_data, require_utils, require_schemes, require_fast_uri, require_uri, require_core, require_id, require_ref, require_core2, require_limitNumber, require_multipleOf, require_ucs2length, require_limitLength, require_pattern, require_limitProperties, require_required, require_limitItems, require_equal, require_uniqueItems, require_const, require_enum, require_validation, require_additionalItems, require_items, require_prefixItems, require_items2020, require_contains, require_dependencies, require_propertyNames, require_additionalProperties, require_properties, require_patternProperties, require_not, require_anyOf, require_oneOf, require_allOf, require_if, require_thenElse, require_applicator, require_format, require_format2, require_metadata, require_draft7, require_types, require_discriminator, require_json_schema_draft_07, require_ajv, require_formats, require_limit, require_dist, import_ajv, import_ajv_formats, AjvJsonSchemaValidator, init_ajv_provider, ExperimentalServerTasks, init_server, init_helpers, Server, init_server2, COMPLETABLE_SYMBOL, McpZodTypeKind, init_completable, init_uriTemplate, TOOL_NAME_REGEX, init_toolNameValidation, ExperimentalMcpServerTasks, init_mcp_server, init_zod, McpServer, EMPTY_OBJECT_JSON_SCHEMA, EMPTY_COMPLETION_RESULT, init_mcp, RequestError, toRequestError, GlobalRequest, Request2, newHeadersFromIncoming, wrapBodyStream, newRequestFromIncoming, getRequestCache, requestCache, incomingKey, urlKey, headersKey, abortControllerKey, getAbortController, requestPrototype, newRequest, responseCache, getResponseCache, cacheKey, GlobalResponse, Response2, buildOutgoingHttpHeaders, X_ALREADY_SENT, outgoingEnded, handleRequestError, handleFetchError, handleResponseError, flushHeaders, responseViaCache, isPromise, responseViaResponseObject, getRequestListener, init_dist22, require_content_type, import_content_type, init_mediaType, DEFAULT_MAX_REQUEST_BODY_SIZE, MAX_BATCH_SIZE, init_requestBody, DEFAULT_SSE_KEEP_ALIVE_MS, MAX_TIMER_DELAY_MS, init_sseKeepAlive, WebStandardStreamableHTTPServerTransport, init_webStandardStreamableHttp, StreamableHTTPServerTransport, init_streamableHttp, AgentVaultMcpServer, init_mcp_server2, init_mcp_handlers, init_skill_manifest, init_skill_invoker, spanBuffer, init_skill_telemetry, PolicyEnforcer, init_policy_enforcer, VERSION, init_index;
17684
+ var __create, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf, __hasOwnProp, __esm2, __commonJS, __export2, __copyProps, __toESM, SENTINEL, WRAPPERS, INSTRUCTION, init_abstention, AMBIGUOUS_OWNER_ERROR, init_owner_routing, init_envelope_text, init_mls_commit_classify, MENTION_RE, BROADCAST_NAMES, init_room_protocol, __filename, __dirname, url, path, Module, Module, root, window_, crypto_, randomValuesStandard, crypto2, randomValueNodeJS, _Module, libsodium_sumo_default, init_libsodium_sumo, a, r, t, c, libsodium_wrappers_default, init_libsodium_wrappers, init_keys, init_x3dh, MAX_SKIP, CHAIN_KEY_SEED, MSG_KEY_SEED, HEADER_KEY_SEED, DoubleRatchet, init_ratchet, init_file_crypto, DOMAIN_DID_DOCUMENT, DOMAIN_TRANSFER_INTENT, DOMAIN_TRANSFER_ACCEPT, BASE58_ALPHABET, init_did, BUILTIN_PATTERNS, ScanEngine, init_scan_engine, init_merkle, VC_CONTEXT_V2, AV_CREDENTIAL_CONTEXT, CRYPTOSUITE, BASE58_ALPHABET2, init_vc, init_transport, init_telemetry, TelemetryReporter, init_telemetry_reporter, CROCKFORD, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, BACKUP_VERSION, MAX_BACKUP_SIZE, init_backup, atitle, aobject, aopts, isLE, swap8IfBE, swap32IfBE, hasHexBuiltin, hexes, oidNist, init_utils, BSIGMA, init_blake, U32_MASK64, _32n, fromNumH, fromNumL, shrSH, shrSL, rotrSH, rotrSL, rotrBH, rotrBL, rotr32H, rotr32L, add3L, add3H, add4L, add4H, add5L, add5H, init_u64, HashMD, SHA256_IV, SHA384_IV, SHA512_IV, init_md, B2B_IV, BBUF, _BLAKE2, _BLAKE2b, blake2b, init_blake2, CROCKFORD2, SALT_BYTES2, NONCE_BYTES2, KEY_BYTES2, TAG_BYTES, ENVELOPE_OVERHEAD, AAD_PREFIX, UUID_RE, UUID_V4_RE, DIGEST_ID_RE, TIMESTAMP_RE, encoder, decoder, HISTORY_MAGIC, HISTORY_ARCHIVE_VERSION, HISTORY_MAX_ENTRIES, HISTORY_MAX_BLOB_BYTES, HISTORY_KDF_OPSLIMIT, HISTORY_KDF_MEMLIMIT, HistoryEntryTooLargeError, init_history_backup, init_approval, encVoid, init_tlsEncoder, uint8Encoder, encodeUint8, decodeUint8, uint16Encoder, encodeUint16, decodeUint16, uint32Encoder, encodeUint32, decodeUint32, uint64Encoder, encodeUint64, decodeUint64, init_number, init_tlsDecoder, init_enumHelpers, defaultProposalTypes, defaultProposalTypeEncoder, encodeDefaultProposalType, decodeDefaultProposalType, init_defaultProposalType, defaultExtensionTypes, defaultExtensionTypeEncoder, encodeDefaultExtensionType, decodeDefaultExtensionType, init_defaultExtensionType, acceptAll, init_incomingMessageAction, MlsError, ValidationError, CodecError, UsageError, DependencyError, CryptoVerificationError, CryptoError, InternalError, init_mlsError, init_byteArray, varLenDataEncoder, decodeVarLenData, init_variableLength, init_constantTimeCompare, extensionTypeEncoder, encodeExtensionType, decodeExtensionType, extensionEncoder, encodeExtension, decodeExtension, init_extension, credentialTypes, credentialTypeEncoder, encodeCredentialType, decodeCredentialType, init_credentialType, credentialBasicEncoder, encodeCredentialBasic, credentialX509Encoder, encodeCredentialX509, credentialCustomEncoder, encodeCredentialCustom, credentialEncoder, encodeCredential, decodeCredentialBasic, decodeCredentialX509, decodeCredential, init_credential, externalSenderEncoder, encodeExternalSender, decodeExternalSender, init_externalSender, init_hash, init_optional, ciphersuites, ciphersuiteEncoder, encodeCiphersuite, decodeCiphersuite, ciphersuiteValues, init_ciphersuite, init_signature, protocolVersions, protocolVersionEncoder, encodeProtocolVersion, decodeProtocolVersion, init_protocolVersion, capabilitiesEncoder, encodeCapabilities, decodeCapabilities, init_capabilities, leafNodeSources, leafNodeSourceEncoder, encodeLeafNodeSource, decodeLeafNodeSource, init_leafNodeSource, lifetimeEncoder, encodeLifetime, decodeLifetime, defaultLifetime, init_lifetime, leafNodeDataEncoder, encodeLeafNodeData, decodeLeafNodeData, leafNodeInfoKeyPackageEncoder, encodeLeafNodeInfoKeyPackage, leafNodeInfoUpdateOmittedEncoder, encodeLeafNodeInfoUpdateOmitted, leafNodeInfoCommitOmittedEncoder, encodeLeafNodeInfoCommitOmitted, leafNodeInfoOmittedEncoder, encodeLeafNodeInfoOmitted, decodeLeafNodeInfoKeyPackage, decodeLeafNodeInfoUpdateOmitted, decodeLeafNodeInfoCommitOmitted, decodeLeafNodeInfoOmitted, leafNodeInfoUpdateEncoder, encodeLeafNodeInfoUpdate, leafNodeInfoCommitEncoder, encodeLeafNodeInfoCommit, leafNodeInfoEncoder, encodeLeafNodeInfo, decodeLeafNodeInfoUpdate, decodeLeafNodeInfoCommit, decodeLeafNodeInfo, leafNodeTBSEncoder, encodeLeafNodeTBS, leafNodeEncoder, encodeLeafNode, decodeLeafNode, decodeLeafNodeKeyPackage, decodeLeafNodeCommit, decodeLeafNodeUpdate, init_leafNode, keyPackageTBSEncoder, encodeKeyPackageTBS, decodeKeyPackageTBS, keyPackageEncoder, encodeKeyPackage, decodeKeyPackage, init_keyPackage, init_kdf, pskTypes, pskTypeEncoder, encodePskType, decodePskType, resumptionPSKUsages, resumptionPSKUsageEncoder, encodeResumptionPSKUsage, decodeResumptionPSKUsage, encodePskInfoExternal, encodePskInfoResumption, decodePskInfoResumption, pskInfoEncoder, encodePskInfo, decodePskInfo, pskIdEncoder, encodePskId, decodePskId, pskLabelEncoder, encodePskLabel, decodePskLabel, init_presharedkey, addEncoder, encodeAdd, decodeAdd, updateEncoder, encodeUpdate, decodeUpdate, removeEncoder, encodeRemove, decodeRemove, pskEncoder, encodePSK, decodePSK, reinitEncoder, encodeReinit, decodeReinit, externalInitEncoder, encodeExternalInit, decodeExternalInit, groupContextExtensionsEncoder, encodeGroupContextExtensions, decodeGroupContextExtensions, proposalAddEncoder, encodeProposalAdd, proposalUpdateEncoder, encodeProposalUpdate, proposalRemoveEncoder, encodeProposalRemove, proposalPSKEncoder, encodeProposalPSK, proposalReinitEncoder, encodeProposalReinit, proposalExternalInitEncoder, encodeProposalExternalInit, proposalGroupContextExtensionsEncoder, encodeProposalGroupContextExtensions, proposalCustomEncoder, encodeProposalCustom, proposalEncoder, encodeProposal, decodeProposalAdd, decodeProposalUpdate, decodeProposalRemove, decodeProposalPSK, decodeProposalReinit, decodeProposalExternalInit, decodeProposalGroupContextExtensions, decodeProposal, init_proposal, proposalOrRefTypes, proposalOrRefTypeEncoder, encodeProposalOrRefType, decodeProposalOrRefType, proposalOrRefProposalEncoder, encodeProposalOrRefProposal, proposalOrRefProposalRefEncoder, encodeProposalOrRefProposalRef, proposalOrRefEncoder, encodeProposalOrRef, decodeProposalOrRef, init_proposalOrRefType, init_hpke, groupContextEncoder, encodeGroupContext, decodeGroupContext, init_groupContext, nodeTypes, nodeTypeEncoder, encodeNodeType, decodeNodeType, init_nodeType, parentNodeEncoder, encodeParentNode, decodeParentNode, init_parentNode, init_treemath, nodeEncoder, encodeNode, decodeNode, ratchetTreeEncoder, encodeRatchetTree, decodeRatchetTree, init_ratchetTree, leafNodeHashInputEncoder, encodeLeafNodeHashInput, decodeLeafNodeHashInput, parentNodeHashInputEncoder, encodeParentNodeHashInput, decodeParentNodeHashInput, treeHashInputEncoder, encodeTreeHashInput, decodeTreeHashInput, init_treeHash, parentHashInputEncoder, encodeParentHashInput, decodeParentHashInput, init_parentHash, hpkeCiphertextEncoder, encodeHpkeCiphertext, decodeHpkeCiphertext, init_hpkeCiphertext, updatePathNodeEncoder, encodeUpdatePathNode, decodeUpdatePathNode, updatePathEncoder, encodeUpdatePath, decodeUpdatePath, init_updatePath, commitEncoder, encodeCommit, decodeCommit, init_commit, contentTypes, contentTypeEncoder, encodeContentType, decodeContentType, init_contentType, wireformats, wireformatEncoder, encodeWireformat, decodeWireformat, init_wireformat, senderTypes, senderTypeEncoder, encodeSenderType, decodeSenderType, senderEncoder, encodeSender, decodeSender, reuseGuardEncoder, encodeReuseGuard, decodeReuseGuard, senderDataEncoder, encodeSenderData, decodeSenderData, senderDataAADEncoder, encodeSenderDataAAD, decodeSenderDataAAD, init_sender, framedContentApplicationDataEncoder, encodeFramedContentApplicationData, framedContentProposalDataEncoder, encodeFramedContentProposalData, framedContentCommitDataEncoder, encodeFramedContentCommitData, framedContentInfoEncoder, encodeFramedContentInfo, decodeFramedContentApplicationData, decodeFramedContentProposalData, decodeFramedContentCommitData, decodeFramedContentInfo, framedContentEncoder, encodeFramedContent, decodeFramedContent, senderInfoEncoder, encodeSenderInfo, framedContentTBSEncoder, encodeFramedContentTBS, encodeFramedContentAuthDataContent, encodeFramedContentAuthDataCommit, framedContentAuthDataEncoder, encodeFramedContentAuthData, decodeFramedContentAuthDataCommit, init_framedContent, authenticatedContentEncoder, encodeAuthenticatedContent, decodeAuthenticatedContent, authenticatedContentTBMEncoder, encodeAuthenticatedContentTBM, init_authenticatedContent, publicMessageInfoEncoder, encodePublicMessageInfo, publicMessageEncoder, encodePublicMessage, decodePublicMessage, init_publicMessage, init_messageProtectionPublic, init_externalProposal, requiredCapabilitiesEncoder, encodeRequiredCapabilities, decodeRequiredCapabilities, init_requiredCapabilities, defaultAuthenticationService, init_authenticationService, defaultPaddingConfig, init_paddingConfig, defaultKeyPackageEqualityConfig, init_keyPackageEqualityConfig, defaultLifetimeConfig, init_lifetimeConfig, defaultKeyRetentionConfig, init_keyRetentionConfig, groupInfoTBSEncoder, encodeGroupInfoTBS, decodeGroupInfoTBS, groupInfoEncoder, encodeGroupInfo, decodeGroupInfo, init_groupInfo, keyScheduleEncoder, encodeKeySchedule, decodeKeySchedule, init_keySchedule, generationSecretEncoder, decodeGenerationSecret, secretTreeNodeEncoder, decodeSecretTreeNode, secretTreeEncoder, decodeSecretTree, init_secretTree, confirmedTranscriptHashInputEncoder, encodeConfirmedTranscriptHashInput, decodeConfirmedTranscriptHashInput, init_transcriptHash, groupSecretsEncoder, encodeGroupSecrets, decodeGroupSecrets, init_groupSecrets, encryptedGroupSecretsEncoder, encodeEncryptedGroupSecrets, decodeEncryptedGroupSecrets, welcomeEncoder, encodeWelcome, decodeWelcome, init_welcome, init_pathSecrets, privateKeyPathEncoder, decodePrivateKeyPath, init_privateKeyPath, proposalWithSenderEncoder, decodeProposalWithSender, unappliedProposalsEncoder, decodeUnappliedProposals, init_unappliedProposals, emptyPskIndex, init_pskIndex, init_addToMap, defaultClientConfig, init_clientConfig, init_array, stringEncoder, encodeString, decodeString, init_string, activeEncoder, suspendedPendingReinitEncoder, removedFromGroupEncoder, groupActiveStateEncoder, decodeGroupActiveState, init_groupActiveState, epochReceiverDataEncoder, decodeEpochReceiverData, init_epochReceiverData, groupStateEncoder, encodeGroupState, decodeGroupState, groupStateEncoderWithoutTree, encodeGroupStateWithoutTree, emptyProposals, init_clientState, privateMessageEncoder, encodePrivateMessage, decodePrivateMessage, privateContentAADEncoder, encodePrivateContentAAD, decodePrivateContentAAD, init_privateMessage, init_messageProtection, init_createMessage, init_createCommit, init_processMessages, init_makeHashImpl, HpkeError, InvalidParamError, SerializeError, DeserializeError, EncapError, DecapError, ExportError, SealError, OpenError, MessageLimitReachedError, DeriveKeyPairError, NotSupportedError, init_errors, dntGlobals, dntGlobalThis, init_dnt_shims, NativeAlgorithm, init_algorithm, Mode, KemId, KdfId, AeadId, init_identifiers, INPUT_LENGTH_LIMIT, INFO_LENGTH_LIMIT, MINIMUM_PSK_LENGTH, EMPTY, BYTE_TO_BIGINT_256, init_consts, SUITE_ID_HEADER_KEM, init_kemInterface, HPKE_VERSION, HkdfNative, HkdfSha256Native, HkdfSha384Native, HkdfSha512Native, init_hkdf, isCryptoKeyPair, init_misc, LABEL_EAE_PRK, LABEL_SHARED_SECRET, Dhkem, init_dhkem, KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, init_dhkemPrimitives, Bignum, init_bignum, LABEL_CANDIDATE, ORDER_P_256, ORDER_P_384, ORDER_P_521, PKCS8_ALG_ID_P_256, PKCS8_ALG_ID_P_384, PKCS8_ALG_ID_P_521, EC_P_256_PARAMS, EC_P_384_PARAMS, EC_P_521_PARAMS, Ec, init_ec, init_xCryptoKey, init_xCurve, init_hybridkem, AEAD_USAGES, init_aeadEncryptionContext, _endianTestBuffer, _endianTestBytes, isLE2, init_noble, init_hash2, _HMAC, hmac, init_hmac, init_md2, U32_MASK642, _32n2, init_u642, init_sha2, _0n, _1n, _2n, _7n, _256n, _0x71n, SHA3_PI, SHA3_ROTL, _SHA3_IOTA, IOTAS, SHA3_IOTA_H, SHA3_IOTA_L, init_sha3, init_modular, init_curve, init_montgomery, init_mod, AesGcmContext, Aes128Gcm, Aes256Gcm, init_aesGcm, init_exportOnly, init_emitNotSupported, LABEL_SEC, ExporterContextImpl, RecipientExporterContextImpl, SenderExporterContextImpl, init_exporterContext, EncryptionContextImpl, init_encryptionContext, __classPrivateFieldGet, __classPrivateFieldSet, _Mutex_locked, Mutex, init_mutex, __classPrivateFieldGet2, __classPrivateFieldSet2, _RecipientContextImpl_mutex, RecipientContextImpl, init_recipientContext, __classPrivateFieldGet3, __classPrivateFieldSet3, _SenderContextImpl_mutex, SenderContextImpl, init_senderContext, LABEL_BASE_NONCE, LABEL_EXP, LABEL_INFO_HASH, LABEL_KEY, LABEL_PSK_ID_HASH, LABEL_SECRET, SUITE_ID_HEADER_HPKE, CipherSuiteNative, init_cipherSuiteNative, DhkemP256HkdfSha256Native, DhkemP384HkdfSha384Native, DhkemP521HkdfSha512Native, init_dhkemNative, CipherSuite, DhkemP256HkdfSha256, DhkemP384HkdfSha384, DhkemP521HkdfSha512, HkdfSha256, HkdfSha384, HkdfSha512, init_native, ALG_NAME, PKCS8_ALG_ID_X25519, BASE_POINT_X25519, X25519, init_x25519, DhkemX25519HkdfSha256, init_dhkemX25519, PKCS8_ALG_ID_X448, init_x448, init_dhkemX448, init_mod2, init_hpke2, isLE3, wrapCipher, init_utils2, encodeStr, sigma16, sigma32, sigma16_32, sigma32_32, BLOCK_LEN, BLOCK_LEN32, MAX_COUNTER, U32_EMPTY, _XorStreamPRG, createPRG, init_arx, Poly1305, poly1305, init_poly1305, chacha_exports, chacha20orig, chacha20, xchacha20, chacha8, chacha12, ZEROS16, updatePadded, ZEROS32, _poly1305_aead, chacha20poly1305, xchacha20poly1305, rngChacha20, rngChacha8, init_chacha, init_makeAead, init_makeKdfImpl, init_makeDhKem, init_makeHpke, defaultRng, init_rng, crypto3, init_cryptoNode, isLE4, swap32IfBE3, hasHexBuiltin2, hexes2, asciis, Hash, init_utils3, HashMD3, SHA256_IV3, SHA384_IV3, SHA512_IV3, init_md3, U32_MASK643, _32n3, shrSH3, shrSL3, rotrSH3, rotrSL3, rotrBH3, rotrBL3, rotlSH2, rotlSL2, rotlBH2, rotlBL2, add3L3, add3H3, add4L3, add4H3, add5L3, add5H3, init_u643, SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384, sha2563, sha5122, sha3842, init_sha22, _0n2, _1n2, isPosBig, bitMask, notImplemented, init_utils4, _0n3, _1n3, _2n2, _3n, _4n, _5n, _7n2, _8n, _9n, _16n, isNegativeLE, FIELD_FIELDS, init_modular2, _0n4, _1n4, pointPrecomputes, pointWindowSizes, wNAF, init_curve2, _0n5, _1n5, _2n3, _8n2, PrimeEdwardsPoint, init_edwards, os2ip, _DST_scalar, init_hash_to_curve, _0n6, _1n6, _2n4, init_montgomery2, ed25519_exports, _0n7, _1n7, _2n5, _3n2, _5n2, _8n3, ed25519_CURVE_p, ed25519_CURVE, ED25519_SQRT_M1, Fp, Fn, ed25519Defaults, ed25519, ed25519ctx, ed25519ph, x25519, ELL2_C1, ELL2_C2, ELL2_C3, ELL2_C1_EDWARDS, ed25519_hasher, SQRT_M1, SQRT_AD_MINUS_ONE, INVSQRT_A_MINUS_D, ONE_MINUS_D_SQ, D_MINUS_ONE_SQ, invertSqrt, MAX_255B, bytes255ToNumberLE, _RistrettoPoint, ristretto255, ristretto255_hasher, ED25519_TORSION_SUBGROUP, edwardsToMontgomery, RistrettoPoint, hashToCurve, encodeToCurve, hashToRistretto255, hash_to_ristretto255, init_ed25519, _0n8, _1n8, _2n6, _7n3, _256n2, _0x71n2, SHA3_PI2, SHA3_ROTL2, _SHA3_IOTA2, IOTAS2, SHA3_IOTA_H2, SHA3_IOTA_L2, rotlH, rotlL, Keccak, genShake, shake2562, init_sha32, ed448_exports, ed448_CURVE, E448_CURVE, shake256_114, shake256_64, _1n9, _2n7, _3n3, _4n2, _11n, _22n, _44n, _88n, _223n, Fp2, Fn2, Fp448, Fn448, ED448_DEF, ed448, ed448ph, E448, x448, ELL2_C12, ELL2_J, ed448_hasher, ONE_MINUS_D, ONE_MINUS_TWO_D, SQRT_MINUS_D, INVSQRT_MINUS_D, invertSqrt2, _DecafPoint, decaf448, decaf448_hasher, ED448_TORSION_SUBGROUP, DecafPoint, hashToCurve2, encodeToCurve2, hashToDecaf448, hash_to_decaf448, edwardsToMontgomery2, init_ed448, HMAC, hmac2, init_hmac2, divNearest, DERErr, DER, _0n9, _1n10, _2n8, _3n4, _4n3, init_weierstrass, init_shortw_utils, nist_exports, p256_CURVE, p384_CURVE, p521_CURVE, Fp256, Fp384, Fp521, p256, p256_hasher, p384, p384_hasher, p521, secp256r1, secp384r1, secp521r1, p521_hasher, init_nist, init_makeNobleSignatureImpl, defaultCryptoProvider, init_provider, init_getCiphersuiteImpl, init_resumption, SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384, sha2564, sha5123, sha3843, init_sha23, _HMAC2, hmac3, init_hmac3, init_makeHashImpl2, init_makeNobleSignatureImpl2, BLOCK_SIZE, ZEROS162, ZEROS322, POLY, mul2, swapLE, estimateWindow, GHASH, Polyval, ghash, polyval, init_polyval, BLOCK_SIZE2, BLOCK_SIZE32, EMPTY_BLOCK, POLY2, sbox, rotr32_8, rotl32_8, tableEncoding, xPowers, gcm, _CMAC, cmac, init_aes, init_makeAead2, init_makeKdfImpl2, init_makeDhKem2, init_makeHpke2, init_rng2, nobleCryptoProvider, init_provider2, mlsPublicMessageEncoder, encodeMlsPublicMessage, mlsWelcomeEncoder, encodeMlsWelcome, mlsPrivateMessageEncoder, encodeMlsPrivateMessage, mlsGroupInfoEncoder, encodeMlsGroupInfo, mlsKeyPackageEncoder, encodeMlsKeyPackage, mlsMessageContentEncoder, encodeMlsMessageContent, decodeMlsMessageContent, mlsMessageEncoder, encodeMlsMessage, decodeMlsMessage, init_message, greaseValues, defaultGreaseConfig, init_grease, init_defaultCapabilities, init_src, DEFAULT_CIPHERSUITE, MLSGroupManager, init_mls_group, DOMAIN, NONCE_BYTES3, init_owner_sync, init_mls_delivery_order, init_mls_presend_epoch, dist_exports, init_dist2, DIR_MODE, FILE_MODE, init_secure_file, SYNC_LOCK_STALE_MS, pendingKpPath, init_mls_state, init_mls_kp_pool, PACKAGE, FALLBACK, MAX_LEN, DISALLOWED, init_client_version, CredentialStore, init_credential_store, init_crypto_helpers, STATE_FILE, LEGACY_STATE_FILE, init_state, ACTIVATION_DOMAIN, UUID_RE2, init_transport2, A2ALogGate, init_a2a_log_gate, init_mls_membership_probe, FIRST_DIRTY_DELAY_MS, RETRY_BASE_DELAYS_MS, MAX_RETRY_DELAY_MS, JITTER_FRACTION, HistoryBackupScheduler, init_history_backup_scheduler, FILE_MODE2, init_history_recovery_file, TENANT_ID_PATTERN, DIR_MODE2, FILE_MODE3, HISTORY_RECOVERY_VERIFY_TIMEOUT_MS, VERIFY_TIMEOUT_MESSAGE, HistoryRecoveryVerificationTimeoutError, init_history_recovery_code, ACTIONS, init_decision_reply, 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;
17634
17685
  var init_dist = __esm({
17635
17686
  async "../plugin/dist/index.js"() {
17636
17687
  "use strict";
@@ -17683,6 +17734,12 @@ var init_dist = __esm({
17683
17734
  INSTRUCTION = "not every message needs an answer from you: if this one is not addressed to you and asks nothing of you, reply with exactly " + SENTINEL + " and nothing else \u2014 that is discarded, not posted, and is how you stay quiet; never post a message SAYING that you are staying quiet";
17684
17735
  }
17685
17736
  });
17737
+ init_owner_routing = __esm2({
17738
+ "src/owner-routing.ts"() {
17739
+ "use strict";
17740
+ AMBIGUOUS_OWNER_ERROR = `More than one person is talking to this agent right now, so it can't tell who this is for. Add 'conversation_id' to say which conversation, or send audience "everyone" to reach them all.`;
17741
+ }
17742
+ });
17686
17743
  init_envelope_text = __esm2({
17687
17744
  "src/envelope-text.ts"() {
17688
17745
  "use strict";
@@ -70514,6 +70571,7 @@ var init_dist = __esm({
70514
70571
  init_http_handlers = __esm2({
70515
70572
  "src/http-handlers.ts"() {
70516
70573
  "use strict";
70574
+ init_owner_routing();
70517
70575
  }
70518
70576
  });
70519
70577
  mcp_proxy_helpers_exports = {};
@@ -70543,6 +70601,7 @@ var init_dist = __esm({
70543
70601
  async "src/channel.ts"() {
70544
70602
  "use strict";
70545
70603
  init_abstention();
70604
+ init_owner_routing();
70546
70605
  init_envelope_text();
70547
70606
  init_mls_commit_classify();
70548
70607
  init_room_protocol();
@@ -70592,6 +70651,11 @@ var init_dist = __esm({
70592
70651
  OUTBOUND_DEDUPE_TYPES = /* @__PURE__ */ new Set(["text", "status_alert", "artifact", "attachment"]);
70593
70652
  RETRY_CANDIDATE_TTL_MS = 6e4;
70594
70653
  RETRY_CANDIDATE_MAX = 32;
70654
+ _turnConversation = new AsyncLocalStorage();
70655
+ PERSON_INVOLVED_WINDOW_MS = 5 * 6e4;
70656
+ ATTESTED_INBOUND_MAX = 64;
70657
+ UNMAPPED_RECONCILE_COOLDOWN_MS = 6e4;
70658
+ TOPIC_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
70595
70659
  ROOM_FULFIL_COOLDOWN_MS = 6e4;
70596
70660
  SecureChannel = class _SecureChannel extends EventEmitter {
70597
70661
  constructor(config2) {
@@ -70818,10 +70882,42 @@ ${text}`;
70818
70882
  _scanEngine = null;
70819
70883
  _scanRuleSetVersion = 0;
70820
70884
  _telemetryReporter = null;
70821
- /** Topic ID from the most recent inbound message — used as fallback for replies. */
70822
- _lastIncomingTopicId;
70885
+ /**
70886
+ * #1416: topic of the most recent inbound message, PER conversation group —
70887
+ * the fallback for a reply that names no topic. Keyed by `_topicScope()`:
70888
+ * `g:<group>` normally, `c:<conversation>` for a conversation whose group is
70889
+ * not known yet, `*` for a legacy agent that knows no groups at all. It used
70890
+ * to be one value for the whole agent, so a broadcast into person B's group
70891
+ * carried the topic of person A's last message. In memory only, as before.
70892
+ */
70893
+ _lastIncomingTopics = /* @__PURE__ */ new Map();
70823
70894
  /** Room ID from the most recent inbound room message — used as fallback for HTTP /send replies. */
70824
70895
  _lastInboundRoomId;
70896
+ /**
70897
+ * #1418: the most recent owner 1:1 message that reached the agent — the
70898
+ * person involved in whatever the agent says next without naming a
70899
+ * conversation (see `_involvedPerson`). In memory only: after a restart
70900
+ * there is no trigger, so untargeted content goes to the primary person.
70901
+ */
70902
+ _lastInboundDm;
70903
+ /** #1418: turns in progress (`runForConversation`). */
70904
+ _activeTurns = /* @__PURE__ */ new Set();
70905
+ /**
70906
+ * #1418: recent owner 1:1 messages that decrypted, keyed by
70907
+ * conversation|group — evidence of which conversation, group and browser
70908
+ * belong together (one person). In memory only, bounded.
70909
+ */
70910
+ _attestedInbound = /* @__PURE__ */ new Map();
70911
+ /** #1418: per UNMAPPED group (or conversation), the last time it asked for a reconcile. */
70912
+ _unmappedReconcileAt = /* @__PURE__ */ new Map();
70913
+ /**
70914
+ * #1418: 1:1 groups joined by a Welcome IN THIS PROCESS while no
70915
+ * conversation mapped them — a person who has not been learned yet, counted
70916
+ * as one until the next successful reconcile. Persisted husks never are.
70917
+ */
70918
+ _welcomedUnmapped = /* @__PURE__ */ new Map();
70919
+ /** #1418: what the last SUCCESSFUL reconcile reported live, and when it started. */
70920
+ _lastReconcile;
70825
70921
  /** Rate-limit: last resync_request timestamp per conversation (5-min cooldown). */
70826
70922
  _lastResyncRequest = /* @__PURE__ */ new Map();
70827
70923
  /** Dedup: last room/group welcome self-heal request timestamp per group (30s window). */
@@ -71397,13 +71493,449 @@ ${text}`;
71397
71493
  }
71398
71494
  return `${kind}:${id ?? ""}`;
71399
71495
  }
71496
+ /*
71497
+ * #1416 — DM history is partitioned by conversation GROUP.
71498
+ *
71499
+ * Since #1399 every person has their own 1:1 group with the agent, but the
71500
+ * agent kept one DM history pool: a catch-up request or a session_init
71501
+ * replay from person B's group was answered with person A's plaintext too.
71502
+ * A DM entry's context now names its group:
71503
+ *
71504
+ * dm:g:<groupId>:<topicId> — the group is known
71505
+ * dm:c:<convId>:<topicId> — the conversation's group is not known yet
71506
+ * dm:<topicId> — legacy (pre-#1416): the PRIMARY group's
71507
+ *
71508
+ * Every form keeps the `dm:` prefix the archive, the web client and Hermes
71509
+ * test for, and the archive format (`topicId` is a free string) is unchanged.
71510
+ * An agent that knows at most one group selects exactly what it did before.
71511
+ */
71512
+ /** The DM history context for a message in `gid` (or `convId`'s group). */
71513
+ _dmHistoryContext(topicId, gid, convId) {
71514
+ const g2 = gid ?? (convId ? this._sessionGroupIds.get(convId) : void 0);
71515
+ if (g2) return `dm:g:${g2}:${topicId ?? ""}`;
71516
+ if (convId && this._knownDmGroups().size > 0) return `dm:c:${convId}:${topicId ?? ""}`;
71517
+ const legacyTopic = topicId && /^[gc]:/.test(topicId) ? "" : topicId;
71518
+ return this._historyContext("dm", legacyTopic);
71519
+ }
71520
+ /** Every conversation group this agent knows of. */
71521
+ _knownDmGroups() {
71522
+ const known = new Set(this._sessionGroupIds.values());
71523
+ if (this._persisted?.groupId) known.add(this._persisted.groupId);
71524
+ return known;
71525
+ }
71526
+ // --- #1418: only the person involved ----------------------------------
71527
+ /**
71528
+ * Run `fn` as the work an inbound 1:1 message from `conversationId`
71529
+ * triggered. Untargeted owner content sent while it runs — from inside its
71530
+ * async call chain, or from anywhere while it is the only turn in progress —
71531
+ * goes to that conversation's person only.
71532
+ *
71533
+ * `opts.groupId` is the group that message DECRYPTED under
71534
+ * (`metadata.conversationGroupId`). Pass it: it outranks the local
71535
+ * conversation→group map, which can be stale, and it is all there is for a
71536
+ * frame whose conversation is not mapped yet. With neither an id nor a
71537
+ * group, `fn` runs unchanged.
71538
+ */
71539
+ async runForConversation(conversationId, fn, opts) {
71540
+ const groupId = typeof opts?.groupId === "string" && opts.groupId ? opts.groupId : void 0;
71541
+ if (!conversationId && !groupId) return fn();
71542
+ const store = { convId: conversationId || void 0, groupId, ended: false };
71543
+ this._activeTurns.add(store);
71544
+ try {
71545
+ return await _turnConversation.run(store, fn);
71546
+ } finally {
71547
+ store.ended = true;
71548
+ store.endedAt = Date.now();
71549
+ this._activeTurns.delete(store);
71550
+ }
71551
+ }
71552
+ /**
71553
+ * The turn this call chain belongs to (#1418) — running, or ended but
71554
+ * still within the window in which work it left behind is for its person.
71555
+ * `"expired"` once that window is over: the work is proactive now.
71556
+ */
71557
+ _currentTurn() {
71558
+ const store = _turnConversation.getStore();
71559
+ if (!store) return void 0;
71560
+ if (!store.ended) return store;
71561
+ return Date.now() - (store.endedAt ?? 0) < PERSON_INVOLVED_WINDOW_MS ? store : "expired";
71562
+ }
71563
+ /**
71564
+ * Record an owner 1:1 message that just decrypted (#1418).
71565
+ *
71566
+ * Always kept as evidence of which conversation, group and browser belong
71567
+ * together (see `_dmPeople`). It makes its person "the person involved" only
71568
+ * when it is RECENT by the server's `createdAt`: a frame replayed from
71569
+ * backlog on reconnect is not something anyone is waiting on an answer to.
71570
+ */
71571
+ _noteInboundDm(convId, groupId, opts = {}) {
71572
+ if (!convId && !groupId) return;
71573
+ const now = Date.now();
71574
+ const sentAt = opts.createdAt ? Date.parse(opts.createdAt) : NaN;
71575
+ const at = Number.isFinite(sentAt) ? Math.min(now, sentAt) : now;
71576
+ const sender = opts.senderDeviceId && opts.senderDeviceId !== this._deviceId ? opts.senderDeviceId : void 0;
71577
+ const key = `${convId ?? ""}|${groupId ?? ""}|${sender ?? ""}`;
71578
+ const prior = this._attestedInbound.get(key);
71579
+ this._attestedInbound.delete(key);
71580
+ this._attestedInbound.set(key, { convId, groupId, senderDeviceId: sender, at: Math.max(prior?.at ?? 0, at) });
71581
+ while (this._attestedInbound.size > ATTESTED_INBOUND_MAX) {
71582
+ const oldest = this._attestedInbound.keys().next().value;
71583
+ if (oldest === void 0) break;
71584
+ this._attestedInbound.delete(oldest);
71585
+ }
71586
+ if (this._lastInboundDm && this._lastInboundDm.at > at) return;
71587
+ this._lastInboundDm = {
71588
+ convId,
71589
+ groupId: groupId ?? (convId ? this._sessionGroupIds.get(convId) : void 0),
71590
+ at
71591
+ };
71592
+ }
71593
+ /** The group `convId`'s most recent inbound decrypted under, if any. */
71594
+ _attestedGroupOf(convId) {
71595
+ if (!convId) return void 0;
71596
+ let gid;
71597
+ for (const a2 of this._attestedInbound.values()) {
71598
+ if (a2.convId === convId && a2.groupId) gid = a2.groupId;
71599
+ }
71600
+ return gid;
71601
+ }
71602
+ /** Does some mapped conversation point at `groupId`? */
71603
+ _isMappedGroup(groupId) {
71604
+ for (const gid of this._sessionGroupIds.values()) if (gid === groupId) return true;
71605
+ return false;
71606
+ }
71607
+ /**
71608
+ * An owner message decrypted under a group no mapped conversation points at
71609
+ * (#1418): the map is stale — a Welcome landed before its conversation was
71610
+ * learned, or a conversation was recreated. Re-resolve it from the server.
71611
+ * Fire-and-forget and rate-limited per group: never awaited on the receive
71612
+ * or Welcome path, so it can never hold up MLS processing.
71613
+ */
71614
+ _reconcileForUnmappedGroup(groupId) {
71615
+ if (!groupId || this._isMappedGroup(groupId)) return;
71616
+ this._reconcileSoon(`g:${groupId}`);
71617
+ }
71618
+ /** The same for a Double Ratchet message on a conversation the map does not know. */
71619
+ _reconcileForUnmappedConversation(convId) {
71620
+ if (!convId || this._sessionGroupIds.size === 0 || this._sessionGroupIds.has(convId)) return;
71621
+ this._reconcileSoon(`c:${convId}`);
71622
+ }
71623
+ _reconcileSoon(key) {
71624
+ const now = Date.now();
71625
+ if (now - (this._unmappedReconcileAt.get(key) ?? 0) < UNMAPPED_RECONCILE_COOLDOWN_MS) return;
71626
+ this._unmappedReconcileAt.set(key, now);
71627
+ void Promise.resolve().then(() => this._reconcileConversationGroups()).catch((err) => console.warn("[SecureChannel] Conversation-group reconcile (unmapped group) failed:", err));
71628
+ }
71629
+ /** A conversation of `groupId`, for an MLS frame that named only its group. */
71630
+ _conversationOfGroup(groupId) {
71631
+ if (!groupId) return void 0;
71632
+ if (this._primaryConversationId && this._sessionGroupIds.get(this._primaryConversationId) === groupId) {
71633
+ return this._primaryConversationId;
71634
+ }
71635
+ for (const [convId, gid] of this._sessionGroupIds) {
71636
+ if (gid === groupId) return convId;
71637
+ }
71638
+ return void 0;
71639
+ }
71640
+ /** Is `convId` one of this agent's own 1:1 conversations (never a room's or an A2A channel's)? */
71641
+ _isOwnDmConversation(convId) {
71642
+ if (this._isNonDmConversation(convId)) return false;
71643
+ return this._sessions.has(convId) || this._sessionGroupIds.has(convId) || !!this._persisted?.mlsConversations?.[convId] || convId === this._primaryConversationId;
71644
+ }
71645
+ /**
71646
+ * #1418 — the PEOPLE this agent has a 1:1 with, or `undefined` when it
71647
+ * cannot tell (no conversation is mapped: then it behaves as before #1418).
71648
+ *
71649
+ * People, not groups. Since #1399 one person has one group, but an agent
71650
+ * also keeps joined groups that are nobody's any more — husks of deleted or
71651
+ * recreated conversations. Measured 2026-10-24: wren held 13 joined groups
71652
+ * for 1 mapped, loopita 2 for 1, wowzer 2 for 1. Counting joined groups made
71653
+ * all three single-person agents look like several people, and their
71654
+ * replies could go only to a dead group.
71655
+ *
71656
+ * So a person is built from the conversations the server mapped, joined by
71657
+ * evidence that two things are the same person:
71658
+ * - the same group (a legacy group shared by several people cannot be told
71659
+ * apart, so it stays one — exactly the pre-#1418 behaviour);
71660
+ * - the same owner browser (a browser belongs to exactly one person);
71661
+ * - a message that decrypted under a group, from a conversation and browser.
71662
+ * A joined group nothing maps and nobody has spoken in is not a person. A
71663
+ * message on an unmapped group from a browser nobody knows IS someone —
71664
+ * that fails closed, toward "only them".
71665
+ */
71666
+ _dmPeople() {
71667
+ if (this._sessionGroupIds.size === 0) return void 0;
71668
+ const parent2 = /* @__PURE__ */ new Map();
71669
+ const add4 = (x2) => {
71670
+ if (!parent2.has(x2)) parent2.set(x2, x2);
71671
+ };
71672
+ const find = (x2) => {
71673
+ let root3 = x2;
71674
+ while (parent2.get(root3) !== root3) root3 = parent2.get(root3);
71675
+ return root3;
71676
+ };
71677
+ const union2 = (a2, b2) => {
71678
+ if (!a2 || !b2) return;
71679
+ add4(a2);
71680
+ add4(b2);
71681
+ const ra2 = find(a2), rb = find(b2);
71682
+ if (ra2 !== rb) parent2.set(ra2, rb);
71683
+ };
71684
+ const ownerOf = (convId) => {
71685
+ const owner = this._sessions.get(convId)?.ownerDeviceId ?? this._persisted?.sessions?.[convId]?.ownerDeviceId;
71686
+ return owner ? `d:${owner}` : void 0;
71687
+ };
71688
+ for (const [convId, gid] of this._sessionGroupIds) {
71689
+ add4(`c:${convId}`);
71690
+ union2(`c:${convId}`, `g:${gid}`);
71691
+ union2(`c:${convId}`, ownerOf(convId));
71692
+ }
71693
+ const primary = this._primaryConversationId || this._persisted?.primaryConversationId;
71694
+ const primaryGid = this._persisted?.groupId;
71695
+ if (primary && primaryGid && (parent2.has(`c:${primary}`) || parent2.has(`g:${primaryGid}`))) {
71696
+ union2(`c:${primary}`, `g:${primaryGid}`);
71697
+ }
71698
+ for (const gid of this._welcomedUnmapped.keys()) add4(`g:${gid}`);
71699
+ const records = [...this._attestedInbound.values()].map((a2) => ({
71700
+ a: a2,
71701
+ nodes: [
71702
+ a2.convId ? `c:${a2.convId}` : void 0,
71703
+ a2.groupId ? `g:${a2.groupId}` : void 0,
71704
+ a2.senderDeviceId ? `d:${a2.senderDeviceId}` : void 0
71705
+ ].filter((n2) => !!n2)
71706
+ }));
71707
+ const placed = /* @__PURE__ */ new Set();
71708
+ const place = (i2) => {
71709
+ const { a: a2, nodes } = records[i2];
71710
+ for (const n2 of nodes) add4(n2);
71711
+ for (const n2 of nodes.slice(1)) union2(nodes[0], n2);
71712
+ if (a2.convId && this._sessionGroupIds.has(a2.convId)) union2(`c:${a2.convId}`, ownerOf(a2.convId));
71713
+ placed.add(i2);
71714
+ };
71715
+ const linkKnown = () => {
71716
+ for (let progress = true; progress; ) {
71717
+ progress = false;
71718
+ records.forEach((r2, i2) => {
71719
+ if (!placed.has(i2) && r2.nodes.some((n2) => parent2.has(n2))) {
71720
+ place(i2);
71721
+ progress = true;
71722
+ }
71723
+ });
71724
+ }
71725
+ };
71726
+ linkKnown();
71727
+ records.forEach((r2, i2) => {
71728
+ if (!placed.has(i2) && this._mayBeNewPerson(r2.a)) place(i2);
71729
+ });
71730
+ linkKnown();
71731
+ const roots = /* @__PURE__ */ new Set();
71732
+ for (const node2 of parent2.keys()) {
71733
+ if (!node2.startsWith("d:")) roots.add(find(node2));
71734
+ }
71735
+ return {
71736
+ count: roots.size,
71737
+ keyOf: (convId, groupId) => {
71738
+ if (convId && parent2.has(`c:${convId}`)) return find(`c:${convId}`);
71739
+ if (groupId && parent2.has(`g:${groupId}`)) return find(`g:${groupId}`);
71740
+ return void 0;
71741
+ }
71742
+ };
71743
+ }
71744
+ /**
71745
+ * May this inbound evidence stand for a person nobody knows yet (#1418)?
71746
+ * Only if it was sent recently, and the last successful reconcile — when it
71747
+ * started after the message was sent — listed its conversation or group.
71748
+ */
71749
+ _mayBeNewPerson(a2) {
71750
+ if (Date.now() - a2.at >= PERSON_INVOLVED_WINDOW_MS) return false;
71751
+ const r2 = this._lastReconcile;
71752
+ if (r2 && a2.at <= r2.at && !(a2.convId && r2.convs.has(a2.convId)) && !(a2.groupId && r2.groups.has(a2.groupId))) return false;
71753
+ return true;
71754
+ }
71755
+ /** More than one person has a 1:1 with this agent (#1418). Unknown counts as one: the old behaviour. */
71756
+ _isMultiPerson() {
71757
+ return (this._dmPeople()?.count ?? 0) > 1;
71758
+ }
71759
+ /**
71760
+ * The group a turn's message decrypted under, for placing the turn when its
71761
+ * conversation is not mapped (a mapped conversation already names its person).
71762
+ */
71763
+ _turnGroup(turn) {
71764
+ return turn.groupId ?? this._attestedGroupOf(turn.convId);
71765
+ }
71766
+ /** The people with a 1:1 turn in progress, one turn each (#1418). */
71767
+ _activeTurnPeople() {
71768
+ const people = this._dmPeople();
71769
+ const out = /* @__PURE__ */ new Map();
71770
+ for (const turn of this._activeTurns) {
71771
+ if (turn.convId && (turn.groupId ? this._isNonDmConversation(turn.convId) : !this._isOwnDmConversation(turn.convId))) continue;
71772
+ const gid = this._turnGroup(turn);
71773
+ const key = people?.keyOf(turn.convId, gid) ?? (gid ? `g:${gid}` : `c:${turn.convId}`);
71774
+ if (!out.has(key)) out.set(key, turn);
71775
+ }
71776
+ return out;
71777
+ }
71778
+ /**
71779
+ * The person an untargeted owner message is for (#1418), in order:
71780
+ *
71781
+ * 1. the turn this call chain belongs to — always, and only, that
71782
+ * conversation, reached on the group its message decrypted under. A turn
71783
+ * never borrows another conversation's turn: one it cannot place fails
71784
+ * closed to its own conversation. Work the turn left running (a timer, a
71785
+ * dispatch orphaned by the turn budget) stays with that person for
71786
+ * `PERSON_INVOLVED_WINDOW_MS` after the turn, then is proactive (4);
71787
+ * 2. with no turn context (a skill's HTTP call), the one person with a turn
71788
+ * in progress;
71789
+ * 3. the last inbound 1:1 message, if it is recent — a reply produced in
71790
+ * response to it;
71791
+ * 4. otherwise the content is proactive: the PRIMARY conversation's person.
71792
+ */
71793
+ _involvedPerson() {
71794
+ const person = (convId, groupId, reason) => ({
71795
+ convId,
71796
+ groupId: groupId ?? this._attestedGroupOf(convId) ?? (convId ? this._sessionGroupIds.get(convId) : void 0),
71797
+ reason
71798
+ });
71799
+ const turn = this._currentTurn();
71800
+ if (turn && turn !== "expired") {
71801
+ return person(turn.convId ?? this._conversationOfGroup(turn.groupId), turn.groupId, turn.ended ? "outlived-turn" : "turn");
71802
+ }
71803
+ if (turn === "expired") return this._primaryPerson();
71804
+ const active = this._activeTurnPeople();
71805
+ if (active.size === 1) {
71806
+ const [only] = active.values();
71807
+ return person(only.convId ?? this._conversationOfGroup(only.groupId), only.groupId, "active-turn");
71808
+ }
71809
+ const last = this._lastInboundDm;
71810
+ if (active.size === 0 && last && Date.now() - last.at < PERSON_INVOLVED_WINDOW_MS) {
71811
+ return person(last.convId ?? this._conversationOfGroup(last.groupId), last.groupId, "last-inbound");
71812
+ }
71813
+ return this._primaryPerson();
71814
+ }
71815
+ /** The PRIMARY conversation's person — where proactive content goes. */
71816
+ _primaryPerson() {
71817
+ const primary = this._primaryConversationId || this._persisted?.primaryConversationId || void 0;
71818
+ const primaryGroup = (primary ? this._sessionGroupIds.get(primary) : void 0) ?? this._persisted?.groupId;
71819
+ return {
71820
+ convId: primary,
71821
+ groupId: primaryGroup ?? this._attestedGroupOf(primary),
71822
+ reason: "primary"
71823
+ };
71824
+ }
71825
+ /**
71826
+ * #1418 — would an untargeted owner send right now have to GUESS between
71827
+ * people? True only with no turn context while two or more people have a
71828
+ * turn in progress. The local HTTP API refuses such a request (409) and
71829
+ * asks for a conversation instead of picking one.
71830
+ */
71831
+ isUntargetedOwnerAmbiguous(options) {
71832
+ if (options?.conversationId !== void 0 || options?.audience === "everyone") return false;
71833
+ if (this._currentTurn()) return false;
71834
+ if (!this._isMultiPerson()) return false;
71835
+ return this._activeTurnPeople().size > 1;
71836
+ }
71837
+ /**
71838
+ * Who an UNTARGETED owner send reaches, or `null` for "every session, as
71839
+ * before". `null` when the caller chose `audience: "everyone"`, and when the
71840
+ * agent has one person (or cannot tell how many) — nothing to choose
71841
+ * between, so its recipients are exactly what they always were.
71842
+ */
71843
+ _untargetedAudience(options) {
71844
+ if (options?.conversationId !== void 0) return null;
71845
+ if (options?.audience === "everyone") return null;
71846
+ if (!this._isMultiPerson()) return null;
71847
+ return this._involvedPerson();
71848
+ }
71849
+ /** A stable name for who an untargeted owner send reaches right now, or undefined when that is "everyone, as before". */
71850
+ _audienceTag(options) {
71851
+ if (options?.audience === "everyone") return "everyone";
71852
+ const person = this._untargetedAudience(options);
71853
+ return person ? `person:${person.groupId ?? person.convId ?? ""}` : void 0;
71854
+ }
71855
+ /** Does conversation `convId` belong to `person`? A conversation nothing ties to them fails closed. */
71856
+ _isPersonsConversation(person, convId) {
71857
+ if (convId === person.convId) return true;
71858
+ const gid = this._sessionGroupIds.get(convId);
71859
+ if (gid !== void 0 && gid === person.groupId) return true;
71860
+ const people = this._dmPeople();
71861
+ const theirs = people?.keyOf(person.convId, person.groupId);
71862
+ return theirs !== void 0 && people.keyOf(convId, gid) === theirs;
71863
+ }
71864
+ /**
71865
+ * #1418: the Double Ratchet sessions an owner-bound FILE (attachment or
71866
+ * artifact) goes to, bucketed by the conversation its blob is uploaded
71867
+ * under. The blob is uploaded under a conversation of the person who gets
71868
+ * it — the backend only lets that conversation's participants download it —
71869
+ * so an explicit "everyone" uploads once per person.
71870
+ */
71871
+ _ownerFileRecipients(routing) {
71872
+ const roomConvIds = /* @__PURE__ */ new Set();
71873
+ for (const room of Object.values(this._persisted?.rooms ?? {})) {
71874
+ for (const cid of room.conversationIds ?? []) roomConvIds.add(cid);
71875
+ }
71876
+ const live = [...this._sessions].filter(([convId, session2]) => session2.activated && !roomConvIds.has(convId)).map(([convId]) => convId);
71877
+ const person = routing?.conversationId !== void 0 ? { convId: routing.conversationId, groupId: this._sessionGroupIds.get(routing.conversationId), reason: "target" } : this._untargetedAudience(routing);
71878
+ if (person) {
71879
+ const convIds = live.filter((convId) => this._isPersonsConversation(person, convId));
71880
+ const uploadConvId = person.convId ?? convIds[0];
71881
+ return uploadConvId && convIds.length > 0 ? [{ uploadConvId, convIds }] : [];
71882
+ }
71883
+ if (live.length === 0) return [];
71884
+ if (!this._isMultiPerson()) {
71885
+ return [{ uploadConvId: this._primaryConversationId, convIds: live }];
71886
+ }
71887
+ const people = this._dmPeople();
71888
+ const buckets = /* @__PURE__ */ new Map();
71889
+ for (const convId of live) {
71890
+ const gid = this._sessionGroupIds.get(convId);
71891
+ const key = people?.keyOf(convId, gid) ?? gid ?? `c:${convId}`;
71892
+ buckets.set(key, [...buckets.get(key) ?? [], convId]);
71893
+ }
71894
+ return [...buckets.values()].map((convIds) => ({
71895
+ uploadConvId: convIds.includes(this._primaryConversationId) ? this._primaryConversationId : convIds[0],
71896
+ convIds
71897
+ }));
71898
+ }
71899
+ /** The group a DM history entry belongs to (see the forms above). */
71900
+ _dmEntryScope(entry, known) {
71901
+ const t2 = entry.topicId ?? "";
71902
+ let scope;
71903
+ if (t2.startsWith("dm:g:")) {
71904
+ scope = t2.slice("dm:g:".length).split(":")[0];
71905
+ } else if (t2.startsWith("dm:c:")) {
71906
+ const conv = t2.slice("dm:c:".length).split(":")[0];
71907
+ scope = this._sessionGroupIds.get(conv) ?? `c:${conv}`;
71908
+ } else {
71909
+ scope = this._persisted?.groupId;
71910
+ }
71911
+ if ((scope === void 0 || scope.startsWith("c:")) && known.size === 1) {
71912
+ return [...known][0];
71913
+ }
71914
+ return scope;
71915
+ }
71916
+ /**
71917
+ * The group a DM history request is answered from, or `null` for "every DM
71918
+ * entry" (an agent that knows no groups at all — the old behaviour). A
71919
+ * request whose group cannot be told fails closed to its own conversation.
71920
+ */
71921
+ _dmRequestScope(gid, convId, known) {
71922
+ if (known.size === 0) return null;
71923
+ const g2 = gid ?? (convId ? this._sessionGroupIds.get(convId) : void 0);
71924
+ if (g2) return g2;
71925
+ const isPrimaryConv = convId === void 0 || convId === this._primaryConversationId;
71926
+ if (known.size === 1 && isPrimaryConv) return [...known][0];
71927
+ if (convId && convId === this._primaryConversationId && this._persisted?.groupId) {
71928
+ return this._persisted.groupId;
71929
+ }
71930
+ return `c:${convId ?? ""}`;
71931
+ }
71400
71932
  /**
71401
71933
  * Normalize one accepted application envelope before it enters plaintext
71402
71934
  * history. Protocol/control types and empty attachment-only envelopes are
71403
71935
  * never archived, and attachment key material can never become the fallback
71404
71936
  * text.
71405
71937
  */
71406
- async _captureHistoryApplication(sender, rawPlaintext, kind, id, transportTimestamp, declaredType = "message") {
71938
+ async _captureHistoryApplication(sender, rawPlaintext, kind, id, transportTimestamp, declaredType = "message", dmScope) {
71407
71939
  let messageType = declaredType;
71408
71940
  let text = rawPlaintext;
71409
71941
  try {
@@ -71418,14 +71950,14 @@ ${text}`;
71418
71950
  await this._appendHistory(
71419
71951
  sender,
71420
71952
  text,
71421
- this._historyContext(kind, id),
71953
+ kind === "dm" ? this._dmHistoryContext(id, dmScope?.groupId, dmScope?.conversationId) : this._historyContext(kind, id),
71422
71954
  transportTimestamp
71423
71955
  );
71424
71956
  return text;
71425
71957
  }
71426
71958
  /** Select a context before applying the optional lower bound and final cap. */
71427
- _historyForCatchup(kind, id, sinceTs) {
71428
- let filtered = this._selectHistoryContext(kind, id);
71959
+ _historyForCatchup(kind, id, sinceTs, dmScope) {
71960
+ let filtered = this._selectHistoryContext(kind, id, dmScope);
71429
71961
  if (sinceTs !== void 0 && sinceTs !== null) {
71430
71962
  if (typeof sinceTs !== "string" || !CANONICAL_TIMESTAMP_RE.test(sinceTs) || !Number.isFinite(Date.parse(sinceTs)) || new Date(Date.parse(sinceTs)).toISOString() !== sinceTs) {
71431
71963
  throw new Error("Invalid history catch-up timestamp");
@@ -71435,11 +71967,17 @@ ${text}`;
71435
71967
  return filtered.sort((a2, b2) => Date.parse(a2.ts) - Date.parse(b2.ts) || a2.id.localeCompare(b2.id)).slice(-100);
71436
71968
  }
71437
71969
  /** Shared exact routing selector for catch-up and legacy DR replay. */
71438
- _selectHistoryContext(kind, id) {
71970
+ _selectHistoryContext(kind, id, dmScope) {
71439
71971
  const history = this._persisted?.messageHistory ?? [];
71440
- return kind === "room" ? history.filter((entry) => entry.topicId === this._historyContext("room", id)) : history.filter(
71972
+ if (kind === "room") {
71973
+ return history.filter((entry) => entry.topicId === this._historyContext("room", id));
71974
+ }
71975
+ const dm = history.filter(
71441
71976
  (entry) => entry.topicId?.startsWith("dm:") === true || !entry.topicId?.startsWith("room:") && !entry.topicId?.startsWith("a2a:")
71442
71977
  );
71978
+ const known = this._knownDmGroups();
71979
+ const want = this._dmRequestScope(dmScope?.groupId, dmScope?.conversationId, known);
71980
+ return want === null ? dm : dm.filter((entry) => this._dmEntryScope(entry, known) === want);
71443
71981
  }
71444
71982
  _markHistoryDirty() {
71445
71983
  this._historyBackupScheduler.markDirty();
@@ -71929,7 +72467,10 @@ ${text}`;
71929
72467
  Promise.resolve().then(() => (init_openclaw_compat(), openclaw_compat_exports)).then(({ requestHeartbeatNow: requestHeartbeatNow2 }) => requestHeartbeatNow2({ reason: "channel-send" })).catch(() => {
71930
72468
  });
71931
72469
  const targetConvId = options?.conversationId;
71932
- const topicId = options?.topicId ?? this._lastIncomingTopicId ?? this._persisted?.defaultTopicId;
72470
+ const audience = this._untargetedAudience(options);
72471
+ const explicitTopicId = options?.topicId;
72472
+ const targeted = targetConvId !== void 0;
72473
+ const frameHistoryContexts = [];
71933
72474
  const messageType = options?.messageType ?? "text";
71934
72475
  const priority = options?.priority ?? "normal";
71935
72476
  const parentSpanId = options?.parentSpanId;
@@ -71965,7 +72506,7 @@ ${text}`;
71965
72506
  if (this._persisted?.mlsGroups && this._state === "ready" && this._ws) {
71966
72507
  const targetSharedGid = targetConvId ? this._sessionGroupIds?.get(targetConvId) : void 0;
71967
72508
  console.log(
71968
- `[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)"}`
72509
+ `[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)"}`
71969
72510
  );
71970
72511
  const skipped = [];
71971
72512
  for (const [gid, entry] of Object.entries(this._persisted.mlsGroups)) {
@@ -71973,6 +72514,10 @@ ${text}`;
71973
72514
  skipped.push(`${gid.slice(0, 8)}:not-target`);
71974
72515
  continue;
71975
72516
  }
72517
+ if (audience && gid !== audience.groupId) {
72518
+ skipped.push(`${gid.slice(0, 8)}:not-involved`);
72519
+ continue;
72520
+ }
71976
72521
  if (!entry.mlsGroupId) {
71977
72522
  skipped.push(`${gid.slice(0, 8)}:no-mlsGroupId`);
71978
72523
  continue;
@@ -71996,11 +72541,12 @@ ${text}`;
71996
72541
  plaintextBytes
71997
72542
  );
71998
72543
  await saveMlsState(this.config.dataDir, entry.mlsGroupId, JSON.stringify(mlsGroup.exportState()));
72544
+ const frameTopicId = this._topicForFrame(gid, targetConvId, explicitTopicId, targeted);
71999
72545
  const payload = {
72000
72546
  group_id: entry.mlsGroupId,
72001
72547
  epoch: Number(mlsGroup.epoch),
72002
72548
  payload: Buffer.from(cipherBytes).toString("hex"),
72003
- topic_id: topicId,
72549
+ topic_id: frameTopicId,
72004
72550
  client_message_id: clientMessageId,
72005
72551
  message_type: messageType,
72006
72552
  priority,
@@ -72010,6 +72556,7 @@ ${text}`;
72010
72556
  if (this._persisted?.hubAddress) payload.hub_address = this._persisted.hubAddress;
72011
72557
  if (this._persisted?.hubId) payload.sender_hub_id = this._persisted.hubId;
72012
72558
  pendingWsSends.push(JSON.stringify({ event: "message_mls", data: payload }));
72559
+ frameHistoryContexts.push(this._dmHistoryContext(frameTopicId, gid, targetConvId));
72013
72560
  addressedMlsGroupIds.push(entry.mlsGroupId);
72014
72561
  sentSharedGroupIds.add(gid);
72015
72562
  sentCount++;
@@ -72027,12 +72574,14 @@ ${text}`;
72027
72574
  if (!session2.activated) continue;
72028
72575
  if (roomConvIds.has(convId)) continue;
72029
72576
  if (targetConvId && convId !== targetConvId) continue;
72577
+ if (audience && !this._isPersonsConversation(audience, convId)) continue;
72030
72578
  const convGroupId = this._sessionGroupIds?.get(convId);
72031
72579
  if (convGroupId && sentSharedGroupIds.has(convGroupId)) {
72032
72580
  sentCount++;
72033
72581
  continue;
72034
72582
  }
72035
72583
  try {
72584
+ const topicId = this._topicForFrame(convGroupId, convId, explicitTopicId, targeted);
72036
72585
  const mlsGroup = (convGroupId ? this._mlsGroups.get(`1to1-group:${convGroupId}`) : null) ?? this._mlsGroups.get(`conv:${convId}`);
72037
72586
  const mlsGroupId = (convGroupId ? this._persisted?.mlsGroups?.[convGroupId]?.mlsGroupId : null) ?? this._persisted?.mlsConversations?.[convId]?.mlsGroupId;
72038
72587
  if (convGroupId && mlsGroupId && sentSharedGroupIds.has(convGroupId)) {
@@ -72074,6 +72623,7 @@ ${text}`;
72074
72623
  data: payload
72075
72624
  })
72076
72625
  );
72626
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, convGroupId, convId));
72077
72627
  addressedMlsGroupIds.push(mlsGroupId);
72078
72628
  if (convGroupId) sentSharedGroupIds.add(convGroupId);
72079
72629
  } else if (!options?.bypassMlsHold && this._shouldHoldForMls(convGroupId, mlsGroup, mlsGroupId)) {
@@ -72093,7 +72643,7 @@ ${text}`;
72093
72643
  history: {
72094
72644
  id: clientMessageId,
72095
72645
  text: plaintext,
72096
- topicId: this._historyContext("dm", topicId)
72646
+ topicId: this._dmHistoryContext(topicId, convGroupId, convId)
72097
72647
  }
72098
72648
  } : {}
72099
72649
  };
@@ -72122,6 +72672,7 @@ ${text}`;
72122
72672
  data: payload
72123
72673
  })
72124
72674
  );
72675
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, convGroupId, convId));
72125
72676
  } else {
72126
72677
  if (!this._persisted.outboundQueue) {
72127
72678
  this._persisted.outboundQueue = [];
@@ -72142,6 +72693,7 @@ ${text}`;
72142
72693
  if (this._persisted?.mlsConversations && this._state === "ready" && this._ws) {
72143
72694
  for (const [mlsConvId, entry] of Object.entries(this._persisted.mlsConversations)) {
72144
72695
  if (targetConvId && mlsConvId !== targetConvId) continue;
72696
+ if (audience && !this._isPersonsConversation(audience, mlsConvId)) continue;
72145
72697
  if (this._sessions.has(mlsConvId)) continue;
72146
72698
  if (roomConvIds.has(mlsConvId)) continue;
72147
72699
  const mlsOnlyConvGroupId = this._sessionGroupIds?.get(mlsConvId);
@@ -72153,6 +72705,7 @@ ${text}`;
72153
72705
  continue;
72154
72706
  }
72155
72707
  try {
72708
+ const topicId = this._topicForFrame(mlsOnlyConvGroupId, mlsConvId, explicitTopicId, targeted);
72156
72709
  const plaintextBytes = new TextEncoder().encode(plaintext);
72157
72710
  const mlsOnlyGroupKey = mlsOnlyConvGroupId && this._mlsGroups.has(`1to1-group:${mlsOnlyConvGroupId}`) ? `1to1-group:${mlsOnlyConvGroupId}` : `conv:${mlsConvId}`;
72158
72711
  const cipherBytes = await this._encryptWithCatchUp(
@@ -72178,6 +72731,7 @@ ${text}`;
72178
72731
  if (this._persisted?.hubAddress) payload.hub_address = this._persisted.hubAddress;
72179
72732
  if (this._persisted?.hubId) payload.sender_hub_id = this._persisted.hubId;
72180
72733
  pendingWsSends.push(JSON.stringify({ event: "message_mls", data: payload }));
72734
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, mlsOnlyConvGroupId, mlsConvId));
72181
72735
  addressedMlsGroupIds.push(resolvedMlsGroupId);
72182
72736
  sentCount++;
72183
72737
  if (mlsOnlyConvGroupId) sentSharedGroupIds.add(mlsOnlyConvGroupId);
@@ -72199,11 +72753,15 @@ ${text}`;
72199
72753
  );
72200
72754
  }
72201
72755
  let writtenFrames = 0;
72202
- for (const frame of pendingWsSends) {
72203
- if (this._sendApplicationFrame(frame)) writtenFrames += 1;
72756
+ let historyContext;
72757
+ for (const [i2, frame] of pendingWsSends.entries()) {
72758
+ if (this._sendApplicationFrame(frame)) {
72759
+ if (writtenFrames === 0) historyContext = frameHistoryContexts[i2];
72760
+ writtenFrames += 1;
72761
+ }
72204
72762
  }
72205
72763
  if (!options?.isResend && messageType === "text" && writtenFrames > 0) {
72206
- await this._appendHistory("agent", plaintext, this._historyContext("dm", topicId), void 0, clientMessageId);
72764
+ await this._appendHistory("agent", plaintext, historyContext ?? this._historyContext("dm"), void 0, clientMessageId);
72207
72765
  }
72208
72766
  if (writtenFrames > 0) {
72209
72767
  console.log(
@@ -72259,7 +72817,7 @@ ${text}`;
72259
72817
  */
72260
72818
  sendActivitySpan(spanData) {
72261
72819
  if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
72262
- const pluginVersion = true ? "0.23.50" : "0.0.0-dev";
72820
+ const pluginVersion = true ? "0.23.52" : "0.0.0-dev";
72263
72821
  const agentName = this.config.agentName ?? "Agent";
72264
72822
  const resource = {
72265
72823
  "service.name": "agentvault-agent",
@@ -72311,7 +72869,7 @@ ${text}`;
72311
72869
  * Builds a structured envelope with decision metadata and sends it
72312
72870
  * as a high-priority message. Returns the generated decision_id.
72313
72871
  */
72314
- async sendDecisionRequest(request) {
72872
+ async sendDecisionRequest(request, routing) {
72315
72873
  const decision_id = `dec_${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
72316
72874
  const payload = JSON.stringify({
72317
72875
  type: "message",
@@ -72322,6 +72880,8 @@ ${text}`;
72322
72880
  }
72323
72881
  });
72324
72882
  await this.send(payload, {
72883
+ conversationId: routing?.conversationId,
72884
+ audience: routing?.audience,
72325
72885
  messageType: "decision_request",
72326
72886
  priority: "high",
72327
72887
  metadata: {
@@ -72728,6 +73288,7 @@ ${text}`;
72728
73288
  const jwt = this._deviceJwt ?? this._persisted?.deviceJwt;
72729
73289
  if (!jwt || !this._persisted) return false;
72730
73290
  let rows;
73291
+ const reconcileStartedAt = Date.now();
72731
73292
  try {
72732
73293
  const res = await fetch(`${this.config.apiUrl}/api/v1/conversations`, {
72733
73294
  headers: { Authorization: `Bearer ${jwt}` }
@@ -72744,8 +73305,31 @@ ${text}`;
72744
73305
  );
72745
73306
  if (mine.length === 0) return false;
72746
73307
  const before = this._persisted.groupId;
73308
+ const primaryBefore = this._persisted.primaryConversationId;
73309
+ const knownBefore = this._knownDmGroups();
73310
+ const ownersBefore = /* @__PURE__ */ new Set();
73311
+ if (before) {
73312
+ for (const [convId, gid] of this._sessionGroupIds) {
73313
+ if (gid !== before) continue;
73314
+ const owner = this._sessions.get(convId)?.ownerDeviceId ?? this._persisted.sessions?.[convId]?.ownerDeviceId;
73315
+ if (owner) ownersBefore.add(owner);
73316
+ }
73317
+ }
72747
73318
  this._sessionGroupIds = new Map(mine.map((r2) => [r2.id, r2.group_id]));
72748
73319
  this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
73320
+ {
73321
+ const convs = new Set(mine.map((r2) => r2.id));
73322
+ const groups = new Set(mine.map((r2) => r2.group_id));
73323
+ this._lastReconcile = { at: reconcileStartedAt, convs, groups };
73324
+ for (const [key, a2] of this._attestedInbound) {
73325
+ if (a2.at > reconcileStartedAt) continue;
73326
+ if (a2.convId && convs.has(a2.convId) || a2.groupId && groups.has(a2.groupId)) continue;
73327
+ this._attestedInbound.delete(key);
73328
+ }
73329
+ for (const [gid, at] of this._welcomedUnmapped) {
73330
+ if (at <= reconcileStartedAt) this._welcomedUnmapped.delete(gid);
73331
+ }
73332
+ }
72749
73333
  const joined = mine.find((r2) => this._persisted.mlsGroups?.[r2.group_id]);
72750
73334
  const primary = mine.find((r2) => r2.id === this._persisted.primaryConversationId) ?? joined ?? mine[0];
72751
73335
  if (!mine.some((r2) => r2.id === this._persisted.primaryConversationId)) {
@@ -72755,6 +73339,23 @@ ${text}`;
72755
73339
  }
72756
73340
  this._persisted.groupId = primary.group_id;
72757
73341
  this._persisted.primaryConversationId = primary.id;
73342
+ for (const r2 of mine) {
73343
+ if (typeof r2.default_topic_id === "string") this._recordDefaultTopic(r2.group_id, r2.default_topic_id);
73344
+ }
73345
+ const primaryDefault = this._persisted.defaultTopicIds?.[primary.group_id];
73346
+ if (primaryDefault) this._persisted.defaultTopicId = primaryDefault;
73347
+ const primaryOwner = primary.owner_device_id;
73348
+ const samePerson = primary.id === primaryBefore || typeof primaryOwner === "string" && ownersBefore.has(primaryOwner);
73349
+ let retagged = false;
73350
+ if (before && primary.group_id !== before && knownBefore.size === 1 && knownBefore.has(before) && samePerson) {
73351
+ const oldPrefix = `dm:g:${before}:`;
73352
+ for (const entry of this._persisted.messageHistory ?? []) {
73353
+ if (entry.topicId?.startsWith(oldPrefix)) {
73354
+ entry.topicId = `dm:g:${primary.group_id}:${entry.topicId.slice(oldPrefix.length)}`;
73355
+ retagged = true;
73356
+ }
73357
+ }
73358
+ }
72758
73359
  const liveGroupIds = new Set(mine.map((r2) => r2.group_id));
72759
73360
  if (staleGid && staleMlsGroupId && !liveGroupIds.has(staleGid)) {
72760
73361
  try {
@@ -72769,6 +73370,10 @@ ${text}`;
72769
73370
  });
72770
73371
  }
72771
73372
  await this._persistState();
73373
+ if (retagged) {
73374
+ this._markHistoryDirty();
73375
+ await this._saveHistoryState();
73376
+ }
72772
73377
  console.log(
72773
73378
  `[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))`
72774
73379
  );
@@ -72918,7 +73523,7 @@ ${text}`;
72918
73523
  }
72919
73524
  this._heartbeatCallback = null;
72920
73525
  }
72921
- async sendStatusAlert(alert) {
73526
+ async sendStatusAlert(alert, routing) {
72922
73527
  const priority = alert.severity === "error" || alert.severity === "critical" ? "high" : "normal";
72923
73528
  const envelope = {
72924
73529
  title: alert.title,
@@ -72932,52 +73537,61 @@ ${text}`;
72932
73537
  await this.send(
72933
73538
  JSON.stringify(envelope),
72934
73539
  {
73540
+ conversationId: routing?.conversationId,
73541
+ audience: routing?.audience,
72935
73542
  messageType: "status_alert",
72936
73543
  priority,
72937
73544
  metadata: { severity: alert.severity }
72938
73545
  }
72939
73546
  );
72940
73547
  }
72941
- async sendArtifact(artifact) {
73548
+ async sendArtifact(artifact, routing) {
72942
73549
  if (this._state !== "ready" || this._sessions.size === 0 || !this._ws) {
72943
73550
  throw new Error("Channel is not ready");
72944
73551
  }
72945
- const attachMeta = await this._uploadAttachment(artifact.filePath, this._primaryConversationId);
72946
- const envelope = JSON.stringify({
72947
- type: "artifact",
72948
- blob_id: attachMeta.blobId,
72949
- blob_url: attachMeta.blobUrl,
72950
- filename: artifact.filename,
72951
- mime_type: artifact.mimeType,
72952
- size_bytes: attachMeta.size,
72953
- description: artifact.description,
72954
- attachment: attachMeta
72955
- });
72956
73552
  const messageGroupId = randomUUID4();
72957
73553
  const pendingWsSends = [];
72958
- for (const [convId, session2] of this._sessions) {
72959
- if (!session2.activated) continue;
72960
- const encrypted = session2.ratchet.encrypt(envelope);
72961
- const transport = encryptedMessageToTransport(encrypted);
72962
- pendingWsSends.push(
72963
- JSON.stringify({
72964
- event: "message",
72965
- data: {
72966
- conversation_id: convId,
72967
- header_blob: transport.header_blob,
72968
- ciphertext: transport.ciphertext,
72969
- message_group_id: messageGroupId,
72970
- message_type: "artifact_share"
72971
- }
72972
- })
72973
- );
73554
+ const buckets = this._ownerFileRecipients(routing);
73555
+ if (buckets.length === 0) {
73556
+ console.warn("[SecureChannel] sendArtifact(): no live session for the person involved \u2014 nothing sent");
73557
+ throw new Error("No conversation is ready to receive this file");
73558
+ }
73559
+ for (const bucket of buckets) {
73560
+ const attachMeta = await this._uploadAttachment(artifact.filePath, bucket.uploadConvId);
73561
+ const envelope = JSON.stringify({
73562
+ type: "artifact",
73563
+ blob_id: attachMeta.blobId,
73564
+ blob_url: attachMeta.blobUrl,
73565
+ filename: artifact.filename,
73566
+ mime_type: artifact.mimeType,
73567
+ size_bytes: attachMeta.size,
73568
+ description: artifact.description,
73569
+ attachment: attachMeta
73570
+ });
73571
+ for (const convId of bucket.convIds) {
73572
+ const session2 = this._sessions.get(convId);
73573
+ const encrypted = session2.ratchet.encrypt(envelope);
73574
+ const transport = encryptedMessageToTransport(encrypted);
73575
+ pendingWsSends.push(
73576
+ JSON.stringify({
73577
+ event: "message",
73578
+ data: {
73579
+ conversation_id: convId,
73580
+ header_blob: transport.header_blob,
73581
+ ciphertext: transport.ciphertext,
73582
+ message_group_id: messageGroupId,
73583
+ message_type: "artifact_share"
73584
+ }
73585
+ })
73586
+ );
73587
+ }
72974
73588
  }
72975
73589
  await this._persistState();
72976
73590
  for (const frame of pendingWsSends) {
72977
73591
  this._ws.send(frame);
72978
73592
  }
72979
73593
  }
72980
- async sendActionConfirmation(confirmation) {
73594
+ async sendActionConfirmation(confirmation, routing) {
72981
73595
  const envelope = {
72982
73596
  type: "action_confirmation",
72983
73597
  action: confirmation.action,
@@ -72988,6 +73602,8 @@ ${text}`;
72988
73602
  await this.send(
72989
73603
  JSON.stringify(envelope),
72990
73604
  {
73605
+ conversationId: routing?.conversationId,
73606
+ audience: routing?.audience,
72991
73607
  messageType: "action_confirmation",
72992
73608
  metadata: { status: confirmation.status }
72993
73609
  }
@@ -73093,9 +73709,23 @@ ${text}`;
73093
73709
  } else {
73094
73710
  return { ok: false, destination: { kind: "owner" }, error: "Unknown target kind", timestamp: ts };
73095
73711
  }
73712
+ if (resolved.kind === "owner" && options?.refuseIfAmbiguous && this.isUntargetedOwnerAmbiguous(options)) {
73713
+ console.log(`[deliver] target=owner content=${content.type} result=REFUSED: ambiguous (several people mid-turn)`);
73714
+ return { ok: false, ambiguous: true, destination: resolved, error: AMBIGUOUS_OWNER_ERROR, timestamp: ts };
73715
+ }
73096
73716
  let dedupeKey = null;
73097
73717
  try {
73098
- dedupeKey = outboundDedupeKey(resolved, content, options);
73718
+ let audienceTag;
73719
+ try {
73720
+ audienceTag = resolved.kind === "owner" && options?.conversationId === void 0 ? this._audienceTag(options) : void 0;
73721
+ } catch {
73722
+ audienceTag = void 0;
73723
+ }
73724
+ dedupeKey = outboundDedupeKey(
73725
+ resolved,
73726
+ content,
73727
+ audienceTag ? { ...options, conversationId: audienceTag } : options
73728
+ );
73099
73729
  if (dedupeKey) {
73100
73730
  const now = Date.now();
73101
73731
  const recent = this._recentDeliveries ??= /* @__PURE__ */ new Map();
@@ -73115,6 +73745,10 @@ ${text}`;
73115
73745
  }
73116
73746
  try {
73117
73747
  let decisionId;
73748
+ const ownerRouting = {
73749
+ conversationId: options?.conversationId,
73750
+ audience: options?.audience
73751
+ };
73118
73752
  if (content.type === "text") {
73119
73753
  if (resolved.kind === "room") {
73120
73754
  await this.sendToRoom(resolved.id, content.text, {
@@ -73133,6 +73767,7 @@ ${text}`;
73133
73767
  } else {
73134
73768
  await this.send(content.text, {
73135
73769
  conversationId: options?.conversationId,
73770
+ audience: options?.audience,
73136
73771
  topicId: options?.topicId,
73137
73772
  messageType: options?.metadata?.message_type,
73138
73773
  priority: options?.priority,
@@ -73145,7 +73780,7 @@ ${text}`;
73145
73780
  console.log(`[deliver] target=${resolved.kind}:${resolved.id} content=decision_request result=FAIL: ${err}`);
73146
73781
  return { ok: false, destination: resolved, error: err, timestamp: ts };
73147
73782
  }
73148
- decisionId = await this.sendDecisionRequest(content.request);
73783
+ decisionId = await this.sendDecisionRequest(content.request, ownerRouting);
73149
73784
  } else if (content.type === "status_alert") {
73150
73785
  if (resolved.kind === "room") {
73151
73786
  const envelope = {
@@ -73163,7 +73798,7 @@ ${text}`;
73163
73798
  metadata: { severity: content.alert.severity }
73164
73799
  });
73165
73800
  } else if (resolved.kind === "owner") {
73166
- await this.sendStatusAlert(content.alert);
73801
+ await this.sendStatusAlert(content.alert, ownerRouting);
73167
73802
  } else {
73168
73803
  return { ok: false, destination: resolved, error: "Status alerts cannot be sent to A2A targets", timestamp: ts };
73169
73804
  }
@@ -73171,7 +73806,7 @@ ${text}`;
73171
73806
  if (resolved.kind === "room") {
73172
73807
  await this.sendActionConfirmationToRoom(resolved.id, content.confirmation);
73173
73808
  } else if (resolved.kind === "owner") {
73174
- await this.sendActionConfirmation(content.confirmation);
73809
+ await this.sendActionConfirmation(content.confirmation, ownerRouting);
73175
73810
  } else {
73176
73811
  return { ok: false, destination: resolved, error: "Action confirmations cannot be sent to A2A targets", timestamp: ts };
73177
73812
  }
@@ -73179,13 +73814,14 @@ ${text}`;
73179
73814
  if (resolved.kind !== "owner") {
73180
73815
  return { ok: false, destination: resolved, error: "Artifacts can only be sent to owner", timestamp: ts };
73181
73816
  }
73182
- await this.sendArtifact(content.artifact);
73817
+ await this.sendArtifact(content.artifact, ownerRouting);
73183
73818
  } else if (content.type === "attachment") {
73184
73819
  if (resolved.kind !== "owner") {
73185
73820
  return { ok: false, destination: resolved, error: "Attachments can only be sent to owner", timestamp: ts };
73186
73821
  }
73187
73822
  await this.sendWithAttachment(content.text, content.filePath, {
73188
- topicId: options?.topicId
73823
+ topicId: options?.topicId,
73824
+ ...ownerRouting
73189
73825
  });
73190
73826
  }
73191
73827
  const targetLabel = resolved.kind === "owner" ? "owner" : `${resolved.kind}:${resolved.id?.slice(0, 8)}...`;
@@ -73502,15 +74138,105 @@ ${text}`;
73502
74138
  return this._mcpServer;
73503
74139
  }
73504
74140
  // --- Topic management ---
74141
+ /*
74142
+ * #1416 — topics are per conversation GROUP.
74143
+ *
74144
+ * Since #1399 every person has their own 1:1 group with the agent, and a
74145
+ * topic belongs to exactly one group (`topics.group_id`). The agent used to
74146
+ * keep ONE default topic (the primary group's) and ONE last-incoming topic,
74147
+ * and stamped both on every frame — so a reply into person B's group could
74148
+ * carry person A's topic, and B's web client (which filters live messages by
74149
+ * the topic it is viewing) dropped it until a reload.
74150
+ *
74151
+ * The rule now: a frame's topic comes from THAT frame's group. A group with
74152
+ * no known topic gets none — the server then files the message under that
74153
+ * conversation's own default topic (`ws.py`, lazily created) — rather than
74154
+ * borrowing another group's.
74155
+ */
74156
+ /** Scope key for per-group topic state; see `_lastIncomingTopics`. */
74157
+ _topicScope(gid, convId) {
74158
+ if (gid) return `g:${gid}`;
74159
+ if (!this._persisted?.groupId && this._sessionGroupIds.size === 0) return "*";
74160
+ return convId ? `c:${convId}` : void 0;
74161
+ }
74162
+ /** Record the topic of an inbound 1:1 message for its own group (#1416). */
74163
+ _rememberIncomingTopic(convId, gid, topicId) {
74164
+ const scope = this._topicScope(gid ?? (convId ? this._sessionGroupIds.get(convId) : void 0), convId);
74165
+ if (!scope) return;
74166
+ if (topicId && !isTopicId(topicId)) return;
74167
+ if (topicId) this._lastIncomingTopics.set(scope, topicId);
74168
+ else this._lastIncomingTopics.delete(scope);
74169
+ }
73505
74170
  /**
73506
- * Create a new topic within the conversation group.
73507
- * Requires the channel to be initialized with a groupId (from activation).
74171
+ * Record a group's default topic (#1416). The legacy `defaultTopicId` keeps
74172
+ * mirroring the PRIMARY group's entry, for older readers and backups.
73508
74173
  */
73509
- async createTopic(name) {
74174
+ _recordDefaultTopic(gid, topicId) {
74175
+ if (!gid || !topicId || !this._persisted) return;
74176
+ (this._persisted.defaultTopicIds ??= {})[gid] = topicId;
74177
+ if (gid === this._persisted.groupId) this._persisted.defaultTopicId = topicId;
74178
+ }
74179
+ /** The group a topic is known to belong to, if any. */
74180
+ _groupOfTopic(topicId) {
74181
+ const p2 = this._persisted;
74182
+ for (const [gid, tid] of Object.entries(p2?.defaultTopicIds ?? {})) {
74183
+ if (tid === topicId) return gid;
74184
+ }
74185
+ if (p2?.defaultTopicId === topicId && p2.groupId) return p2.groupId;
74186
+ for (const t2 of p2?.topics ?? []) {
74187
+ if (t2.id === topicId) return t2.groupId ?? p2?.groupId;
74188
+ }
74189
+ for (const [scope, tid] of this._lastIncomingTopics) {
74190
+ if (tid === topicId && scope.startsWith("g:")) return scope.slice(2);
74191
+ }
74192
+ return void 0;
74193
+ }
74194
+ /**
74195
+ * The topic one outgoing 1:1 frame carries (#1416), or `undefined` to send
74196
+ * none. `gid` is the frame's conversation group (looked up from `convId`
74197
+ * when not given); `explicit` is the caller's `topicId`; `targeted` is true
74198
+ * when the caller addressed one conversation.
74199
+ */
74200
+ _topicForFrame(gid, convId, explicit, targeted, useLastIncoming = true) {
74201
+ const p2 = this._persisted;
74202
+ const g2 = gid ?? (convId ? this._sessionGroupIds.get(convId) : void 0);
74203
+ const primaryScope = g2 !== void 0 ? g2 === p2?.groupId : convId === this._primaryConversationId || !p2?.groupId;
74204
+ if (isTopicId(explicit)) {
74205
+ const owner = this._groupOfTopic(explicit);
74206
+ if (owner !== void 0 ? owner === g2 : targeted || primaryScope) return explicit;
74207
+ }
74208
+ const scope = this._topicScope(g2, convId);
74209
+ const last = scope && useLastIncoming ? this._lastIncomingTopics.get(scope) : void 0;
74210
+ if (last) return last;
74211
+ if (g2 && p2?.defaultTopicIds?.[g2]) return p2.defaultTopicIds[g2];
74212
+ if (primaryScope && p2?.defaultTopicId) return p2.defaultTopicId;
74213
+ return void 0;
74214
+ }
74215
+ /**
74216
+ * The conversation group a topic call addresses (#1416): the named
74217
+ * conversation's own group, else the primary group. A named conversation
74218
+ * whose group is unknown is an error — falling back to the primary group
74219
+ * would create/list topics in somebody else's chat.
74220
+ */
74221
+ _topicGroupFor(conversationId) {
74222
+ if (conversationId) {
74223
+ const gid = this._sessionGroupIds.get(conversationId);
74224
+ if (!gid) throw new Error("Conversation group unknown for topic call");
74225
+ return gid;
74226
+ }
73510
74227
  if (!this._persisted?.groupId) {
73511
74228
  throw new Error("Channel not initialized or groupId unknown");
73512
74229
  }
73513
- if (!this._deviceJwt) {
74230
+ return this._persisted.groupId;
74231
+ }
74232
+ /**
74233
+ * Create a new topic within a conversation group — the given conversation's
74234
+ * own group (#1416), or the primary group when none is named.
74235
+ * Requires the channel to be initialized with a groupId (from activation).
74236
+ */
74237
+ async createTopic(name, options) {
74238
+ const groupId = this._topicGroupFor(options?.conversationId);
74239
+ if (!this._deviceJwt || !this._persisted) {
73514
74240
  throw new Error("Channel not authenticated");
73515
74241
  }
73516
74242
  const res = await fetch(`${this.config.apiUrl}/api/v1/topics`, {
@@ -73520,7 +74246,7 @@ ${text}`;
73520
74246
  Authorization: `Bearer ${this._deviceJwt}`
73521
74247
  },
73522
74248
  body: JSON.stringify({
73523
- group_id: this._persisted.groupId,
74249
+ group_id: groupId,
73524
74250
  name,
73525
74251
  creator_device_id: this._persisted.deviceId
73526
74252
  })
@@ -73534,23 +74260,23 @@ ${text}`;
73534
74260
  if (!this._persisted.topics) {
73535
74261
  this._persisted.topics = [];
73536
74262
  }
73537
- this._persisted.topics.push(topic);
74263
+ this._persisted.topics.push({ ...topic, groupId });
74264
+ if (topic.isDefault) this._recordDefaultTopic(groupId, topic.id);
73538
74265
  await this._persistState();
73539
74266
  return topic;
73540
74267
  }
73541
74268
  /**
73542
- * List all topics in the conversation group.
74269
+ * List all topics in a conversation group — the given conversation's own
74270
+ * group (#1416), or the primary group when none is named.
73543
74271
  * Requires the channel to be initialized with a groupId (from activation).
73544
74272
  */
73545
- async listTopics() {
73546
- if (!this._persisted?.groupId) {
73547
- throw new Error("Channel not initialized or groupId unknown");
73548
- }
73549
- if (!this._deviceJwt) {
74273
+ async listTopics(options) {
74274
+ const groupId = this._topicGroupFor(options?.conversationId);
74275
+ if (!this._deviceJwt || !this._persisted) {
73550
74276
  throw new Error("Channel not authenticated");
73551
74277
  }
73552
74278
  const res = await fetch(
73553
- `${this.config.apiUrl}/api/v1/topics?group_id=${encodeURIComponent(this._persisted.groupId)}`,
74279
+ `${this.config.apiUrl}/api/v1/topics?group_id=${encodeURIComponent(groupId)}`,
73554
74280
  {
73555
74281
  headers: {
73556
74282
  Authorization: `Bearer ${this._deviceJwt}`
@@ -73563,7 +74289,13 @@ ${text}`;
73563
74289
  }
73564
74290
  const resp = await res.json();
73565
74291
  const topics = resp.map((t2) => ({ id: t2.id, name: t2.name, isDefault: t2.is_default }));
73566
- this._persisted.topics = topics;
74292
+ const primaryGid = this._persisted.groupId;
74293
+ this._persisted.topics = [
74294
+ ...(this._persisted.topics ?? []).filter((t2) => (t2.groupId ?? primaryGid) !== groupId),
74295
+ ...topics.map((t2) => ({ ...t2, groupId }))
74296
+ ];
74297
+ const def = topics.find((t2) => t2.isDefault);
74298
+ if (def) this._recordDefaultTopic(groupId, def.id);
73567
74299
  await this._persistState();
73568
74300
  return topics;
73569
74301
  }
@@ -74147,6 +74879,9 @@ ${text}`;
74147
74879
  this._persisted.defaultTopicId = primary.default_topic_id;
74148
74880
  }
74149
74881
  }
74882
+ for (const conv of conversations) {
74883
+ this._recordDefaultTopic(conv.group_id, conv.default_topic_id);
74884
+ }
74150
74885
  this._sessionGroupIds = /* @__PURE__ */ new Map();
74151
74886
  for (const conv of conversations) {
74152
74887
  if (conv.group_id) {
@@ -74259,7 +74994,7 @@ ${text}`;
74259
74994
  agentVersion: this.config.agentVersion ?? "0.0.0",
74260
74995
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
74261
74996
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
74262
- pluginVersion: true ? "0.23.50" : "0.0.0-dev"
74997
+ pluginVersion: true ? "0.23.52" : "0.0.0-dev"
74263
74998
  });
74264
74999
  this._telemetryReporter.startAutoFlush(3e4);
74265
75000
  }
@@ -74587,7 +75322,7 @@ ${text}`;
74587
75322
  agentVersion: this.config.agentVersion ?? "0.0.0",
74588
75323
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
74589
75324
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
74590
- pluginVersion: true ? "0.23.50" : "0.0.0-dev"
75325
+ pluginVersion: true ? "0.23.52" : "0.0.0-dev"
74591
75326
  });
74592
75327
  this._telemetryReporter.startAutoFlush(3e4);
74593
75328
  }
@@ -75050,11 +75785,15 @@ ${text}`;
75050
75785
  if (decisionReply) messageType = "decision_response";
75051
75786
  } catch {
75052
75787
  }
75788
+ const dmGroupId = convGroupId ?? (mgrKey?.startsWith("1to1-group:") ? mgrKey.slice("1to1-group:".length) : void 0);
75053
75789
  if (messageType === "history_catchup_request") {
75054
75790
  try {
75055
75791
  const request = JSON.parse(plaintext);
75056
75792
  if (typeof request.requesting_device_id !== "string") return;
75057
- const filtered = this._historyForCatchup("dm", void 0, request.since_ts);
75793
+ const filtered = this._historyForCatchup("dm", void 0, request.since_ts, {
75794
+ groupId: dmGroupId,
75795
+ conversationId: convId
75796
+ });
75058
75797
  const responsePayload = JSON.stringify({
75059
75798
  type: "history_catchup_response",
75060
75799
  target_device_id: request.requesting_device_id,
@@ -75109,6 +75848,9 @@ ${text}`;
75109
75848
  console.log(`[SecureChannel] Session ${convId.slice(0, 8)} activated via MLS message`);
75110
75849
  }
75111
75850
  }
75851
+ if (topicId) {
75852
+ this._rememberIncomingTopic(convId, dmGroupId, topicId);
75853
+ }
75112
75854
  if (mlsAttachment) {
75113
75855
  text = await this._augmentWithAttachment(mlsAttachment, text);
75114
75856
  }
@@ -75118,11 +75860,21 @@ ${text}`;
75118
75860
  "dm",
75119
75861
  topicId,
75120
75862
  data.created_at,
75121
- messageType
75863
+ messageType,
75864
+ { groupId: dmGroupId, conversationId: convId }
75122
75865
  );
75866
+ const dmConvId = convId ?? this._conversationOfGroup(dmGroupId);
75867
+ this._noteInboundDm(dmConvId, dmGroupId, { createdAt: data.created_at, senderDeviceId });
75868
+ this._reconcileForUnmappedGroup(dmGroupId);
75123
75869
  const metadata = {
75124
75870
  messageId: data.message_id ?? `mls_${Date.now()}`,
75125
- conversationId: convId ?? this._primaryConversationId,
75871
+ // A frame on a KNOWN group that no conversation maps yet is not the
75872
+ // primary person's: leave the conversation unnamed rather than hand
75873
+ // the reply to someone else; `conversationGroupId` still places it.
75874
+ conversationId: dmConvId ?? (dmGroupId ? void 0 : this._primaryConversationId),
75875
+ // #1418: the group this message decrypted under — attested, so a turn
75876
+ // answers here even when the local map is stale.
75877
+ conversationGroupId: dmGroupId,
75126
75878
  timestamp: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
75127
75879
  topicId,
75128
75880
  // #621: positive attestation that this decrypted under the OWNER'S 1:1
@@ -75303,7 +76055,7 @@ ${text}`;
75303
76055
  }
75304
76056
  if (messageType === "message" || messageType === "decision_response" && decisionReply) {
75305
76057
  const topicId = msgData.topic_id;
75306
- this._lastIncomingTopicId = topicId;
76058
+ this._rememberIncomingTopic(convId, void 0, topicId);
75307
76059
  let attachData;
75308
76060
  if (attachmentInfo) {
75309
76061
  try {
@@ -75331,7 +76083,8 @@ ${text}`;
75331
76083
  "dm",
75332
76084
  topicId,
75333
76085
  msgData.created_at,
75334
- messageType
76086
+ messageType,
76087
+ { conversationId: convId }
75335
76088
  );
75336
76089
  let emitText = messageText;
75337
76090
  if (attachData) {
@@ -75376,6 +76129,13 @@ ${messageText}`;
75376
76129
  // envelope text before the fold; `emitText` is the folded copy.
75377
76130
  caption: messageText
75378
76131
  };
76132
+ if (!roomId) {
76133
+ this._noteInboundDm(convId, void 0, {
76134
+ createdAt: msgData.created_at,
76135
+ senderDeviceId: msgData.sender_device_id
76136
+ });
76137
+ this._reconcileForUnmappedConversation(convId);
76138
+ }
75379
76139
  this.emit("message", emitText, metadata);
75380
76140
  Promise.resolve(this.config.onMessage?.(emitText, metadata)).catch((err) => {
75381
76141
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -75524,40 +76284,53 @@ ${baseText}`;
75524
76284
  if (this._state !== "ready" || this._sessions.size === 0 || !this._ws) {
75525
76285
  throw new Error("Channel is not ready");
75526
76286
  }
75527
- const topicId = options?.topicId ?? this._persisted?.defaultTopicId;
75528
- const attachMeta = await this._uploadAttachment(filePath, this._primaryConversationId);
75529
- const envelope = JSON.stringify({
75530
- type: "message",
75531
- text: plaintext,
75532
- topicId,
75533
- attachment: attachMeta
75534
- });
75535
76287
  const messageGroupId = randomUUID4();
75536
76288
  const pendingWsSends = [];
75537
- for (const [convId, session2] of this._sessions) {
75538
- if (!session2.activated) continue;
75539
- const encrypted = session2.ratchet.encrypt(envelope);
75540
- const transport = encryptedMessageToTransport(encrypted);
75541
- pendingWsSends.push(
75542
- JSON.stringify({
75543
- event: "message",
75544
- data: {
75545
- conversation_id: convId,
75546
- header_blob: transport.header_blob,
75547
- ciphertext: transport.ciphertext,
75548
- message_group_id: messageGroupId,
75549
- topic_id: topicId
75550
- }
75551
- })
75552
- );
76289
+ const frameHistoryContexts = [];
76290
+ const buckets = this._ownerFileRecipients(options);
76291
+ if (buckets.length === 0) {
76292
+ console.warn("[SecureChannel] sendWithAttachment(): no live session for the person involved \u2014 nothing sent");
76293
+ throw new Error("No conversation is ready to receive this file");
76294
+ }
76295
+ for (const bucket of buckets) {
76296
+ const attachMeta = await this._uploadAttachment(filePath, bucket.uploadConvId);
76297
+ for (const convId of bucket.convIds) {
76298
+ const session2 = this._sessions.get(convId);
76299
+ const topicId = this._topicForFrame(void 0, convId, options?.topicId, false, false);
76300
+ const envelope = JSON.stringify({
76301
+ type: "message",
76302
+ text: plaintext,
76303
+ topicId,
76304
+ attachment: attachMeta
76305
+ });
76306
+ const encrypted = session2.ratchet.encrypt(envelope);
76307
+ const transport = encryptedMessageToTransport(encrypted);
76308
+ pendingWsSends.push(
76309
+ JSON.stringify({
76310
+ event: "message",
76311
+ data: {
76312
+ conversation_id: convId,
76313
+ header_blob: transport.header_blob,
76314
+ ciphertext: transport.ciphertext,
76315
+ message_group_id: messageGroupId,
76316
+ topic_id: topicId
76317
+ }
76318
+ })
76319
+ );
76320
+ frameHistoryContexts.push(this._dmHistoryContext(topicId, void 0, convId));
76321
+ }
75553
76322
  }
75554
76323
  await this._persistState();
75555
76324
  let deliveredFrames = 0;
75556
- for (const frame of pendingWsSends) {
75557
- if (this._sendApplicationFrame(frame)) deliveredFrames += 1;
76325
+ let historyContext;
76326
+ for (const [i2, frame] of pendingWsSends.entries()) {
76327
+ if (this._sendApplicationFrame(frame)) {
76328
+ if (deliveredFrames === 0) historyContext = frameHistoryContexts[i2];
76329
+ deliveredFrames += 1;
76330
+ }
75558
76331
  }
75559
76332
  if (deliveredFrames > 0) {
75560
- await this._appendHistory("agent", plaintext, this._historyContext("dm", topicId), void 0, messageGroupId);
76333
+ await this._appendHistory("agent", plaintext, historyContext ?? this._historyContext("dm"), void 0, messageGroupId);
75561
76334
  }
75562
76335
  }
75563
76336
  /**
@@ -75582,9 +76355,13 @@ ${baseText}`;
75582
76355
  topicId
75583
76356
  });
75584
76357
  const pendingWsSends = [];
76358
+ const sourceGid = this._sessionGroupIds.get(sourceConvId);
76359
+ const knowsGroups = this._sessionGroupIds.size > 0;
75585
76360
  for (const [siblingConvId, siblingSession] of this._sessions) {
75586
76361
  if (siblingConvId === sourceConvId) continue;
75587
76362
  if (!siblingSession.activated) continue;
76363
+ const siblingGid = this._sessionGroupIds.get(siblingConvId);
76364
+ if (knowsGroups && !(sourceGid && siblingGid && siblingGid === sourceGid)) continue;
75588
76365
  if (roomConvIds.has(siblingConvId)) continue;
75589
76366
  const syncEncrypted = siblingSession.ratchet.encrypt(syncPayload);
75590
76367
  const syncTransport = encryptedMessageToTransport(syncEncrypted);
@@ -75665,7 +76442,7 @@ ${baseText}`;
75665
76442
  async _replayHistoryToSession(convId) {
75666
76443
  const session2 = this._sessions.get(convId);
75667
76444
  if (!session2 || !session2.activated || !this._ws) return;
75668
- const history = this._selectHistoryContext("dm");
76445
+ const history = this._selectHistoryContext("dm", void 0, { conversationId: convId });
75669
76446
  if (history.length === 0) {
75670
76447
  console.log(`[SecureChannel] No history to replay for ${convId.slice(0, 8)}...`);
75671
76448
  return;
@@ -75701,10 +76478,15 @@ ${baseText}`;
75701
76478
  `[SecureChannel] New owner device linked: ${event.owner_device_id.slice(0, 8)}...`
75702
76479
  );
75703
76480
  try {
76481
+ if (event.group_id && !this._sessionGroupIds.has(event.conversation_id)) {
76482
+ this._sessionGroupIds.set(event.conversation_id, event.group_id);
76483
+ this._persisted.conversationGroupIds = Object.fromEntries(this._sessionGroupIds);
76484
+ }
75704
76485
  if (!event.owner_identity_public_key) {
75705
76486
  console.error(
75706
76487
  `[SecureChannel] device_linked event missing owner keys for conv ${event.conversation_id.slice(0, 8)}...`
75707
76488
  );
76489
+ await this._persistState();
75708
76490
  return;
75709
76491
  }
75710
76492
  const identity = this._persisted.identityKeypair;
@@ -77408,6 +78190,10 @@ ${baseText}`;
77408
78190
  await this._persistState();
77409
78191
  }
77410
78192
  console.log(`[SecureChannel] Joined shared 1:1 MLS group for group ${conversationGroupId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
78193
+ if (!this._isMappedGroup(conversationGroupId)) {
78194
+ this._welcomedUnmapped.set(conversationGroupId, Date.now());
78195
+ }
78196
+ this._reconcileForUnmappedGroup(conversationGroupId);
77411
78197
  await this._flushMlsHold(conversationGroupId);
77412
78198
  return;
77413
78199
  }
@@ -78037,7 +78823,7 @@ ${baseText}`;
78037
78823
  }
78038
78824
  if (messageType === "message" || messageType === "decision_response" && decisionReply) {
78039
78825
  const topicId = msg.topic_id;
78040
- await this._appendHistory("owner", messageText, this._historyContext("dm", topicId), msg.created_at, msg.message_id);
78826
+ await this._appendHistory("owner", messageText, this._dmHistoryContext(topicId, void 0, msg.conversation_id), msg.created_at, msg.message_id);
78041
78827
  const metadata = {
78042
78828
  messageId: msg.message_id,
78043
78829
  conversationId: msg.conversation_id,
@@ -78049,6 +78835,7 @@ ${baseText}`;
78049
78835
  ownerDm1to1: true,
78050
78836
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
78051
78837
  };
78838
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
78052
78839
  this.emit("message", messageText, metadata);
78053
78840
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
78054
78841
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -78643,7 +79430,7 @@ ${baseText}`;
78643
79430
  }
78644
79431
  if (messageType === "message" || messageType === "decision_response" && decisionReply) {
78645
79432
  const topicId = msg.topic_id;
78646
- await this._appendHistory("owner", messageText, this._historyContext("dm", topicId), msg.created_at, msg.id);
79433
+ await this._appendHistory("owner", messageText, this._dmHistoryContext(topicId, void 0, msg.conversation_id), msg.created_at, msg.id);
78647
79434
  const metadata = {
78648
79435
  messageId: msg.id,
78649
79436
  conversationId: msg.conversation_id,
@@ -78655,6 +79442,7 @@ ${baseText}`;
78655
79442
  ownerDm1to1: true,
78656
79443
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
78657
79444
  };
79445
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
78658
79446
  this.emit("message", messageText, metadata);
78659
79447
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
78660
79448
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -78963,7 +79751,7 @@ ${baseText}`;
78963
79751
  }
78964
79752
  if (messageType === "message" || messageType === "decision_response" && decisionReply) {
78965
79753
  const topicId = msg.topic_id;
78966
- await this._appendHistory("owner", messageText, this._historyContext("dm", topicId), msg.created_at, msg.id);
79754
+ await this._appendHistory("owner", messageText, this._dmHistoryContext(topicId, void 0, msg.conversation_id), msg.created_at, msg.id);
78967
79755
  const metadata = {
78968
79756
  messageId: msg.id,
78969
79757
  conversationId: msg.conversation_id,
@@ -78975,6 +79763,7 @@ ${baseText}`;
78975
79763
  ownerDm1to1: true,
78976
79764
  ...decisionReply ? { messageType: "decision_response", decision: decisionReply } : {}
78977
79765
  };
79766
+ this._noteInboundDm(msg.conversation_id, void 0, { createdAt: msg.created_at, senderDeviceId: msg.sender_device_id });
78978
79767
  this.emit("message", messageText, metadata);
78979
79768
  Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
78980
79769
  console.error("[SecureChannel] onMessage callback error:", err);
@@ -79995,7 +80784,7 @@ ${actionsText}`);
79995
80784
  "use strict";
79996
80785
  init_llm_response_parser();
79997
80786
  init_llm_cost();
79998
- traceStore = new AsyncLocalStorage();
80787
+ traceStore = new AsyncLocalStorage2();
79999
80788
  }
80000
80789
  });
80001
80790
  init_tool_audit = __esm2({
@@ -100743,7 +101532,7 @@ data:
100743
101532
  await init_skill_telemetry();
100744
101533
  await init_policy_enforcer();
100745
101534
  init_room_protocol();
100746
- VERSION = true ? "0.23.50" : "0.0.0-dev";
101535
+ VERSION = true ? "0.23.52" : "0.0.0-dev";
100747
101536
  }
100748
101537
  });
100749
101538
  await init_index();
@@ -102604,13 +103393,28 @@ var RoomHushState = class {
102604
103393
  return t2 !== void 0 && now < t2;
102605
103394
  }
102606
103395
  };
103396
+ async function sendDm(channel, t2, text) {
103397
+ if ((t2.conversationId || t2.groupId) && typeof channel.runForConversation === "function") {
103398
+ await channel.runForConversation(
103399
+ t2.conversationId,
103400
+ () => channel.send(text),
103401
+ t2.groupId ? { groupId: t2.groupId } : void 0
103402
+ );
103403
+ } else {
103404
+ await channel.send(text);
103405
+ }
103406
+ }
102607
103407
  var ActiveTarget = class {
102608
103408
  target = null;
102609
103409
  setRoom(roomId) {
102610
103410
  this.target = { kind: "room", roomId };
102611
103411
  }
102612
- setDm() {
102613
- this.target = { kind: "dm" };
103412
+ setDm(conversationId, groupId) {
103413
+ this.target = {
103414
+ kind: "dm",
103415
+ ...conversationId ? { conversationId } : {},
103416
+ ...groupId ? { groupId } : {}
103417
+ };
102614
103418
  }
102615
103419
  get current() {
102616
103420
  return this.target;
@@ -102630,7 +103434,7 @@ var ActiveTarget = class {
102630
103434
  if (!t2) return;
102631
103435
  try {
102632
103436
  if (t2.kind === "room") await channel.sendToRoom(t2.roomId, text);
102633
- else await channel.send(text);
103437
+ else await sendDm(channel, t2, text);
102634
103438
  log(`said to ${where}`);
102635
103439
  } catch (err) {
102636
103440
  log(`send failed to ${where}: ${err instanceof Error ? err.message : String(err)}`);
@@ -102739,7 +103543,7 @@ function wireBridge(channel, session2, target, opts = {}) {
102739
103543
  } else {
102740
103544
  log("inbound 1:1 DM from owner");
102741
103545
  }
102742
- target.setDm();
103546
+ target.setDm(metadata?.conversationId, metadata?.conversationGroupId);
102743
103547
  session2.push(text, target.snapshotReply(channel, log), { autoReplyOnText: ownerAttested });
102744
103548
  });
102745
103549
  }
@@ -102844,7 +103648,7 @@ async function main() {
102844
103648
  const info = parseInfoFlags(process.argv.slice(2));
102845
103649
  if (info.showVersion || info.showHelp) {
102846
103650
  const version2 = buildClientVersion2(
102847
- true ? "0.4.21" : void 0
103651
+ true ? "0.4.23" : void 0
102848
103652
  );
102849
103653
  if (info.showVersion) printLine(version2);
102850
103654
  if (info.showHelp) {
@@ -102883,7 +103687,7 @@ async function main() {
102883
103687
  process.exit(0);
102884
103688
  }
102885
103689
  const cfg = loadConfig(process.env, process.argv.slice(2));
102886
- logLine(`[grok-bridge] version: ${true ? "0.4.21" : "dev"}`);
103690
+ logLine(`[grok-bridge] version: ${true ? "0.4.23" : "dev"}`);
102887
103691
  mkdirSync7(cfg.workspaceDir, { recursive: true });
102888
103692
  mkdirSync7(cfg.fenceHome, { recursive: true });
102889
103693
  seedFenceCredential({
@@ -102898,7 +103702,7 @@ async function main() {
102898
103702
  agentName: cfg.agentName,
102899
103703
  platform: "node",
102900
103704
  clientVersion: buildClientVersion2(
102901
- true ? "0.4.21" : void 0
103705
+ true ? "0.4.23" : void 0
102902
103706
  )
102903
103707
  });
102904
103708
  channelRef = channel;