From 59cd79d37f9ff2b88272da1a0bfae835d9ff0887 Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Fri, 27 Mar 2026 20:03:50 -0500 Subject: [PATCH] fix: use session origin thread metadata in chat routing --- .../chat.directive-tags.test.ts | 43 +++++++++++++++++++ src/gateway/server-methods/chat.ts | 5 ++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/gateway/server-methods/chat.directive-tags.test.ts b/src/gateway/server-methods/chat.directive-tags.test.ts index e6e69b4239a..a0777994662 100644 --- a/src/gateway/server-methods/chat.directive-tags.test.ts +++ b/src/gateway/server-methods/chat.directive-tags.test.ts @@ -894,6 +894,49 @@ describe("chat directive tag stripping for non-streaming final payloads", () => ); }); + it("chat.send falls back to origin thread metadata for configured main CLI delivery inheritance", async () => { + createTranscriptFixture("openclaw-chat-send-config-main-origin-thread-routes-"); + mockState.mainSessionKey = "work"; + mockState.finalText = "ok"; + mockState.sessionEntry = { + origin: { + provider: "telegram", + accountId: "default", + threadId: "42", + }, + lastTo: "telegram:6812765697", + }; + const respond = vi.fn(); + const context = createChatContext(); + + await runNonStreamingChatSend({ + context, + respond, + idempotencyKey: "idem-config-main-origin-thread-routes", + client: { + connect: { + client: { + mode: GATEWAY_CLIENT_MODES.CLI, + id: "cli", + }, + }, + } as unknown, + sessionKey: "agent:main:work", + deliver: true, + expectBroadcast: false, + }); + + expect(mockState.lastDispatchCtx).toEqual( + expect.objectContaining({ + OriginatingChannel: "telegram", + OriginatingTo: "telegram:6812765697", + ExplicitDeliverRoute: true, + AccountId: "default", + MessageThreadId: "42", + }), + ); + }); + it("chat.send keeps configured main delivery inheritance when connect metadata omits client details", async () => { createTranscriptFixture("openclaw-chat-send-config-main-connect-no-client-"); mockState.mainSessionKey = "work"; diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index f1eccbe4109..f6e28a32dee 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -124,6 +124,7 @@ type ChatSendDeliveryEntry = { origin?: { provider?: string; accountId?: string; + threadId?: string | number; }; lastChannel?: string; lastTo?: string; @@ -177,7 +178,9 @@ function resolveChatSendOriginatingRoute(params: { params.entry?.origin?.accountId ?? undefined; const routeThreadIdCandidate = - params.entry?.deliveryContext?.threadId ?? params.entry?.lastThreadId; + params.entry?.deliveryContext?.threadId ?? + params.entry?.lastThreadId ?? + params.entry?.origin?.threadId; if (params.sessionKey.length > CHAT_SEND_SESSION_KEY_MAX_LENGTH) { return { originatingChannel: INTERNAL_MESSAGE_CHANNEL,