@axiom-lattice/gateway 2.1.88 → 2.1.89
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 +10 -10
- package/AGENTS.md +62 -0
- package/CHANGELOG.md +10 -0
- package/dist/index.d.mts +62 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +105 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +105 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/router/MessageRouter.ts +169 -17
package/dist/index.mjs
CHANGED
|
@@ -6637,14 +6637,39 @@ var BindingNotFoundError = class extends Error {
|
|
|
6637
6637
|
};
|
|
6638
6638
|
var MessageRouter = class {
|
|
6639
6639
|
constructor(config) {
|
|
6640
|
+
/**
|
|
6641
|
+
* Tracks reply subscriptions per thread+channel to avoid duplicate
|
|
6642
|
+
* `subscribeOnce` registrations and ensure proper cleanup.
|
|
6643
|
+
*
|
|
6644
|
+
* Key format: `{threadId}:{adapterChannel}:reply`
|
|
6645
|
+
*/
|
|
6646
|
+
this._replySubs = /* @__PURE__ */ new Map();
|
|
6640
6647
|
this.middlewares = [...config.middlewares];
|
|
6641
6648
|
this.bindingRegistry = config.bindingRegistry;
|
|
6642
6649
|
this.adapterRegistry = config.adapterRegistry;
|
|
6643
6650
|
this.installationStore = config.installationStore;
|
|
6644
6651
|
}
|
|
6652
|
+
/**
|
|
6653
|
+
* Register an additional middleware at the end of the chain.
|
|
6654
|
+
*
|
|
6655
|
+
* @param middleware - A {@link MessageMiddleware} function
|
|
6656
|
+
*/
|
|
6645
6657
|
use(middleware) {
|
|
6646
6658
|
this.middlewares.push(middleware);
|
|
6647
6659
|
}
|
|
6660
|
+
/**
|
|
6661
|
+
* Dispatch an inbound channel message to the bound agent.
|
|
6662
|
+
*
|
|
6663
|
+
* Full pipeline: middleware chain → binding resolution → thread lifecycle
|
|
6664
|
+
* → agent.addMessage() → (async) reply via {@link ChannelAdapter.sendReply}.
|
|
6665
|
+
*
|
|
6666
|
+
* If the message has a {@link InboundMessage.replyTarget}, the router subscribes
|
|
6667
|
+
* to the agent's `reply:ready` event before enqueuing the message, and sends
|
|
6668
|
+
* the AI response back to the channel when it arrives.
|
|
6669
|
+
*
|
|
6670
|
+
* @param message - Normalized inbound message from a channel adapter
|
|
6671
|
+
* @returns {@link DispatchResult} with success status, bindingId, and threadId
|
|
6672
|
+
*/
|
|
6648
6673
|
async dispatch(message) {
|
|
6649
6674
|
const ctx = {
|
|
6650
6675
|
inboundMessage: message,
|
|
@@ -6791,32 +6816,96 @@ var MessageRouter = class {
|
|
|
6791
6816
|
workspace_id: ctx.binding.workspaceId || "",
|
|
6792
6817
|
project_id: ctx.binding.projectId || ""
|
|
6793
6818
|
});
|
|
6794
|
-
const addResult = await agent.addMessage({
|
|
6795
|
-
input: { message: message.content.text },
|
|
6796
|
-
custom_run_config: message.content.metadata || {}
|
|
6797
|
-
});
|
|
6798
|
-
console.log({
|
|
6799
|
-
event: "dispatch:complete",
|
|
6800
|
-
agentId: ctx.binding.agentId,
|
|
6801
|
-
threadId,
|
|
6802
|
-
messageId: addResult?.messageId,
|
|
6803
|
-
result: JSON.stringify(addResult)
|
|
6804
|
-
}, "Agent dispatch complete \u2014 messageId = " + (addResult?.messageId || "N/A"));
|
|
6805
6819
|
if (message.replyTarget) {
|
|
6820
|
+
const replySubKey = `${threadId}:${message.replyTarget.adapterChannel}:reply`;
|
|
6806
6821
|
const adapter = this.adapterRegistry.get(message.replyTarget.adapterChannel);
|
|
6807
6822
|
if (adapter) {
|
|
6808
6823
|
const installation = await this.installationStore.getInstallationById(
|
|
6809
6824
|
message.channelInstallationId
|
|
6810
6825
|
);
|
|
6811
6826
|
if (installation) {
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6827
|
+
const existing = this._replySubs.get(replySubKey);
|
|
6828
|
+
if (!existing || existing.count === 0) {
|
|
6829
|
+
const timer = setTimeout(() => {
|
|
6830
|
+
const entry = this._replySubs.get(replySubKey);
|
|
6831
|
+
if (entry) {
|
|
6832
|
+
this._replySubs.delete(replySubKey);
|
|
6833
|
+
console.warn({
|
|
6834
|
+
event: "dispatch:reply:timeout",
|
|
6835
|
+
threadId,
|
|
6836
|
+
channel: message.replyTarget.adapterChannel
|
|
6837
|
+
}, "Reply subscription timed out \u2014 no reply:ready fired within 1h");
|
|
6838
|
+
}
|
|
6839
|
+
}, 36e5);
|
|
6840
|
+
this._replySubs.set(replySubKey, { count: 1, timer });
|
|
6841
|
+
console.log({
|
|
6842
|
+
event: "dispatch:reply:subscribed",
|
|
6843
|
+
threadId,
|
|
6844
|
+
channel: message.replyTarget.adapterChannel,
|
|
6845
|
+
senderId: message.sender.id
|
|
6846
|
+
}, "Subscribed to reply:ready for thread");
|
|
6847
|
+
agent.subscribeOnce("reply:ready", (data) => {
|
|
6848
|
+
const messages = data.state?.values?.messages;
|
|
6849
|
+
const lastAI = messages?.filter((m) => m.type === "ai" || m.getType?.() === "ai").pop();
|
|
6850
|
+
const replyText = lastAI?.content ?? "";
|
|
6851
|
+
const entry = this._replySubs.get(replySubKey);
|
|
6852
|
+
if (entry) {
|
|
6853
|
+
entry.count--;
|
|
6854
|
+
if (entry.count <= 0) {
|
|
6855
|
+
clearTimeout(entry.timer);
|
|
6856
|
+
this._replySubs.delete(replySubKey);
|
|
6857
|
+
}
|
|
6858
|
+
}
|
|
6859
|
+
if (replyText) {
|
|
6860
|
+
console.log({
|
|
6861
|
+
event: "dispatch:reply:sending",
|
|
6862
|
+
threadId,
|
|
6863
|
+
channel: message.replyTarget.adapterChannel,
|
|
6864
|
+
replyLength: replyText.length
|
|
6865
|
+
}, "Sending channel reply");
|
|
6866
|
+
adapter.sendReply(message.replyTarget, { text: replyText }, installation).then(() => {
|
|
6867
|
+
console.log({
|
|
6868
|
+
event: "dispatch:reply:sent",
|
|
6869
|
+
threadId,
|
|
6870
|
+
channel: message.replyTarget.adapterChannel
|
|
6871
|
+
}, "Channel reply sent successfully");
|
|
6872
|
+
}).catch((err) => console.error({
|
|
6873
|
+
event: "dispatch:reply:failed",
|
|
6874
|
+
threadId,
|
|
6875
|
+
channel: message.replyTarget.adapterChannel,
|
|
6876
|
+
error: err instanceof Error ? err.message : String(err)
|
|
6877
|
+
}, "Failed to send channel reply"));
|
|
6878
|
+
} else {
|
|
6879
|
+
console.warn({
|
|
6880
|
+
event: "dispatch:reply:empty",
|
|
6881
|
+
threadId,
|
|
6882
|
+
channel: message.replyTarget.adapterChannel
|
|
6883
|
+
}, "Agent produced no text output \u2014 skipping reply");
|
|
6884
|
+
}
|
|
6885
|
+
});
|
|
6886
|
+
} else {
|
|
6887
|
+
existing.count++;
|
|
6888
|
+
console.log({
|
|
6889
|
+
event: "dispatch:reply:incremented",
|
|
6890
|
+
threadId,
|
|
6891
|
+
channel: message.replyTarget.adapterChannel,
|
|
6892
|
+
count: existing.count
|
|
6893
|
+
}, "Incremented reply counter for thread (already subscribed)");
|
|
6894
|
+
}
|
|
6817
6895
|
}
|
|
6818
6896
|
}
|
|
6819
6897
|
}
|
|
6898
|
+
const addResult = await agent.addMessage({
|
|
6899
|
+
input: { message: message.content.text },
|
|
6900
|
+
custom_run_config: message.replyTarget ? { ...message.content.metadata || {}, _replyTarget: message.replyTarget } : message.content.metadata || {}
|
|
6901
|
+
});
|
|
6902
|
+
console.log({
|
|
6903
|
+
event: "dispatch:complete",
|
|
6904
|
+
agentId: ctx.binding.agentId,
|
|
6905
|
+
threadId,
|
|
6906
|
+
messageId: addResult?.messageId,
|
|
6907
|
+
result: JSON.stringify(addResult)
|
|
6908
|
+
}, "Agent dispatch complete \u2014 messageId = " + (addResult?.messageId || "N/A"));
|
|
6820
6909
|
});
|
|
6821
6910
|
return {
|
|
6822
6911
|
success: true,
|