@axiom-lattice/gateway 4.9.2 → 4.10.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.
- package/dist/embed/{embed-page-AgentDetailSideApp-WQAMMDXN.js → embed-page-AgentDetailSideApp-GH3XNS5A.js} +1 -1
- package/dist/embed/{embed-page-AgentGovernanceWorkbench-VKD4IZIO.js → embed-page-AgentGovernanceWorkbench-AXHLZTUG.js} +1 -1
- package/dist/embed/{embed-page-MessageGraph-C4EJWY3E.js → embed-page-MessageGraph-HLLPBTLQ.js} +1 -1
- package/dist/embed/{embed-page-ReactChart-TNT4TT4C.js → embed-page-ReactChart-46EYPRQ7.js} +1 -1
- package/dist/embed/{embed-page-SkillFlow-WWRDU6GS.js → embed-page-SkillFlow-NMUDTNTY.js} +1 -1
- package/dist/embed/{embed-page-TasksSideApp-73SJLGRY.js → embed-page-TasksSideApp-DOCKHJCF.js} +1 -1
- package/dist/embed/{embed-page-TeamWorkspace-6E4HAH7L.js → embed-page-TeamWorkspace-LXOIMYRW.js} +1 -1
- package/dist/embed/{embed-page-TopologyRuntimeView-SXUNRFT4.js → embed-page-TopologyRuntimeView-DT7XXEK2.js} +1 -1
- package/dist/embed/{embed-page-WorkflowAutomationView-I4VN6YY2.js → embed-page-WorkflowAutomationView-ONAY4RTM.js} +1 -1
- package/dist/embed/{embed-page-chunk-G5NEOKZK.js → embed-page-chunk-F7G2DME5.js} +1 -1
- package/dist/embed/{embed-page-chunk-WUOHF2QZ.js → embed-page-chunk-H4W4NDIY.js} +1 -1
- package/dist/embed/{embed-page-chunk-YZMHK63X.js → embed-page-chunk-JQSBSZMP.js} +1 -1
- package/dist/embed/{embed-page-chunk-IM57IYUL.js → embed-page-chunk-LGZUYB7B.js} +1 -1
- package/dist/embed/{embed-page-chunk-RQXI6NQX.js → embed-page-chunk-NR2PTMJ6.js} +1 -1
- package/dist/embed/{embed-page-chunk-TEIHYMTL.js → embed-page-chunk-OY4CDWED.js} +7 -7
- package/dist/embed/{embed-page-chunk-L7HKGCDN.js → embed-page-chunk-RA35MUYW.js} +1 -1
- package/dist/embed/{embed-page-en-GE4GI4D3.js → embed-page-en-ICVL5QAC.js} +1 -1
- package/dist/embed/{embed-page-zh-KC2E7UVY.js → embed-page-zh-FPYCTKQK.js} +1 -1
- package/dist/embed/embed-page.js +1 -1
- package/dist/index.js +326 -129
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +274 -78
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -7
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,191 @@ 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 { z as z12 } from "zod";
|
|
25325
|
+
import * as WecomAiBot from "@wecom/aibot-node-sdk";
|
|
25326
|
+
|
|
25327
|
+
// src/channels/wecom/parser.ts
|
|
25328
|
+
function parseWecomTextFrame(frame) {
|
|
25329
|
+
if (!frame || typeof frame !== "object") return null;
|
|
25330
|
+
const { headers, body } = frame;
|
|
25331
|
+
const reqId = headers?.req_id;
|
|
25332
|
+
if (typeof reqId !== "string" || !body) return null;
|
|
25333
|
+
if (body.msgtype !== "text") return null;
|
|
25334
|
+
const fromUserId = body.from?.userid;
|
|
25335
|
+
const content = body.text?.content;
|
|
25336
|
+
if (typeof fromUserId !== "string" || typeof content !== "string") {
|
|
25337
|
+
return null;
|
|
25338
|
+
}
|
|
25339
|
+
return {
|
|
25340
|
+
reqId,
|
|
25341
|
+
msgId: typeof body.msgid === "string" ? body.msgid : "",
|
|
25342
|
+
fromUserId,
|
|
25343
|
+
chatId: typeof body.chatid === "string" ? body.chatid : void 0,
|
|
25344
|
+
chatType: body.chattype === "group" ? "group" : "direct",
|
|
25345
|
+
text: content
|
|
25346
|
+
};
|
|
25347
|
+
}
|
|
25348
|
+
|
|
25349
|
+
// src/channels/wecom/WecomChannelAdapter.ts
|
|
25350
|
+
var logger6 = new Logger({ serviceName: "lattice/gateway/wecom" });
|
|
25351
|
+
var wecomConfigSchema = z12.object({
|
|
25352
|
+
botId: z12.string(),
|
|
25353
|
+
secret: z12.string()
|
|
25354
|
+
});
|
|
25355
|
+
var RECONNECT_BASE_MS = 5e3;
|
|
25356
|
+
var RECONNECT_MAX_MS = 6e4;
|
|
25357
|
+
var activeConnections2 = /* @__PURE__ */ new Map();
|
|
25358
|
+
var wecomChannelAdapter = {
|
|
25359
|
+
channel: "wecom",
|
|
25360
|
+
configSchema: wecomConfigSchema,
|
|
25361
|
+
async receive(rawPayload, installation) {
|
|
25362
|
+
const parsed = parseWecomTextFrame(rawPayload);
|
|
25363
|
+
if (!parsed) return null;
|
|
25364
|
+
return {
|
|
25365
|
+
channel: "wecom",
|
|
25366
|
+
channelInstallationId: installation.id,
|
|
25367
|
+
tenantId: installation.tenantId,
|
|
25368
|
+
sender: { id: parsed.fromUserId },
|
|
25369
|
+
content: {
|
|
25370
|
+
text: parsed.text,
|
|
25371
|
+
// `messageId` 供去重中间件使用(企业微信可能重投同一 msgid)。
|
|
25372
|
+
metadata: {
|
|
25373
|
+
messageId: parsed.msgId,
|
|
25374
|
+
chatId: parsed.chatId,
|
|
25375
|
+
chatType: parsed.chatType
|
|
25376
|
+
}
|
|
25377
|
+
},
|
|
25378
|
+
conversation: {
|
|
25379
|
+
id: parsed.chatId ?? parsed.fromUserId,
|
|
25380
|
+
type: parsed.chatType
|
|
25381
|
+
},
|
|
25382
|
+
replyTarget: {
|
|
25383
|
+
adapterChannel: "wecom",
|
|
25384
|
+
channelInstallationId: installation.id,
|
|
25385
|
+
// 回复需原样带回入站帧(含 `headers.req_id`)。frame 是纯 JSON,
|
|
25386
|
+
// replyTarget 仅在内存流转,不落库。
|
|
25387
|
+
rawTarget: { frame: rawPayload }
|
|
25388
|
+
}
|
|
25389
|
+
};
|
|
25390
|
+
},
|
|
25391
|
+
async sendReply(replyTarget, message, installation) {
|
|
25392
|
+
const connection = activeConnections2.get(installation.id);
|
|
25393
|
+
if (!connection) {
|
|
25394
|
+
logger6.warn("WeCom bot not connected, cannot reply", {
|
|
25395
|
+
installationId: installation.id
|
|
25396
|
+
});
|
|
25397
|
+
return;
|
|
25398
|
+
}
|
|
25399
|
+
connection.client.reply(replyTarget.rawTarget.frame, {
|
|
25400
|
+
msgtype: "text",
|
|
25401
|
+
text: { content: message.text }
|
|
25402
|
+
});
|
|
25403
|
+
},
|
|
25404
|
+
resolveThreadId(message, binding) {
|
|
25405
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
25406
|
+
const agentId = binding.agentId;
|
|
25407
|
+
if (message.conversation?.type === "group") {
|
|
25408
|
+
return `wecom:group:${message.conversation.id}:${agentId}:${date}`;
|
|
25409
|
+
}
|
|
25410
|
+
return `wecom:dm:${message.sender.id}:${agentId}:${date}`;
|
|
25411
|
+
},
|
|
25412
|
+
async connect(installation, deps) {
|
|
25413
|
+
const { id: installationId, tenantId, config } = installation;
|
|
25414
|
+
if (!config.botId || !config.secret) {
|
|
25415
|
+
logger6.warn("WeCom installation missing botId/secret, skipping", { installationId });
|
|
25416
|
+
return;
|
|
25417
|
+
}
|
|
25418
|
+
if (activeConnections2.has(installationId)) {
|
|
25419
|
+
logger6.warn("WeCom long connection already running, skipping", { installationId });
|
|
25420
|
+
return;
|
|
25421
|
+
}
|
|
25422
|
+
const { router, wsClientFactory } = deps ?? {};
|
|
25423
|
+
const client = (wsClientFactory ?? createDefaultWecomClient)(config);
|
|
25424
|
+
const connection = { client, intentional: false, attempts: 0 };
|
|
25425
|
+
client.on("message.text", (frame) => {
|
|
25426
|
+
wecomChannelAdapter.receive(frame, installation).then((inbound) => {
|
|
25427
|
+
if (!inbound || !router) return void 0;
|
|
25428
|
+
return router.dispatch(inbound);
|
|
25429
|
+
}).catch((error) => {
|
|
25430
|
+
logger6.error("WeCom message dispatch error", {
|
|
25431
|
+
installationId,
|
|
25432
|
+
error: error instanceof Error ? error.message : String(error)
|
|
25433
|
+
});
|
|
25434
|
+
});
|
|
25435
|
+
});
|
|
25436
|
+
client.on("authenticated", () => {
|
|
25437
|
+
connection.attempts = 0;
|
|
25438
|
+
});
|
|
25439
|
+
client.on("event.disconnected_event", () => {
|
|
25440
|
+
logger6.warn("WeCom connection kicked by a newer connection; will reconnect", {
|
|
25441
|
+
installationId
|
|
25442
|
+
});
|
|
25443
|
+
scheduleReconnect(installationId, connection);
|
|
25444
|
+
});
|
|
25445
|
+
activeConnections2.set(installationId, connection);
|
|
25446
|
+
client.connect();
|
|
25447
|
+
logger6.info("WeCom long connection starting", { installationId, tenantId });
|
|
25448
|
+
},
|
|
25449
|
+
async disconnect(installationId) {
|
|
25450
|
+
const connection = activeConnections2.get(installationId);
|
|
25451
|
+
if (!connection) {
|
|
25452
|
+
logger6.warn("WeCom long connection not running, nothing to disconnect", { installationId });
|
|
25453
|
+
return;
|
|
25454
|
+
}
|
|
25455
|
+
connection.intentional = true;
|
|
25456
|
+
if (connection.timer) {
|
|
25457
|
+
clearTimeout(connection.timer);
|
|
25458
|
+
connection.timer = void 0;
|
|
25459
|
+
}
|
|
25460
|
+
try {
|
|
25461
|
+
connection.client.disconnect();
|
|
25462
|
+
} catch (error) {
|
|
25463
|
+
logger6.error("WeCom long connection stop error", {
|
|
25464
|
+
installationId,
|
|
25465
|
+
error: error instanceof Error ? error.message : String(error)
|
|
25466
|
+
});
|
|
25467
|
+
}
|
|
25468
|
+
activeConnections2.delete(installationId);
|
|
25469
|
+
logger6.info("WeCom long connection disconnected", { installationId });
|
|
25470
|
+
}
|
|
25471
|
+
};
|
|
25472
|
+
function scheduleReconnect(installationId, connection) {
|
|
25473
|
+
if (connection.intentional || connection.timer) return;
|
|
25474
|
+
const delay2 = Math.min(RECONNECT_BASE_MS * 2 ** connection.attempts, RECONNECT_MAX_MS);
|
|
25475
|
+
connection.attempts += 1;
|
|
25476
|
+
logger6.info("WeCom reconnect scheduled", {
|
|
25477
|
+
installationId,
|
|
25478
|
+
delayMs: delay2,
|
|
25479
|
+
attempt: connection.attempts
|
|
25480
|
+
});
|
|
25481
|
+
const timer = setTimeout(() => {
|
|
25482
|
+
connection.timer = void 0;
|
|
25483
|
+
if (connection.intentional || activeConnections2.get(installationId) !== connection) {
|
|
25484
|
+
return;
|
|
25485
|
+
}
|
|
25486
|
+
try {
|
|
25487
|
+
connection.client.connect();
|
|
25488
|
+
} catch (error) {
|
|
25489
|
+
logger6.error("WeCom reconnect failed", {
|
|
25490
|
+
installationId,
|
|
25491
|
+
error: error instanceof Error ? error.message : String(error)
|
|
25492
|
+
});
|
|
25493
|
+
scheduleReconnect(installationId, connection);
|
|
25494
|
+
}
|
|
25495
|
+
}, delay2);
|
|
25496
|
+
timer.unref?.();
|
|
25497
|
+
connection.timer = timer;
|
|
25498
|
+
}
|
|
25499
|
+
function createDefaultWecomClient(config) {
|
|
25500
|
+
return new WecomAiBot.WSClient({
|
|
25501
|
+
botId: config.botId,
|
|
25502
|
+
secret: config.secret,
|
|
25503
|
+
// 断网无限重连;被踢(disconnected_event)由 scheduleReconnect 兜底。
|
|
25504
|
+
maxReconnectAttempts: -1
|
|
25505
|
+
});
|
|
25506
|
+
}
|
|
25507
|
+
|
|
25313
25508
|
// src/swagger.ts
|
|
25314
25509
|
import swagger from "@fastify/swagger";
|
|
25315
25510
|
import swaggerUi from "@fastify/swagger-ui";
|
|
@@ -26299,9 +26494,9 @@ var MessageRouter = class {
|
|
|
26299
26494
|
};
|
|
26300
26495
|
|
|
26301
26496
|
// src/channels/room/RoomChannelAdapter.ts
|
|
26302
|
-
import { z as
|
|
26497
|
+
import { z as z13 } from "zod";
|
|
26303
26498
|
import { snapshotExactRecord as snapshotExactRecord16 } from "@axiom-lattice/protocols";
|
|
26304
|
-
var roomConfigSchema =
|
|
26499
|
+
var roomConfigSchema = z13.object({}).strict();
|
|
26305
26500
|
function createRoomChannelAdapter(writer) {
|
|
26306
26501
|
return {
|
|
26307
26502
|
channel: "room",
|
|
@@ -27190,11 +27385,11 @@ function readPluginDeploymentLimits(env = process.env) {
|
|
|
27190
27385
|
};
|
|
27191
27386
|
}
|
|
27192
27387
|
function startPluginDeploymentRuntime(options) {
|
|
27193
|
-
const { lease, holder, logger:
|
|
27388
|
+
const { lease, holder, logger: logger8 } = options;
|
|
27194
27389
|
const forcedOn = process.env[PLUGIN_DEPLOYMENT_RUNTIME_FLAG] === "true" || process.env[PLUGIN_DEPLOYMENT_RUNTIME_FLAG] === "1";
|
|
27195
27390
|
const effectiveServiceBaseUrl = options.wiring.serviceBaseUrl ?? process.env.MICROSANDBOX_SERVICE_BASE_URL;
|
|
27196
27391
|
if (forcedOn && !effectiveServiceBaseUrl) {
|
|
27197
|
-
|
|
27392
|
+
logger8.warn(
|
|
27198
27393
|
`${PLUGIN_DEPLOYMENT_RUNTIME_FLAG} is enabled but MICROSANDBOX_SERVICE_BASE_URL is empty; skipping plugin deployment runtime`,
|
|
27199
27394
|
{ holder }
|
|
27200
27395
|
);
|
|
@@ -27213,8 +27408,8 @@ function startPluginDeploymentRuntime(options) {
|
|
|
27213
27408
|
};
|
|
27214
27409
|
const service2 = createService(deps);
|
|
27215
27410
|
register(service2);
|
|
27216
|
-
|
|
27217
|
-
const reconcile = runStartupReconcile(service2, reconcileDeadlineMs,
|
|
27411
|
+
logger8.info("plugin deployment runtime started", { holder });
|
|
27412
|
+
const reconcile = runStartupReconcile(service2, reconcileDeadlineMs, logger8, holder);
|
|
27218
27413
|
let held = false;
|
|
27219
27414
|
let inFlight = false;
|
|
27220
27415
|
const tick = async () => {
|
|
@@ -27222,18 +27417,18 @@ function startPluginDeploymentRuntime(options) {
|
|
|
27222
27417
|
inFlight = true;
|
|
27223
27418
|
try {
|
|
27224
27419
|
if (held) {
|
|
27225
|
-
held = await renewLease(lease, holder,
|
|
27420
|
+
held = await renewLease(lease, holder, logger8);
|
|
27226
27421
|
if (!held) {
|
|
27227
|
-
|
|
27422
|
+
logger8.warn("plugin deployment lease lost; watchdog paused", { holder });
|
|
27228
27423
|
}
|
|
27229
27424
|
} else {
|
|
27230
|
-
held = await acquireLease(lease, holder,
|
|
27425
|
+
held = await acquireLease(lease, holder, logger8);
|
|
27231
27426
|
if (held) {
|
|
27232
|
-
|
|
27427
|
+
logger8.info("plugin deployment lease acquired", { holder });
|
|
27233
27428
|
}
|
|
27234
27429
|
}
|
|
27235
27430
|
if (!held) return;
|
|
27236
|
-
await runWatchdog(service2, holder,
|
|
27431
|
+
await runWatchdog(service2, holder, logger8);
|
|
27237
27432
|
} finally {
|
|
27238
27433
|
inFlight = false;
|
|
27239
27434
|
}
|
|
@@ -27249,7 +27444,7 @@ function startPluginDeploymentRuntime(options) {
|
|
|
27249
27444
|
try {
|
|
27250
27445
|
await lease.release(PLUGIN_DEPLOYMENT_LEASE_KEY, holder);
|
|
27251
27446
|
} catch (error) {
|
|
27252
|
-
|
|
27447
|
+
logger8.warn("plugin deployment lease release failed", {
|
|
27253
27448
|
holder,
|
|
27254
27449
|
error: errorMessage5(error)
|
|
27255
27450
|
});
|
|
@@ -27257,16 +27452,16 @@ function startPluginDeploymentRuntime(options) {
|
|
|
27257
27452
|
held = false;
|
|
27258
27453
|
}
|
|
27259
27454
|
register(void 0);
|
|
27260
|
-
|
|
27455
|
+
logger8.info("plugin deployment runtime stopped", { holder });
|
|
27261
27456
|
}
|
|
27262
27457
|
};
|
|
27263
27458
|
}
|
|
27264
|
-
async function runStartupReconcile(service2, deadlineMs,
|
|
27459
|
+
async function runStartupReconcile(service2, deadlineMs, logger8, holder) {
|
|
27265
27460
|
try {
|
|
27266
27461
|
await withDeadline(service2.startupReconcile(), deadlineMs);
|
|
27267
|
-
|
|
27462
|
+
logger8.info("plugin deployment startup reconcile complete", { holder });
|
|
27268
27463
|
} catch (error) {
|
|
27269
|
-
|
|
27464
|
+
logger8.warn("plugin deployment startup reconcile failed", {
|
|
27270
27465
|
holder,
|
|
27271
27466
|
error: errorMessage5(error)
|
|
27272
27467
|
});
|
|
@@ -27289,7 +27484,7 @@ async function withDeadline(work, deadlineMs) {
|
|
|
27289
27484
|
if (timer !== void 0) clearTimeout(timer);
|
|
27290
27485
|
}
|
|
27291
27486
|
}
|
|
27292
|
-
async function acquireLease(lease, holder,
|
|
27487
|
+
async function acquireLease(lease, holder, logger8) {
|
|
27293
27488
|
try {
|
|
27294
27489
|
return await lease.tryAcquire(
|
|
27295
27490
|
PLUGIN_DEPLOYMENT_LEASE_KEY,
|
|
@@ -27297,14 +27492,14 @@ async function acquireLease(lease, holder, logger7) {
|
|
|
27297
27492
|
PLUGIN_DEPLOYMENT_LEASE_TTL_MS
|
|
27298
27493
|
);
|
|
27299
27494
|
} catch (error) {
|
|
27300
|
-
|
|
27495
|
+
logger8.warn("plugin deployment lease acquire failed", {
|
|
27301
27496
|
holder,
|
|
27302
27497
|
error: errorMessage5(error)
|
|
27303
27498
|
});
|
|
27304
27499
|
return false;
|
|
27305
27500
|
}
|
|
27306
27501
|
}
|
|
27307
|
-
async function renewLease(lease, holder,
|
|
27502
|
+
async function renewLease(lease, holder, logger8) {
|
|
27308
27503
|
try {
|
|
27309
27504
|
return await lease.renew(
|
|
27310
27505
|
PLUGIN_DEPLOYMENT_LEASE_KEY,
|
|
@@ -27312,18 +27507,18 @@ async function renewLease(lease, holder, logger7) {
|
|
|
27312
27507
|
PLUGIN_DEPLOYMENT_LEASE_TTL_MS
|
|
27313
27508
|
);
|
|
27314
27509
|
} catch (error) {
|
|
27315
|
-
|
|
27510
|
+
logger8.warn("plugin deployment lease renew failed", {
|
|
27316
27511
|
holder,
|
|
27317
27512
|
error: errorMessage5(error)
|
|
27318
27513
|
});
|
|
27319
27514
|
return false;
|
|
27320
27515
|
}
|
|
27321
27516
|
}
|
|
27322
|
-
async function runWatchdog(service2, holder,
|
|
27517
|
+
async function runWatchdog(service2, holder, logger8) {
|
|
27323
27518
|
try {
|
|
27324
27519
|
await service2.healthWatchdog();
|
|
27325
27520
|
} catch (error) {
|
|
27326
|
-
|
|
27521
|
+
logger8.warn("plugin deployment health watchdog failed", {
|
|
27327
27522
|
holder,
|
|
27328
27523
|
error: errorMessage5(error)
|
|
27329
27524
|
});
|
|
@@ -27361,29 +27556,29 @@ function storeClassName(kind) {
|
|
|
27361
27556
|
return void 0;
|
|
27362
27557
|
}
|
|
27363
27558
|
}
|
|
27364
|
-
function warnMultiReplicaReadiness(
|
|
27559
|
+
function warnMultiReplicaReadiness(logger8) {
|
|
27365
27560
|
if (typeof process.env.AXIOM_REPLICA_ID !== "string" || process.env.AXIOM_REPLICA_ID.trim() === "") return;
|
|
27366
27561
|
for (const kind of SHARED_STORE_KINDS) {
|
|
27367
27562
|
const name = storeClassName(kind);
|
|
27368
27563
|
if (name === void 0 || !name.startsWith("InMemory")) continue;
|
|
27369
|
-
|
|
27564
|
+
logger8.warn(`Multi-replica: store '${kind}' is ${name} (not shared); configure a shared store`, {
|
|
27370
27565
|
phase: "multi_replica_readiness",
|
|
27371
27566
|
store: kind
|
|
27372
27567
|
});
|
|
27373
27568
|
}
|
|
27374
27569
|
if (!process.env.AUTH_TOKEN_SECRET?.trim() && !process.env.JWT_SECRET?.trim()) {
|
|
27375
|
-
|
|
27570
|
+
logger8.warn(
|
|
27376
27571
|
"Multi-replica: AUTH_TOKEN_SECRET/JWT_SECRET unset; console sessions are signed per-process and will not verify across replicas",
|
|
27377
27572
|
{ phase: "multi_replica_readiness", env: "AUTH_TOKEN_SECRET" }
|
|
27378
27573
|
);
|
|
27379
27574
|
}
|
|
27380
27575
|
if (!process.env.LATTICE_ENCRYPTION_KEY?.trim()) {
|
|
27381
|
-
|
|
27576
|
+
logger8.warn(
|
|
27382
27577
|
"Multi-replica: LATTICE_ENCRYPTION_KEY unset; stored credentials use the shared dev default and may not decrypt across differing keys",
|
|
27383
27578
|
{ phase: "multi_replica_readiness", env: "LATTICE_ENCRYPTION_KEY" }
|
|
27384
27579
|
);
|
|
27385
27580
|
}
|
|
27386
|
-
|
|
27581
|
+
logger8.warn(
|
|
27387
27582
|
"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
27583
|
{ phase: "multi_replica_readiness", feature: "agent-run-sse" }
|
|
27389
27584
|
);
|
|
@@ -27524,7 +27719,7 @@ var DEFAULT_LOGGER_CONFIG = {
|
|
|
27524
27719
|
loggerName: "lattice/gateway"
|
|
27525
27720
|
};
|
|
27526
27721
|
var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
|
|
27527
|
-
var
|
|
27722
|
+
var logger7 = loggerLattice.client;
|
|
27528
27723
|
function initializeLogger(config) {
|
|
27529
27724
|
if (loggerLatticeManager.hasLattice("default")) {
|
|
27530
27725
|
loggerLatticeManager.removeLattice("default");
|
|
@@ -27611,7 +27806,7 @@ app.setErrorHandler((error, request, reply) => {
|
|
|
27611
27806
|
"x-request-id": getHeaderValue(request.headers["x-request-id"]),
|
|
27612
27807
|
"x-user-id": getHeaderValue(request.headers["x-user-id"])
|
|
27613
27808
|
};
|
|
27614
|
-
|
|
27809
|
+
logger7.error(
|
|
27615
27810
|
`\u8BF7\u6C42\u9519\u8BEF: ${request.method} ${request.url} error:${error.message}`,
|
|
27616
27811
|
{
|
|
27617
27812
|
...context,
|
|
@@ -27647,14 +27842,14 @@ async function restoreMcpConnections() {
|
|
|
27647
27842
|
const storeLattice = getStoreLattice30("default", "mcp");
|
|
27648
27843
|
const store = storeLattice.store;
|
|
27649
27844
|
if (!store) {
|
|
27650
|
-
|
|
27845
|
+
logger7.info("MCP store not configured, skipping connection restoration");
|
|
27651
27846
|
return;
|
|
27652
27847
|
}
|
|
27653
27848
|
const configs = (await store.getAllConfigsWithoutTenant()).filter(
|
|
27654
27849
|
(c2) => c2.status === "connected"
|
|
27655
27850
|
);
|
|
27656
27851
|
if (configs.length === 0) return;
|
|
27657
|
-
|
|
27852
|
+
logger7.info(`Restoring ${configs.length} MCP server connections...`);
|
|
27658
27853
|
const deps = {
|
|
27659
27854
|
store,
|
|
27660
27855
|
manager: mcpManager3,
|
|
@@ -27671,15 +27866,15 @@ async function restoreMcpConnections() {
|
|
|
27671
27866
|
results.forEach((result, index) => {
|
|
27672
27867
|
if (result.status === "rejected") {
|
|
27673
27868
|
const config = configs[index];
|
|
27674
|
-
|
|
27869
|
+
logger7.warn(
|
|
27675
27870
|
`Failed to restore MCP server "${config.tenantId}/${config.key}"`,
|
|
27676
27871
|
{ error: result.reason }
|
|
27677
27872
|
);
|
|
27678
27873
|
}
|
|
27679
27874
|
});
|
|
27680
|
-
|
|
27875
|
+
logger7.info(`MCP connection restoration complete: ${configs.length} servers`);
|
|
27681
27876
|
} catch (err) {
|
|
27682
|
-
|
|
27877
|
+
logger7.error("MCP connection restoration failed", { error: err });
|
|
27683
27878
|
}
|
|
27684
27879
|
}
|
|
27685
27880
|
var start = async (config) => {
|
|
@@ -27692,7 +27887,7 @@ var start = async (config) => {
|
|
|
27692
27887
|
file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
|
|
27693
27888
|
};
|
|
27694
27889
|
loggerLattice = initializeLogger(loggerConfig);
|
|
27695
|
-
|
|
27890
|
+
logger7 = loggerLattice.client;
|
|
27696
27891
|
}
|
|
27697
27892
|
app.decorate("loggerLattice", loggerLattice);
|
|
27698
27893
|
const projectRoomRealtimeMode = resolveProjectRoomRealtimeMode();
|
|
@@ -27702,12 +27897,13 @@ var start = async (config) => {
|
|
|
27702
27897
|
tasks: getStoreLattice30("default", "task").store,
|
|
27703
27898
|
rooms: getStoreLattice30("default", "projectRoom").store,
|
|
27704
27899
|
memberships: getStoreLattice30("default", "projectBotMembership").store,
|
|
27705
|
-
log: { warn: (message, context) =>
|
|
27900
|
+
log: { warn: (message, context) => logger7.warn(message, context) }
|
|
27706
27901
|
});
|
|
27707
27902
|
}
|
|
27708
27903
|
let channelDeps;
|
|
27709
27904
|
const adapterRegistry = new ChannelAdapterRegistry();
|
|
27710
27905
|
adapterRegistry.register(larkChannelAdapter);
|
|
27906
|
+
adapterRegistry.register(wecomChannelAdapter);
|
|
27711
27907
|
const { wechatChannelAdapter } = await import("./WechatChannelAdapter-7WHE5UGY.mjs");
|
|
27712
27908
|
adapterRegistry.register(wechatChannelAdapter);
|
|
27713
27909
|
try {
|
|
@@ -27720,7 +27916,7 @@ var start = async (config) => {
|
|
|
27720
27916
|
createRateLimitMiddleware(),
|
|
27721
27917
|
createAuditLoggerMiddleware()
|
|
27722
27918
|
],
|
|
27723
|
-
warn: (message, context) =>
|
|
27919
|
+
warn: (message, context) => logger7.warn(message, context),
|
|
27724
27920
|
realtime: projectRoomRealtimeRuntime?.publisher
|
|
27725
27921
|
});
|
|
27726
27922
|
const bindingStore = infrastructure.bindingRegistry;
|
|
@@ -27734,10 +27930,10 @@ var start = async (config) => {
|
|
|
27734
27930
|
installationStore,
|
|
27735
27931
|
bindingRegistry: bindingStore,
|
|
27736
27932
|
realtime: projectRoomRealtimeRuntime?.publisher,
|
|
27737
|
-
warn: (message, context) =>
|
|
27933
|
+
warn: (message, context) => logger7.warn(message, context)
|
|
27738
27934
|
};
|
|
27739
27935
|
} catch (err) {
|
|
27740
|
-
|
|
27936
|
+
logger7.warn("Channel infrastructure unavailable", {
|
|
27741
27937
|
error: err instanceof Error ? err.message : String(err)
|
|
27742
27938
|
});
|
|
27743
27939
|
}
|
|
@@ -27745,7 +27941,7 @@ var start = async (config) => {
|
|
|
27745
27941
|
try {
|
|
27746
27942
|
const menuStore = getStoreLattice30("default", "menu").store;
|
|
27747
27943
|
setMenuRegistry(menuStore);
|
|
27748
|
-
|
|
27944
|
+
logger7.info("Menu registry initialized");
|
|
27749
27945
|
} catch {
|
|
27750
27946
|
}
|
|
27751
27947
|
registerAllBuiltinEntities();
|
|
@@ -27754,7 +27950,7 @@ var start = async (config) => {
|
|
|
27754
27950
|
}
|
|
27755
27951
|
const routes = registerLatticeRoutes(app, channelDeps, {
|
|
27756
27952
|
projectTaskEnabled: process.env.AXIOM_PROJECT_TASK_EXECUTION_ENABLED !== "false",
|
|
27757
|
-
projectTaskLog: { warn: (message, context) =>
|
|
27953
|
+
projectTaskLog: { warn: (message, context) => logger7.warn(message, context) },
|
|
27758
27954
|
projectRoomRealtimeRuntime
|
|
27759
27955
|
});
|
|
27760
27956
|
try {
|
|
@@ -27782,9 +27978,9 @@ var start = async (config) => {
|
|
|
27782
27978
|
getProjectStore: () => projectStore
|
|
27783
27979
|
});
|
|
27784
27980
|
a2a.registerA2ARoutes(app);
|
|
27785
|
-
|
|
27981
|
+
logger7.info("A2A standard routes registered");
|
|
27786
27982
|
} catch (err) {
|
|
27787
|
-
|
|
27983
|
+
logger7.warn("A2A standard routes unavailable", {
|
|
27788
27984
|
error: err instanceof Error ? err.message : String(err)
|
|
27789
27985
|
});
|
|
27790
27986
|
}
|
|
@@ -27821,26 +28017,26 @@ var start = async (config) => {
|
|
|
27821
28017
|
registerOpenFilesRoutes(app);
|
|
27822
28018
|
registerOpenAuditRoutes(app);
|
|
27823
28019
|
registerOpenExposureRoutes(app);
|
|
27824
|
-
|
|
28020
|
+
logger7.info("Open API routes registered (kb + sandbox providers, session exchange)");
|
|
27825
28021
|
} catch (err) {
|
|
27826
|
-
|
|
28022
|
+
logger7.warn("Open API routes unavailable", {
|
|
27827
28023
|
error: err instanceof Error ? err.message : String(err)
|
|
27828
28024
|
});
|
|
27829
28025
|
}
|
|
27830
28026
|
try {
|
|
27831
28027
|
const { registerGatewaySandboxOpenCredentialProvider } = await import("./sandboxOpenCredentialProvider-USIU7Z7H.mjs");
|
|
27832
28028
|
registerGatewaySandboxOpenCredentialProvider((error) => {
|
|
27833
|
-
|
|
28029
|
+
logger7.warn("sandbox open-credential provider failed", { error });
|
|
27834
28030
|
});
|
|
27835
|
-
|
|
28031
|
+
logger7.info("Sandbox open-credential provider registered");
|
|
27836
28032
|
} catch (err) {
|
|
27837
|
-
|
|
28033
|
+
logger7.warn("Sandbox open-credential provider unavailable", {
|
|
27838
28034
|
error: err instanceof Error ? err.message : String(err)
|
|
27839
28035
|
});
|
|
27840
28036
|
}
|
|
27841
28037
|
if (!sandboxLatticeManager2.hasLattice("default")) {
|
|
27842
28038
|
sandboxLatticeManager2.registerLattice("default", getConfiguredSandboxProvider());
|
|
27843
|
-
|
|
28039
|
+
logger7.info("Registered sandbox manager from env configuration");
|
|
27844
28040
|
}
|
|
27845
28041
|
if (isPluginDeploymentRuntimeEnabled()) {
|
|
27846
28042
|
try {
|
|
@@ -27867,21 +28063,21 @@ var start = async (config) => {
|
|
|
27867
28063
|
listAllDeployments,
|
|
27868
28064
|
// The service logs fields-first; the gateway logger is message-first.
|
|
27869
28065
|
logger: {
|
|
27870
|
-
info: (fields, message) =>
|
|
27871
|
-
warn: (fields, message) =>
|
|
27872
|
-
error: (fields, message) =>
|
|
28066
|
+
info: (fields, message) => logger7.info(message ?? "plugin deployment", fields),
|
|
28067
|
+
warn: (fields, message) => logger7.warn(message ?? "plugin deployment", fields),
|
|
28068
|
+
error: (fields, message) => logger7.error(message ?? "plugin deployment", fields)
|
|
27873
28069
|
}
|
|
27874
28070
|
},
|
|
27875
28071
|
lease: leaseStore2,
|
|
27876
28072
|
holder: getReplicaId7(),
|
|
27877
|
-
logger:
|
|
28073
|
+
logger: logger7
|
|
27878
28074
|
});
|
|
27879
28075
|
app.addHook("onClose", async () => {
|
|
27880
28076
|
await pluginDeploymentRuntime.dispose();
|
|
27881
28077
|
});
|
|
27882
|
-
|
|
28078
|
+
logger7.info("Plugin deployment runtime started");
|
|
27883
28079
|
} catch (err) {
|
|
27884
|
-
|
|
28080
|
+
logger7.warn("Plugin deployment runtime unavailable", {
|
|
27885
28081
|
error: err instanceof Error ? err.message : String(err)
|
|
27886
28082
|
});
|
|
27887
28083
|
}
|
|
@@ -27894,12 +28090,12 @@ var start = async (config) => {
|
|
|
27894
28090
|
store: sharedResourceStore,
|
|
27895
28091
|
sandboxManager: sandboxLatticeManager2,
|
|
27896
28092
|
cache,
|
|
27897
|
-
logger:
|
|
28093
|
+
logger: logger7
|
|
27898
28094
|
});
|
|
27899
28095
|
registerResourceRoutes(app, resourceController);
|
|
27900
|
-
|
|
28096
|
+
logger7.info("Resource share routes registered");
|
|
27901
28097
|
} catch (err) {
|
|
27902
|
-
|
|
28098
|
+
logger7.warn("Resource share infrastructure unavailable", {
|
|
27903
28099
|
error: err instanceof Error ? err.message : String(err)
|
|
27904
28100
|
});
|
|
27905
28101
|
}
|
|
@@ -27912,14 +28108,14 @@ var start = async (config) => {
|
|
|
27912
28108
|
deps: { router: channelDeps.router }
|
|
27913
28109
|
}),
|
|
27914
28110
|
disconnect: () => disconnectAllChannels((channel) => adapterRegistry.get(channel)),
|
|
27915
|
-
log: { warn: (message, context) =>
|
|
28111
|
+
log: { warn: (message, context) => logger7.warn(message, context) }
|
|
27916
28112
|
});
|
|
27917
28113
|
app.addHook("onClose", async () => {
|
|
27918
28114
|
await channelLeader.stop();
|
|
27919
28115
|
});
|
|
27920
28116
|
channelLeader.start();
|
|
27921
28117
|
} catch (err) {
|
|
27922
|
-
|
|
28118
|
+
logger7.error("Failed to start channel connections", {
|
|
27923
28119
|
error: err instanceof Error ? err.message : String(err)
|
|
27924
28120
|
});
|
|
27925
28121
|
}
|
|
@@ -27966,24 +28162,24 @@ var start = async (config) => {
|
|
|
27966
28162
|
await handleModelProviderChanged(payload, (tenantId, providerId2) => controller.reconcileProvider(tenantId, providerId2));
|
|
27967
28163
|
}
|
|
27968
28164
|
},
|
|
27969
|
-
log:
|
|
28165
|
+
log: logger7
|
|
27970
28166
|
});
|
|
27971
28167
|
try {
|
|
27972
28168
|
await outboxPoller.start();
|
|
27973
28169
|
} catch (err) {
|
|
27974
|
-
|
|
28170
|
+
logger7.warn("Outbox poller failed to start", { error: err instanceof Error ? err.message : String(err) });
|
|
27975
28171
|
}
|
|
27976
28172
|
const leaseStore = getStoreLattice30("default", "lease").store;
|
|
27977
28173
|
if (leaseStore.constructor?.name === "InMemoryLeaseStore") {
|
|
27978
|
-
|
|
28174
|
+
logger7.warn(
|
|
27979
28175
|
"Startup recovery leader gate uses a non-distributed lease store (per-process only); configure a shared 'lease' store for multi-replica deployments",
|
|
27980
28176
|
{ phase: "startup_recovery" }
|
|
27981
28177
|
);
|
|
27982
28178
|
}
|
|
27983
|
-
warnMultiReplicaReadiness(
|
|
28179
|
+
warnMultiReplicaReadiness(logger7);
|
|
27984
28180
|
const startup = await runAsLeader(leaseStore, "startup-recovery", async () => {
|
|
27985
28181
|
if (routes.projectTaskRuntime) {
|
|
27986
|
-
await prepareProjectTaskRuntime(routes.projectTaskRuntime,
|
|
28182
|
+
await prepareProjectTaskRuntime(routes.projectTaskRuntime, logger7);
|
|
27987
28183
|
}
|
|
27988
28184
|
if (process.env.AXIOM_TASK_ORPHAN_RECOVERY === "true") {
|
|
27989
28185
|
try {
|
|
@@ -27994,19 +28190,19 @@ var start = async (config) => {
|
|
|
27994
28190
|
workItemStore: getStoreLattice30("default", "taskWorkItem").store,
|
|
27995
28191
|
tenantStore: getStoreLattice30("default", "tenant").store,
|
|
27996
28192
|
...createRecoveryCallerDeps2(),
|
|
27997
|
-
log:
|
|
28193
|
+
log: logger7
|
|
27998
28194
|
});
|
|
27999
28195
|
await runtime.recoverAll();
|
|
28000
28196
|
} catch (err) {
|
|
28001
|
-
|
|
28197
|
+
logger7.warn("Task orphan recovery failed", { error: err instanceof Error ? err.message : String(err) });
|
|
28002
28198
|
}
|
|
28003
28199
|
}
|
|
28004
28200
|
if (scheduleLatticeManager2.hasLattice("default")) {
|
|
28005
28201
|
try {
|
|
28006
28202
|
const restored = await scheduleLatticeManager2.getScheduleLattice("default").restore();
|
|
28007
|
-
|
|
28203
|
+
logger7.info("Scheduled tasks restored", { phase: "startup_recovery", restored });
|
|
28008
28204
|
} catch (err) {
|
|
28009
|
-
|
|
28205
|
+
logger7.warn("Scheduled task restore failed", {
|
|
28010
28206
|
phase: "startup_recovery",
|
|
28011
28207
|
error: err instanceof Error ? err.message : String(err)
|
|
28012
28208
|
});
|
|
@@ -28014,13 +28210,13 @@ var start = async (config) => {
|
|
|
28014
28210
|
}
|
|
28015
28211
|
}, { hold: true, ttlMs: 5 * 6e4 });
|
|
28016
28212
|
if (!startup.ran) {
|
|
28017
|
-
|
|
28213
|
+
logger7.info("Startup recovery skipped (another replica leads)", { phase: "startup_recovery" });
|
|
28018
28214
|
}
|
|
28019
28215
|
await app.listen({ port: target_port, host: "0.0.0.0" });
|
|
28020
|
-
|
|
28216
|
+
logger7.info(`Lattice Gateway is running on port: ${target_port}`);
|
|
28021
28217
|
const outboxRetention = createOutboxRetentionJob({
|
|
28022
28218
|
outbox: outboxStore,
|
|
28023
|
-
log:
|
|
28219
|
+
log: logger7
|
|
28024
28220
|
});
|
|
28025
28221
|
outboxRetention.start();
|
|
28026
28222
|
let agentTaskConsumer;
|
|
@@ -28033,15 +28229,15 @@ var start = async (config) => {
|
|
|
28033
28229
|
}
|
|
28034
28230
|
}
|
|
28035
28231
|
restoreMcpConnections().catch((error) => {
|
|
28036
|
-
|
|
28232
|
+
logger7.error("MCP connection restoration failed", { error });
|
|
28037
28233
|
});
|
|
28038
28234
|
if (config?.gracefulShutdown !== false && !shutdownHandlersInstalled) {
|
|
28039
28235
|
shutdownHandlersInstalled = true;
|
|
28040
28236
|
const gracefulShutdown = createGracefulShutdown({
|
|
28041
28237
|
timeoutMs: config?.gracefulShutdownTimeoutMs ?? 1e4,
|
|
28042
28238
|
log: {
|
|
28043
|
-
info: (message, context) =>
|
|
28044
|
-
warn: (message, context) =>
|
|
28239
|
+
info: (message, context) => logger7.info(message, context),
|
|
28240
|
+
warn: (message, context) => logger7.warn(message, context)
|
|
28045
28241
|
},
|
|
28046
28242
|
steps: [
|
|
28047
28243
|
async () => {
|
|
@@ -28059,7 +28255,7 @@ var start = async (config) => {
|
|
|
28059
28255
|
process.once("SIGINT", () => void gracefulShutdown("SIGINT"));
|
|
28060
28256
|
}
|
|
28061
28257
|
} catch (err) {
|
|
28062
|
-
|
|
28258
|
+
logger7.error("Server start failed", { error: err });
|
|
28063
28259
|
process.exit(1);
|
|
28064
28260
|
}
|
|
28065
28261
|
};
|