@axiom-lattice/gateway 2.1.81 → 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 +6 -0
- package/dist/index.js +64 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -2
- package/src/router/MessageRouter.ts +32 -0
- package/src/router/middlewares/deduplication.ts +19 -6
- package/src/router/middlewares/rateLimit.ts +8 -0
- package/src/routes/index.ts +6 -1
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -6642,7 +6642,12 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
6642
6642
|
replyTarget: msg.replyTarget
|
|
6643
6643
|
};
|
|
6644
6644
|
await router.dispatch(inboundMessage).catch((error) => {
|
|
6645
|
-
console.error(
|
|
6645
|
+
console.error(JSON.stringify({
|
|
6646
|
+
event: "inbound:dispatch_error",
|
|
6647
|
+
error: error instanceof Error ? error.message : String(error),
|
|
6648
|
+
channel: inboundMessage.channel,
|
|
6649
|
+
senderId: inboundMessage.sender.id
|
|
6650
|
+
}));
|
|
6646
6651
|
});
|
|
6647
6652
|
reply.status(200).send({ accepted: true });
|
|
6648
6653
|
} catch (error) {
|
|
@@ -6711,6 +6716,13 @@ var MessageRouter = class {
|
|
|
6711
6716
|
await this.runMiddlewares(ctx, async () => {
|
|
6712
6717
|
const tenantId = message.tenantId || (await this.installationStore.getInstallationById(message.channelInstallationId))?.tenantId;
|
|
6713
6718
|
if (!tenantId) {
|
|
6719
|
+
this.logger?.error({
|
|
6720
|
+
event: "dispatch:error",
|
|
6721
|
+
error: "tenantId missing",
|
|
6722
|
+
channel: message.channel,
|
|
6723
|
+
channelInstallationId: message.channelInstallationId,
|
|
6724
|
+
senderId: message.sender.id
|
|
6725
|
+
}, "tenantId is required");
|
|
6714
6726
|
throw new Error(
|
|
6715
6727
|
"tenantId is required: provide it in the message or ensure the channelInstallation has a tenantId"
|
|
6716
6728
|
);
|
|
@@ -6727,11 +6739,24 @@ var MessageRouter = class {
|
|
|
6727
6739
|
message.channelInstallationId
|
|
6728
6740
|
);
|
|
6729
6741
|
if (installation?.rejectWhenNoBinding) {
|
|
6742
|
+
this.logger?.warn({
|
|
6743
|
+
event: "dispatch:no_binding",
|
|
6744
|
+
channel: message.channel,
|
|
6745
|
+
senderId: message.sender.id,
|
|
6746
|
+
tenantId,
|
|
6747
|
+
channelInstallationId: message.channelInstallationId
|
|
6748
|
+
}, "No binding found and rejectWhenNoBinding is enabled");
|
|
6730
6749
|
throw new BindingNotFoundError(
|
|
6731
6750
|
`No binding for sender "${message.sender.id}" on channel "${message.channel}"`
|
|
6732
6751
|
);
|
|
6733
6752
|
}
|
|
6734
6753
|
if (installation?.fallbackAgentId) {
|
|
6754
|
+
this.logger?.warn({
|
|
6755
|
+
event: "dispatch:fallback",
|
|
6756
|
+
channel: message.channel,
|
|
6757
|
+
senderId: message.sender.id,
|
|
6758
|
+
fallbackAgentId: installation.fallbackAgentId
|
|
6759
|
+
}, "No binding found, falling back to fallbackAgentId");
|
|
6735
6760
|
binding = {
|
|
6736
6761
|
id: "fallback",
|
|
6737
6762
|
channel: message.channel,
|
|
@@ -6746,6 +6771,12 @@ var MessageRouter = class {
|
|
|
6746
6771
|
updatedAt: /* @__PURE__ */ new Date()
|
|
6747
6772
|
};
|
|
6748
6773
|
} else {
|
|
6774
|
+
this.logger?.error({
|
|
6775
|
+
event: "dispatch:no_fallback",
|
|
6776
|
+
channel: message.channel,
|
|
6777
|
+
senderId: message.sender.id,
|
|
6778
|
+
tenantId
|
|
6779
|
+
}, "No binding found and no fallbackAgentId configured");
|
|
6749
6780
|
throw new BindingNotFoundError(
|
|
6750
6781
|
`No binding for sender "${message.sender.id}" and no fallback configured`
|
|
6751
6782
|
);
|
|
@@ -6769,6 +6800,12 @@ var MessageRouter = class {
|
|
|
6769
6800
|
}, "per_conversation mode active \u2014 thread lookup by conversation not yet implemented, using binding.threadId");
|
|
6770
6801
|
}
|
|
6771
6802
|
if (!binding.enabled) {
|
|
6803
|
+
this.logger?.warn({
|
|
6804
|
+
event: "dispatch:binding_disabled",
|
|
6805
|
+
bindingId: binding.id,
|
|
6806
|
+
agentId: binding.agentId,
|
|
6807
|
+
senderId: message.sender.id
|
|
6808
|
+
}, "Binding is disabled, rejecting message");
|
|
6772
6809
|
throw new BindingNotFoundError(
|
|
6773
6810
|
`Binding for sender "${message.sender.id}" is disabled`
|
|
6774
6811
|
);
|
|
@@ -6896,15 +6933,25 @@ var ChannelAdapterRegistry = class {
|
|
|
6896
6933
|
|
|
6897
6934
|
// src/router/middlewares/deduplication.ts
|
|
6898
6935
|
var processedMessages = /* @__PURE__ */ new Map();
|
|
6899
|
-
function createDeduplicationMiddleware(ttlMs = 5 * 60 * 1e3) {
|
|
6936
|
+
function createDeduplicationMiddleware(ttlMs = 5 * 60 * 1e3, logger4) {
|
|
6900
6937
|
return async (ctx, next) => {
|
|
6901
6938
|
const msg = ctx.inboundMessage;
|
|
6902
6939
|
const msgId = msg.content.metadata?.messageId;
|
|
6903
|
-
const key = msgId ? `${msg.channel}:${msg.channelInstallationId}:${msgId}` :
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6940
|
+
const key = msgId ? `${msg.channel}:${msg.channelInstallationId}:${msgId}` : null;
|
|
6941
|
+
if (key) {
|
|
6942
|
+
const now = Date.now();
|
|
6943
|
+
const lastProcessed = processedMessages.get(key);
|
|
6944
|
+
if (lastProcessed && now - lastProcessed < ttlMs) {
|
|
6945
|
+
logger4?.warn({
|
|
6946
|
+
event: "dedup:blocked",
|
|
6947
|
+
channel: msg.channel,
|
|
6948
|
+
senderId: msg.sender.id,
|
|
6949
|
+
messageId: msgId
|
|
6950
|
+
}, "Duplicate message blocked by deduplication");
|
|
6951
|
+
return;
|
|
6952
|
+
}
|
|
6953
|
+
processedMessages.set(key, now);
|
|
6954
|
+
}
|
|
6908
6955
|
if (processedMessages.size > 1e4) {
|
|
6909
6956
|
const oldest = Array.from(processedMessages.entries()).sort((a, b) => a[1] - b[1])[0];
|
|
6910
6957
|
if (oldest) processedMessages.delete(oldest[0]);
|
|
@@ -6921,7 +6968,7 @@ var RateLimitError = class extends Error {
|
|
|
6921
6968
|
}
|
|
6922
6969
|
};
|
|
6923
6970
|
var rateCounters = /* @__PURE__ */ new Map();
|
|
6924
|
-
function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEntries = 1e4) {
|
|
6971
|
+
function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEntries = 1e4, logger4) {
|
|
6925
6972
|
return async (ctx, next) => {
|
|
6926
6973
|
const senderKey = `${ctx.inboundMessage.channel}:${ctx.inboundMessage.sender.id}`;
|
|
6927
6974
|
const now = Date.now();
|
|
@@ -6936,6 +6983,13 @@ function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEnt
|
|
|
6936
6983
|
if (oldest) rateCounters.delete(oldest[0]);
|
|
6937
6984
|
}
|
|
6938
6985
|
if (counter.count > maxRequests) {
|
|
6986
|
+
logger4?.warn({
|
|
6987
|
+
event: "ratelimit:blocked",
|
|
6988
|
+
channel: ctx.inboundMessage.channel,
|
|
6989
|
+
senderId: ctx.inboundMessage.sender.id,
|
|
6990
|
+
count: counter.count,
|
|
6991
|
+
maxRequests
|
|
6992
|
+
}, "Rate limit exceeded");
|
|
6939
6993
|
throw new RateLimitError(`Rate limit exceeded`);
|
|
6940
6994
|
}
|
|
6941
6995
|
await next();
|
|
@@ -7459,8 +7513,8 @@ var start = async (config) => {
|
|
|
7459
7513
|
adapterRegistry.register(larkChannelAdapter);
|
|
7460
7514
|
const router = new MessageRouter({
|
|
7461
7515
|
middlewares: [
|
|
7462
|
-
createDeduplicationMiddleware(),
|
|
7463
|
-
createRateLimitMiddleware(),
|
|
7516
|
+
createDeduplicationMiddleware(void 0, logger3),
|
|
7517
|
+
createRateLimitMiddleware(void 0, void 0, void 0, logger3),
|
|
7464
7518
|
createAuditLoggerMiddleware()
|
|
7465
7519
|
],
|
|
7466
7520
|
bindingRegistry: bindingStore,
|