@axiom-lattice/gateway 2.1.74 → 2.1.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -5700,12 +5700,8 @@ function registerAuthRoutes(app2, config) {
5700
5700
  );
5701
5701
  }
5702
5702
 
5703
- // src/channels/lark/routes.ts
5704
- import { getStoreLattice as getStoreLattice14 } from "@axiom-lattice/core";
5705
- import {
5706
- ChannelIdentityMappingStore,
5707
- PostgreSQLChannelInstallationStore
5708
- } from "@axiom-lattice/pg-stores";
5703
+ // src/channels/lark/LarkChannelAdapter.ts
5704
+ import { z } from "zod";
5709
5705
 
5710
5706
  // src/channels/lark/parser.ts
5711
5707
  function parseLarkMessageEvent(payload) {
@@ -5745,276 +5741,59 @@ function normalizeChatType(chatType) {
5745
5741
  return chatType === "p2p" ? "direct" : "group";
5746
5742
  }
5747
5743
 
5748
- // src/channels/lark/controller.ts
5749
- function createLarkEventHandler(dependencies) {
5750
- return async function handleLarkEvent2(request, reply) {
5751
- const installationId = request.params?.installationId;
5752
- if (!installationId) {
5753
- reply.status(400).send({ success: false, message: "Missing installationId" });
5754
- return;
5755
- }
5756
- const config = await dependencies.getInstallationConfig(installationId);
5757
- if (!config) {
5758
- reply.status(404).send({ success: false, message: "Lark installation not found" });
5759
- return;
5760
- }
5761
- const body = dependencies.parseRequestBody(
5762
- request.body,
5763
- config.encryptKey
5764
- );
5765
- if (!dependencies.verifyParsedBody(body, config)) {
5766
- reply.status(401).send({ success: false, message: "Invalid Lark request" });
5767
- return;
5768
- }
5769
- if (body.type === "url_verification" && body.challenge) {
5770
- reply.status(200).send({ challenge: body.challenge });
5771
- return;
5772
- }
5773
- const parsed = dependencies.parseEvent(request.body);
5774
- if (!parsed) {
5775
- reply.status(200).send({ success: true, ignored: true });
5776
- return;
5777
- }
5778
- const receipt = await dependencies.claimInboundReceipt({
5779
- channel: "lark",
5780
- channelAppId: config.appId,
5781
- externalMessageId: parsed.messageId,
5782
- tenantId: config.tenantId
5783
- });
5784
- if (!receipt.accepted) {
5785
- reply.status(200).send(
5786
- receipt.status === "processing" ? { success: true, processing: true } : { success: true, duplicate: true }
5787
- );
5788
- return;
5789
- }
5790
- try {
5791
- const { threadId } = await dependencies.resolveThread({
5792
- channel: "lark",
5793
- channelAppId: config.appId,
5794
- tenantId: config.tenantId,
5795
- assistantId: config.assistantId,
5796
- mappingMode: config.mappingMode,
5797
- openId: parsed.openId,
5798
- chatId: parsed.chatId,
5799
- chatType: parsed.chatType,
5800
- messageId: parsed.messageId,
5801
- workspaceId: config.workspaceId,
5802
- projectId: config.projectId
5803
- });
5804
- const text = await dependencies.runAgentAndCollectText({
5805
- tenantId: config.tenantId,
5806
- assistantId: config.assistantId,
5807
- threadId,
5808
- text: parsed.text,
5809
- workspaceId: config.workspaceId,
5810
- projectId: config.projectId
5811
- });
5812
- await dependencies.sendTextReply({
5813
- chatId: parsed.chatId,
5814
- text,
5815
- config
5816
- });
5817
- await dependencies.markInboundReceiptCompleted({
5818
- channel: "lark",
5819
- channelAppId: config.appId,
5820
- externalMessageId: parsed.messageId,
5821
- tenantId: config.tenantId,
5822
- threadId
5823
- });
5824
- reply.status(200).send({ success: true, threadId });
5825
- } catch (error) {
5826
- await dependencies.markInboundReceiptFailed({
5827
- channel: "lark",
5828
- channelAppId: config.appId,
5829
- externalMessageId: parsed.messageId,
5830
- tenantId: config.tenantId
5831
- });
5832
- throw error;
5833
- }
5834
- };
5835
- }
5836
- var handleLarkEvent = createLarkEventHandler({
5837
- getInstallationConfig: async () => null,
5838
- parseRequestBody: (body) => body || {},
5839
- verifyParsedBody: () => true,
5840
- parseEvent: parseLarkMessageEvent,
5841
- claimInboundReceipt: async () => ({ accepted: true, status: "processing" }),
5842
- markInboundReceiptCompleted: async () => void 0,
5843
- markInboundReceiptFailed: async () => void 0,
5844
- resolveThread: async () => ({ threadId: "" }),
5845
- runAgentAndCollectText: async () => "",
5846
- sendTextReply: async () => void 0
5744
+ // src/channels/lark/LarkChannelAdapter.ts
5745
+ var larkConfigSchema = z.object({
5746
+ appId: z.string(),
5747
+ appSecret: z.string(),
5748
+ verificationToken: z.string().optional(),
5749
+ encryptKey: z.string().optional()
5847
5750
  });
5848
-
5849
- // src/channels/lark/config.ts
5850
- function loadLarkIngressConfig() {
5851
- return {
5852
- enabled: process.env.LARK_ENABLED !== "false",
5853
- appId: process.env.LARK_APP_ID || "",
5854
- appSecret: process.env.LARK_APP_SECRET || "",
5855
- verificationToken: process.env.LARK_VERIFICATION_TOKEN,
5856
- encryptKey: process.env.LARK_ENCRYPT_KEY,
5857
- tenantId: process.env.LARK_TENANT_ID || "default",
5858
- assistantId: process.env.LARK_ASSISTANT_ID || "default_agent",
5859
- workspaceId: process.env.LARK_WORKSPACE_ID,
5860
- projectId: process.env.LARK_PROJECT_ID,
5861
- mappingMode: process.env.LARK_MAPPING_MODE || "hybrid"
5862
- };
5863
- }
5864
- function isLarkIngressEnabled(config) {
5865
- return config.enabled;
5866
- }
5867
-
5868
- // src/channels/lark/mapping-service.ts
5869
- import { randomUUID as randomUUID6 } from "crypto";
5870
- function createChannelThreadMappingService(deps) {
5871
- return {
5872
- async getOrCreateThread(input) {
5873
- const externalSubjectKey = buildExternalSubjectKey(input);
5874
- const existing = await deps.mappingStore.getMappingBySubject({
5875
- channel: input.channel,
5876
- channelAppId: input.channelAppId,
5877
- tenantId: input.tenantId,
5878
- assistantId: input.assistantId,
5879
- externalSubjectKey
5880
- });
5881
- if (existing) {
5882
- return { threadId: existing.threadId };
5883
- }
5884
- const threadId = (deps.uuid || randomUUID6)();
5885
- await deps.threadStore.createThread(input.tenantId, input.assistantId, threadId, {
5751
+ var larkChannelAdapter = {
5752
+ channel: "lark",
5753
+ configSchema: larkConfigSchema,
5754
+ async receive(rawPayload, installation) {
5755
+ const event = parseLarkMessageEvent(rawPayload);
5756
+ if (!event) return null;
5757
+ return {
5758
+ channel: "lark",
5759
+ channelInstallationId: installation.id,
5760
+ tenantId: installation.tenantId,
5761
+ sender: {
5762
+ id: event.openId,
5763
+ displayName: void 0
5764
+ },
5765
+ content: {
5766
+ text: event.text,
5886
5767
  metadata: {
5887
- tenantId: input.tenantId,
5888
- workspaceId: input.workspaceId,
5889
- projectId: input.projectId,
5890
- channel: input.channel,
5891
- larkChatId: input.chatId,
5892
- larkOpenId: input.openId
5768
+ chatId: event.chatId,
5769
+ chatType: event.chatType,
5770
+ messageId: event.messageId
5893
5771
  }
5894
- });
5895
- try {
5896
- await deps.mappingStore.createMapping({
5897
- channel: input.channel,
5898
- channelAppId: input.channelAppId,
5899
- tenantId: input.tenantId,
5900
- assistantId: input.assistantId,
5901
- mappingMode: input.mappingMode,
5902
- externalSubjectType: resolveSubjectType(input.mappingMode, input.chatType) === "user" ? "user" : "chat",
5903
- externalSubjectKey,
5904
- larkOpenId: input.openId,
5905
- larkChatId: input.chatId,
5906
- larkMessageId: input.messageId,
5907
- threadId
5908
- });
5909
- } catch (error) {
5910
- if (!isUniqueViolation(error)) {
5911
- throw error;
5912
- }
5913
- const canonical = await deps.mappingStore.getMappingBySubject({
5914
- channel: input.channel,
5915
- channelAppId: input.channelAppId,
5916
- tenantId: input.tenantId,
5917
- assistantId: input.assistantId,
5918
- externalSubjectKey
5919
- });
5920
- if (!canonical) {
5921
- throw error;
5772
+ },
5773
+ conversation: {
5774
+ id: event.chatId,
5775
+ type: event.chatType
5776
+ },
5777
+ replyTarget: {
5778
+ adapterChannel: "lark",
5779
+ channelInstallationId: installation.id,
5780
+ rawTarget: {
5781
+ chatId: event.chatId,
5782
+ messageId: event.messageId,
5783
+ chatType: event.chatType
5922
5784
  }
5923
- await deps.threadStore.deleteThread(input.tenantId, threadId);
5924
- return { threadId: canonical.threadId };
5925
5785
  }
5926
- return { threadId };
5927
- }
5928
- };
5929
- }
5930
- function isUniqueViolation(error) {
5931
- return typeof error === "object" && error !== null && "code" in error && error.code === "23505";
5932
- }
5933
- function buildExternalSubjectKey(input) {
5934
- const subjectType = resolveSubjectType(input.mappingMode, input.chatType);
5935
- const subjectValue = subjectType === "user" ? input.openId : input.chatId;
5936
- return [
5937
- input.channel,
5938
- input.channelAppId,
5939
- `tenant:${input.tenantId}`,
5940
- `assistant:${input.assistantId}`,
5941
- `${subjectType}:${subjectValue}`
5942
- ].join(":");
5943
- }
5944
- function resolveSubjectType(mappingMode, chatType) {
5945
- if (mappingMode === "user") {
5946
- return "user";
5947
- }
5948
- if (mappingMode === "group") {
5949
- return "chat";
5950
- }
5951
- return chatType === "direct" ? "user" : "chat";
5952
- }
5953
-
5954
- // src/channels/lark/runner.ts
5955
- import { agentInstanceManager as agentInstanceManager6 } from "@axiom-lattice/core";
5956
- import { MessageChunkTypes as MessageChunkTypes4 } from "@axiom-lattice/protocols";
5957
-
5958
- // src/channels/lark/aggregator.ts
5959
- import { MessageChunkTypes as MessageChunkTypes3 } from "@axiom-lattice/protocols";
5960
- function aggregateLarkReply(messageId, chunks) {
5961
- return chunks.filter(
5962
- (chunk) => chunk.type === MessageChunkTypes3.AI && chunk.data.id === messageId
5963
- ).map((chunk) => chunk.data.content || "").join("").trim();
5964
- }
5965
-
5966
- // src/channels/lark/runner.ts
5967
- async function runAgentAndCollectLarkReply(input) {
5968
- const agent = agentInstanceManager6.getAgent({
5969
- tenant_id: input.tenantId,
5970
- assistant_id: input.assistantId,
5971
- thread_id: input.threadId,
5972
- workspace_id: input.workspaceId,
5973
- project_id: input.projectId
5974
- });
5975
- const result = await agent.addMessage({
5976
- input: {
5977
- message: input.text
5978
- }
5979
- });
5980
- const chunks = [];
5981
- const stream = agent.chunkStream(result.messageId, [
5982
- MessageChunkTypes4.MESSAGE_COMPLETED
5983
- ]);
5984
- for await (const chunk of stream) {
5985
- chunks.push(chunk);
5786
+ };
5787
+ },
5788
+ async sendReply(replyTarget, message, installation) {
5789
+ const { createLarkSender } = await import("./sender-PX32VSHB.mjs");
5790
+ const sender = createLarkSender(installation.config);
5791
+ await sender.sendTextReply({
5792
+ chatId: replyTarget.rawTarget.chatId,
5793
+ text: message.text
5794
+ });
5986
5795
  }
5987
- return aggregateLarkReply(result.messageId, chunks);
5988
- }
5989
-
5990
- // src/channels/lark/sender.ts
5991
- async function createLarkSender(config, client) {
5992
- const resolved = client ?? await createDefaultLarkClient(config);
5993
- return {
5994
- async sendTextReply(input) {
5995
- const response = await resolved.im.v1.message.create({
5996
- params: {
5997
- receive_id_type: "chat_id"
5998
- },
5999
- data: {
6000
- receive_id: input.chatId,
6001
- msg_type: "text",
6002
- content: JSON.stringify({ text: input.text })
6003
- }
6004
- });
6005
- if (response.code && response.code !== 0) {
6006
- throw new Error("Failed to send Lark reply");
6007
- }
6008
- }
6009
- };
6010
- }
6011
- async function createDefaultLarkClient(config) {
6012
- const Lark = await import("@larksuiteoapi/node-sdk");
6013
- return new Lark.Client({
6014
- appId: config.appId,
6015
- appSecret: config.appSecret
6016
- });
6017
- }
5796
+ };
6018
5797
 
6019
5798
  // src/channels/lark/verification.ts
6020
5799
  import crypto2 from "crypto";
@@ -6037,127 +5816,199 @@ function decryptLarkPayload(encryptKey, encryptedPayload) {
6037
5816
  ]).toString("utf8");
6038
5817
  return JSON.parse(plaintext);
6039
5818
  }
6040
- function createLarkRequestVerifier(config) {
6041
- return function verifyRequest(request) {
6042
- const body = parseLarkRequestBody(request.body, config.encryptKey);
6043
- return verifyLarkParsedBody(body, config);
6044
- };
6045
- }
6046
- function verifyLarkParsedBody(body, config) {
6047
- if (!config.verificationToken) {
6048
- return true;
5819
+
5820
+ // src/logger/Logger.ts
5821
+ import pino from "pino";
5822
+ import "pino-pretty";
5823
+ import "pino-roll";
5824
+ var PinoLoggerFactory = class _PinoLoggerFactory {
5825
+ constructor() {
5826
+ const isProd = process.env.NODE_ENV === "production";
5827
+ const loggerConfig = {
5828
+ // 自定义时间戳格式
5829
+ timestamp: () => `,"@timestamp":"${(/* @__PURE__ */ new Date()).toISOString()}"`,
5830
+ // 关闭默认的时间戳键
5831
+ base: {
5832
+ "@version": "1",
5833
+ app_name: "lattice",
5834
+ service_name: "lattice/graph-server",
5835
+ thread_name: "main",
5836
+ logger_name: "lattice-graph-logger"
5837
+ },
5838
+ formatters: {
5839
+ level: (label, number) => {
5840
+ return {
5841
+ level: label.toUpperCase(),
5842
+ level_value: number * 1e3
5843
+ };
5844
+ }
5845
+ }
5846
+ };
5847
+ if (isProd) {
5848
+ try {
5849
+ this.pinoLogger = pino(
5850
+ loggerConfig,
5851
+ pino.transport({
5852
+ target: "pino-roll",
5853
+ options: {
5854
+ file: "./logs/fin_ai_graph_server",
5855
+ frequency: "daily",
5856
+ mkdir: true
5857
+ }
5858
+ })
5859
+ );
5860
+ } catch (error) {
5861
+ console.error(
5862
+ "\u65E0\u6CD5\u521D\u59CB\u5316 pino-roll \u65E5\u5FD7\u8BB0\u5F55\u5668\uFF0C\u56DE\u9000\u5230\u63A7\u5236\u53F0\u65E5\u5FD7",
5863
+ error
5864
+ );
5865
+ this.pinoLogger = pino({
5866
+ ...loggerConfig,
5867
+ transport: {
5868
+ target: "pino-pretty",
5869
+ options: {
5870
+ colorize: true
5871
+ }
5872
+ }
5873
+ });
5874
+ }
5875
+ } else {
5876
+ this.pinoLogger = pino({
5877
+ ...loggerConfig,
5878
+ transport: {
5879
+ target: "pino-pretty",
5880
+ options: {
5881
+ colorize: true
5882
+ }
5883
+ }
5884
+ });
5885
+ }
6049
5886
  }
6050
- return extractVerificationToken(body) === config.verificationToken;
6051
- }
6052
- function extractVerificationToken(body) {
6053
- if (typeof body.token === "string") {
6054
- return body.token;
5887
+ static getInstance() {
5888
+ if (!_PinoLoggerFactory.instance) {
5889
+ _PinoLoggerFactory.instance = new _PinoLoggerFactory();
5890
+ }
5891
+ return _PinoLoggerFactory.instance;
6055
5892
  }
6056
- if (typeof body.header?.token === "string") {
6057
- return body.header.token;
5893
+ getPinoLogger() {
5894
+ return this.pinoLogger;
6058
5895
  }
6059
- return void 0;
5896
+ };
5897
+ var Logger = class _Logger {
5898
+ constructor(options) {
5899
+ this.context = options?.context || {};
5900
+ this.name = options?.name || "lattice-graph-logger";
5901
+ this.serviceName = options?.serviceName || "lattice/graph-server";
5902
+ }
5903
+ /**
5904
+ * 获取合并了上下文的日志对象
5905
+ * @param additionalContext 额外的上下文数据
5906
+ * @returns 带有上下文的pino日志对象
5907
+ */
5908
+ getContextualLogger(additionalContext) {
5909
+ const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();
5910
+ const contextObj = {
5911
+ "x-user-id": this.context["x-user-id"] || "",
5912
+ "x-tenant-id": this.context["x-tenant-id"] || "",
5913
+ "x-request-id": this.context["x-request-id"] || "",
5914
+ "x-task-id": this.context["x-task-id"] || "",
5915
+ "x-thread-id": this.context["x-thread-id"] || "",
5916
+ service_name: this.serviceName,
5917
+ logger_name: this.name,
5918
+ ...additionalContext
5919
+ };
5920
+ return pinoLogger.child(contextObj);
5921
+ }
5922
+ info(msg, obj) {
5923
+ this.getContextualLogger(obj).info(msg);
5924
+ }
5925
+ error(msg, obj) {
5926
+ this.getContextualLogger(obj).error(msg);
5927
+ }
5928
+ warn(msg, obj) {
5929
+ this.getContextualLogger(obj).warn(msg);
5930
+ }
5931
+ debug(msg, obj) {
5932
+ this.getContextualLogger(obj).debug(msg);
5933
+ }
5934
+ /**
5935
+ * 更新Logger实例的上下文
5936
+ */
5937
+ updateContext(context) {
5938
+ this.context = {
5939
+ ...this.context,
5940
+ ...context
5941
+ };
5942
+ }
5943
+ /**
5944
+ * 创建一个新的Logger实例,继承当前Logger的上下文
5945
+ */
5946
+ child(options) {
5947
+ return new _Logger({
5948
+ name: options.name || this.name,
5949
+ serviceName: options.serviceName || this.serviceName,
5950
+ context: {
5951
+ ...this.context,
5952
+ ...options.context
5953
+ }
5954
+ });
5955
+ }
5956
+ };
5957
+
5958
+ // src/channels/lark/controller.ts
5959
+ var logger = new Logger({ serviceName: "lattice/gateway/lark" });
5960
+ function createLarkEventHandler(deps) {
5961
+ return async function handleLarkEvent(request, reply) {
5962
+ const { installationId } = request.params;
5963
+ const installation = await deps.installationStore.getInstallationById(installationId);
5964
+ if (!installation || installation.channel !== "lark") {
5965
+ reply.status(404).send({ success: false, message: "Installation not found" });
5966
+ return;
5967
+ }
5968
+ const body = parseLarkRequestBody(request.body, installation.config.encryptKey);
5969
+ if (body.type === "url_verification" && body.challenge) {
5970
+ reply.status(200).send({ challenge: body.challenge });
5971
+ return;
5972
+ }
5973
+ const inboundMessage = await larkChannelAdapter.receive(request.body, installation);
5974
+ if (!inboundMessage) {
5975
+ reply.status(200).send();
5976
+ return;
5977
+ }
5978
+ deps.router.dispatch(inboundMessage).catch((error) => {
5979
+ logger.error("Lark message dispatch error", {
5980
+ error: error instanceof Error ? error.message : String(error)
5981
+ });
5982
+ });
5983
+ reply.status(200).send();
5984
+ };
6060
5985
  }
6061
5986
 
6062
5987
  // src/channels/lark/routes.ts
6063
- function registerLarkChannelRoutes(app2, dependencies) {
6064
- const config = loadLarkIngressConfig();
6065
- if (!dependencies && !isLarkIngressEnabled(config)) {
6066
- return;
6067
- }
6068
- const handlerDependencies = dependencies || createDefaultLarkDependencies();
5988
+ function registerLarkChannelRoutes(app2, deps) {
5989
+ const handler = createLarkEventHandler({
5990
+ installationStore: deps.installationStore,
5991
+ router: deps.router
5992
+ });
6069
5993
  app2.post(
6070
5994
  "/api/channels/lark/installations/:installationId/events",
6071
- createLarkEventHandler({
6072
- ...handlerDependencies
6073
- })
5995
+ handler
6074
5996
  );
6075
5997
  }
6076
- function createDefaultLarkDependencies() {
6077
- const installationStore = new PostgreSQLChannelInstallationStore({
6078
- poolConfig: getDatabaseUrl()
6079
- });
6080
- const threadStore = getStoreLattice14("default", "thread").store;
6081
- const mappingStore = new ChannelIdentityMappingStore({
6082
- poolConfig: getDatabaseUrl()
6083
- });
6084
- const mappingService = createChannelThreadMappingService({
6085
- mappingStore,
6086
- threadStore
6087
- });
6088
- return {
6089
- getInstallationConfig: async (installationId) => {
6090
- const installation = await installationStore.getInstallationById(
6091
- installationId
6092
- );
6093
- if (!installation || installation.channel !== "lark") {
6094
- return null;
6095
- }
6096
- return {
6097
- enabled: true,
6098
- installationId: installation.id,
6099
- tenantId: installation.tenantId,
6100
- assistantId: installation.config.assistantId,
6101
- appId: installation.config.appId,
6102
- appSecret: installation.config.appSecret,
6103
- verificationToken: installation.config.verificationToken,
6104
- encryptKey: installation.config.encryptKey,
6105
- workspaceId: installation.config.workspaceId,
6106
- projectId: installation.config.projectId,
6107
- mappingMode: installation.config.mappingMode
6108
- };
6109
- },
6110
- parseRequestBody: (body, encryptKey) => parseLarkRequestBody(body, encryptKey),
6111
- verifyParsedBody: (body, config) => {
6112
- if (!config.verificationToken) {
6113
- return true;
6114
- }
6115
- return createLarkRequestVerifier(config)({
6116
- body
6117
- });
6118
- },
6119
- parseEvent: parseLarkMessageEvent,
6120
- claimInboundReceipt: (input) => mappingStore.claimInboundReceipt(input),
6121
- markInboundReceiptCompleted: (input) => mappingStore.markInboundReceiptCompleted(input),
6122
- markInboundReceiptFailed: (input) => mappingStore.markInboundReceiptFailed(input),
6123
- resolveThread: (input) => mappingService.getOrCreateThread(input),
6124
- runAgentAndCollectText: ({ tenantId, assistantId, threadId, text, workspaceId, projectId }) => runAgentAndCollectLarkReply({
6125
- tenantId,
6126
- assistantId,
6127
- threadId,
6128
- text,
6129
- workspaceId,
6130
- projectId
6131
- }),
6132
- sendTextReply: async ({ chatId, text, config }) => {
6133
- const sender = await createLarkSender({
6134
- appId: config.appId,
6135
- appSecret: config.appSecret
6136
- });
6137
- await sender.sendTextReply({ chatId, text });
6138
- }
6139
- };
6140
- }
6141
- function getDatabaseUrl() {
6142
- const databaseUrl = process.env.DATABASE_URL;
6143
- if (!databaseUrl) {
6144
- throw new Error("DATABASE_URL is required for Lark channel ingress");
6145
- }
6146
- return databaseUrl;
6147
- }
6148
5998
 
6149
5999
  // src/channels/routes.ts
6150
6000
  var channelRouteRegistrars = [
6151
- (app2, dependencies) => registerLarkChannelRoutes(app2, dependencies.lark)
6001
+ (app2, deps) => registerLarkChannelRoutes(app2, deps)
6152
6002
  ];
6153
- function registerChannelRoutes(app2, dependencies = {}) {
6003
+ function registerChannelRoutes(app2, dependencies) {
6004
+ if (!dependencies) return;
6154
6005
  for (const registerRoutes of channelRouteRegistrars) {
6155
6006
  registerRoutes(app2, dependencies);
6156
6007
  }
6157
6008
  }
6158
6009
 
6159
6010
  // src/controllers/channel-installations.ts
6160
- import { randomUUID as randomUUID7 } from "crypto";
6011
+ import { randomUUID as randomUUID6 } from "crypto";
6161
6012
  function getTenantId11(request) {
6162
6013
  const userTenantId = request.user?.tenantId;
6163
6014
  if (userTenantId) {
@@ -6166,12 +6017,15 @@ function getTenantId11(request) {
6166
6017
  return request.headers["x-tenant-id"] || "default";
6167
6018
  }
6168
6019
  async function getInstallationStore() {
6169
- const { PostgreSQLChannelInstallationStore: PostgreSQLChannelInstallationStore2 } = await import("@axiom-lattice/pg-stores");
6020
+ const { getStoreLattice: getStoreLattice16 } = await import("@axiom-lattice/core");
6021
+ const store = getStoreLattice16("default", "channelInstallation").store;
6022
+ if (store) return store;
6023
+ const { PostgreSQLChannelInstallationStore } = await import("@axiom-lattice/pg-stores");
6170
6024
  const databaseUrl = process.env.DATABASE_URL;
6171
6025
  if (!databaseUrl) {
6172
6026
  throw new Error("DATABASE_URL is required for channel installation store");
6173
6027
  }
6174
- return new PostgreSQLChannelInstallationStore2({
6028
+ return new PostgreSQLChannelInstallationStore({
6175
6029
  poolConfig: databaseUrl
6176
6030
  });
6177
6031
  }
@@ -6270,7 +6124,7 @@ async function createChannelInstallation(request, reply) {
6270
6124
  }
6271
6125
  }
6272
6126
  const store = await getInstallationStore();
6273
- const installationId = body.id || randomUUID7();
6127
+ const installationId = body.id || randomUUID6();
6274
6128
  const installation = await store.createInstallation(
6275
6129
  tenantId,
6276
6130
  installationId,
@@ -6393,8 +6247,129 @@ function registerChannelInstallationRoutes(app2) {
6393
6247
  app2.delete("/api/channel-installations/:installationId", deleteChannelInstallation);
6394
6248
  }
6395
6249
 
6250
+ // src/bindings/index.ts
6251
+ var registryInstance = null;
6252
+ function setBindingRegistry(registry) {
6253
+ registryInstance = registry;
6254
+ }
6255
+ function getBindingRegistry() {
6256
+ if (!registryInstance) {
6257
+ throw new Error("BindingRegistry not initialized. Call setBindingRegistry() first.");
6258
+ }
6259
+ return registryInstance;
6260
+ }
6261
+
6262
+ // src/controllers/channel-bindings.ts
6263
+ function getTenantId12(request) {
6264
+ const userTenantId = request.user?.tenantId;
6265
+ if (userTenantId) return userTenantId;
6266
+ return request.headers["x-tenant-id"] || "default";
6267
+ }
6268
+ async function getBindingList(request, _reply) {
6269
+ const tenantId = getTenantId12(request);
6270
+ const { channel, agentId, channelInstallationId, limit, offset } = request.query;
6271
+ try {
6272
+ const registry = getBindingRegistry();
6273
+ const bindings = await registry.list({ channel, agentId, tenantId, channelInstallationId, limit, offset });
6274
+ return { success: true, message: "Bindings retrieved", data: { records: bindings, total: bindings.length } };
6275
+ } catch (error) {
6276
+ console.error("Failed to get bindings:", error);
6277
+ return { success: false, message: "Failed to retrieve bindings", data: { records: [], total: 0 } };
6278
+ }
6279
+ }
6280
+ async function getBinding(request, reply) {
6281
+ const tenantId = getTenantId12(request);
6282
+ try {
6283
+ const registry = getBindingRegistry();
6284
+ const bindings = await registry.list({ tenantId });
6285
+ const binding = bindings.find((b) => b.id === request.params.id);
6286
+ if (!binding || binding.tenantId !== tenantId) {
6287
+ reply.status(404);
6288
+ return { success: false, message: "Binding not found" };
6289
+ }
6290
+ return { success: true, message: "Binding retrieved", data: binding };
6291
+ } catch (error) {
6292
+ console.error("Failed to get binding:", error);
6293
+ return { success: false, message: "Failed to retrieve binding" };
6294
+ }
6295
+ }
6296
+ async function createBinding(request, reply) {
6297
+ const tenantId = getTenantId12(request);
6298
+ try {
6299
+ const registry = getBindingRegistry();
6300
+ const binding = await registry.create({ ...request.body, tenantId });
6301
+ reply.status(201);
6302
+ return { success: true, message: "Binding created", data: binding };
6303
+ } catch (error) {
6304
+ console.error("Failed to create binding:", error);
6305
+ reply.status(500);
6306
+ return { success: false, message: "Failed to create binding" };
6307
+ }
6308
+ }
6309
+ async function updateBinding(request, reply) {
6310
+ try {
6311
+ const tenantId = getTenantId12(request);
6312
+ const registry = getBindingRegistry();
6313
+ const bindings = await registry.list({ tenantId });
6314
+ const existing = bindings.find((b) => b.id === request.params.id);
6315
+ if (!existing || existing.tenantId !== tenantId) {
6316
+ reply.status(404);
6317
+ return { success: false, message: "Binding not found" };
6318
+ }
6319
+ const binding = await registry.update(request.params.id, request.body);
6320
+ return { success: true, message: "Binding updated", data: binding };
6321
+ } catch (error) {
6322
+ console.error("Failed to update binding:", error);
6323
+ reply.status(500);
6324
+ return { success: false, message: "Failed to update binding" };
6325
+ }
6326
+ }
6327
+ async function deleteBinding(request, reply) {
6328
+ try {
6329
+ const tenantId = getTenantId12(request);
6330
+ const registry = getBindingRegistry();
6331
+ const bindings = await registry.list({ tenantId });
6332
+ const existing = bindings.find((b) => b.id === request.params.id);
6333
+ if (!existing || existing.tenantId !== tenantId) {
6334
+ reply.status(404);
6335
+ return { success: false, message: "Binding not found" };
6336
+ }
6337
+ await registry.delete(request.params.id);
6338
+ return { success: true, message: "Binding deleted" };
6339
+ } catch (error) {
6340
+ console.error("Failed to delete binding:", error);
6341
+ reply.status(500);
6342
+ return { success: false, message: "Failed to delete binding" };
6343
+ }
6344
+ }
6345
+ async function resolveBinding(request, _reply) {
6346
+ const tenantId = getTenantId12(request);
6347
+ const { channel, senderId, channelInstallationId } = request.query;
6348
+ try {
6349
+ const registry = getBindingRegistry();
6350
+ const binding = await registry.resolve({ channel, senderId, channelInstallationId, tenantId });
6351
+ if (!binding) {
6352
+ return { success: false, message: "No binding found", data: null };
6353
+ }
6354
+ return { success: true, message: "Binding found", data: binding };
6355
+ } catch (error) {
6356
+ console.error("Failed to resolve binding:", error);
6357
+ return { success: false, message: "Failed to resolve binding", data: null };
6358
+ }
6359
+ }
6360
+
6361
+ // src/routes/channel-bindings.ts
6362
+ function registerChannelBindingRoutes(app2) {
6363
+ app2.get("/api/channel-bindings", getBindingList);
6364
+ app2.get("/api/channel-bindings/resolve", resolveBinding);
6365
+ app2.post("/api/channel-bindings", createBinding);
6366
+ app2.get("/api/channel-bindings/:id", getBinding);
6367
+ app2.put("/api/channel-bindings/:id", updateBinding);
6368
+ app2.delete("/api/channel-bindings/:id", deleteBinding);
6369
+ }
6370
+
6396
6371
  // src/routes/index.ts
6397
- var registerLatticeRoutes = (app2) => {
6372
+ var registerLatticeRoutes = (app2, channelDeps) => {
6398
6373
  app2.post("/api/runs", createRun);
6399
6374
  app2.post("/api/resume_stream", resumeStream);
6400
6375
  app2.post("/api/assistants/:assistantId/threads/:threadId/abort", abortRun);
@@ -6529,8 +6504,46 @@ var registerLatticeRoutes = (app2) => {
6529
6504
  autoApproveUsers: process.env.AUTO_APPROVE_USERS !== "false",
6530
6505
  allowTenantRegistration: process.env.ALLOW_TENANT_REGISTRATION !== "false"
6531
6506
  });
6532
- registerChannelRoutes(app2);
6507
+ registerChannelRoutes(app2, channelDeps);
6533
6508
  registerChannelInstallationRoutes(app2);
6509
+ if (channelDeps) {
6510
+ registerChannelBindingRoutes(app2);
6511
+ }
6512
+ if (channelDeps?.router) {
6513
+ app2.post("/api/channels/inbound", async (request, reply) => {
6514
+ try {
6515
+ const router = channelDeps.router;
6516
+ const msg = request.body;
6517
+ if (!msg.channel || !msg.sender || !msg.content) {
6518
+ reply.status(400).send({
6519
+ success: false,
6520
+ message: "Missing required fields: channel, sender, content"
6521
+ });
6522
+ return;
6523
+ }
6524
+ const inboundMessage = {
6525
+ channel: msg.channel,
6526
+ channelInstallationId: msg.channelInstallationId || "",
6527
+ tenantId: msg.tenantId || "default",
6528
+ sender: {
6529
+ id: msg.sender.id,
6530
+ displayName: msg.sender.displayName
6531
+ },
6532
+ content: {
6533
+ text: msg.content.text
6534
+ },
6535
+ replyTarget: msg.replyTarget
6536
+ };
6537
+ await router.dispatch(inboundMessage).catch((error) => {
6538
+ console.error("Inbound dispatch error:", error);
6539
+ });
6540
+ reply.status(200).send({ accepted: true });
6541
+ } catch (error) {
6542
+ console.error("Inbound route error:", error);
6543
+ reply.status(500).send({ success: false, message: "Internal error" });
6544
+ }
6545
+ });
6546
+ }
6534
6547
  app2.get(
6535
6548
  "/api/workflows/definitions",
6536
6549
  getAllWorkflowDefinitions
@@ -6561,6 +6574,270 @@ var registerLatticeRoutes = (app2) => {
6561
6574
  );
6562
6575
  };
6563
6576
 
6577
+ // src/router/MessageRouter.ts
6578
+ import {
6579
+ getStoreLattice as getStoreLattice14,
6580
+ agentInstanceManager as agentInstanceManager6
6581
+ } from "@axiom-lattice/core";
6582
+ import { randomUUID as randomUUID7 } from "crypto";
6583
+ var BindingNotFoundError = class extends Error {
6584
+ constructor(message) {
6585
+ super(message);
6586
+ this.name = "BindingNotFoundError";
6587
+ }
6588
+ };
6589
+ var MessageRouter = class {
6590
+ constructor(config) {
6591
+ this.middlewares = [...config.middlewares];
6592
+ this.bindingRegistry = config.bindingRegistry;
6593
+ this.adapterRegistry = config.adapterRegistry;
6594
+ this.installationStore = config.installationStore;
6595
+ }
6596
+ use(middleware) {
6597
+ this.middlewares.push(middleware);
6598
+ }
6599
+ async dispatch(message) {
6600
+ const ctx = {
6601
+ inboundMessage: message,
6602
+ metadata: {}
6603
+ };
6604
+ try {
6605
+ await this.runMiddlewares(ctx, async () => {
6606
+ let binding = await this.bindingRegistry.resolve({
6607
+ channel: message.channel,
6608
+ senderId: message.sender.id,
6609
+ channelInstallationId: message.channelInstallationId,
6610
+ tenantId: message.tenantId
6611
+ });
6612
+ if (!binding) {
6613
+ const installation = await this.installationStore.getInstallationById(
6614
+ message.channelInstallationId
6615
+ );
6616
+ if (installation?.rejectWhenNoBinding) {
6617
+ throw new BindingNotFoundError(
6618
+ `No binding for sender "${message.sender.id}" on channel "${message.channel}"`
6619
+ );
6620
+ }
6621
+ if (installation?.fallbackAgentId) {
6622
+ binding = {
6623
+ id: "fallback",
6624
+ channel: message.channel,
6625
+ channelInstallationId: message.channelInstallationId,
6626
+ tenantId: message.tenantId,
6627
+ senderId: message.sender.id,
6628
+ agentId: installation.fallbackAgentId,
6629
+ threadId: void 0,
6630
+ threadMode: "fixed",
6631
+ enabled: true,
6632
+ createdAt: /* @__PURE__ */ new Date(),
6633
+ updatedAt: /* @__PURE__ */ new Date()
6634
+ };
6635
+ } else {
6636
+ throw new BindingNotFoundError(
6637
+ `No binding for sender "${message.sender.id}" and no fallback configured`
6638
+ );
6639
+ }
6640
+ }
6641
+ ctx.binding = binding;
6642
+ if (!binding.enabled) {
6643
+ throw new BindingNotFoundError(
6644
+ `Binding for sender "${message.sender.id}" is disabled`
6645
+ );
6646
+ }
6647
+ let threadId = ctx.binding.threadId;
6648
+ if (!threadId) {
6649
+ const threadStore = getStoreLattice14("default", "thread").store;
6650
+ const newThreadId = randomUUID7();
6651
+ const newThread = await threadStore.createThread(
6652
+ message.tenantId,
6653
+ ctx.binding.agentId,
6654
+ newThreadId,
6655
+ {
6656
+ metadata: {
6657
+ channel: message.channel,
6658
+ channelInstallationId: message.channelInstallationId,
6659
+ senderId: message.sender.id,
6660
+ bindingId: ctx.binding.id
6661
+ }
6662
+ }
6663
+ );
6664
+ threadId = newThread.id;
6665
+ if (ctx.binding.id !== "fallback") {
6666
+ await this.bindingRegistry.update(ctx.binding.id, { threadId });
6667
+ ctx.binding.threadId = threadId;
6668
+ } else {
6669
+ ctx.binding.threadId = threadId;
6670
+ }
6671
+ }
6672
+ const agent = agentInstanceManager6.getAgent({
6673
+ tenant_id: message.tenantId,
6674
+ assistant_id: ctx.binding.agentId,
6675
+ thread_id: threadId,
6676
+ workspace_id: ctx.binding.workspaceId || "",
6677
+ project_id: ctx.binding.projectId || ""
6678
+ });
6679
+ const invokeResult = await agent.invoke({
6680
+ input: { message: message.content.text }
6681
+ });
6682
+ ctx.result = extractTextFromInvokeResult(invokeResult);
6683
+ if (message.replyTarget) {
6684
+ const adapter = this.adapterRegistry.get(message.replyTarget.adapterChannel);
6685
+ if (adapter) {
6686
+ const installation = await this.installationStore.getInstallationById(
6687
+ message.channelInstallationId
6688
+ );
6689
+ if (installation) {
6690
+ await adapter.sendReply(
6691
+ message.replyTarget,
6692
+ { text: ctx.result },
6693
+ installation
6694
+ );
6695
+ }
6696
+ }
6697
+ }
6698
+ });
6699
+ return {
6700
+ success: true,
6701
+ bindingId: ctx.binding?.id,
6702
+ threadId: ctx.binding?.threadId,
6703
+ result: ctx.result
6704
+ };
6705
+ } catch (error) {
6706
+ ctx.error = error instanceof Error ? error : new Error(String(error));
6707
+ return {
6708
+ success: false,
6709
+ bindingId: ctx.binding?.id,
6710
+ threadId: ctx.binding?.threadId,
6711
+ error: ctx.error
6712
+ };
6713
+ }
6714
+ }
6715
+ async runMiddlewares(ctx, finalHandler) {
6716
+ const dispatch = (index) => {
6717
+ if (index >= this.middlewares.length) {
6718
+ return finalHandler();
6719
+ }
6720
+ const middleware = this.middlewares[index];
6721
+ return middleware(ctx, () => dispatch(index + 1));
6722
+ };
6723
+ return dispatch(0);
6724
+ }
6725
+ };
6726
+ function extractTextFromInvokeResult(result) {
6727
+ if (result && typeof result === "object" && "messages" in result) {
6728
+ const messages = result.messages;
6729
+ if (Array.isArray(messages)) {
6730
+ const aiMessages = messages.filter((m) => m.role === "ai");
6731
+ if (aiMessages.length > 0) {
6732
+ return aiMessages.map((m) => m.content).join("\n");
6733
+ }
6734
+ }
6735
+ }
6736
+ return JSON.stringify(result);
6737
+ }
6738
+
6739
+ // src/channels/registry.ts
6740
+ var ChannelAdapterRegistry = class {
6741
+ constructor() {
6742
+ this.adapters = /* @__PURE__ */ new Map();
6743
+ }
6744
+ register(adapter) {
6745
+ if (this.adapters.has(adapter.channel)) {
6746
+ throw new Error(`Channel adapter "${adapter.channel}" already registered`);
6747
+ }
6748
+ this.adapters.set(adapter.channel, adapter);
6749
+ }
6750
+ get(channel) {
6751
+ return this.adapters.get(channel);
6752
+ }
6753
+ list() {
6754
+ return Array.from(this.adapters.keys());
6755
+ }
6756
+ };
6757
+
6758
+ // src/router/middlewares/deduplication.ts
6759
+ var processedMessages = /* @__PURE__ */ new Map();
6760
+ function createDeduplicationMiddleware(ttlMs = 5 * 60 * 1e3) {
6761
+ return async (ctx, next) => {
6762
+ const msg = ctx.inboundMessage;
6763
+ const msgId = msg.content.metadata?.messageId;
6764
+ const key = msgId ? `${msg.channel}:${msg.channelInstallationId}:${msgId}` : `${msg.channel}:${msg.channelInstallationId}:${msg.sender.id}`;
6765
+ const now = Date.now();
6766
+ const lastProcessed = processedMessages.get(key);
6767
+ if (lastProcessed && now - lastProcessed < ttlMs) return;
6768
+ processedMessages.set(key, now);
6769
+ if (processedMessages.size > 1e4) {
6770
+ const oldest = Array.from(processedMessages.entries()).sort((a, b) => a[1] - b[1])[0];
6771
+ if (oldest) processedMessages.delete(oldest[0]);
6772
+ }
6773
+ await next();
6774
+ };
6775
+ }
6776
+
6777
+ // src/router/middlewares/rateLimit.ts
6778
+ var RateLimitError = class extends Error {
6779
+ constructor(message) {
6780
+ super(message);
6781
+ this.name = "RateLimitError";
6782
+ }
6783
+ };
6784
+ var rateCounters = /* @__PURE__ */ new Map();
6785
+ function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEntries = 1e4) {
6786
+ return async (ctx, next) => {
6787
+ const senderKey = `${ctx.inboundMessage.channel}:${ctx.inboundMessage.sender.id}`;
6788
+ const now = Date.now();
6789
+ let counter = rateCounters.get(senderKey);
6790
+ if (!counter || now > counter.resetAt) {
6791
+ counter = { count: 0, resetAt: now + windowMs };
6792
+ }
6793
+ counter.count++;
6794
+ rateCounters.set(senderKey, counter);
6795
+ if (rateCounters.size > maxEntries) {
6796
+ const oldest = Array.from(rateCounters.entries()).sort((a, b) => a[1].resetAt - b[1].resetAt)[0];
6797
+ if (oldest) rateCounters.delete(oldest[0]);
6798
+ }
6799
+ if (counter.count > maxRequests) {
6800
+ throw new RateLimitError(`Rate limit exceeded`);
6801
+ }
6802
+ await next();
6803
+ };
6804
+ }
6805
+
6806
+ // src/router/middlewares/auditLogger.ts
6807
+ var logger2 = new Logger({ serviceName: "lattice/gateway/audit" });
6808
+ function createAuditLoggerMiddleware() {
6809
+ return async (ctx, next) => {
6810
+ const start2 = Date.now();
6811
+ try {
6812
+ await next();
6813
+ logger2.info("message routed", {
6814
+ event: "message:routed",
6815
+ channel: ctx.inboundMessage.channel,
6816
+ senderId: ctx.inboundMessage.sender.id,
6817
+ agentId: ctx.binding?.agentId,
6818
+ threadId: ctx.binding?.threadId,
6819
+ duration: Date.now() - start2,
6820
+ status: "success"
6821
+ });
6822
+ } catch (error) {
6823
+ logger2.error(
6824
+ error instanceof Error ? error.message : String(error),
6825
+ {
6826
+ event: "message:error",
6827
+ channel: ctx.inboundMessage.channel,
6828
+ senderId: ctx.inboundMessage.sender.id,
6829
+ duration: Date.now() - start2,
6830
+ status: "error"
6831
+ }
6832
+ );
6833
+ throw error;
6834
+ }
6835
+ };
6836
+ }
6837
+
6838
+ // src/index.ts
6839
+ import { setBindingRegistry as setCoreBindingRegistry } from "@axiom-lattice/core";
6840
+
6564
6841
  // src/swagger.ts
6565
6842
  import swagger from "@fastify/swagger";
6566
6843
  import swaggerUi from "@fastify/swagger-ui";
@@ -6906,7 +7183,7 @@ var DEFAULT_LOGGER_CONFIG = {
6906
7183
  loggerName: "lattice/gateway"
6907
7184
  };
6908
7185
  var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
6909
- var logger = loggerLattice.client;
7186
+ var logger3 = loggerLattice.client;
6910
7187
  function initializeLogger(config) {
6911
7188
  if (loggerLatticeManager.hasLattice("default")) {
6912
7189
  loggerLatticeManager.removeLattice("default");
@@ -6999,7 +7276,7 @@ app.setErrorHandler((error, request, reply) => {
6999
7276
  "x-request-id": getHeaderValue(request.headers["x-request-id"]),
7000
7277
  "x-user-id": getHeaderValue(request.headers["x-user-id"])
7001
7278
  };
7002
- logger.error(
7279
+ logger3.error(
7003
7280
  `\u8BF7\u6C42\u9519\u8BEF: ${request.method} ${request.url} error:${error.message}`,
7004
7281
  {
7005
7282
  ...context,
@@ -7039,29 +7316,51 @@ var start = async (config) => {
7039
7316
  file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
7040
7317
  };
7041
7318
  loggerLattice = initializeLogger(loggerConfig);
7042
- logger = loggerLattice.client;
7319
+ logger3 = loggerLattice.client;
7043
7320
  }
7044
7321
  app.decorate("loggerLattice", loggerLattice);
7045
- registerLatticeRoutes(app);
7322
+ let channelDeps;
7323
+ try {
7324
+ const { getStoreLattice: getStoreLattice16 } = await import("@axiom-lattice/core");
7325
+ const bindingStore = getStoreLattice16("default", "channelBinding").store;
7326
+ const installationStore = getStoreLattice16("default", "channelInstallation").store;
7327
+ setBindingRegistry(bindingStore);
7328
+ setCoreBindingRegistry(bindingStore);
7329
+ const adapterRegistry = new ChannelAdapterRegistry();
7330
+ adapterRegistry.register(larkChannelAdapter);
7331
+ const router = new MessageRouter({
7332
+ middlewares: [
7333
+ createDeduplicationMiddleware(),
7334
+ createRateLimitMiddleware(),
7335
+ createAuditLoggerMiddleware()
7336
+ ],
7337
+ bindingRegistry: bindingStore,
7338
+ adapterRegistry,
7339
+ installationStore
7340
+ });
7341
+ channelDeps = { router, installationStore };
7342
+ } catch {
7343
+ }
7344
+ registerLatticeRoutes(app, channelDeps);
7046
7345
  try {
7047
7346
  const storeLattice = getStoreLattice15("default", "database");
7048
7347
  const store = storeLattice.store;
7049
7348
  sqlDatabaseManager2.setConfigStore(store);
7050
- logger.info("Database config store set for SqlDatabaseManager");
7349
+ logger3.info("Database config store set for SqlDatabaseManager");
7051
7350
  } catch (error) {
7052
- logger.warn("Failed to set database config store: " + (error instanceof Error ? error.message : String(error)));
7351
+ logger3.warn("Failed to set database config store: " + (error instanceof Error ? error.message : String(error)));
7053
7352
  }
7054
7353
  if (!sandboxLatticeManager2.hasLattice("default")) {
7055
7354
  sandboxLatticeManager2.registerLattice("default", getConfiguredSandboxProvider());
7056
- logger.info("Registered sandbox manager from env configuration");
7355
+ logger3.info("Registered sandbox manager from env configuration");
7057
7356
  }
7058
7357
  const target_port = config?.port || Number(process.env.PORT) || 4001;
7059
7358
  await app.listen({ port: target_port, host: "0.0.0.0" });
7060
- logger.info(`Lattice Gateway is running on port: ${target_port}`);
7359
+ logger3.info(`Lattice Gateway is running on port: ${target_port}`);
7061
7360
  try {
7062
- logger.info("AgentLifecycleManager initialized");
7361
+ logger3.info("AgentLifecycleManager initialized");
7063
7362
  } catch (error) {
7064
- logger.warn("Failed to initialize AgentLifecycleManager", { error });
7363
+ logger3.warn("Failed to initialize AgentLifecycleManager", { error });
7065
7364
  }
7066
7365
  const queueServiceConfig = config?.queueServiceConfig;
7067
7366
  if (queueServiceConfig) {
@@ -7072,14 +7371,14 @@ var start = async (config) => {
7072
7371
  }
7073
7372
  }
7074
7373
  try {
7075
- logger.info("Starting agent instance recovery...");
7374
+ logger3.info("Starting agent instance recovery...");
7076
7375
  const restoreStats = await agentInstanceManager8.restore();
7077
- logger.info(`Agent recovery complete: ${restoreStats.restored} threads restored, ${restoreStats.errors} errors`);
7376
+ logger3.info(`Agent recovery complete: ${restoreStats.restored} threads restored, ${restoreStats.errors} errors`);
7078
7377
  } catch (error) {
7079
- logger.error("Agent recovery failed", { error });
7378
+ logger3.error("Agent recovery failed", { error });
7080
7379
  }
7081
7380
  } catch (err) {
7082
- logger.error("Server start failed", { error: err });
7381
+ logger3.error("Server start failed", { error: err });
7083
7382
  process.exit(1);
7084
7383
  }
7085
7384
  };