@axiom-lattice/gateway 2.1.81 → 2.1.83
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/.turbo/turbo-build.log +32 -0
- package/CHANGELOG.md +18 -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 +6 -6
- 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/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) {
|
|
@@ -6659,6 +6664,13 @@ var MessageRouter = class {
|
|
|
6659
6664
|
await this.runMiddlewares(ctx, async () => {
|
|
6660
6665
|
const tenantId = message.tenantId || (await this.installationStore.getInstallationById(message.channelInstallationId))?.tenantId;
|
|
6661
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");
|
|
6662
6674
|
throw new Error(
|
|
6663
6675
|
"tenantId is required: provide it in the message or ensure the channelInstallation has a tenantId"
|
|
6664
6676
|
);
|
|
@@ -6675,11 +6687,24 @@ var MessageRouter = class {
|
|
|
6675
6687
|
message.channelInstallationId
|
|
6676
6688
|
);
|
|
6677
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");
|
|
6678
6697
|
throw new BindingNotFoundError(
|
|
6679
6698
|
`No binding for sender "${message.sender.id}" on channel "${message.channel}"`
|
|
6680
6699
|
);
|
|
6681
6700
|
}
|
|
6682
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");
|
|
6683
6708
|
binding = {
|
|
6684
6709
|
id: "fallback",
|
|
6685
6710
|
channel: message.channel,
|
|
@@ -6694,6 +6719,12 @@ var MessageRouter = class {
|
|
|
6694
6719
|
updatedAt: /* @__PURE__ */ new Date()
|
|
6695
6720
|
};
|
|
6696
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");
|
|
6697
6728
|
throw new BindingNotFoundError(
|
|
6698
6729
|
`No binding for sender "${message.sender.id}" and no fallback configured`
|
|
6699
6730
|
);
|
|
@@ -6717,6 +6748,12 @@ var MessageRouter = class {
|
|
|
6717
6748
|
}, "per_conversation mode active \u2014 thread lookup by conversation not yet implemented, using binding.threadId");
|
|
6718
6749
|
}
|
|
6719
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");
|
|
6720
6757
|
throw new BindingNotFoundError(
|
|
6721
6758
|
`Binding for sender "${message.sender.id}" is disabled`
|
|
6722
6759
|
);
|
|
@@ -6844,15 +6881,25 @@ var ChannelAdapterRegistry = class {
|
|
|
6844
6881
|
|
|
6845
6882
|
// src/router/middlewares/deduplication.ts
|
|
6846
6883
|
var processedMessages = /* @__PURE__ */ new Map();
|
|
6847
|
-
function createDeduplicationMiddleware(ttlMs = 5 * 60 * 1e3) {
|
|
6884
|
+
function createDeduplicationMiddleware(ttlMs = 5 * 60 * 1e3, logger4) {
|
|
6848
6885
|
return async (ctx, next) => {
|
|
6849
6886
|
const msg = ctx.inboundMessage;
|
|
6850
6887
|
const msgId = msg.content.metadata?.messageId;
|
|
6851
|
-
const key = msgId ? `${msg.channel}:${msg.channelInstallationId}:${msgId}` :
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
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
|
+
}
|
|
6856
6903
|
if (processedMessages.size > 1e4) {
|
|
6857
6904
|
const oldest = Array.from(processedMessages.entries()).sort((a, b) => a[1] - b[1])[0];
|
|
6858
6905
|
if (oldest) processedMessages.delete(oldest[0]);
|
|
@@ -6869,7 +6916,7 @@ var RateLimitError = class extends Error {
|
|
|
6869
6916
|
}
|
|
6870
6917
|
};
|
|
6871
6918
|
var rateCounters = /* @__PURE__ */ new Map();
|
|
6872
|
-
function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEntries = 1e4) {
|
|
6919
|
+
function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEntries = 1e4, logger4) {
|
|
6873
6920
|
return async (ctx, next) => {
|
|
6874
6921
|
const senderKey = `${ctx.inboundMessage.channel}:${ctx.inboundMessage.sender.id}`;
|
|
6875
6922
|
const now = Date.now();
|
|
@@ -6884,6 +6931,13 @@ function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEnt
|
|
|
6884
6931
|
if (oldest) rateCounters.delete(oldest[0]);
|
|
6885
6932
|
}
|
|
6886
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");
|
|
6887
6941
|
throw new RateLimitError(`Rate limit exceeded`);
|
|
6888
6942
|
}
|
|
6889
6943
|
await next();
|
|
@@ -7417,8 +7471,8 @@ var start = async (config) => {
|
|
|
7417
7471
|
adapterRegistry.register(larkChannelAdapter);
|
|
7418
7472
|
const router = new MessageRouter({
|
|
7419
7473
|
middlewares: [
|
|
7420
|
-
createDeduplicationMiddleware(),
|
|
7421
|
-
createRateLimitMiddleware(),
|
|
7474
|
+
createDeduplicationMiddleware(void 0, logger3),
|
|
7475
|
+
createRateLimitMiddleware(void 0, void 0, void 0, logger3),
|
|
7422
7476
|
createAuditLoggerMiddleware()
|
|
7423
7477
|
],
|
|
7424
7478
|
bindingRegistry: bindingStore,
|