@axiom-lattice/gateway 2.1.80 → 2.1.82
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/CHANGELOG.md +16 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +110 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +110 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +3 -2
- package/src/router/MessageRouter.ts +83 -18
- package/src/router/middlewares/deduplication.ts +19 -6
- package/src/router/middlewares/rateLimit.ts +8 -0
- package/src/routes/index.ts +6 -1
- package/.turbo/turbo-build.log +0 -32
package/dist/index.mjs
CHANGED
|
@@ -6587,7 +6587,12 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
6587
6587
|
replyTarget: msg.replyTarget
|
|
6588
6588
|
};
|
|
6589
6589
|
await router.dispatch(inboundMessage).catch((error) => {
|
|
6590
|
-
console.error(
|
|
6590
|
+
console.error(JSON.stringify({
|
|
6591
|
+
event: "inbound:dispatch_error",
|
|
6592
|
+
error: error instanceof Error ? error.message : String(error),
|
|
6593
|
+
channel: inboundMessage.channel,
|
|
6594
|
+
senderId: inboundMessage.sender.id
|
|
6595
|
+
}));
|
|
6591
6596
|
});
|
|
6592
6597
|
reply.status(200).send({ accepted: true });
|
|
6593
6598
|
} catch (error) {
|
|
@@ -6645,6 +6650,7 @@ var MessageRouter = class {
|
|
|
6645
6650
|
this.bindingRegistry = config.bindingRegistry;
|
|
6646
6651
|
this.adapterRegistry = config.adapterRegistry;
|
|
6647
6652
|
this.installationStore = config.installationStore;
|
|
6653
|
+
this.logger = config.logger;
|
|
6648
6654
|
}
|
|
6649
6655
|
use(middleware) {
|
|
6650
6656
|
this.middlewares.push(middleware);
|
|
@@ -6658,10 +6664,18 @@ var MessageRouter = class {
|
|
|
6658
6664
|
await this.runMiddlewares(ctx, async () => {
|
|
6659
6665
|
const tenantId = message.tenantId || (await this.installationStore.getInstallationById(message.channelInstallationId))?.tenantId;
|
|
6660
6666
|
if (!tenantId) {
|
|
6667
|
+
this.logger?.error({
|
|
6668
|
+
event: "dispatch:error",
|
|
6669
|
+
error: "tenantId missing",
|
|
6670
|
+
channel: message.channel,
|
|
6671
|
+
channelInstallationId: message.channelInstallationId,
|
|
6672
|
+
senderId: message.sender.id
|
|
6673
|
+
}, "tenantId is required");
|
|
6661
6674
|
throw new Error(
|
|
6662
6675
|
"tenantId is required: provide it in the message or ensure the channelInstallation has a tenantId"
|
|
6663
6676
|
);
|
|
6664
6677
|
}
|
|
6678
|
+
this.logger?.info({ event: "dispatch:start", channel: message.channel, senderId: message.sender.id, tenantId }, "Message dispatch started");
|
|
6665
6679
|
let binding = await this.bindingRegistry.resolve({
|
|
6666
6680
|
channel: message.channel,
|
|
6667
6681
|
senderId: message.sender.id,
|
|
@@ -6673,11 +6687,24 @@ var MessageRouter = class {
|
|
|
6673
6687
|
message.channelInstallationId
|
|
6674
6688
|
);
|
|
6675
6689
|
if (installation?.rejectWhenNoBinding) {
|
|
6690
|
+
this.logger?.warn({
|
|
6691
|
+
event: "dispatch:no_binding",
|
|
6692
|
+
channel: message.channel,
|
|
6693
|
+
senderId: message.sender.id,
|
|
6694
|
+
tenantId,
|
|
6695
|
+
channelInstallationId: message.channelInstallationId
|
|
6696
|
+
}, "No binding found and rejectWhenNoBinding is enabled");
|
|
6676
6697
|
throw new BindingNotFoundError(
|
|
6677
6698
|
`No binding for sender "${message.sender.id}" on channel "${message.channel}"`
|
|
6678
6699
|
);
|
|
6679
6700
|
}
|
|
6680
6701
|
if (installation?.fallbackAgentId) {
|
|
6702
|
+
this.logger?.warn({
|
|
6703
|
+
event: "dispatch:fallback",
|
|
6704
|
+
channel: message.channel,
|
|
6705
|
+
senderId: message.sender.id,
|
|
6706
|
+
fallbackAgentId: installation.fallbackAgentId
|
|
6707
|
+
}, "No binding found, falling back to fallbackAgentId");
|
|
6681
6708
|
binding = {
|
|
6682
6709
|
id: "fallback",
|
|
6683
6710
|
channel: message.channel,
|
|
@@ -6692,13 +6719,41 @@ var MessageRouter = class {
|
|
|
6692
6719
|
updatedAt: /* @__PURE__ */ new Date()
|
|
6693
6720
|
};
|
|
6694
6721
|
} else {
|
|
6722
|
+
this.logger?.error({
|
|
6723
|
+
event: "dispatch:no_fallback",
|
|
6724
|
+
channel: message.channel,
|
|
6725
|
+
senderId: message.sender.id,
|
|
6726
|
+
tenantId
|
|
6727
|
+
}, "No binding found and no fallbackAgentId configured");
|
|
6695
6728
|
throw new BindingNotFoundError(
|
|
6696
6729
|
`No binding for sender "${message.sender.id}" and no fallback configured`
|
|
6697
6730
|
);
|
|
6698
6731
|
}
|
|
6699
6732
|
}
|
|
6700
6733
|
ctx.binding = binding;
|
|
6734
|
+
this.logger?.info({
|
|
6735
|
+
event: "dispatch:binding",
|
|
6736
|
+
bindingId: binding.id,
|
|
6737
|
+
agentId: binding.agentId,
|
|
6738
|
+
threadId: binding.threadId,
|
|
6739
|
+
threadMode: binding.threadMode,
|
|
6740
|
+
workspaceId: binding.workspaceId,
|
|
6741
|
+
projectId: binding.projectId
|
|
6742
|
+
}, "Binding resolved");
|
|
6743
|
+
if (binding.threadMode === "per_conversation") {
|
|
6744
|
+
this.logger?.warn({
|
|
6745
|
+
event: "dispatch:per_conversation",
|
|
6746
|
+
bindingId: binding.id,
|
|
6747
|
+
conversationId: message.conversation?.id
|
|
6748
|
+
}, "per_conversation mode active \u2014 thread lookup by conversation not yet implemented, using binding.threadId");
|
|
6749
|
+
}
|
|
6701
6750
|
if (!binding.enabled) {
|
|
6751
|
+
this.logger?.warn({
|
|
6752
|
+
event: "dispatch:binding_disabled",
|
|
6753
|
+
bindingId: binding.id,
|
|
6754
|
+
agentId: binding.agentId,
|
|
6755
|
+
senderId: message.sender.id
|
|
6756
|
+
}, "Binding is disabled, rejecting message");
|
|
6702
6757
|
throw new BindingNotFoundError(
|
|
6703
6758
|
`Binding for sender "${message.sender.id}" is disabled`
|
|
6704
6759
|
);
|
|
@@ -6707,6 +6762,12 @@ var MessageRouter = class {
|
|
|
6707
6762
|
if (!threadId) {
|
|
6708
6763
|
const threadStore = getStoreLattice14("default", "thread").store;
|
|
6709
6764
|
const newThreadId = randomUUID7();
|
|
6765
|
+
this.logger?.info({
|
|
6766
|
+
event: "dispatch:thread:create",
|
|
6767
|
+
agentId: ctx.binding.agentId,
|
|
6768
|
+
newThreadId,
|
|
6769
|
+
tenantId
|
|
6770
|
+
}, "Creating new thread for binding");
|
|
6710
6771
|
const newThread = await threadStore.createThread(
|
|
6711
6772
|
tenantId,
|
|
6712
6773
|
ctx.binding.agentId,
|
|
@@ -6728,6 +6789,14 @@ var MessageRouter = class {
|
|
|
6728
6789
|
ctx.binding.threadId = threadId;
|
|
6729
6790
|
}
|
|
6730
6791
|
}
|
|
6792
|
+
this.logger?.info({
|
|
6793
|
+
event: "dispatch:agent",
|
|
6794
|
+
agentId: ctx.binding.agentId,
|
|
6795
|
+
threadId,
|
|
6796
|
+
threadMode: ctx.binding.threadMode,
|
|
6797
|
+
senderId: message.sender.id,
|
|
6798
|
+
contentLength: message.content.text.length
|
|
6799
|
+
}, "Dispatching to agent");
|
|
6731
6800
|
const agent = agentInstanceManager6.getAgent({
|
|
6732
6801
|
tenant_id: tenantId,
|
|
6733
6802
|
assistant_id: ctx.binding.agentId,
|
|
@@ -6735,10 +6804,17 @@ var MessageRouter = class {
|
|
|
6735
6804
|
workspace_id: ctx.binding.workspaceId || "",
|
|
6736
6805
|
project_id: ctx.binding.projectId || ""
|
|
6737
6806
|
});
|
|
6738
|
-
const
|
|
6739
|
-
input: { message: message.content.text }
|
|
6807
|
+
const addResult = await agent.addMessage({
|
|
6808
|
+
input: { message: message.content.text },
|
|
6809
|
+
custom_run_config: message.content.metadata || {}
|
|
6740
6810
|
});
|
|
6741
|
-
|
|
6811
|
+
this.logger?.info({
|
|
6812
|
+
event: "dispatch:complete",
|
|
6813
|
+
agentId: ctx.binding.agentId,
|
|
6814
|
+
threadId,
|
|
6815
|
+
messageId: addResult?.messageId,
|
|
6816
|
+
result: JSON.stringify(addResult)
|
|
6817
|
+
}, "Agent dispatch complete \u2014 messageId = " + (addResult?.messageId || "N/A"));
|
|
6742
6818
|
if (message.replyTarget) {
|
|
6743
6819
|
const adapter = this.adapterRegistry.get(message.replyTarget.adapterChannel);
|
|
6744
6820
|
if (adapter) {
|
|
@@ -6748,7 +6824,7 @@ var MessageRouter = class {
|
|
|
6748
6824
|
if (installation) {
|
|
6749
6825
|
await adapter.sendReply(
|
|
6750
6826
|
message.replyTarget,
|
|
6751
|
-
{ text: ctx.result },
|
|
6827
|
+
{ text: ctx.result || "" },
|
|
6752
6828
|
installation
|
|
6753
6829
|
);
|
|
6754
6830
|
}
|
|
@@ -6763,6 +6839,7 @@ var MessageRouter = class {
|
|
|
6763
6839
|
};
|
|
6764
6840
|
} catch (error) {
|
|
6765
6841
|
ctx.error = error instanceof Error ? error : new Error(String(error));
|
|
6842
|
+
this.logger?.error({ event: "dispatch:error", error: ctx.error.message, channel: message.channel, senderId: message.sender.id }, "Message dispatch failed");
|
|
6766
6843
|
return {
|
|
6767
6844
|
success: false,
|
|
6768
6845
|
bindingId: ctx.binding?.id,
|
|
@@ -6782,18 +6859,6 @@ var MessageRouter = class {
|
|
|
6782
6859
|
return dispatch(0);
|
|
6783
6860
|
}
|
|
6784
6861
|
};
|
|
6785
|
-
function extractTextFromInvokeResult(result) {
|
|
6786
|
-
if (result && typeof result === "object" && "messages" in result) {
|
|
6787
|
-
const messages = result.messages;
|
|
6788
|
-
if (Array.isArray(messages)) {
|
|
6789
|
-
const aiMessages = messages.filter((m) => m.role === "ai");
|
|
6790
|
-
if (aiMessages.length > 0) {
|
|
6791
|
-
return aiMessages.map((m) => m.content).join("\n");
|
|
6792
|
-
}
|
|
6793
|
-
}
|
|
6794
|
-
}
|
|
6795
|
-
return JSON.stringify(result);
|
|
6796
|
-
}
|
|
6797
6862
|
|
|
6798
6863
|
// src/channels/registry.ts
|
|
6799
6864
|
var ChannelAdapterRegistry = class {
|
|
@@ -6816,15 +6881,25 @@ var ChannelAdapterRegistry = class {
|
|
|
6816
6881
|
|
|
6817
6882
|
// src/router/middlewares/deduplication.ts
|
|
6818
6883
|
var processedMessages = /* @__PURE__ */ new Map();
|
|
6819
|
-
function createDeduplicationMiddleware(ttlMs = 5 * 60 * 1e3) {
|
|
6884
|
+
function createDeduplicationMiddleware(ttlMs = 5 * 60 * 1e3, logger4) {
|
|
6820
6885
|
return async (ctx, next) => {
|
|
6821
6886
|
const msg = ctx.inboundMessage;
|
|
6822
6887
|
const msgId = msg.content.metadata?.messageId;
|
|
6823
|
-
const key = msgId ? `${msg.channel}:${msg.channelInstallationId}:${msgId}` :
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6888
|
+
const key = msgId ? `${msg.channel}:${msg.channelInstallationId}:${msgId}` : null;
|
|
6889
|
+
if (key) {
|
|
6890
|
+
const now = Date.now();
|
|
6891
|
+
const lastProcessed = processedMessages.get(key);
|
|
6892
|
+
if (lastProcessed && now - lastProcessed < ttlMs) {
|
|
6893
|
+
logger4?.warn({
|
|
6894
|
+
event: "dedup:blocked",
|
|
6895
|
+
channel: msg.channel,
|
|
6896
|
+
senderId: msg.sender.id,
|
|
6897
|
+
messageId: msgId
|
|
6898
|
+
}, "Duplicate message blocked by deduplication");
|
|
6899
|
+
return;
|
|
6900
|
+
}
|
|
6901
|
+
processedMessages.set(key, now);
|
|
6902
|
+
}
|
|
6828
6903
|
if (processedMessages.size > 1e4) {
|
|
6829
6904
|
const oldest = Array.from(processedMessages.entries()).sort((a, b) => a[1] - b[1])[0];
|
|
6830
6905
|
if (oldest) processedMessages.delete(oldest[0]);
|
|
@@ -6841,7 +6916,7 @@ var RateLimitError = class extends Error {
|
|
|
6841
6916
|
}
|
|
6842
6917
|
};
|
|
6843
6918
|
var rateCounters = /* @__PURE__ */ new Map();
|
|
6844
|
-
function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEntries = 1e4) {
|
|
6919
|
+
function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEntries = 1e4, logger4) {
|
|
6845
6920
|
return async (ctx, next) => {
|
|
6846
6921
|
const senderKey = `${ctx.inboundMessage.channel}:${ctx.inboundMessage.sender.id}`;
|
|
6847
6922
|
const now = Date.now();
|
|
@@ -6856,6 +6931,13 @@ function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEnt
|
|
|
6856
6931
|
if (oldest) rateCounters.delete(oldest[0]);
|
|
6857
6932
|
}
|
|
6858
6933
|
if (counter.count > maxRequests) {
|
|
6934
|
+
logger4?.warn({
|
|
6935
|
+
event: "ratelimit:blocked",
|
|
6936
|
+
channel: ctx.inboundMessage.channel,
|
|
6937
|
+
senderId: ctx.inboundMessage.sender.id,
|
|
6938
|
+
count: counter.count,
|
|
6939
|
+
maxRequests
|
|
6940
|
+
}, "Rate limit exceeded");
|
|
6859
6941
|
throw new RateLimitError(`Rate limit exceeded`);
|
|
6860
6942
|
}
|
|
6861
6943
|
await next();
|
|
@@ -7389,13 +7471,14 @@ var start = async (config) => {
|
|
|
7389
7471
|
adapterRegistry.register(larkChannelAdapter);
|
|
7390
7472
|
const router = new MessageRouter({
|
|
7391
7473
|
middlewares: [
|
|
7392
|
-
createDeduplicationMiddleware(),
|
|
7393
|
-
createRateLimitMiddleware(),
|
|
7474
|
+
createDeduplicationMiddleware(void 0, logger3),
|
|
7475
|
+
createRateLimitMiddleware(void 0, void 0, void 0, logger3),
|
|
7394
7476
|
createAuditLoggerMiddleware()
|
|
7395
7477
|
],
|
|
7396
7478
|
bindingRegistry: bindingStore,
|
|
7397
7479
|
adapterRegistry,
|
|
7398
|
-
installationStore
|
|
7480
|
+
installationStore,
|
|
7481
|
+
logger: logger3
|
|
7399
7482
|
});
|
|
7400
7483
|
channelDeps = { router, installationStore };
|
|
7401
7484
|
} catch {
|