mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-07 22:09:57 +00:00
Fix: TUI messages route correctly instead of leaking WhatsApp route
This commit is contained in:
@@ -4,7 +4,7 @@ import path from "node:path";
|
||||
import { CURRENT_SESSION_VERSION } from "@mariozechner/pi-coding-agent";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import type { MsgContext } from "../../auto-reply/templating.js";
|
||||
import { GATEWAY_CLIENT_CAPS } from "../protocol/client-info.js";
|
||||
import { GATEWAY_CLIENT_CAPS, GATEWAY_CLIENT_MODES } from "../protocol/client-info.js";
|
||||
import type { GatewayRequestContext } from "./types.js";
|
||||
|
||||
const mockState = vi.hoisted(() => ({
|
||||
@@ -550,6 +550,47 @@ describe("chat directive tag stripping for non-streaming final payloads", () =>
|
||||
);
|
||||
});
|
||||
|
||||
it("chat.send does not inherit external delivery context for UI clients on main sessions", async () => {
|
||||
createTranscriptFixture("openclaw-chat-send-main-ui-routes-");
|
||||
mockState.finalText = "ok";
|
||||
mockState.sessionEntry = {
|
||||
deliveryContext: {
|
||||
channel: "whatsapp",
|
||||
to: "whatsapp:+8613800138000",
|
||||
accountId: "default",
|
||||
},
|
||||
lastChannel: "whatsapp",
|
||||
lastTo: "whatsapp:+8613800138000",
|
||||
lastAccountId: "default",
|
||||
};
|
||||
const respond = vi.fn();
|
||||
const context = createChatContext();
|
||||
|
||||
await runNonStreamingChatSend({
|
||||
context,
|
||||
respond,
|
||||
idempotencyKey: "idem-main-ui-routes",
|
||||
client: {
|
||||
connect: {
|
||||
client: {
|
||||
mode: GATEWAY_CLIENT_MODES.UI,
|
||||
id: "openclaw-tui",
|
||||
},
|
||||
},
|
||||
} as unknown,
|
||||
sessionKey: "agent:main:main",
|
||||
expectBroadcast: false,
|
||||
});
|
||||
|
||||
expect(mockState.lastDispatchCtx).toEqual(
|
||||
expect.objectContaining({
|
||||
OriginatingChannel: "webchat",
|
||||
OriginatingTo: undefined,
|
||||
AccountId: undefined,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("chat.send does not inherit external delivery context for non-channel custom sessions", async () => {
|
||||
createTranscriptFixture("openclaw-chat-send-custom-no-cross-route-");
|
||||
mockState.finalText = "ok";
|
||||
|
||||
@@ -17,7 +17,11 @@ import {
|
||||
stripInlineDirectiveTagsForDisplay,
|
||||
stripInlineDirectiveTagsFromMessageForDisplay,
|
||||
} from "../../utils/directive-tags.js";
|
||||
import { INTERNAL_MESSAGE_CHANNEL, normalizeMessageChannel } from "../../utils/message-channel.js";
|
||||
import {
|
||||
INTERNAL_MESSAGE_CHANNEL,
|
||||
isWebchatClient,
|
||||
normalizeMessageChannel,
|
||||
} from "../../utils/message-channel.js";
|
||||
import {
|
||||
abortChatRunById,
|
||||
abortChatRunsForSessionKey,
|
||||
@@ -28,7 +32,11 @@ import {
|
||||
} from "../chat-abort.js";
|
||||
import { type ChatImageContent, parseMessageWithAttachments } from "../chat-attachments.js";
|
||||
import { stripEnvelopeFromMessage, stripEnvelopeFromMessages } from "../chat-sanitize.js";
|
||||
import { GATEWAY_CLIENT_CAPS, hasGatewayClientCap } from "../protocol/client-info.js";
|
||||
import {
|
||||
GATEWAY_CLIENT_CAPS,
|
||||
GATEWAY_CLIENT_MODES,
|
||||
hasGatewayClientCap,
|
||||
} from "../protocol/client-info.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
errorShape,
|
||||
@@ -880,14 +888,18 @@ export const chatHandlers: GatewayRequestHandlers = {
|
||||
!isChannelScopedSession &&
|
||||
typeof sessionScopeParts[1] === "string" &&
|
||||
sessionChannelHint === routeChannelCandidate;
|
||||
// Only inherit prior external route metadata for channel-scoped sessions.
|
||||
// Channel-agnostic sessions (main, direct:<peer>, etc.) can otherwise
|
||||
// leak stale routes across surfaces.
|
||||
const clientMode = client?.connect?.client?.mode;
|
||||
const isFromWebchatClient =
|
||||
isWebchatClient(client?.connect?.client) || clientMode === GATEWAY_CLIENT_MODES.UI;
|
||||
// Channel-agnostic session scopes (main, direct:<peer>, etc.) can leak
|
||||
// stale routes across surfaces. Allow main sessions only from non-Webchat
|
||||
// clients so CLI replies can keep the last WA/Telegram route.
|
||||
const canInheritDeliverableRoute = Boolean(
|
||||
sessionChannelHint &&
|
||||
sessionChannelHint !== INTERNAL_MESSAGE_CHANNEL &&
|
||||
!isChannelAgnosticSessionScope &&
|
||||
(isChannelScopedSession || hasLegacyChannelPeerShape),
|
||||
((!isChannelAgnosticSessionScope &&
|
||||
(isChannelScopedSession || hasLegacyChannelPeerShape)) ||
|
||||
(sessionChannelHint === "main" && client?.connect !== undefined && !isFromWebchatClient)),
|
||||
);
|
||||
const hasDeliverableRoute =
|
||||
canInheritDeliverableRoute &&
|
||||
|
||||
Reference in New Issue
Block a user