@axiom-lattice/gateway 4.9.2 → 4.10.1

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 (25) hide show
  1. package/dist/embed/{embed-page-AgentDetailSideApp-WQAMMDXN.js → embed-page-AgentDetailSideApp-2M4MLVQQ.js} +1 -1
  2. package/dist/embed/{embed-page-AgentGovernanceWorkbench-VKD4IZIO.js → embed-page-AgentGovernanceWorkbench-KEVBIQP6.js} +1 -1
  3. package/dist/embed/{embed-page-MessageGraph-C4EJWY3E.js → embed-page-MessageGraph-PRBUQINR.js} +1 -1
  4. package/dist/embed/{embed-page-ReactChart-TNT4TT4C.js → embed-page-ReactChart-V6JJXCEV.js} +1 -1
  5. package/dist/embed/{embed-page-SkillFlow-WWRDU6GS.js → embed-page-SkillFlow-6LPE2VG3.js} +1 -1
  6. package/dist/embed/{embed-page-TasksSideApp-73SJLGRY.js → embed-page-TasksSideApp-OFZI54MF.js} +1 -1
  7. package/dist/embed/{embed-page-TeamWorkspace-6E4HAH7L.js → embed-page-TeamWorkspace-QSSAF3AA.js} +1 -1
  8. package/dist/embed/{embed-page-TopologyRuntimeView-SXUNRFT4.js → embed-page-TopologyRuntimeView-PHULW2NG.js} +1 -1
  9. package/dist/embed/{embed-page-WorkflowAutomationView-I4VN6YY2.js → embed-page-WorkflowAutomationView-LQS6H7X6.js} +1 -1
  10. package/dist/embed/{embed-page-chunk-TEIHYMTL.js → embed-page-chunk-7PNQFZMK.js} +7 -7
  11. package/dist/embed/{embed-page-chunk-G5NEOKZK.js → embed-page-chunk-D5EY6ASK.js} +1 -1
  12. package/dist/embed/{embed-page-chunk-YZMHK63X.js → embed-page-chunk-IJ2YWGKU.js} +1 -1
  13. package/dist/embed/{embed-page-chunk-WUOHF2QZ.js → embed-page-chunk-O44JEYLD.js} +7 -7
  14. package/dist/embed/embed-page-chunk-PFCR6CFL.js +2 -0
  15. package/dist/embed/{embed-page-chunk-L7HKGCDN.js → embed-page-chunk-SSWDAKQU.js} +1 -1
  16. package/dist/embed/{embed-page-chunk-IM57IYUL.js → embed-page-chunk-YNHKD2CY.js} +1 -1
  17. package/dist/embed/{embed-page-en-GE4GI4D3.js → embed-page-en-ICVL5QAC.js} +1 -1
  18. package/dist/embed/{embed-page-zh-KC2E7UVY.js → embed-page-zh-FPYCTKQK.js} +1 -1
  19. package/dist/embed/embed-page.js +1 -1
  20. package/dist/index.js +342 -140
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +287 -86
  23. package/dist/index.mjs.map +1 -1
  24. package/package.json +8 -7
  25. package/dist/embed/embed-page-chunk-RQXI6NQX.js +0 -2
