@axiom-lattice/gateway 7.0.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/{WechatChannelAdapter-7WHE5UGY.mjs → WechatChannelAdapter-QLPJJD6S.mjs} +55 -4
  2. package/dist/WechatChannelAdapter-QLPJJD6S.mjs.map +1 -0
  3. package/dist/{a2a-standard-DP53K7RC.mjs → a2a-standard-VL5I7B4W.mjs} +831 -59
  4. package/dist/a2a-standard-VL5I7B4W.mjs.map +1 -0
  5. package/dist/{chunk-FGSFOXIX.mjs → chunk-L6MBEEII.mjs} +2 -2
  6. package/dist/{chunk-J6B2VFJ7.mjs → chunk-W3YH4S6G.mjs} +2 -1
  7. package/dist/{chunk-MWWLJMYN.mjs → chunk-XUWD4VKY.mjs} +4 -2
  8. package/dist/chunk-XUWD4VKY.mjs.map +1 -0
  9. package/dist/embed/embed-page-AgentDetailSideApp-NK6VQBXS.js +1 -0
  10. package/dist/embed/embed-page-AgentGovernanceWorkbench-TKVV2GA6.js +1 -0
  11. package/dist/embed/embed-page-LangfuseDashboard-EYK2T2VK.js +1 -0
  12. package/dist/embed/embed-page-MessageGraph-P73B52OR.js +6 -0
  13. package/dist/embed/embed-page-ReactChart-LK6DUA4R.js +1 -0
  14. package/dist/embed/embed-page-SkillFlow-54RIT6M2.js +1 -0
  15. package/dist/embed/{embed-page-TasksSideApp-D7FFG2OC.js → embed-page-TasksSideApp-RK64OPAA.js} +1 -1
  16. package/dist/embed/embed-page-ThreadMaintenancePanel-PI3U76W3.js +1 -0
  17. package/dist/embed/{embed-page-TopologyRuntimeView-IS6HEO4F.js → embed-page-TopologyRuntimeView-X6QPRQE2.js} +1 -1
  18. package/dist/embed/{embed-page-WorkflowAutomationView-IDVSQTJB.js → embed-page-WorkflowAutomationView-3PE6YCRK.js} +1 -1
  19. package/dist/embed/{embed-page-chunk-NFMLKSPM.js → embed-page-chunk-3VNL5M2Q.js} +1 -1
  20. package/dist/embed/embed-page-chunk-767LVAGR.js +7 -0
  21. package/dist/embed/embed-page-chunk-A5GIM22E.js +117 -0
  22. package/dist/embed/{embed-page-chunk-SRMYHWL3.js → embed-page-chunk-AICFKU43.js} +1 -1
  23. package/dist/embed/{embed-page-chunk-XFV3N2LD.js → embed-page-chunk-BD7DUF2M.js} +1 -1
  24. package/dist/embed/embed-page-chunk-D7YTSCUO.js +1 -0
  25. package/dist/embed/{embed-page-chunk-N66H4DNH.js → embed-page-chunk-EB43T3BJ.js} +283 -194
  26. package/dist/embed/{embed-page-chunk-JFMBLJXY.js → embed-page-chunk-GYO2ELMI.js} +1 -1
  27. package/dist/embed/{embed-page-chunk-EYYKNTX7.js → embed-page-chunk-KF3HZ4TX.js} +1 -1
  28. package/dist/embed/embed-page-chunk-MEY3NEJZ.js +211 -0
  29. package/dist/embed/{embed-page-chunk-TVVAPR7I.js → embed-page-chunk-OIML5DX4.js} +1 -1
  30. package/dist/embed/{embed-page-chunk-FEMHLB6I.js → embed-page-chunk-OKZPPZMF.js} +1 -1
  31. package/dist/embed/embed-page-chunk-T2HKN7ZS.js +459 -0
  32. package/dist/embed/{embed-page-chunk-S2KVN3RB.js → embed-page-chunk-TSZQWEXD.js} +1 -1
  33. package/dist/embed/embed-page-chunk-US46Q3B7.js +15 -0
  34. package/dist/embed/{embed-page-chunk-BOEX26H7.js → embed-page-chunk-UV6IYDW5.js} +8 -8
  35. package/dist/embed/embed-page-chunk-WXMPVIXV.js +59 -0
  36. package/dist/embed/embed-page-chunk-YWJQVBZV.js +1 -0
  37. package/dist/embed/embed-page-code-highlighter-DD23LJY3.js +1 -0
  38. package/dist/embed/{embed-page-en-ETUCVCSC.js → embed-page-en-E35GE7TA.js} +1 -1
  39. package/dist/embed/embed-page-en-EKHHBS6L.js +1 -0
  40. package/dist/embed/embed-page-en-KAXIJJ4X.js +1 -0
  41. package/dist/embed/embed-page-en-OIICQSPX.js +3 -0
  42. package/dist/embed/embed-page-en-PQOH5CU4.js +1 -0
  43. package/dist/embed/embed-page-en-TMGUHZ6Y.js +1 -0
  44. package/dist/embed/embed-page-en-XJYWUJEL.js +1 -0
  45. package/dist/embed/{embed-page-en-2SWQHPAC.js → embed-page-en-ZCNNAMUD.js} +1 -1
  46. package/dist/embed/{embed-page-mermaid-KEBBKHQH.js → embed-page-mermaid-IN3A3YH2.js} +1 -1
  47. package/dist/embed/embed-page-zh-2UVQB4RP.js +3 -0
  48. package/dist/embed/embed-page-zh-6EBUEFKP.js +1 -0
  49. package/dist/embed/embed-page-zh-B3WBWQAV.js +1 -0
  50. package/dist/embed/embed-page-zh-KEMYJJLT.js +1 -0
  51. package/dist/embed/embed-page-zh-XO36BV2R.js +1 -0
  52. package/dist/embed/{embed-page-zh-PRMID3YQ.js → embed-page-zh-Z3URTIHW.js} +1 -1
  53. package/dist/embed/{embed-page-zh-D3IC6BGA.js → embed-page-zh-ZLK3GLM3.js} +1 -1
  54. package/dist/embed/embed-page.js +1 -1
  55. package/dist/index.d.mts +118 -3
  56. package/dist/index.d.ts +118 -3
  57. package/dist/index.js +3862 -1525
  58. package/dist/index.js.map +1 -1
  59. package/dist/index.mjs +2105 -598
  60. package/dist/index.mjs.map +1 -1
  61. package/dist/{open-NTH7AGD3.mjs → open-7ED27I5B.mjs} +3 -3
  62. package/dist/{open-exposure-AGNG4MC3.mjs → open-exposure-I3DN2X4E.mjs} +6 -4
  63. package/dist/{open-exposure-AGNG4MC3.mjs.map → open-exposure-I3DN2X4E.mjs.map} +1 -1
  64. package/package.json +13 -7
  65. package/dist/WechatChannelAdapter-7WHE5UGY.mjs.map +0 -1
  66. package/dist/a2a-standard-DP53K7RC.mjs.map +0 -1
  67. package/dist/chunk-MWWLJMYN.mjs.map +0 -1
  68. package/dist/embed/embed-page-AgentDetailSideApp-KNVDO3FZ.js +0 -1
  69. package/dist/embed/embed-page-AgentGovernanceWorkbench-QSKWVADP.js +0 -1
  70. package/dist/embed/embed-page-MessageGraph-VGXX4OWU.js +0 -6
  71. package/dist/embed/embed-page-ReactChart-PIISVBLU.js +0 -1
  72. package/dist/embed/embed-page-SkillFlow-JLI5MEZE.js +0 -1
  73. package/dist/embed/embed-page-ThreadMaintenancePanel-FSQVVIIG.js +0 -1
  74. package/dist/embed/embed-page-chunk-37LGEEJU.js +0 -21
  75. package/dist/embed/embed-page-chunk-436REIWY.js +0 -1
  76. package/dist/embed/embed-page-chunk-4W34QOXT.js +0 -517
  77. package/dist/embed/embed-page-chunk-BANVRQT7.js +0 -322
  78. package/dist/embed/embed-page-code-highlighter-66CSPTFK.js +0 -1
  79. package/dist/embed/embed-page-en-7IHJFS63.js +0 -1
  80. package/dist/embed/embed-page-en-7NF4GCC2.js +0 -1
  81. package/dist/embed/embed-page-en-FP6DWSG3.js +0 -1
  82. package/dist/embed/embed-page-en-GHTROC4H.js +0 -1
  83. package/dist/embed/embed-page-en-WUFULCUS.js +0 -1
  84. package/dist/embed/embed-page-en-XUMHP5CL.js +0 -1
  85. package/dist/embed/embed-page-zh-G75LDQU4.js +0 -1
  86. package/dist/embed/embed-page-zh-KJXKOUIY.js +0 -1
  87. package/dist/embed/embed-page-zh-RMSS6PXD.js +0 -1
  88. package/dist/embed/embed-page-zh-VH6J7XZO.js +0 -1
  89. package/dist/embed/embed-page-zh-Y5X5Y2DF.js +0 -1
  90. /package/dist/{chunk-FGSFOXIX.mjs.map → chunk-L6MBEEII.mjs.map} +0 -0
  91. /package/dist/{chunk-J6B2VFJ7.mjs.map → chunk-W3YH4S6G.mjs.map} +0 -0
  92. /package/dist/{open-NTH7AGD3.mjs.map → open-7ED27I5B.mjs.map} +0 -0
