fix: stop main-session UI replies inheriting channel routes
This commit is contained in:
@@ -656,6 +656,49 @@ 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 when deliver is enabled", async () => {
|
||||
createTranscriptFixture("openclaw-chat-send-main-ui-deliver-no-route-");
|
||||
mockState.finalText = "ok";
|
||||
mockState.sessionEntry = {
|
||||
deliveryContext: {
|
||||
channel: "telegram",
|
||||
to: "telegram:200482621",
|
||||
accountId: "default",
|
||||
},
|
||||
lastChannel: "telegram",
|
||||
lastTo: "telegram:200482621",
|
||||
lastAccountId: "default",
|
||||
};
|
||||
const respond = vi.fn();
|
||||
const context = createChatContext();
|
||||
|
||||
await runNonStreamingChatSend({
|
||||
context,
|
||||
respond,
|
||||
idempotencyKey: "idem-main-ui-deliver-no-route",
|
||||
client: {
|
||||
connect: {
|
||||
client: {
|
||||
mode: GATEWAY_CLIENT_MODES.UI,
|
||||
id: "openclaw-tui",
|
||||
},
|
||||
},
|
||||
} as unknown,
|
||||
sessionKey: "agent:main:main",
|
||||
deliver: true,
|
||||
expectBroadcast: false,
|
||||
});
|
||||
|
||||
expect(mockState.lastDispatchCtx).toEqual(
|
||||
expect.objectContaining({
|
||||
OriginatingChannel: "webchat",
|
||||
OriginatingTo: undefined,
|
||||
ExplicitDeliverRoute: false,
|
||||
AccountId: undefined,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("chat.send inherits external delivery context for CLI clients on configured main sessions", async () => {
|
||||
createTranscriptFixture("openclaw-chat-send-config-main-cli-routes-");
|
||||
mockState.mainSessionKey = "work";
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
} from "../../utils/directive-tags.js";
|
||||
import {
|
||||
INTERNAL_MESSAGE_CHANNEL,
|
||||
isGatewayCliClient,
|
||||
isWebchatClient,
|
||||
normalizeMessageChannel,
|
||||
} from "../../utils/message-channel.js";
|
||||
@@ -181,21 +182,27 @@ function resolveChatSendOriginatingRoute(params: {
|
||||
typeof sessionScopeParts[1] === "string" &&
|
||||
sessionChannelHint === routeChannelCandidate;
|
||||
const isFromWebchatClient = isWebchatClient(params.client);
|
||||
const isFromGatewayCliClient = isGatewayCliClient(params.client);
|
||||
const hasClientMetadata =
|
||||
(typeof params.client?.mode === "string" && params.client.mode.trim().length > 0) ||
|
||||
(typeof params.client?.id === "string" && params.client.id.trim().length > 0);
|
||||
const configuredMainKey = (params.mainKey ?? "main").trim().toLowerCase();
|
||||
const isConfiguredMainSessionScope =
|
||||
normalizedSessionScopeHead.length > 0 && normalizedSessionScopeHead === configuredMainKey;
|
||||
const canInheritConfiguredMainRoute =
|
||||
isConfiguredMainSessionScope &&
|
||||
params.hasConnectedClient &&
|
||||
(isFromGatewayCliClient || !hasClientMetadata);
|
||||
|
||||
// Webchat/Control UI clients never inherit external delivery routes, even when
|
||||
// accessing channel-scoped sessions. External routes are only for non-webchat
|
||||
// clients where the session key explicitly encodes an external target.
|
||||
// Preserve the old configured-main contract: any connected non-webchat client
|
||||
// may inherit the last external route even when client metadata is absent.
|
||||
// Webchat clients never inherit external delivery routes. Configured-main
|
||||
// sessions are stricter than channel-scoped sessions: only CLI callers, or
|
||||
// legacy callers with no client metadata, may inherit the last external route.
|
||||
const canInheritDeliverableRoute = Boolean(
|
||||
!isFromWebchatClient &&
|
||||
sessionChannelHint &&
|
||||
sessionChannelHint !== INTERNAL_MESSAGE_CHANNEL &&
|
||||
((!isChannelAgnosticSessionScope && (isChannelScopedSession || hasLegacyChannelPeerShape)) ||
|
||||
(isConfiguredMainSessionScope && params.hasConnectedClient)),
|
||||
canInheritConfiguredMainRoute),
|
||||
);
|
||||
const hasDeliverableRoute =
|
||||
canInheritDeliverableRoute &&
|
||||
|
||||
Reference in New Issue
Block a user