package/dist/index.mjs CHANGED
@@ -10668,6 +10668,9 @@ function isLarkConfig(config) {
10668
10668
  function isWechatConfig(config) {
10669
10669
  return isString(config.botToken) && isOptionalString(config.uin);
10670
10670
  }
10671
+ function isWecomConfig(config) {
10672
+ return isString(config.botId) && isString(config.secret) && isOptionalString(config.assistantId);
10673
+ }
10671
10674
  function snapshotPublicCreateRequest(value) {
10672
10675
  const body = snapshotPlainObject(value);
10673
10676
  const allowedKeys = /* @__PURE__ */ new Set([
@@ -10694,6 +10697,9 @@ function snapshotPublicCreateRequest(value) {
10694
10697
  if (body.channel === "wechat" && isWechatConfig(config)) {
10695
10698
  return { ...base, channel: "wechat", config };
10696
10699
  }
10700
+ if (body.channel === "wecom" && isWecomConfig(config)) {
10701
+ return { ...base, channel: "wecom", config };
10702
+ }
10697
10703
  if (body.channel === "email" || body.channel === "slack") return { ...base, channel: body.channel, config };
10698
10704
  return null;
10699
10705
  }
@@ -10714,6 +10720,7 @@ function snapshotPublicUpdateRequest(value, channel) {
10714
10720
  if (!config) return null;
10715
10721
  if (channel === "lark" && !isLarkConfig(config)) return null;
10716
10722
  if (channel === "wechat" && !isWechatConfig(config)) return null;
10723
+ if (channel === "wecom" && !isWecomConfig(config)) return null;
10717
10724
  }
10718
10725
  return {
10719
10726
  name: body.name,
@@ -11066,7 +11073,7 @@ function registerChannelInstallationRoutes(app2) {
11066
11073
  type: "object",
11067
11074
  additionalProperties: false,
11068
11075
  properties: {
11069
- channel: { type: "string", enum: ["lark", "email", "slack", "wechat"] }
11076
+ channel: { type: "string", enum: ["lark", "email", "slack", "wechat", "wecom"] }
11070
11077
  }
11071
11078
  }
11072
11079
  }
@@ -24605,7 +24612,7 @@ var collectionRegistration = {
24605
24612
  import { getStoreLattice as getStoreLattice25 } from "@axiom-lattice/core";
24606
24613
  import { randomUUID as randomUUID25 } from "crypto";
24607
24614
  var UUID_PATTERN2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
24608
- var PUBLIC_CHANNELS = /* @__PURE__ */ new Set(["lark", "email", "slack", "wechat"]);
24615
+ var PUBLIC_CHANNELS = /* @__PURE__ */ new Set(["lark", "email", "slack", "wechat", "wecom"]);
24609
24616
  function isPublicChannel(channel) {
24610
24617
  return typeof channel === "string" && PUBLIC_CHANNELS.has(channel);
24611
24618
  }
@@ -24626,6 +24633,9 @@ function validateImportData(data) {
24626
24633
  if (channel === "wechat" && typeof configRecord.botToken !== "string") {
24627
24634
  throw new Error("WeChat channel installation config requires botToken");
24628
24635
  }
24636
+ if (channel === "wecom" && (typeof configRecord.botId !== "string" || typeof configRecord.secret !== "string")) {
24637
+ throw new Error("WeCom channel installation config requires botId and secret");
24638
+ }
24629
24639
  return {
24630
24640
  channel,
24631
24641
  name: typeof data.name === "string" ? data.name : void 0,
@@ -25310,6 +25320,196 @@ function createAuditLoggerMiddleware() {
25310
25320
  // src/index.ts
25311
25321
  import { setBindingRegistry, setMenuRegistry, setEvalRunService } from "@axiom-lattice/core";
25312
25322
 
25323
+ // src/channels/wecom/WecomChannelAdapter.ts
25324
+ import { randomUUID as randomUUID26 } from "crypto";
25325
+ import { z as z12 } from "zod";
25326
+ import * as WecomAiBot from "@wecom/aibot-node-sdk";
25327
+
25328
+ // src/channels/wecom/parser.ts
25329
+ function parseWecomTextFrame(frame) {
25330
+ if (!frame || typeof frame !== "object") return null;
25331
+ const { headers, body } = frame;
25332
+ const reqId = headers?.req_id;
25333
+ if (typeof reqId !== "string" || !body) return null;
25334
+ if (body.msgtype !== "text") return null;
25335
+ const fromUserId = body.from?.userid;
25336
+ const content = body.text?.content;
25337
+ if (typeof fromUserId !== "string" || typeof content !== "string") {
25338
+ return null;
25339
+ }
25340
+ return {
25341
+ reqId,
25342
+ msgId: typeof body.msgid === "string" ? body.msgid : "",
25343
+ fromUserId,
25344
+ chatId: typeof body.chatid === "string" ? body.chatid : void 0,
25345
+ chatType: body.chattype === "group" ? "group" : "direct",
25346
+ text: content
25347
+ };
25348
+ }
25349
+
25350
+ // src/channels/wecom/WecomChannelAdapter.ts
25351
+ var logger6 = new Logger({ serviceName: "lattice/gateway/wecom" });
25352
+ var wecomConfigSchema = z12.object({
25353
+ botId: z12.string(),
25354
+ secret: z12.string()
25355
+ });
25356
+ var RECONNECT_BASE_MS = 5e3;
25357
+ var RECONNECT_MAX_MS = 6e4;
25358
+ var activeConnections2 = /* @__PURE__ */ new Map();
25359
+ var wecomChannelAdapter = {
25360
+ channel: "wecom",
25361
+ configSchema: wecomConfigSchema,
25362
+ async receive(rawPayload, installation) {
25363
+ const parsed = parseWecomTextFrame(rawPayload);
25364
+ if (!parsed) return null;
25365
+ return {
25366
+ channel: "wecom",
25367
+ channelInstallationId: installation.id,
25368
+ tenantId: installation.tenantId,
25369
+ sender: { id: parsed.fromUserId },
25370
+ content: {
25371
+ text: parsed.text,
25372
+ // `messageId` 供去重中间件使用(企业微信可能重投同一 msgid)。
25373
+ metadata: {
25374
+ messageId: parsed.msgId,
25375
+ chatId: parsed.chatId,
25376
+ chatType: parsed.chatType
25377
+ }
25378
+ },
25379
+ conversation: {
25380
+ id: parsed.chatId ?? parsed.fromUserId,
25381
+ type: parsed.chatType
25382
+ },
25383
+ replyTarget: {
25384
+ adapterChannel: "wecom",
25385
+ channelInstallationId: installation.id,
25386
+ // 回复需原样带回入站帧(含 `headers.req_id`)。frame 是纯 JSON,
25387
+ // replyTarget 仅在内存流转,不落库。
25388
+ rawTarget: { frame: rawPayload }
25389
+ }
25390
+ };
25391
+ },
25392
+ async sendReply(replyTarget, message, installation) {
25393
+ const connection = activeConnections2.get(installation.id);
25394
+ if (!connection) {
25395
+ logger6.warn("WeCom bot not connected, cannot reply", {
25396
+ installationId: installation.id
25397
+ });
25398
+ return;
25399
+ }
25400
+ connection.client.reply(replyTarget.rawTarget.frame, {
25401
+ msgtype: "stream",
25402
+ stream: {
25403
+ id: randomUUID26(),
25404
+ finish: true,
25405
+ content: message.text
25406
+ }
25407
+ });
25408
+ },
25409
+ resolveThreadId(message, binding) {
25410
+ const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
25411
+ const agentId = binding.agentId;
25412
+ if (message.conversation?.type === "group") {
25413
+ return `wecom:group:${message.conversation.id}:${agentId}:${date}`;
25414
+ }
25415
+ return `wecom:dm:${message.sender.id}:${agentId}:${date}`;
25416
+ },
25417
+ async connect(installation, deps) {
25418
+ const { id: installationId, tenantId, config } = installation;
25419
+ if (!config.botId || !config.secret) {
25420
+ logger6.warn("WeCom installation missing botId/secret, skipping", { installationId });
25421
+ return;
25422
+ }
25423
+ if (activeConnections2.has(installationId)) {
25424
+ logger6.warn("WeCom long connection already running, skipping", { installationId });
25425
+ return;
25426
+ }
25427
+ const { router, wsClientFactory } = deps ?? {};
25428
+ const client = (wsClientFactory ?? createDefaultWecomClient)(config);
25429
+ const connection = { client, intentional: false, attempts: 0 };
25430
+ client.on("message.text", (frame) => {
25431
+ wecomChannelAdapter.receive(frame, installation).then((inbound) => {
25432
+ if (!inbound || !router) return void 0;
25433
+ return router.dispatch(inbound);
25434
+ }).catch((error) => {
25435
+ logger6.error("WeCom message dispatch error", {
25436
+ installationId,
25437
+ error: error instanceof Error ? error.message : String(error)
25438
+ });
25439
+ });
25440
+ });
25441
+ client.on("authenticated", () => {
25442
+ connection.attempts = 0;
25443
+ });
25444
+ client.on("event.disconnected_event", () => {
25445
+ logger6.warn("WeCom connection kicked by a newer connection; will reconnect", {
25446
+ installationId
25447
+ });
25448
+ scheduleReconnect(installationId, connection);
25449
+ });
25450
+ activeConnections2.set(installationId, connection);
25451
+ client.connect();
25452
+ logger6.info("WeCom long connection starting", { installationId, tenantId });
25453
+ },
25454
+ async disconnect(installationId) {
25455
+ const connection = activeConnections2.get(installationId);
25456
+ if (!connection) {
25457
+ logger6.warn("WeCom long connection not running, nothing to disconnect", { installationId });
25458
+ return;
25459
+ }
25460
+ connection.intentional = true;
25461
+ if (connection.timer) {
25462
+ clearTimeout(connection.timer);
25463
+ connection.timer = void 0;
25464
+ }
25465
+ try {
25466
+ connection.client.disconnect();
25467
+ } catch (error) {
25468
+ logger6.error("WeCom long connection stop error", {
25469
+ installationId,
25470
+ error: error instanceof Error ? error.message : String(error)
25471
+ });
25472
+ }
25473
+ activeConnections2.delete(installationId);
25474
+ logger6.info("WeCom long connection disconnected", { installationId });
25475
+ }
25476
+ };
25477
+ function scheduleReconnect(installationId, connection) {
25478
+ if (connection.intentional || connection.timer) return;
25479
+ const delay2 = Math.min(RECONNECT_BASE_MS * 2 ** connection.attempts, RECONNECT_MAX_MS);
25480
+ connection.attempts += 1;
25481
+ logger6.info("WeCom reconnect scheduled", {
25482
+ installationId,
25483
+ delayMs: delay2,
25484
+ attempt: connection.attempts
25485
+ });
25486
+ const timer = setTimeout(() => {
25487
+ connection.timer = void 0;
25488
+ if (connection.intentional || activeConnections2.get(installationId) !== connection) {
25489
+ return;
25490
+ }
25491
+ try {
25492
+ connection.client.connect();
25493
+ } catch (error) {
25494
+ logger6.error("WeCom reconnect failed", {
25495
+ installationId,
25496
+ error: error instanceof Error ? error.message : String(error)
25497
+ });
25498
+ scheduleReconnect(installationId, connection);
25499
+ }
25500
+ }, delay2);
25501
+ timer.unref?.();
25502
+ connection.timer = timer;
25503
+ }
25504
+ function createDefaultWecomClient(config) {
25505
+ return new WecomAiBot.WSClient({
25506
+ botId: config.botId,
25507
+ secret: config.secret,
25508
+ // 断网无限重连;被踢(disconnected_event)由 scheduleReconnect 兜底。
25509
+ maxReconnectAttempts: -1
25510
+ });
25511
+ }
25512
+
25313
25513
  // src/swagger.ts
25314
25514
  import swagger from "@fastify/swagger";
25315
25515
  import swaggerUi from "@fastify/swagger-ui";
@@ -25373,7 +25573,7 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
25373
25573
  };
25374
25574
 
25375
25575
  // src/services/agent_task_consumer.ts
25376
- import { randomUUID as randomUUID26 } from "crypto";
25576
+ import { randomUUID as randomUUID27 } from "crypto";
25377
25577
  import { eventBus as eventBus3, AGENT_TASK_EVENT, agentInstanceManager as agentInstanceManager7, QueueMode as QueueMode2 } from "@axiom-lattice/core";
25378
25578
  import { resolveRunScope } from "@axiom-lattice/protocols";
25379
25579
  var handleAgentTask = async (taskRequest, retryCount = 0) => {
@@ -25397,7 +25597,7 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
25397
25597
  const agent = agentInstanceManager7.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: scope.workspaceId, project_id: scope.projectId, custom_run_config: runConfig });
25398
25598
  if (callback_event) {
25399
25599
  const callbackEvent = callback_event;
25400
- const messageId = typeof input?.id === "string" && input.id !== "" ? input.id : randomUUID26();
25600
+ const messageId = typeof input?.id === "string" && input.id !== "" ? input.id : randomUUID27();
25401
25601
  let settled = false;
25402
25602
  const subscriptions = [];
25403
25603
  const dispose = () => {
@@ -25751,7 +25951,7 @@ import {
25751
25951
  snapshotExactArray as snapshotExactArray3,
25752
25952
  snapshotExactRecord as snapshotExactRecord15
25753
25953
  } from "@axiom-lattice/protocols";
25754
- import { randomUUID as randomUUID27 } from "crypto";
25954
+ import { randomUUID as randomUUID28 } from "crypto";
25755
25955
  var BindingNotFoundError = class extends Error {
25756
25956
  constructor(message) {
25757
25957
  super(message);
@@ -26073,7 +26273,7 @@ var MessageRouter = class {
26073
26273
  }
26074
26274
  if (!threadId) {
26075
26275
  const threadStore = getStoreLattice28("default", "thread").store;
26076
- const newThreadId = randomUUID27();
26276
+ const newThreadId = randomUUID28();
26077
26277
  console.log({
26078
26278
  event: "dispatch:thread:create",
26079
26279
  agentId,
@@ -26119,7 +26319,7 @@ var MessageRouter = class {
26119
26319
  workspace_id: binding?.workspaceId || "",
26120
26320
  project_id: binding?.projectId || ""
26121
26321
  });
26122
- const inputMessageId = randomUUID27();
26322
+ const inputMessageId = randomUUID28();
26123
26323
  const replyTarget = internalRoom ? correlatedRoomReplyTarget(message.replyTarget, inputMessageId) : message.replyTarget;
26124
26324
  const replyAdapter = replyTarget ? this.adapterRegistry.get(replyTarget.adapterChannel) : void 0;
26125
26325
  if (options.trustedMessageOptions && (!this.trustedDispatcher || !replyTarget || !replyAdapter)) {
@@ -26299,9 +26499,9 @@ var MessageRouter = class {
26299
26499
  };
26300
26500
 
26301
26501
  // src/channels/room/RoomChannelAdapter.ts
26302
- import { z as z12 } from "zod";
26502
+ import { z as z13 } from "zod";
26303
26503
  import { snapshotExactRecord as snapshotExactRecord16 } from "@axiom-lattice/protocols";
26304
- var roomConfigSchema = z12.object({}).strict();
26504
+ var roomConfigSchema = z13.object({}).strict();
26305
26505
  function createRoomChannelAdapter(writer) {
26306
26506
  return {
26307
26507
  channel: "room",
@@ -26422,7 +26622,7 @@ async function prepareProjectTaskRuntime(runtime, log2) {
26422
26622
  import { setPluginDeploymentService } from "@axiom-lattice/core";
26423
26623
 
26424
26624
  // src/services/plugins/PluginDeploymentService.ts
26425
- import { randomUUID as randomUUID28 } from "crypto";
26625
+ import { randomUUID as randomUUID29 } from "crypto";
26426
26626
  import {
26427
26627
  PLUGIN_HOST_DIR,
26428
26628
  PluginDeploymentRuntimeRegistry
@@ -26566,7 +26766,7 @@ var PluginDeploymentService = class {
26566
26766
  const failedAt = this.nowIso();
26567
26767
  await this.store.upsert(
26568
26768
  this.buildRecord({
26569
- id: existing?.id ?? randomUUID28(),
26769
+ id: existing?.id ?? randomUUID29(),
26570
26770
  tenantId,
26571
26771
  pluginType,
26572
26772
  pluginVersion: manifest.version,
@@ -26588,7 +26788,7 @@ var PluginDeploymentService = class {
26588
26788
  );
26589
26789
  }
26590
26790
  const record = this.buildRecord({
26591
- id: existing?.id ?? randomUUID28(),
26791
+ id: existing?.id ?? randomUUID29(),
26592
26792
  tenantId,
26593
26793
  pluginType,
26594
26794
  pluginVersion: manifest.version,
@@ -27190,11 +27390,11 @@ function readPluginDeploymentLimits(env = process.env) {
27190
27390
  };
27191
27391
  }
27192
27392
  function startPluginDeploymentRuntime(options) {
27193
- const { lease, holder, logger: logger7 } = options;
27393
+ const { lease, holder, logger: logger8 } = options;
27194
27394
  const forcedOn = process.env[PLUGIN_DEPLOYMENT_RUNTIME_FLAG] === "true" || process.env[PLUGIN_DEPLOYMENT_RUNTIME_FLAG] === "1";
27195
27395
  const effectiveServiceBaseUrl = options.wiring.serviceBaseUrl ?? process.env.MICROSANDBOX_SERVICE_BASE_URL;
27196
27396
  if (forcedOn && !effectiveServiceBaseUrl) {
27197
- logger7.warn(
27397
+ logger8.warn(
27198
27398
  `${PLUGIN_DEPLOYMENT_RUNTIME_FLAG} is enabled but MICROSANDBOX_SERVICE_BASE_URL is empty; skipping plugin deployment runtime`,
27199
27399
  { holder }
27200
27400
  );
@@ -27213,8 +27413,8 @@ function startPluginDeploymentRuntime(options) {
27213
27413
  };
27214
27414
  const service2 = createService(deps);
27215
27415
  register(service2);
27216
- logger7.info("plugin deployment runtime started", { holder });
27217
- const reconcile = runStartupReconcile(service2, reconcileDeadlineMs, logger7, holder);
27416
+ logger8.info("plugin deployment runtime started", { holder });
27417
+ const reconcile = runStartupReconcile(service2, reconcileDeadlineMs, logger8, holder);
27218
27418
  let held = false;
27219
27419
  let inFlight = false;
27220
27420
  const tick = async () => {
@@ -27222,18 +27422,18 @@ function startPluginDeploymentRuntime(options) {
27222
27422
  inFlight = true;
27223
27423
  try {
27224
27424
  if (held) {
27225
- held = await renewLease(lease, holder, logger7);
27425
+ held = await renewLease(lease, holder, logger8);
27226
27426
  if (!held) {
27227
- logger7.warn("plugin deployment lease lost; watchdog paused", { holder });
27427
+ logger8.warn("plugin deployment lease lost; watchdog paused", { holder });
27228
27428
  }
27229
27429
  } else {
27230
- held = await acquireLease(lease, holder, logger7);
27430
+ held = await acquireLease(lease, holder, logger8);
27231
27431
  if (held) {
27232
- logger7.info("plugin deployment lease acquired", { holder });
27432
+ logger8.info("plugin deployment lease acquired", { holder });
27233
27433
  }
27234
27434
  }
27235
27435
  if (!held) return;
27236
- await runWatchdog(service2, holder, logger7);
27436
+ await runWatchdog(service2, holder, logger8);
27237
27437
  } finally {
27238
27438
  inFlight = false;
27239
27439
  }
@@ -27249,7 +27449,7 @@ function startPluginDeploymentRuntime(options) {
27249
27449
  try {
27250
27450
  await lease.release(PLUGIN_DEPLOYMENT_LEASE_KEY, holder);
27251
27451
  } catch (error) {
27252
- logger7.warn("plugin deployment lease release failed", {
27452
+ logger8.warn("plugin deployment lease release failed", {
27253
27453
  holder,
27254
27454
  error: errorMessage5(error)
27255
27455
  });
@@ -27257,16 +27457,16 @@ function startPluginDeploymentRuntime(options) {
27257
27457
  held = false;
27258
27458
  }
27259
27459
  register(void 0);
27260
- logger7.info("plugin deployment runtime stopped", { holder });
27460
+ logger8.info("plugin deployment runtime stopped", { holder });
27261
27461
  }
27262
27462
  };
27263
27463
  }
27264
- async function runStartupReconcile(service2, deadlineMs, logger7, holder) {
27464
+ async function runStartupReconcile(service2, deadlineMs, logger8, holder) {
27265
27465
  try {
27266
27466
  await withDeadline(service2.startupReconcile(), deadlineMs);
27267
- logger7.info("plugin deployment startup reconcile complete", { holder });
27467
+ logger8.info("plugin deployment startup reconcile complete", { holder });
27268
27468
  } catch (error) {
27269
- logger7.warn("plugin deployment startup reconcile failed", {
27469
+ logger8.warn("plugin deployment startup reconcile failed", {
27270
27470
  holder,
27271
27471
  error: errorMessage5(error)
27272
27472
  });
@@ -27289,7 +27489,7 @@ async function withDeadline(work, deadlineMs) {
27289
27489
  if (timer !== void 0) clearTimeout(timer);
27290
27490
  }
27291
27491
  }
27292
- async function acquireLease(lease, holder, logger7) {
27492
+ async function acquireLease(lease, holder, logger8) {
27293
27493
  try {
27294
27494
  return await lease.tryAcquire(
27295
27495
  PLUGIN_DEPLOYMENT_LEASE_KEY,
@@ -27297,14 +27497,14 @@ async function acquireLease(lease, holder, logger7) {
27297
27497
  PLUGIN_DEPLOYMENT_LEASE_TTL_MS
27298
27498
  );
27299
27499
  } catch (error) {
27300
- logger7.warn("plugin deployment lease acquire failed", {
27500
+ logger8.warn("plugin deployment lease acquire failed", {
27301
27501
  holder,
27302
27502
  error: errorMessage5(error)
27303
27503
  });
27304
27504
  return false;
27305
27505
  }
27306
27506
  }
27307
- async function renewLease(lease, holder, logger7) {
27507
+ async function renewLease(lease, holder, logger8) {
27308
27508
  try {
27309
27509
  return await lease.renew(
27310
27510
  PLUGIN_DEPLOYMENT_LEASE_KEY,
@@ -27312,18 +27512,18 @@ async function renewLease(lease, holder, logger7) {
27312
27512
  PLUGIN_DEPLOYMENT_LEASE_TTL_MS
27313
27513
  );
27314
27514
  } catch (error) {
27315
- logger7.warn("plugin deployment lease renew failed", {
27515
+ logger8.warn("plugin deployment lease renew failed", {
27316
27516
  holder,
27317
27517
  error: errorMessage5(error)
27318
27518
  });
27319
27519
  return false;
27320
27520
  }
27321
27521
  }
27322
- async function runWatchdog(service2, holder, logger7) {
27522
+ async function runWatchdog(service2, holder, logger8) {
27323
27523
  try {
27324
27524
  await service2.healthWatchdog();
27325
27525
  } catch (error) {
27326
- logger7.warn("plugin deployment health watchdog failed", {
27526
+ logger8.warn("plugin deployment health watchdog failed", {
27327
27527
  holder,
27328
27528
  error: errorMessage5(error)
27329
27529
  });
@@ -27361,29 +27561,29 @@ function storeClassName(kind) {
27361
27561
  return void 0;
27362
27562
  }
27363
27563
  }
27364
- function warnMultiReplicaReadiness(logger7) {
27564
+ function warnMultiReplicaReadiness(logger8) {
27365
27565
  if (typeof process.env.AXIOM_REPLICA_ID !== "string" || process.env.AXIOM_REPLICA_ID.trim() === "") return;
27366
27566
  for (const kind of SHARED_STORE_KINDS) {
27367
27567
  const name = storeClassName(kind);
27368
27568
  if (name === void 0 || !name.startsWith("InMemory")) continue;
27369
- logger7.warn(`Multi-replica: store '${kind}' is ${name} (not shared); configure a shared store`, {
27569
+ logger8.warn(`Multi-replica: store '${kind}' is ${name} (not shared); configure a shared store`, {
27370
27570
  phase: "multi_replica_readiness",
27371
27571
  store: kind
27372
27572
  });
27373
27573
  }
27374
27574
  if (!process.env.AUTH_TOKEN_SECRET?.trim() && !process.env.JWT_SECRET?.trim()) {
27375
- logger7.warn(
27575
+ logger8.warn(
27376
27576
  "Multi-replica: AUTH_TOKEN_SECRET/JWT_SECRET unset; console sessions are signed per-process and will not verify across replicas",
27377
27577
  { phase: "multi_replica_readiness", env: "AUTH_TOKEN_SECRET" }
27378
27578
  );
27379
27579
  }
27380
27580
  if (!process.env.LATTICE_ENCRYPTION_KEY?.trim()) {
27381
- logger7.warn(
27581
+ logger8.warn(
27382
27582
  "Multi-replica: LATTICE_ENCRYPTION_KEY unset; stored credentials use the shared dev default and may not decrypt across differing keys",
27383
27583
  { phase: "multi_replica_readiness", env: "LATTICE_ENCRYPTION_KEY" }
27384
27584
  );
27385
27585
  }
27386
- logger7.warn(
27586
+ logger8.warn(
27387
27587
  "Multi-replica: agent run SSE and resume_stream are process-local; route a thread's follow-up runs to the replica streaming it (sticky routing) or share the stream/queue state",
27388
27588
  { phase: "multi_replica_readiness", feature: "agent-run-sse" }
27389
27589
  );
@@ -27524,7 +27724,7 @@ var DEFAULT_LOGGER_CONFIG = {
27524
27724
  loggerName: "lattice/gateway"
27525
27725
  };
27526
27726
  var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
27527
- var logger6 = loggerLattice.client;
27727
+ var logger7 = loggerLattice.client;
27528
27728
  function initializeLogger(config) {
27529
27729
  if (loggerLatticeManager.hasLattice("default")) {
27530
27730
  loggerLatticeManager.removeLattice("default");
@@ -27611,7 +27811,7 @@ app.setErrorHandler((error, request, reply) => {
27611
27811
  "x-request-id": getHeaderValue(request.headers["x-request-id"]),
27612
27812
  "x-user-id": getHeaderValue(request.headers["x-user-id"])
27613
27813
  };
27614
- logger6.error(
27814
+ logger7.error(
27615
27815
  `\u8BF7\u6C42\u9519\u8BEF: ${request.method} ${request.url} error:${error.message}`,
27616
27816
  {
27617
27817
  ...context,
@@ -27647,14 +27847,14 @@ async function restoreMcpConnections() {
27647
27847
  const storeLattice = getStoreLattice30("default", "mcp");
27648
27848
  const store = storeLattice.store;
27649
27849
  if (!store) {
27650
- logger6.info("MCP store not configured, skipping connection restoration");
27850
+ logger7.info("MCP store not configured, skipping connection restoration");
27651
27851
  return;
27652
27852
  }
27653
27853
  const configs = (await store.getAllConfigsWithoutTenant()).filter(
27654
27854
  (c2) => c2.status === "connected"
27655
27855
  );
27656
27856
  if (configs.length === 0) return;
27657
- logger6.info(`Restoring ${configs.length} MCP server connections...`);
27857
+ logger7.info(`Restoring ${configs.length} MCP server connections...`);
27658
27858
  const deps = {
27659
27859
  store,
27660
27860
  manager: mcpManager3,
@@ -27671,15 +27871,15 @@ async function restoreMcpConnections() {
27671
27871
  results.forEach((result, index) => {
27672
27872
  if (result.status === "rejected") {
27673
27873
  const config = configs[index];
27674
- logger6.warn(
27874
+ logger7.warn(
27675
27875
  `Failed to restore MCP server "${config.tenantId}/${config.key}"`,
27676
27876
  { error: result.reason }
27677
27877
  );
27678
27878
  }
27679
27879
  });
27680
- logger6.info(`MCP connection restoration complete: ${configs.length} servers`);
27880
+ logger7.info(`MCP connection restoration complete: ${configs.length} servers`);
27681
27881
  } catch (err) {
27682
- logger6.error("MCP connection restoration failed", { error: err });
27882
+ logger7.error("MCP connection restoration failed", { error: err });
27683
27883
  }
27684
27884
  }
27685
27885
  var start = async (config) => {
@@ -27692,7 +27892,7 @@ var start = async (config) => {
27692
27892
  file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
27693
27893
  };
27694
27894
  loggerLattice = initializeLogger(loggerConfig);
27695
- logger6 = loggerLattice.client;
27895
+ logger7 = loggerLattice.client;
27696
27896
  }
27697
27897
  app.decorate("loggerLattice", loggerLattice);
27698
27898
  const projectRoomRealtimeMode = resolveProjectRoomRealtimeMode();
@@ -27702,12 +27902,13 @@ var start = async (config) => {
27702
27902
  tasks: getStoreLattice30("default", "task").store,
27703
27903
  rooms: getStoreLattice30("default", "projectRoom").store,
27704
27904
  memberships: getStoreLattice30("default", "projectBotMembership").store,
27705
- log: { warn: (message, context) => logger6.warn(message, context) }
27905
+ log: { warn: (message, context) => logger7.warn(message, context) }
27706
27906
  });
27707
27907
  }
27708
27908
  let channelDeps;
27709
27909
  const adapterRegistry = new ChannelAdapterRegistry();
27710
27910
  adapterRegistry.register(larkChannelAdapter);
27911
+ adapterRegistry.register(wecomChannelAdapter);
27711
27912
  const { wechatChannelAdapter } = await import("./WechatChannelAdapter-7WHE5UGY.mjs");
27712
27913
  adapterRegistry.register(wechatChannelAdapter);
27713
27914
  try {
@@ -27720,7 +27921,7 @@ var start = async (config) => {
27720
27921
  createRateLimitMiddleware(),
27721
27922
  createAuditLoggerMiddleware()
27722
27923
  ],
27723
- warn: (message, context) => logger6.warn(message, context),
27924
+ warn: (message, context) => logger7.warn(message, context),
27724
27925
  realtime: projectRoomRealtimeRuntime?.publisher
27725
27926
  });
27726
27927
  const bindingStore = infrastructure.bindingRegistry;
@@ -27734,10 +27935,10 @@ var start = async (config) => {
27734
27935
  installationStore,
27735
27936
  bindingRegistry: bindingStore,
27736
27937
  realtime: projectRoomRealtimeRuntime?.publisher,
27737
- warn: (message, context) => logger6.warn(message, context)
27938
+ warn: (message, context) => logger7.warn(message, context)
27738
27939
  };
27739
27940
  } catch (err) {
27740
- logger6.warn("Channel infrastructure unavailable", {
27941
+ logger7.warn("Channel infrastructure unavailable", {
27741
27942
  error: err instanceof Error ? err.message : String(err)
27742
27943
  });
27743
27944
  }
@@ -27745,7 +27946,7 @@ var start = async (config) => {
27745
27946
  try {
27746
27947
  const menuStore = getStoreLattice30("default", "menu").store;
27747
27948
  setMenuRegistry(menuStore);
27748
- logger6.info("Menu registry initialized");
27949
+ logger7.info("Menu registry initialized");
27749
27950
  } catch {
27750
27951
  }
27751
27952
  registerAllBuiltinEntities();
@@ -27754,7 +27955,7 @@ var start = async (config) => {
27754
27955
  }
27755
27956
  const routes = registerLatticeRoutes(app, channelDeps, {
27756
27957
  projectTaskEnabled: process.env.AXIOM_PROJECT_TASK_EXECUTION_ENABLED !== "false",
27757
- projectTaskLog: { warn: (message, context) => logger6.warn(message, context) },
27958
+ projectTaskLog: { warn: (message, context) => logger7.warn(message, context) },
27758
27959
  projectRoomRealtimeRuntime
27759
27960
  });
27760
27961
  try {
@@ -27782,9 +27983,9 @@ var start = async (config) => {
27782
27983
  getProjectStore: () => projectStore
27783
27984
  });
27784
27985
  a2a.registerA2ARoutes(app);
27785
- logger6.info("A2A standard routes registered");
27986
+ logger7.info("A2A standard routes registered");
27786
27987
  } catch (err) {
27787
- logger6.warn("A2A standard routes unavailable", {
27988
+ logger7.warn("A2A standard routes unavailable", {
27788
27989
  error: err instanceof Error ? err.message : String(err)
27789
27990
  });
27790
27991
  }
@@ -27821,26 +28022,26 @@ var start = async (config) => {
27821
28022
  registerOpenFilesRoutes(app);
27822
28023
  registerOpenAuditRoutes(app);
27823
28024
  registerOpenExposureRoutes(app);
27824
- logger6.info("Open API routes registered (kb + sandbox providers, session exchange)");
28025
+ logger7.info("Open API routes registered (kb + sandbox providers, session exchange)");
27825
28026
  } catch (err) {
27826
- logger6.warn("Open API routes unavailable", {
28027
+ logger7.warn("Open API routes unavailable", {
27827
28028
  error: err instanceof Error ? err.message : String(err)
27828
28029
  });
27829
28030
  }
27830
28031
  try {
27831
28032
  const { registerGatewaySandboxOpenCredentialProvider } = await import("./sandboxOpenCredentialProvider-USIU7Z7H.mjs");
27832
28033
  registerGatewaySandboxOpenCredentialProvider((error) => {
27833
- logger6.warn("sandbox open-credential provider failed", { error });
28034
+ logger7.warn("sandbox open-credential provider failed", { error });
27834
28035
  });
27835
- logger6.info("Sandbox open-credential provider registered");
28036
+ logger7.info("Sandbox open-credential provider registered");
27836
28037
  } catch (err) {
27837
- logger6.warn("Sandbox open-credential provider unavailable", {
28038
+ logger7.warn("Sandbox open-credential provider unavailable", {
27838
28039
  error: err instanceof Error ? err.message : String(err)
27839
28040
  });
27840
28041
  }
27841
28042
  if (!sandboxLatticeManager2.hasLattice("default")) {
27842
28043
  sandboxLatticeManager2.registerLattice("default", getConfiguredSandboxProvider());
27843
- logger6.info("Registered sandbox manager from env configuration");
28044
+ logger7.info("Registered sandbox manager from env configuration");
27844
28045
  }
27845
28046
  if (isPluginDeploymentRuntimeEnabled()) {
27846
28047
  try {
@@ -27867,21 +28068,21 @@ var start = async (config) => {
27867
28068
  listAllDeployments,
27868
28069
  // The service logs fields-first; the gateway logger is message-first.
27869
28070
  logger: {
27870
- info: (fields, message) => logger6.info(message ?? "plugin deployment", fields),
27871
- warn: (fields, message) => logger6.warn(message ?? "plugin deployment", fields),
27872
- error: (fields, message) => logger6.error(message ?? "plugin deployment", fields)
28071
+ info: (fields, message) => logger7.info(message ?? "plugin deployment", fields),
28072
+ warn: (fields, message) => logger7.warn(message ?? "plugin deployment", fields),
28073
+ error: (fields, message) => logger7.error(message ?? "plugin deployment", fields)
27873
28074
  }
27874
28075
  },
27875
28076
  lease: leaseStore2,
27876
28077
  holder: getReplicaId7(),
27877
- logger: logger6
28078
+ logger: logger7
27878
28079
  });
27879
28080
  app.addHook("onClose", async () => {
27880
28081
  await pluginDeploymentRuntime.dispose();
27881
28082
  });
27882
- logger6.info("Plugin deployment runtime started");
28083
+ logger7.info("Plugin deployment runtime started");
27883
28084
  } catch (err) {
27884
- logger6.warn("Plugin deployment runtime unavailable", {
28085
+ logger7.warn("Plugin deployment runtime unavailable", {
27885
28086
  error: err instanceof Error ? err.message : String(err)
27886
28087
  });
27887
28088
  }
@@ -27894,12 +28095,12 @@ var start = async (config) => {
27894
28095
  store: sharedResourceStore,
27895
28096
  sandboxManager: sandboxLatticeManager2,
27896
28097
  cache,
27897
- logger: logger6
28098
+ logger: logger7
27898
28099
  });
27899
28100
  registerResourceRoutes(app, resourceController);
27900
- logger6.info("Resource share routes registered");
28101
+ logger7.info("Resource share routes registered");
27901
28102
  } catch (err) {
27902
- logger6.warn("Resource share infrastructure unavailable", {
28103
+ logger7.warn("Resource share infrastructure unavailable", {
27903
28104
  error: err instanceof Error ? err.message : String(err)
27904
28105
  });
27905
28106
  }
@@ -27912,14 +28113,14 @@ var start = async (config) => {
27912
28113
  deps: { router: channelDeps.router }
27913
28114
  }),
27914
28115
  disconnect: () => disconnectAllChannels((channel) => adapterRegistry.get(channel)),
27915
- log: { warn: (message, context) => logger6.warn(message, context) }
28116
+ log: { warn: (message, context) => logger7.warn(message, context) }
27916
28117
  });
27917
28118
  app.addHook("onClose", async () => {
27918
28119
  await channelLeader.stop();
27919
28120
  });
27920
28121
  channelLeader.start();
27921
28122
  } catch (err) {
27922
- logger6.error("Failed to start channel connections", {
28123
+ logger7.error("Failed to start channel connections", {
27923
28124
  error: err instanceof Error ? err.message : String(err)
27924
28125
  });
27925
28126
  }
@@ -27966,24 +28167,24 @@ var start = async (config) => {
27966
28167
  await handleModelProviderChanged(payload, (tenantId, providerId2) => controller.reconcileProvider(tenantId, providerId2));
27967
28168
  }
27968
28169
  },
27969
- log: logger6
28170
+ log: logger7
27970
28171
  });
27971
28172
  try {
27972
28173
  await outboxPoller.start();
27973
28174
  } catch (err) {
27974
- logger6.warn("Outbox poller failed to start", { error: err instanceof Error ? err.message : String(err) });
28175
+ logger7.warn("Outbox poller failed to start", { error: err instanceof Error ? err.message : String(err) });
27975
28176
  }
27976
28177
  const leaseStore = getStoreLattice30("default", "lease").store;
27977
28178
  if (leaseStore.constructor?.name === "InMemoryLeaseStore") {
27978
- logger6.warn(
28179
+ logger7.warn(
27979
28180
  "Startup recovery leader gate uses a non-distributed lease store (per-process only); configure a shared 'lease' store for multi-replica deployments",
27980
28181
  { phase: "startup_recovery" }
27981
28182
  );
27982
28183
  }
27983
- warnMultiReplicaReadiness(logger6);
28184
+ warnMultiReplicaReadiness(logger7);
27984
28185
  const startup = await runAsLeader(leaseStore, "startup-recovery", async () => {
27985
28186
  if (routes.projectTaskRuntime) {
27986
- await prepareProjectTaskRuntime(routes.projectTaskRuntime, logger6);
28187
+ await prepareProjectTaskRuntime(routes.projectTaskRuntime, logger7);
27987
28188
  }
27988
28189
  if (process.env.AXIOM_TASK_ORPHAN_RECOVERY === "true") {
27989
28190
  try {
@@ -27994,19 +28195,19 @@ var start = async (config) => {
27994
28195
  workItemStore: getStoreLattice30("default", "taskWorkItem").store,
27995
28196
  tenantStore: getStoreLattice30("default", "tenant").store,
27996
28197
  ...createRecoveryCallerDeps2(),
27997
- log: logger6
28198
+ log: logger7
27998
28199
  });
27999
28200
  await runtime.recoverAll();
28000
28201
  } catch (err) {
28001
- logger6.warn("Task orphan recovery failed", { error: err instanceof Error ? err.message : String(err) });
28202
+ logger7.warn("Task orphan recovery failed", { error: err instanceof Error ? err.message : String(err) });
28002
28203
  }
28003
28204
  }
28004
28205
  if (scheduleLatticeManager2.hasLattice("default")) {
28005
28206
  try {
28006
28207
  const restored = await scheduleLatticeManager2.getScheduleLattice("default").restore();
28007
- logger6.info("Scheduled tasks restored", { phase: "startup_recovery", restored });
28208
+ logger7.info("Scheduled tasks restored", { phase: "startup_recovery", restored });
28008
28209
  } catch (err) {
28009
- logger6.warn("Scheduled task restore failed", {
28210
+ logger7.warn("Scheduled task restore failed", {
28010
28211
  phase: "startup_recovery",
28011
28212
  error: err instanceof Error ? err.message : String(err)
28012
28213
  });
@@ -28014,13 +28215,13 @@ var start = async (config) => {
28014
28215
  }
28015
28216
  }, { hold: true, ttlMs: 5 * 6e4 });
28016
28217
  if (!startup.ran) {
28017
- logger6.info("Startup recovery skipped (another replica leads)", { phase: "startup_recovery" });
28218
+ logger7.info("Startup recovery skipped (another replica leads)", { phase: "startup_recovery" });
28018
28219
  }
28019
28220
  await app.listen({ port: target_port, host: "0.0.0.0" });
28020
- logger6.info(`Lattice Gateway is running on port: ${target_port}`);
28221
+ logger7.info(`Lattice Gateway is running on port: ${target_port}`);
28021
28222
  const outboxRetention = createOutboxRetentionJob({
28022
28223
  outbox: outboxStore,
28023
- log: logger6
28224
+ log: logger7
28024
28225
  });
28025
28226
  outboxRetention.start();
28026
28227
  let agentTaskConsumer;
@@ -28033,15 +28234,15 @@ var start = async (config) => {
28033
28234
  }
28034
28235
  }
28035
28236
  restoreMcpConnections().catch((error) => {
28036
- logger6.error("MCP connection restoration failed", { error });
28237
+ logger7.error("MCP connection restoration failed", { error });
28037
28238
  });
28038
28239
  if (config?.gracefulShutdown !== false && !shutdownHandlersInstalled) {
28039
28240
  shutdownHandlersInstalled = true;
28040
28241
  const gracefulShutdown = createGracefulShutdown({
28041
28242
  timeoutMs: config?.gracefulShutdownTimeoutMs ?? 1e4,
28042
28243
  log: {
28043
- info: (message, context) => logger6.info(message, context),
28044
- warn: (message, context) => logger6.warn(message, context)
28244
+ info: (message, context) => logger7.info(message, context),
28245
+ warn: (message, context) => logger7.warn(message, context)
28045
28246
  },
28046
28247
  steps: [
28047
28248
  async () => {
@@ -28059,7 +28260,7 @@ var start = async (config) => {
28059
28260
  process.once("SIGINT", () => void gracefulShutdown("SIGINT"));
28060
28261
  }
28061
28262
  } catch (err) {
28062
- logger6.error("Server start failed", { error: err });
28263
+ logger7.error("Server start failed", { error: err });
28063
28264
  process.exit(1);
28064
28265
  }
28065
28266
  };