evOo-local/packages/adapters/src/tool-loop.test.ts

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);
});
});