99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
import { __testing } from "./compaction-safeguard.js";
|
|
|
|
const { collectToolFailures, formatToolFailuresSection } = __testing;
|
|
|
|
describe("compaction-safeguard tool failures", () => {
|
|
it("formats tool failures with meta and summary", () => {
|
|
const messages: AgentMessage[] = [
|
|
{
|
|
role: "toolResult",
|
|
toolCallId: "call-1",
|
|
toolName: "exec",
|
|
isError: true,
|
|
details: { status: "failed", exitCode: 1 },
|
|
content: [{ type: "text", text: "ENOENT: missing file" }],
|
|
timestamp: Date.now(),
|
|
},
|
|
{
|
|
role: "toolResult",
|
|
toolCallId: "call-2",
|
|
toolName: "read",
|
|
isError: false,
|
|
content: [{ type: "text", text: "ok" }],
|
|
timestamp: Date.now(),
|
|
},
|
|
];
|
|
|
|
const failures = collectToolFailures(messages);
|
|
expect(failures).toHaveLength(1);
|
|
|
|
const section = formatToolFailuresSection(failures);
|
|
expect(section).toContain("## Tool Failures");
|
|
expect(section).toContain("exec (status=failed exitCode=1): ENOENT: missing file");
|
|
});
|
|
|
|
it("dedupes by toolCallId and handles empty output", () => {
|
|
const messages: AgentMessage[] = [
|
|
{
|
|
role: "toolResult",
|
|
toolCallId: "call-1",
|
|
toolName: "exec",
|
|
isError: true,
|
|
details: { exitCode: 2 },
|
|
content: [],
|
|
timestamp: Date.now(),
|
|
},
|
|
{
|
|
role: "toolResult",
|
|
toolCallId: "call-1",
|
|
toolName: "exec",
|
|
isError: true,
|
|
content: [{ type: "text", text: "ignored" }],
|
|
timestamp: Date.now(),
|
|
},
|
|
];
|
|
|
|
const failures = collectToolFailures(messages);
|
|
expect(failures).toHaveLength(1);
|
|
|
|
const section = formatToolFailuresSection(failures);
|
|
expect(section).toContain("exec (exitCode=2): failed");
|
|
});
|
|
|
|
it("caps the number of failures and adds overflow line", () => {
|
|
const messages: AgentMessage[] = Array.from({ length: 9 }, (_, idx) => ({
|
|
role: "toolResult",
|
|
toolCallId: `call-${idx}`,
|
|
toolName: "exec",
|
|
isError: true,
|
|
content: [{ type: "text", text: `error ${idx}` }],
|
|
timestamp: Date.now(),
|
|
}));
|
|
|
|
const failures = collectToolFailures(messages);
|
|
const section = formatToolFailuresSection(failures);
|
|
expect(section).toContain("## Tool Failures");
|
|
expect(section).toContain("...and 1 more");
|
|
});
|
|
|
|
it("omits section when there are no tool failures", () => {
|
|
const messages: AgentMessage[] = [
|
|
{
|
|
role: "toolResult",
|
|
toolCallId: "ok",
|
|
toolName: "exec",
|
|
isError: false,
|
|
content: [{ type: "text", text: "ok" }],
|
|
timestamp: Date.now(),
|
|
},
|
|
];
|
|
|
|
const failures = collectToolFailures(messages);
|
|
const section = formatToolFailuresSection(failures);
|
|
expect(section).toBe("");
|
|
});
|
|
});
|