Skip to content

Commit 27a7e3f

Browse files
committed
test(sessions-send): add regression tests for deliveryContextFromSession channel resolution
Covers five scenarios: top-level channel, deliveryContext.channel with stale webchat, lastChannel with empty channel, route metadata channel, and no-routable-channel fallback to webchat. Ref. #94409
1 parent 6e8cd35 commit 27a7e3f

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

src/agents/openclaw-tools.sessions.test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,6 +2072,76 @@ describe("sessions tools", () => {
20722072
expect(calls.some((call) => call.method === "send")).toBe(false);
20732073
});
20742074

2075+
it.each([
2076+
{
2077+
name: "top-level channel",
2078+
entry: { channel: "discord", lastChannel: "discord" },
2079+
expectedChannel: "discord",
2080+
},
2081+
{
2082+
name: "deliveryContext.channel (top-level channel is webchat)",
2083+
entry: { channel: "webchat", deliveryContext: { channel: "telegram", to: "group:chat" } },
2084+
expectedChannel: "telegram",
2085+
},
2086+
{
2087+
name: "lastChannel (top-level channel is empty)",
2088+
entry: { channel: "", lastChannel: "slack", lastTo: "channel:general" },
2089+
expectedChannel: "slack",
2090+
},
2091+
{
2092+
name: "channel in route metadata",
2093+
entry: { channel: "webchat", route: { channel: "discord", target: { to: "channel:dev" } } },
2094+
expectedChannel: "discord",
2095+
},
2096+
{
2097+
name: "no routable channel falls back to webchat",
2098+
entry: {},
2099+
expectedChannel: "webchat",
2100+
},
2101+
])(
2102+
"sessions_send uses deliveryContextFromSession for initial agent call channel — $name",
2103+
async ({ entry, expectedChannel }) => {
2104+
const calls: Array<{ method?: string; params?: unknown }> = [];
2105+
const targetKey = "agent:main:worker";
2106+
loadSessionEntryByKeyMock.mockImplementation((sessionKey: string) =>
2107+
sessionKey === targetKey ? entry : undefined,
2108+
);
2109+
callGatewayMock.mockImplementation(async (opts: unknown) => {
2110+
const request = opts as { method?: string; params?: unknown };
2111+
calls.push(request);
2112+
if (request.method === "agent") {
2113+
return { runId: "regression-run", status: "accepted", acceptedAt: 2000 };
2114+
}
2115+
return {};
2116+
});
2117+
2118+
const tool = createOpenClawTools({
2119+
agentSessionKey: "discord:group:req",
2120+
agentChannel: "discord",
2121+
config: {
2122+
...TEST_CONFIG,
2123+
session: {
2124+
...TEST_CONFIG.session,
2125+
agentToAgent: { maxPingPongTurns: 0 },
2126+
},
2127+
},
2128+
}).find((candidate) => candidate.name === "sessions_send");
2129+
if (!tool) {
2130+
throw new Error("missing sessions_send tool");
2131+
}
2132+
2133+
await tool.execute("regression-delivery-context-channel", {
2134+
sessionKey: targetKey,
2135+
message: "verify delivery context channel resolution",
2136+
timeoutSeconds: 0,
2137+
});
2138+
2139+
const agentCalls = calls.filter((call) => call.method === "agent");
2140+
expect(agentCalls).toHaveLength(1);
2141+
expect(agentParams(agentCalls[0] ?? {}).channel).toBe(expectedChannel);
2142+
},
2143+
);
2144+
20752145
it("sessions_send preserves threadId when announce target is hydrated via sessions.list", async () => {
20762146
const calls: Array<{ method?: string; params?: unknown }> = [];
20772147
let agentCallCount = 0;

0 commit comments

Comments
 (0)