@@ -9,6 +9,19 @@ import "./chunk-NFEGQTCC.mjs";
9
9
  import { z } from "zod";
10
10
 
11
11
  // src/channels/wechat/context-store.ts
12
+ import { getStoreLattice } from "@axiom-lattice/core";
13
+ var SHARED_NAMESPACE = ["channel-runtime", "wechat-context"];
14
+ var SHARED_TTL_MINUTES = 24 * 60;
15
+ function sharedStore() {
16
+ try {
17
+ return getStoreLattice("default", "store").store;
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+ function sharedKey(installationId, senderId) {
23
+ return `${installationId}::${senderId}`;
24
+ }
12
25
  var TOKEN_TTL_MS = 24 * 60 * 60 * 1e3;
13
26
  var store = /* @__PURE__ */ new Map();
14
27
  var timers = /* @__PURE__ */ new Map();
@@ -45,6 +58,44 @@ function deleteContextToken(installationId, senderId) {
45
58
  timers.delete(key);
46
59
  }
47
60
  }
61
+ async function setContextTokenShared(tenantId, installationId, senderId, token) {
62
+ setContextToken(installationId, senderId, token);
63
+ const shared = sharedStore();
64
+ if (!shared) return;
65
+ try {
66
+ await shared.put(tenantId, {
67
+ namespace: SHARED_NAMESPACE,
68
+ key: sharedKey(installationId, senderId),
69
+ value: { token },
70
+ ttlMinutes: SHARED_TTL_MINUTES
71
+ });
72
+ } catch {
73
+ }
74
+ }
75
+ async function getContextTokenShared(tenantId, installationId, senderId) {
76
+ const local = getContextToken(installationId, senderId);
77
+ if (local) return local;
78
+ const shared = sharedStore();
79
+ if (!shared) return void 0;
80
+ try {
81
+ const item = await shared.get(tenantId, SHARED_NAMESPACE, sharedKey(installationId, senderId));
82
+ const token = item?.value?.token;
83
+ if (typeof token !== "string" || token.length === 0) return void 0;
84
+ setContextToken(installationId, senderId, token);
85
+ return token;
86
+ } catch {
87
+ return void 0;
88
+ }
89
+ }
90
+ async function deleteContextTokenShared(tenantId, installationId, senderId) {
91
+ deleteContextToken(installationId, senderId);
92
+ const shared = sharedStore();
93
+ if (!shared) return;
94
+ try {
95
+ await shared.delete(tenantId, SHARED_NAMESPACE, sharedKey(installationId, senderId));
96
+ } catch {
97
+ }
98
+ }
48
99
 
49
100
  // src/channels/wechat/WechatChannelAdapter.ts
50
101
  var logger = new Logger({ serviceName: "lattice/gateway/wechat" });
@@ -88,7 +139,7 @@ var wechatChannelAdapter = {
88
139
  const text = extractText(msg);
89
140
  if (!text) return null;
90
141
  if (msg.context_token) {
91
- setContextToken(installation.id, senderId, msg.context_token);
142
+ await setContextTokenShared(installation.tenantId, installation.id, senderId, msg.context_token);
92
143
  }
93
144
  return {
94
145
  channel: "wechat",
@@ -114,13 +165,13 @@ var wechatChannelAdapter = {
114
165
  },
115
166
  async sendReply(replyTarget, message, installation) {
116
167
  const senderId = replyTarget.rawTarget.senderId;
117
- const contextToken = getContextToken(installation.id, senderId);
168
+ const contextToken = await getContextTokenShared(installation.tenantId, installation.id, senderId);
118
169
  if (!contextToken) {
119
170
  logger.warn("WeChat context token expired, cannot send reply", {
120
171
  installationId: installation.id,
121
172
  senderId
122
173
  });
123
- deleteContextToken(installation.id, senderId);
174
+ await deleteContextTokenShared(installation.tenantId, installation.id, senderId);
124
175
  return;
125
176
  }
126
177
  const { botToken } = installation.config;
@@ -253,4 +304,4 @@ var wechatChannelAdapter = {
253
304
  export {
254
305
  wechatChannelAdapter
255
306
  };
256
- //# sourceMappingURL=WechatChannelAdapter-7WHE5UGY.mjs.map
307
+ //# sourceMappingURL=WechatChannelAdapter-QLPJJD6S.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/channels/wechat/WechatChannelAdapter.ts","../src/channels/wechat/context-store.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type {\n ChannelAdapter,\n InboundMessage,\n OutboundMessage,\n ReplyTarget,\n ChannelInstallation,\n} from \"@axiom-lattice/protocols\";\nimport type { WechatChannelInstallationConfig } from \"@axiom-lattice/protocols\";\nimport { getUpdates, sendMessage } from \"./wechat-client\";\nimport {\n deleteContextTokenShared,\n getContextTokenShared,\n setContextTokenShared,\n} from \"./context-store\";\nimport { Logger } from \"../../logger/Logger\";\n\nconst logger = new Logger({ serviceName: \"lattice/gateway/wechat\" });\n\nconst wechatConfigSchema = z.object({\n botToken: z.string(),\n uin: z.string().optional(),\n});\n\nconst MAX_RECONNECT_DELAY_MS = 30_000;\nconst BASE_RECONNECT_DELAY_MS = 1_000;\nconst HEARTBEAT_INTERVAL_MS = 60_000;\nconst CHANNEL_VERSION = \"1.0.2\";\n\n// ─── Message type constants ───────────────────────────────────────────────\n\nconst MSG_TYPE_USER = 1;\nconst MSG_ITEM_TEXT = 1;\n\n// ─── Polling connection state ─────────────────────────────────────────────\n\ninterface PollingState {\n installationId: string;\n abortController: AbortController;\n lastActivity: number;\n heartbeatTimer: NodeJS.Timeout;\n}\n\nconst activeConnections = new Map<string, PollingState>();\n\n// ─── Message dedup ────────────────────────────────────────────────────────\n\nconst seenClientIds = new Set<string>();\n\nfunction addToDedup(clientId: string): boolean {\n if (!clientId || seenClientIds.has(clientId)) return false;\n seenClientIds.add(clientId);\n if (seenClientIds.size > 1000) {\n const first = seenClientIds.values().next().value;\n if (first !== undefined) seenClientIds.delete(first);\n }\n return true;\n}\n\n// ─── Text extraction from iLink message ───────────────────────────────────\n\nfunction extractText(msg: { item_list?: Array<{ type?: number; text_item?: { text?: string } }> }): string | null {\n if (!msg.item_list?.length) return null;\n for (const item of msg.item_list) {\n if (item.type === MSG_ITEM_TEXT && item.text_item?.text) {\n return item.text_item.text;\n }\n }\n return null;\n}\n\n// ─── Adapter ──────────────────────────────────────────────────────────────\n\nexport const wechatChannelAdapter: ChannelAdapter<WechatChannelInstallationConfig> = {\n channel: \"wechat\",\n\n configSchema: wechatConfigSchema,\n\n async receive(\n rawPayload: unknown,\n installation: ChannelInstallation<WechatChannelInstallationConfig>,\n ): Promise<InboundMessage | null> {\n const msg = rawPayload as {\n from_user_id?: string;\n client_id?: string;\n message_type?: number;\n item_list?: Array<{ type?: number; text_item?: { text?: string } }>;\n context_token?: string;\n };\n\n // Only process user messages (type 1), skip bot echoes (type 2)\n if (msg.message_type !== MSG_TYPE_USER) return null;\n\n const senderId = msg.from_user_id;\n if (!senderId) return null;\n\n const text = extractText(msg);\n if (!text) return null;\n\n // Cache context token for reply\n if (msg.context_token) {\n await setContextTokenShared(installation.tenantId, installation.id, senderId, msg.context_token);\n }\n\n return {\n channel: \"wechat\",\n channelInstallationId: installation.id,\n tenantId: installation.tenantId,\n sender: {\n id: senderId,\n displayName: senderId.split(\"@\")[0],\n },\n content: {\n text,\n },\n conversation: {\n id: senderId,\n type: \"direct\",\n },\n replyTarget: {\n adapterChannel: \"wechat\",\n channelInstallationId: installation.id,\n rawTarget: { senderId },\n },\n };\n },\n\n async sendReply(\n replyTarget: ReplyTarget,\n message: OutboundMessage,\n installation: ChannelInstallation<WechatChannelInstallationConfig>,\n ): Promise<void> {\n const senderId = replyTarget.rawTarget.senderId as string;\n const contextToken = await getContextTokenShared(installation.tenantId, installation.id, senderId);\n\n if (!contextToken) {\n logger.warn(\"WeChat context token expired, cannot send reply\", {\n installationId: installation.id,\n senderId,\n });\n await deleteContextTokenShared(installation.tenantId, installation.id, senderId);\n return;\n }\n\n const { botToken } = installation.config;\n await sendMessage(botToken, senderId, message.text, contextToken);\n },\n\n resolveThreadId(message: InboundMessage, binding: unknown): string {\n const date = new Date().toISOString().split(\"T\")[0];\n const agentId = (binding as { agentId: string }).agentId;\n return `wechat:dm:${message.sender.id}:${agentId}:${date}`;\n },\n\n async connect(\n installation: ChannelInstallation<WechatChannelInstallationConfig>,\n deps?: unknown,\n ): Promise<void> {\n const { id: installationId, tenantId, config } = installation;\n\n if (!config.botToken) {\n logger.warn(\"WeChat installation missing botToken, skipping\", { installationId });\n return;\n }\n\n if (activeConnections.has(installationId)) {\n logger.warn(\"WeChat polling already running for installation, skipping\", { installationId });\n return;\n }\n\n logger.info(\"WeChat polling starting\", { installationId, tenantId });\n\n const abortController = new AbortController();\n\n const heartbeatTimer = setInterval(() => {\n const state2 = activeConnections.get(installationId);\n if (!state2) {\n clearInterval(heartbeatTimer);\n return;\n }\n const elapsed = Date.now() - state2.lastActivity;\n if (elapsed > HEARTBEAT_INTERVAL_MS * 2) {\n logger.error(\"WeChat polling heartbeat lost — no activity\", {\n installationId,\n elapsedMs: elapsed,\n });\n state2.abortController.abort();\n }\n }, HEARTBEAT_INTERVAL_MS);\n\n const state: PollingState = {\n installationId,\n abortController,\n lastActivity: Date.now(),\n heartbeatTimer,\n };\n activeConnections.set(installationId, state);\n\n const router = (deps as { router?: { dispatch(msg: InboundMessage): Promise<unknown> } })?.router;\n\n let syncBuffer = \"\";\n let reconnectDelay = BASE_RECONNECT_DELAY_MS;\n\n const scheduleNextPoll = (): void => {\n poll().catch((err) => {\n logger.error(\"WeChat poll iteration crashed\", {\n installationId,\n error: err instanceof Error ? err.message : String(err),\n });\n const currentState = activeConnections.get(installationId);\n if (currentState && !currentState.abortController.signal.aborted) {\n setTimeout(scheduleNextPoll, reconnectDelay);\n }\n });\n };\n\n const poll = async (): Promise<void> => {\n const currentState = activeConnections.get(installationId);\n if (!currentState || currentState.abortController.signal.aborted) {\n logger.info(\"WeChat polling aborted\", { installationId });\n return;\n }\n\n try {\n const result = await getUpdates(\n config.botToken,\n syncBuffer,\n currentState.abortController.signal,\n );\n syncBuffer = result.syncBuffer;\n reconnectDelay = BASE_RECONNECT_DELAY_MS;\n currentState.lastActivity = Date.now();\n\n if (result.msgs.length > 0) {\n logger.info(\"WeChat poll received messages\", {\n installationId,\n count: result.msgs.length,\n });\n }\n\n for (const rawMsg of result.msgs) {\n // Only user messages, skip bot echoes and non-text\n if (rawMsg.message_type !== MSG_TYPE_USER) continue;\n\n const text = extractText(rawMsg);\n if (!text) continue;\n\n if (!addToDedup((rawMsg as { client_id?: string }).client_id ?? \"\")) continue;\n\n const inbound = await wechatChannelAdapter.receive(\n rawMsg,\n installation as ChannelInstallation<WechatChannelInstallationConfig>,\n );\n if (inbound && router) {\n const dispatchResult = await router.dispatch(inbound);\n if (!(dispatchResult as { success?: boolean }).success) {\n logger.warn(\"WeChat dispatch failed\", {\n installationId,\n error: (dispatchResult as { error?: { message?: string } }).error?.message,\n });\n }\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n logger.info(\"WeChat poll aborted by signal\", { installationId });\n return;\n }\n\n logger.error(\"WeChat poll error\", {\n installationId,\n error: err instanceof Error ? err.message : String(err),\n });\n await new Promise((resolve) => setTimeout(resolve, reconnectDelay));\n reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY_MS);\n }\n\n scheduleNextPoll();\n };\n\n scheduleNextPoll();\n logger.info(\"WeChat polling started\", { installationId });\n },\n\n async disconnect(installationId: string): Promise<void> {\n const state = activeConnections.get(installationId);\n if (!state) {\n logger.warn(\"WeChat polling not running, nothing to disconnect\", { installationId });\n return;\n }\n\n logger.info(\"WeChat polling disconnecting\", { installationId });\n state.abortController.abort();\n clearInterval(state.heartbeatTimer);\n activeConnections.delete(installationId);\n logger.info(\"WeChat polling disconnected\", { installationId });\n },\n};\n","import { getStoreLattice } from \"@axiom-lattice/core\";\nimport type { StoreProtocol } from \"@axiom-lattice/protocols\";\n\nconst SHARED_NAMESPACE = [\"channel-runtime\", \"wechat-context\"];\nconst SHARED_TTL_MINUTES = 24 * 60;\n\nfunction sharedStore(): StoreProtocol | null {\n try {\n return getStoreLattice(\"default\", \"store\").store as StoreProtocol;\n } catch {\n return null;\n }\n}\n\nfunction sharedKey(installationId: string, senderId: string): string {\n return `${installationId}::${senderId}`;\n}\n\ninterface ContextTokenEntry {\n token: string;\n installationId: string;\n senderId: string;\n updatedAt: number;\n}\n\nconst TOKEN_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst store = new Map<string, ContextTokenEntry>();\nconst timers = new Map<string, NodeJS.Timeout>();\n\nfunction makeKey(installationId: string, senderId: string): string {\n return `${installationId}::${senderId}`;\n}\n\nexport function getContextToken(installationId: string, senderId: string): string | undefined {\n const key = makeKey(installationId, senderId);\n const entry = store.get(key);\n if (!entry) return undefined;\n if (Date.now() - entry.updatedAt > TOKEN_TTL_MS) {\n deleteContextToken(installationId, senderId);\n return undefined;\n }\n return entry.token;\n}\n\nexport function setContextToken(installationId: string, senderId: string, token: string): void {\n const key = makeKey(installationId, senderId);\n\n const existingTimer = timers.get(key);\n if (existingTimer) clearTimeout(existingTimer);\n\n store.set(key, { token, installationId, senderId, updatedAt: Date.now() });\n\n const timer = setTimeout(() => {\n store.delete(key);\n timers.delete(key);\n }, TOKEN_TTL_MS);\n timers.set(key, timer);\n}\n\nexport function deleteContextToken(installationId: string, senderId: string): void {\n const key = makeKey(installationId, senderId);\n store.delete(key);\n const timer = timers.get(key);\n if (timer) {\n clearTimeout(timer);\n timers.delete(key);\n }\n}\n\nexport function getContextTokenStoreSize(): number {\n return store.size;\n}\n\n/** Cross-replica context token write (local cache + shared store). */\nexport async function setContextTokenShared(\n tenantId: string,\n installationId: string,\n senderId: string,\n token: string,\n): Promise<void> {\n setContextToken(installationId, senderId, token);\n const shared = sharedStore();\n if (!shared) return;\n try {\n await shared.put(tenantId, {\n namespace: SHARED_NAMESPACE,\n key: sharedKey(installationId, senderId),\n value: { token },\n ttlMinutes: SHARED_TTL_MINUTES,\n });\n } catch {\n // Local cache still serves this replica; shared storage is best-effort here.\n }\n}\n\n/** Cross-replica context token read. */\nexport async function getContextTokenShared(\n tenantId: string,\n installationId: string,\n senderId: string,\n): Promise<string | undefined> {\n const local = getContextToken(installationId, senderId);\n if (local) return local;\n const shared = sharedStore();\n if (!shared) return undefined;\n try {\n const item = await shared.get(tenantId, SHARED_NAMESPACE, sharedKey(installationId, senderId));\n const token = item?.value?.token;\n if (typeof token !== \"string\" || token.length === 0) return undefined;\n setContextToken(installationId, senderId, token);\n return token;\n } catch {\n return undefined;\n }\n}\n\n/** Cross-replica context token deletion. */\nexport async function deleteContextTokenShared(\n tenantId: string,\n installationId: string,\n senderId: string,\n): Promise<void> {\n deleteContextToken(installationId, senderId);\n const shared = sharedStore();\n if (!shared) return;\n try {\n await shared.delete(tenantId, SHARED_NAMESPACE, sharedKey(installationId, senderId));\n } catch {\n // Best-effort cleanup.\n }\n}\n"],"mappings":"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","names":[]}