Agents: fix subagent completion thread routing

This commit is contained in:
Gustavo Madeira Santana
2026-02-17 22:52:46 -05:00
parent 35851cdaff
commit 0bf1b38cc0
8 changed files with 90 additions and 25 deletions

View File

@@ -22,6 +22,8 @@ export const SendParamsSchema = Type.Object(
gifPlayback: Type.Optional(Type.Boolean()),
channel: Type.Optional(Type.String()),
accountId: Type.Optional(Type.String()),
/** Thread id (channel-specific meaning, e.g. Telegram forum topic id). */
threadId: Type.Optional(Type.String()),
/** Optional session key for mirroring delivered output back into the transcript. */
sessionKey: Type.Optional(Type.String()),
idempotencyKey: NonEmptyString,

View File

@@ -235,4 +235,22 @@ describe("gateway send mirroring", () => {
}),
);
});
it("forwards threadId to outbound delivery when provided", async () => {
mocks.deliverOutboundPayloads.mockResolvedValue([{ messageId: "m-thread", channel: "slack" }]);
await runSend({
to: "channel:C1",
message: "hi",
channel: "slack",
threadId: "1710000000.9999",
idempotencyKey: "idem-thread",
});
expect(mocks.deliverOutboundPayloads).toHaveBeenCalledWith(
expect.objectContaining({
threadId: "1710000000.9999",
}),
);
});
});

View File

@@ -64,6 +64,7 @@ export const sendHandlers: GatewayRequestHandlers = {
gifPlayback?: boolean;
channel?: string;
accountId?: string;
threadId?: string;
sessionKey?: string;
idempotencyKey: string;
};
@@ -130,6 +131,10 @@ export const sendHandlers: GatewayRequestHandlers = {
typeof request.accountId === "string" && request.accountId.trim().length
? request.accountId.trim()
: undefined;
const threadId =
typeof request.threadId === "string" && request.threadId.trim().length
? request.threadId.trim()
: undefined;
const outboundChannel = channel;
const plugin = getChannelPlugin(channel);
if (!plugin) {
@@ -182,6 +187,7 @@ export const sendHandlers: GatewayRequestHandlers = {
agentId: derivedAgentId,
accountId,
target: resolved.to,
threadId,
})
: null;
if (derivedRoute) {
@@ -203,6 +209,7 @@ export const sendHandlers: GatewayRequestHandlers = {
? resolveSessionAgentId({ sessionKey: providedSessionKey, config: cfg })
: derivedAgentId,
gifPlayback: request.gifPlayback,
threadId: threadId ?? null,
deps: outboundDeps,
mirror: providedSessionKey
? {