test: simplify session reset and rawbody coverage

This commit is contained in:
Peter Steinberger
2026-02-23 18:19:13 +00:00
parent 783a9134d6
commit 445c7a65e6

View File

@@ -232,47 +232,35 @@ describe("initSessionState thread forking", () => {
}); });
describe("initSessionState RawBody", () => { describe("initSessionState RawBody", () => {
it("triggerBodyNormalized correctly extracts commands when Body contains context but RawBody is clean", async () => { it("uses RawBody for command extraction and reset triggers when Body contains wrapped context", async () => {
const root = await makeCaseDir("openclaw-rawbody-"); const root = await makeCaseDir("openclaw-rawbody-");
const storePath = path.join(root, "sessions.json"); const storePath = path.join(root, "sessions.json");
const cfg = { session: { store: storePath } } as OpenClawConfig; const cfg = { session: { store: storePath } } as OpenClawConfig;
const groupMessageCtx = { const statusResult = await initSessionState({
Body: `[Chat messages since your last reply - for context]\n[WhatsApp ...] Someone: hello\n\n[Current message - respond to this]\n[WhatsApp ...] Jake: /status\n[from: Jake McInteer (+6421807830)]`, ctx: {
RawBody: "/status", Body: `[Chat messages since your last reply - for context]\n[WhatsApp ...] Someone: hello\n\n[Current message - respond to this]\n[WhatsApp ...] Jake: /status\n[from: Jake McInteer (+6421807830)]`,
ChatType: "group", RawBody: "/status",
SessionKey: "agent:main:whatsapp:group:g1", ChatType: "group",
}; SessionKey: "agent:main:whatsapp:group:g1",
},
const result = await initSessionState({
ctx: groupMessageCtx,
cfg, cfg,
commandAuthorized: true, commandAuthorized: true,
}); });
expect(statusResult.triggerBodyNormalized).toBe("/status");
expect(result.triggerBodyNormalized).toBe("/status"); const resetResult = await initSessionState({
}); ctx: {
Body: `[Context]\nJake: /new\n[from: Jake]`,
it("Reset triggers (/new, /reset) work with RawBody", async () => { RawBody: "/new",
const root = await makeCaseDir("openclaw-rawbody-reset-"); ChatType: "group",
const storePath = path.join(root, "sessions.json"); SessionKey: "agent:main:whatsapp:group:g1",
const cfg = { session: { store: storePath } } as OpenClawConfig; },
const groupMessageCtx = {
Body: `[Context]\nJake: /new\n[from: Jake]`,
RawBody: "/new",
ChatType: "group",
SessionKey: "agent:main:whatsapp:group:g1",
};
const result = await initSessionState({
ctx: groupMessageCtx,
cfg, cfg,
commandAuthorized: true, commandAuthorized: true,
}); });
expect(resetResult.isNewSession).toBe(true);
expect(result.isNewSession).toBe(true); expect(resetResult.bodyStripped).toBe("");
expect(result.bodyStripped).toBe("");
}); });
it("preserves argument casing while still matching reset triggers case-insensitively", async () => { it("preserves argument casing while still matching reset triggers case-insensitively", async () => {
@@ -303,25 +291,6 @@ describe("initSessionState RawBody", () => {
expect(result.triggerBodyNormalized).toBe("/NEW KeepThisCase"); expect(result.triggerBodyNormalized).toBe("/NEW KeepThisCase");
}); });
it("falls back to Body when RawBody is undefined", async () => {
const root = await makeCaseDir("openclaw-rawbody-fallback-");
const storePath = path.join(root, "sessions.json");
const cfg = { session: { store: storePath } } as OpenClawConfig;
const ctx = {
Body: "/status",
SessionKey: "agent:main:whatsapp:dm:s1",
};
const result = await initSessionState({
ctx,
cfg,
commandAuthorized: true,
});
expect(result.triggerBodyNormalized).toBe("/status");
});
it("uses the default per-agent sessions store when config store is unset", async () => { it("uses the default per-agent sessions store when config store is unset", async () => {
const root = await makeCaseDir("openclaw-session-store-default-"); const root = await makeCaseDir("openclaw-session-store-default-");
const stateDir = path.join(root, ".openclaw"); const stateDir = path.join(root, ".openclaw");
@@ -643,10 +612,10 @@ describe("initSessionState reset triggers in WhatsApp groups", () => {
it("applies WhatsApp group reset authorization across sender variants", async () => { it("applies WhatsApp group reset authorization across sender variants", async () => {
const sessionKey = "agent:main:whatsapp:group:120363406150318674@g.us"; const sessionKey = "agent:main:whatsapp:group:120363406150318674@g.us";
const existingSessionId = "existing-session-123"; const existingSessionId = "existing-session-123";
const storePath = await createStorePath("openclaw-group-reset");
const cases = [ const cases = [
{ {
name: "authorized sender", name: "authorized sender",
storePrefix: "openclaw-group-reset-",
allowFrom: ["+41796666864"], allowFrom: ["+41796666864"],
body: `[Chat messages since your last reply - for context]\\n[WhatsApp 120363406150318674@g.us 2026-01-13T07:45Z] Someone: hello\\n\\n[Current message - respond to this]\\n[WhatsApp 120363406150318674@g.us 2026-01-13T07:45Z] Peschiño: /new\\n[from: Peschiño (+41796666864)]`, body: `[Chat messages since your last reply - for context]\\n[WhatsApp 120363406150318674@g.us 2026-01-13T07:45Z] Someone: hello\\n\\n[Current message - respond to this]\\n[WhatsApp 120363406150318674@g.us 2026-01-13T07:45Z] Peschiño: /new\\n[from: Peschiño (+41796666864)]`,
senderName: "Peschiño", senderName: "Peschiño",
@@ -654,39 +623,8 @@ describe("initSessionState reset triggers in WhatsApp groups", () => {
senderId: "41796666864:0@s.whatsapp.net", senderId: "41796666864:0@s.whatsapp.net",
expectedIsNewSession: true, expectedIsNewSession: true,
}, },
{
name: "unauthorized sender",
storePrefix: "openclaw-group-reset-unauth-",
allowFrom: ["+41796666864"],
body: `[Context]\\n[WhatsApp ...] OtherPerson: /new\\n[from: OtherPerson (+1555123456)]`,
senderName: "OtherPerson",
senderE164: "+1555123456",
senderId: "1555123456:0@s.whatsapp.net",
expectedIsNewSession: false,
},
{
name: "raw body clean while body wrapped",
storePrefix: "openclaw-group-rawbody-",
allowFrom: ["*"],
body: `[WhatsApp 120363406150318674@g.us 2026-01-13T07:45Z] Jake: /new\n[from: Jake (+1222)]`,
senderName: undefined,
senderE164: "+1222",
senderId: undefined,
expectedIsNewSession: true,
},
{
name: "LID sender with authorized E164",
storePrefix: "openclaw-group-reset-lid-",
allowFrom: ["+41796666864"],
body: `[WhatsApp 120363406150318674@g.us 2026-01-13T07:45Z] Owner: /new\n[from: Owner (+41796666864)]`,
senderName: "Owner",
senderE164: "+41796666864",
senderId: "123@lid",
expectedIsNewSession: true,
},
{ {
name: "LID sender with unauthorized E164", name: "LID sender with unauthorized E164",
storePrefix: "openclaw-group-reset-lid-unauth-",
allowFrom: ["+41796666864"], allowFrom: ["+41796666864"],
body: `[WhatsApp 120363406150318674@g.us 2026-01-13T07:45Z] Other: /new\n[from: Other (+1555123456)]`, body: `[WhatsApp 120363406150318674@g.us 2026-01-13T07:45Z] Other: /new\n[from: Other (+1555123456)]`,
senderName: "Other", senderName: "Other",
@@ -697,7 +635,6 @@ describe("initSessionState reset triggers in WhatsApp groups", () => {
] as const; ] as const;
for (const testCase of cases) { for (const testCase of cases) {
const storePath = await createStorePath(testCase.storePrefix);
await seedSessionStore({ await seedSessionStore({
storePath, storePath,
sessionKey, sessionKey,
@@ -755,57 +692,40 @@ describe("initSessionState reset triggers in Slack channels", () => {
it("supports mention-prefixed Slack reset commands and preserves args", async () => { it("supports mention-prefixed Slack reset commands and preserves args", async () => {
const existingSessionId = "existing-session-123"; const existingSessionId = "existing-session-123";
const cases = [ const sessionKey = "agent:main:slack:channel:c2";
{ const body = "<@U123> /new take notes";
name: "reset command", const storePath = await createStorePath("openclaw-slack-channel-new-");
storePrefix: "openclaw-slack-channel-reset-", await seedSessionStore({
sessionKey: "agent:main:slack:channel:c1", storePath,
body: "<@U123> /reset", sessionKey,
expectedBodyStripped: "", sessionId: existingSessionId,
});
const cfg = {
session: { store: storePath, idleMinutes: 999 },
} as OpenClawConfig;
const result = await initSessionState({
ctx: {
Body: body,
RawBody: body,
CommandBody: body,
From: "slack:channel:C1",
To: "channel:C1",
ChatType: "channel",
SessionKey: sessionKey,
Provider: "slack",
Surface: "slack",
SenderId: "U123",
SenderName: "Owner",
}, },
{ cfg,
name: "new command with args", commandAuthorized: true,
storePrefix: "openclaw-slack-channel-new-", });
sessionKey: "agent:main:slack:channel:c2",
body: "<@U123> /new take notes",
expectedBodyStripped: "take notes",
},
] as const;
for (const testCase of cases) { expect(result.isNewSession).toBe(true);
const storePath = await createStorePath(testCase.storePrefix); expect(result.resetTriggered).toBe(true);
await seedSessionStore({ expect(result.sessionId).not.toBe(existingSessionId);
storePath, expect(result.bodyStripped).toBe("take notes");
sessionKey: testCase.sessionKey,
sessionId: existingSessionId,
});
const cfg = {
session: { store: storePath, idleMinutes: 999 },
} as OpenClawConfig;
const result = await initSessionState({
ctx: {
Body: testCase.body,
RawBody: testCase.body,
CommandBody: testCase.body,
From: "slack:channel:C1",
To: "channel:C1",
ChatType: "channel",
SessionKey: testCase.sessionKey,
Provider: "slack",
Surface: "slack",
SenderId: "U123",
SenderName: "Owner",
},
cfg,
commandAuthorized: true,
});
expect(result.isNewSession, testCase.name).toBe(true);
expect(result.resetTriggered, testCase.name).toBe(true);
expect(result.sessionId, testCase.name).not.toBe(existingSessionId);
expect(result.bodyStripped, testCase.name).toBe(testCase.expectedBodyStripped);
}
}); });
}); });
@@ -920,150 +840,60 @@ describe("initSessionState preserves behavior overrides across /new and /reset",
}); });
} }
it("/new preserves verboseLevel from previous session", async () => { it("preserves behavior overrides across /new and /reset", async () => {
const storePath = await createStorePath("openclaw-reset-verbose-"); const storePath = await createStorePath("openclaw-reset-overrides-");
const sessionKey = "agent:main:telegram:dm:user1"; const sessionKey = "agent:main:telegram:dm:user-overrides";
const existingSessionId = "existing-session-verbose"; const existingSessionId = "existing-session-overrides";
await seedSessionStoreWithOverrides({ const overrides = {
storePath, verboseLevel: "on",
sessionKey, thinkingLevel: "high",
sessionId: existingSessionId, reasoningLevel: "low",
overrides: { verboseLevel: "on" }, label: "telegram-priority",
}); } as const;
await fs.writeFile( const cases = [
path.join(path.dirname(storePath), `${existingSessionId}.jsonl`), {
"", name: "new preserves behavior overrides",
"utf-8", body: "/new",
);
const cfg = {
session: { store: storePath, idleMinutes: 999 },
} as OpenClawConfig;
const result = await initSessionState({
ctx: {
Body: "/new",
RawBody: "/new",
CommandBody: "/new",
From: "user1",
To: "bot",
ChatType: "direct",
SessionKey: sessionKey,
Provider: "telegram",
Surface: "telegram",
}, },
cfg, {
commandAuthorized: true, name: "reset preserves behavior overrides",
}); body: "/reset",
expect(result.isNewSession).toBe(true);
expect(result.resetTriggered).toBe(true);
expect(result.sessionId).not.toBe(existingSessionId);
expect(result.sessionEntry.verboseLevel).toBe("on");
});
it("/reset preserves thinkingLevel and reasoningLevel from previous session", async () => {
const storePath = await createStorePath("openclaw-reset-thinking-");
const sessionKey = "agent:main:telegram:dm:user2";
const existingSessionId = "existing-session-thinking";
await seedSessionStoreWithOverrides({
storePath,
sessionKey,
sessionId: existingSessionId,
overrides: { thinkingLevel: "high", reasoningLevel: "low" },
});
const cfg = {
session: { store: storePath, idleMinutes: 999 },
} as OpenClawConfig;
const result = await initSessionState({
ctx: {
Body: "/reset",
RawBody: "/reset",
CommandBody: "/reset",
From: "user2",
To: "bot",
ChatType: "direct",
SessionKey: sessionKey,
Provider: "telegram",
Surface: "telegram",
}, },
cfg, ] as const;
commandAuthorized: true,
});
expect(result.isNewSession).toBe(true); for (const testCase of cases) {
expect(result.resetTriggered).toBe(true); await seedSessionStoreWithOverrides({
expect(result.sessionId).not.toBe(existingSessionId); storePath,
expect(result.sessionEntry.thinkingLevel).toBe("high"); sessionKey,
expect(result.sessionEntry.reasoningLevel).toBe("low"); sessionId: existingSessionId,
}); overrides: { ...overrides },
});
it("/new preserves session label from previous session", async () => { const cfg = {
const storePath = await createStorePath("openclaw-reset-label-"); session: { store: storePath, idleMinutes: 999 },
const sessionKey = "agent:main:telegram:dm:user-label"; } as OpenClawConfig;
const existingSessionId = "existing-session-label";
await seedSessionStoreWithOverrides({
storePath,
sessionKey,
sessionId: existingSessionId,
overrides: { label: "telegram-priority" },
});
const cfg = { const result = await initSessionState({
session: { store: storePath, idleMinutes: 999 }, ctx: {
} as OpenClawConfig; Body: testCase.body,
RawBody: testCase.body,
CommandBody: testCase.body,
From: "user-overrides",
To: "bot",
ChatType: "direct",
SessionKey: sessionKey,
Provider: "telegram",
Surface: "telegram",
},
cfg,
commandAuthorized: true,
});
const result = await initSessionState({ expect(result.isNewSession, testCase.name).toBe(true);
ctx: { expect(result.resetTriggered, testCase.name).toBe(true);
Body: "/new", expect(result.sessionId, testCase.name).not.toBe(existingSessionId);
RawBody: "/new", expect(result.sessionEntry, testCase.name).toMatchObject(overrides);
CommandBody: "/new", }
From: "user-label",
To: "bot",
ChatType: "direct",
SessionKey: sessionKey,
Provider: "telegram",
Surface: "telegram",
},
cfg,
commandAuthorized: true,
});
expect(result.isNewSession).toBe(true);
expect(result.resetTriggered).toBe(true);
expect(result.sessionEntry.label).toBe("telegram-priority");
});
it("/new in a new session does not preserve overrides", async () => {
const storePath = await createStorePath("openclaw-new-no-preserve-");
const sessionKey = "agent:main:telegram:dm:user3";
const cfg = {
session: { store: storePath, idleMinutes: 999 },
} as OpenClawConfig;
const result = await initSessionState({
ctx: {
Body: "/new",
RawBody: "/new",
CommandBody: "/new",
From: "user3",
To: "bot",
ChatType: "direct",
SessionKey: sessionKey,
Provider: "telegram",
Surface: "telegram",
},
cfg,
commandAuthorized: true,
});
expect(result.isNewSession).toBe(true);
expect(result.resetTriggered).toBe(true);
expect(result.sessionEntry.verboseLevel).toBeUndefined();
expect(result.sessionEntry.thinkingLevel).toBeUndefined();
}); });
it("archives the old session store entry on /new", async () => { it("archives the old session store entry on /new", async () => {