test: update expectations for session reset behavior

This commit is contained in:
Peter Steinberger
2026-01-18 22:49:28 +00:00
parent 404c373153
commit 0d543dd1ff
3 changed files with 23 additions and 15 deletions

View File

@@ -94,7 +94,7 @@ describe("buildAgentSystemPrompt", () => {
expect(prompt).toContain("- Read: Read file contents"); expect(prompt).toContain("- Read: Read file contents");
expect(prompt).toContain("- Exec: Run shell commands"); expect(prompt).toContain("- Exec: Run shell commands");
expect(prompt).toContain( expect(prompt).toContain(
"read its SKILL.md at <location> with `Read`", "- If exactly one skill clearly applies: read its SKILL.md at <location> with `Read`, then follow it.",
); );
expect(prompt).toContain("Clawdbot docs: /tmp/clawd/docs"); expect(prompt).toContain("Clawdbot docs: /tmp/clawd/docs");
expect(prompt).toContain( expect(prompt).toContain(
@@ -188,7 +188,7 @@ describe("buildAgentSystemPrompt", () => {
expect(prompt).toContain("## Skills"); expect(prompt).toContain("## Skills");
expect(prompt).toContain( expect(prompt).toContain(
"read its SKILL.md at <location> with `read`", "- If exactly one skill clearly applies: read its SKILL.md at <location> with `read`, then follow it.",
); );
}); });

View File

@@ -44,10 +44,6 @@ vi.mock("./queue.js", async () => {
import { runReplyAgent } from "./agent-runner.js"; import { runReplyAgent } from "./agent-runner.js";
beforeEach(() => {
runEmbeddedPiAgentMock.mockReset();
});
function createMinimalRun(params?: { function createMinimalRun(params?: {
opts?: GetReplyOptions; opts?: GetReplyOptions;
resolvedVerboseLevel?: "off" | "on"; resolvedVerboseLevel?: "off" | "on";
@@ -125,6 +121,10 @@ function createMinimalRun(params?: {
} }
describe("runReplyAgent typing (heartbeat)", () => { describe("runReplyAgent typing (heartbeat)", () => {
beforeEach(() => {
runEmbeddedPiAgentMock.mockReset();
});
it("retries after compaction failure by resetting the session", async () => { it("retries after compaction failure by resetting the session", async () => {
const prevStateDir = process.env.CLAWDBOT_STATE_DIR; const prevStateDir = process.env.CLAWDBOT_STATE_DIR;
const stateDir = await fs.mkdtemp(path.join(tmpdir(), "clawdbot-session-compaction-reset-")); const stateDir = await fs.mkdtemp(path.join(tmpdir(), "clawdbot-session-compaction-reset-"));
@@ -141,11 +141,11 @@ describe("runReplyAgent typing (heartbeat)", () => {
await fs.mkdir(path.dirname(transcriptPath), { recursive: true }); await fs.mkdir(path.dirname(transcriptPath), { recursive: true });
await fs.writeFile(transcriptPath, "ok", "utf-8"); await fs.writeFile(transcriptPath, "ok", "utf-8");
runEmbeddedPiAgentMock.mockRejectedValueOnce( runEmbeddedPiAgentMock.mockImplementationOnce(async () => {
new Error( throw new Error(
'Context overflow: Summarization failed: 400 {"message":"prompt is too long"}', 'Context overflow: Summarization failed: 400 {"message":"prompt is too long"}',
),
); );
});
const { run } = createMinimalRun({ const { run } = createMinimalRun({
sessionEntry, sessionEntry,
@@ -160,6 +160,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
expect(payload).toMatchObject({ expect(payload).toMatchObject({
text: expect.stringContaining("Context limit exceeded during compaction"), text: expect.stringContaining("Context limit exceeded during compaction"),
}); });
expect(payload.text?.toLowerCase()).toContain("reset");
expect(sessionStore.main.sessionId).not.toBe(sessionId); expect(sessionStore.main.sessionId).not.toBe(sessionId);
const persisted = JSON.parse(await fs.readFile(storePath, "utf-8")); const persisted = JSON.parse(await fs.readFile(storePath, "utf-8"));
@@ -172,6 +173,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
} }
} }
}); });
it("retries after context overflow payload by resetting the session", async () => { it("retries after context overflow payload by resetting the session", async () => {
const prevStateDir = process.env.CLAWDBOT_STATE_DIR; const prevStateDir = process.env.CLAWDBOT_STATE_DIR;
const stateDir = await fs.mkdtemp(path.join(tmpdir(), "clawdbot-session-overflow-reset-")); const stateDir = await fs.mkdtemp(path.join(tmpdir(), "clawdbot-session-overflow-reset-"));
@@ -188,7 +190,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
await fs.mkdir(path.dirname(transcriptPath), { recursive: true }); await fs.mkdir(path.dirname(transcriptPath), { recursive: true });
await fs.writeFile(transcriptPath, "ok", "utf-8"); await fs.writeFile(transcriptPath, "ok", "utf-8");
runEmbeddedPiAgentMock.mockResolvedValueOnce({ runEmbeddedPiAgentMock.mockImplementationOnce(async () => ({
payloads: [{ text: "Context overflow: prompt too large", isError: true }], payloads: [{ text: "Context overflow: prompt too large", isError: true }],
meta: { meta: {
durationMs: 1, durationMs: 1,
@@ -198,7 +200,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
'Context overflow: Summarization failed: 400 {"message":"prompt is too long"}', 'Context overflow: Summarization failed: 400 {"message":"prompt is too long"}',
}, },
}, },
}); }));
const { run } = createMinimalRun({ const { run } = createMinimalRun({
sessionEntry, sessionEntry,
@@ -211,8 +213,9 @@ describe("runReplyAgent typing (heartbeat)", () => {
expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1); expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
const payload = Array.isArray(res) ? res[0] : res; const payload = Array.isArray(res) ? res[0] : res;
expect(payload).toMatchObject({ expect(payload).toMatchObject({
text: expect.stringContaining("Context limit exceeded."), text: expect.stringContaining("Context limit exceeded"),
}); });
expect(payload.text?.toLowerCase()).toContain("reset");
expect(sessionStore.main.sessionId).not.toBe(sessionId); expect(sessionStore.main.sessionId).not.toBe(sessionId);
const persisted = JSON.parse(await fs.readFile(storePath, "utf-8")); const persisted = JSON.parse(await fs.readFile(storePath, "utf-8"));
@@ -225,6 +228,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
} }
} }
}); });
it("resets the session after role ordering payloads", async () => { it("resets the session after role ordering payloads", async () => {
const prevStateDir = process.env.CLAWDBOT_STATE_DIR; const prevStateDir = process.env.CLAWDBOT_STATE_DIR;
const stateDir = await fs.mkdtemp(path.join(tmpdir(), "clawdbot-session-role-ordering-")); const stateDir = await fs.mkdtemp(path.join(tmpdir(), "clawdbot-session-role-ordering-"));

View File

@@ -266,7 +266,9 @@ describe("memory cli", () => {
registerMemoryCli(program); registerMemoryCli(program);
await program.parseAsync(["memory", "index"], { from: "user" }); await program.parseAsync(["memory", "index"], { from: "user" });
expect(sync).toHaveBeenCalledWith({ reason: "cli", force: false }); expect(sync).toHaveBeenCalledWith(
expect.objectContaining({ reason: "cli", force: false, progress: expect.any(Function) }),
);
expect(close).toHaveBeenCalled(); expect(close).toHaveBeenCalled();
expect(log).toHaveBeenCalledWith("Memory index updated (main)."); expect(log).toHaveBeenCalledWith("Memory index updated (main).");
}); });
@@ -291,7 +293,9 @@ describe("memory cli", () => {
registerMemoryCli(program); registerMemoryCli(program);
await program.parseAsync(["memory", "index"], { from: "user" }); await program.parseAsync(["memory", "index"], { from: "user" });
expect(sync).toHaveBeenCalledWith({ reason: "cli", force: false }); expect(sync).toHaveBeenCalledWith(
expect.objectContaining({ reason: "cli", force: false, progress: expect.any(Function) }),
);
expect(close).toHaveBeenCalled(); expect(close).toHaveBeenCalled();
expect(error).toHaveBeenCalledWith( expect(error).toHaveBeenCalledWith(
expect.stringContaining("Memory manager close failed: close boom"), expect.stringContaining("Memory manager close failed: close boom"),