mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-21 16:41:56 +00:00
fix(session): prefer webchat routes for direct ui turns (#37135)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import type { SessionEntry } from "../../config/sessions.js";
|
||||
import { buildAgentMainSessionKey } from "../../routing/session-key.js";
|
||||
import { parseAgentSessionKey } from "../../sessions/session-key-utils.js";
|
||||
import { deriveSessionChatType, parseAgentSessionKey } from "../../sessions/session-key-utils.js";
|
||||
import {
|
||||
deliveryContextFromSession,
|
||||
deliveryContextKey,
|
||||
@@ -38,6 +38,10 @@ function isMainSessionKey(sessionKey?: string): boolean {
|
||||
return parsed.rest.trim().toLowerCase() === "main";
|
||||
}
|
||||
|
||||
function isDirectSessionKey(sessionKey?: string): boolean {
|
||||
return deriveSessionChatType(sessionKey) === "direct";
|
||||
}
|
||||
|
||||
function isExternalRoutingChannel(channel?: string): channel is string {
|
||||
return Boolean(
|
||||
channel && channel !== INTERNAL_MESSAGE_CHANNEL && isDeliverableMessageChannel(channel),
|
||||
@@ -50,7 +54,12 @@ export function resolveLastChannelRaw(params: {
|
||||
sessionKey?: string;
|
||||
}): string | undefined {
|
||||
const originatingChannel = normalizeMessageChannel(params.originatingChannelRaw);
|
||||
if (originatingChannel === INTERNAL_MESSAGE_CHANNEL && isMainSessionKey(params.sessionKey)) {
|
||||
// WebChat should own reply routing for direct-session UI turns, even when the
|
||||
// session previously replied through an external channel like iMessage.
|
||||
if (
|
||||
originatingChannel === INTERNAL_MESSAGE_CHANNEL &&
|
||||
(isMainSessionKey(params.sessionKey) || isDirectSessionKey(params.sessionKey))
|
||||
) {
|
||||
return params.originatingChannelRaw;
|
||||
}
|
||||
const persistedChannel = normalizeMessageChannel(params.persistedLastChannel);
|
||||
@@ -77,7 +86,10 @@ export function resolveLastToRaw(params: {
|
||||
sessionKey?: string;
|
||||
}): string | undefined {
|
||||
const originatingChannel = normalizeMessageChannel(params.originatingChannelRaw);
|
||||
if (originatingChannel === INTERNAL_MESSAGE_CHANNEL && isMainSessionKey(params.sessionKey)) {
|
||||
if (
|
||||
originatingChannel === INTERNAL_MESSAGE_CHANNEL &&
|
||||
(isMainSessionKey(params.sessionKey) || isDirectSessionKey(params.sessionKey))
|
||||
) {
|
||||
return params.originatingToRaw || params.toRaw;
|
||||
}
|
||||
const persistedChannel = normalizeMessageChannel(params.persistedLastChannel);
|
||||
|
||||
@@ -1926,6 +1926,43 @@ describe("initSessionState internal channel routing preservation", () => {
|
||||
expect(result.sessionEntry.deliveryContext?.to).toBe("group:12345");
|
||||
});
|
||||
|
||||
it("lets direct webchat turns override persisted external routes for per-channel-peer sessions", async () => {
|
||||
const storePath = await createStorePath("webchat-direct-route-override-");
|
||||
const sessionKey = "agent:main:imessage:direct:+1555";
|
||||
await writeSessionStoreFast(storePath, {
|
||||
[sessionKey]: {
|
||||
sessionId: "sess-webchat-direct",
|
||||
updatedAt: Date.now(),
|
||||
lastChannel: "imessage",
|
||||
lastTo: "+1555",
|
||||
deliveryContext: {
|
||||
channel: "imessage",
|
||||
to: "+1555",
|
||||
},
|
||||
},
|
||||
});
|
||||
const cfg = {
|
||||
session: { store: storePath, dmScope: "per-channel-peer" },
|
||||
} as OpenClawConfig;
|
||||
|
||||
const result = await initSessionState({
|
||||
ctx: {
|
||||
Body: "reply from control ui",
|
||||
SessionKey: sessionKey,
|
||||
OriginatingChannel: "webchat",
|
||||
OriginatingTo: "session:dashboard",
|
||||
Surface: "webchat",
|
||||
},
|
||||
cfg,
|
||||
commandAuthorized: true,
|
||||
});
|
||||
|
||||
expect(result.sessionEntry.lastChannel).toBe("webchat");
|
||||
expect(result.sessionEntry.lastTo).toBe("session:dashboard");
|
||||
expect(result.sessionEntry.deliveryContext?.channel).toBe("webchat");
|
||||
expect(result.sessionEntry.deliveryContext?.to).toBe("session:dashboard");
|
||||
});
|
||||
|
||||
it("keeps persisted external route when OriginatingChannel is non-deliverable", async () => {
|
||||
const storePath = await createStorePath("preserve-nondeliverable-route-");
|
||||
const sessionKey = "agent:main:discord:channel:24680";
|
||||
|
||||
Reference in New Issue
Block a user