54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { advanceToolCallLoopGuard } from "./tool-loop.js";
|
|
|
|
describe("advanceToolCallLoopGuard", () => {
|
|
it("allows a parallel Open Connector batch with distinct action inputs", () => {
|
|
let streak = { key: undefined as string | undefined, count: 0 };
|
|
|
|
for (let index = 0; index < 20; index += 1) {
|
|
const result = advanceToolCallLoopGuard(streak, "mcp__open-connector__execute_action", {
|
|
actionId: "records.get",
|
|
input: { recordId: index + 1 },
|
|
});
|
|
streak = result.streak;
|
|
expect(result.stuck).toBe(false);
|
|
}
|
|
});
|
|
|
|
it("stops six consecutive calls with identical inputs", () => {
|
|
let streak = { key: undefined as string | undefined, count: 0 };
|
|
let stuck = false;
|
|
|
|
for (let index = 0; index < 6; index += 1) {
|
|
const result = advanceToolCallLoopGuard(streak, "shell", { command: "npm test" });
|
|
streak = result.streak;
|
|
stuck = result.stuck;
|
|
}
|
|
|
|
expect(stuck).toBe(true);
|
|
expect(streak.count).toBe(6);
|
|
});
|
|
|
|
it("stops alternating ping-pong loops (A <-> B) with identical inputs", () => {
|
|
let streak = { key: undefined as string | undefined, count: 0 };
|
|
let stuck = false;
|
|
|
|
for (let cycle = 0; cycle < 4; cycle += 1) {
|
|
const readRes = advanceToolCallLoopGuard(streak, "read_file", { path: "style.css" });
|
|
streak = readRes.streak;
|
|
expect(readRes.stuck).toBe(false);
|
|
|
|
const editRes = advanceToolCallLoopGuard(streak, "edit_file", {
|
|
path: "style.css",
|
|
old_text: "a",
|
|
new_text: "b",
|
|
});
|
|
streak = editRes.streak;
|
|
stuck = editRes.stuck;
|
|
}
|
|
|
|
expect(stuck).toBe(true);
|
|
expect(streak.count).toBe(8);
|
|
});
|
|
});
|