mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 13:21:25 +00:00
test: dedupe agent tests and session helpers
This commit is contained in:
@@ -121,13 +121,35 @@ describe("before_tool_call loop detection behavior", () => {
|
||||
};
|
||||
}
|
||||
|
||||
it("blocks known poll loops when no progress repeats", async () => {
|
||||
function createNoProgressProcessFixture(sessionId: string) {
|
||||
const execute = vi.fn().mockResolvedValue({
|
||||
content: [{ type: "text", text: "(no new output)\n\nProcess still running." }],
|
||||
details: { status: "running", aggregated: "steady" },
|
||||
});
|
||||
const tool = createWrappedTool("process", execute);
|
||||
const params = { action: "poll", sessionId: "sess-1" };
|
||||
return {
|
||||
tool: createWrappedTool("process", execute),
|
||||
params: { action: "poll", sessionId },
|
||||
};
|
||||
}
|
||||
|
||||
function expectCriticalLoopEvent(
|
||||
loopEvent: DiagnosticToolLoopEvent | undefined,
|
||||
params: {
|
||||
detector: "ping_pong" | "known_poll_no_progress";
|
||||
toolName: string;
|
||||
count?: number;
|
||||
},
|
||||
) {
|
||||
expect(loopEvent?.type).toBe("tool.loop");
|
||||
expect(loopEvent?.level).toBe("critical");
|
||||
expect(loopEvent?.action).toBe("block");
|
||||
expect(loopEvent?.detector).toBe(params.detector);
|
||||
expect(loopEvent?.count).toBe(params.count ?? CRITICAL_THRESHOLD);
|
||||
expect(loopEvent?.toolName).toBe(params.toolName);
|
||||
}
|
||||
|
||||
it("blocks known poll loops when no progress repeats", async () => {
|
||||
const { tool, params } = createNoProgressProcessFixture("sess-1");
|
||||
|
||||
for (let i = 0; i < CRITICAL_THRESHOLD; i += 1) {
|
||||
await expect(tool.execute(`poll-${i}`, params, undefined, undefined)).resolves.toBeDefined();
|
||||
@@ -245,12 +267,10 @@ describe("before_tool_call loop detection behavior", () => {
|
||||
).rejects.toThrow("CRITICAL");
|
||||
|
||||
const loopEvent = emitted.at(-1);
|
||||
expect(loopEvent?.type).toBe("tool.loop");
|
||||
expect(loopEvent?.level).toBe("critical");
|
||||
expect(loopEvent?.action).toBe("block");
|
||||
expect(loopEvent?.detector).toBe("ping_pong");
|
||||
expect(loopEvent?.count).toBe(CRITICAL_THRESHOLD);
|
||||
expect(loopEvent?.toolName).toBe("list");
|
||||
expectCriticalLoopEvent(loopEvent, {
|
||||
detector: "ping_pong",
|
||||
toolName: "list",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -281,12 +301,7 @@ describe("before_tool_call loop detection behavior", () => {
|
||||
|
||||
it("emits structured critical diagnostic events when blocking loops", async () => {
|
||||
await withToolLoopEvents(async (emitted) => {
|
||||
const execute = vi.fn().mockResolvedValue({
|
||||
content: [{ type: "text", text: "(no new output)\n\nProcess still running." }],
|
||||
details: { status: "running", aggregated: "steady" },
|
||||
});
|
||||
const tool = createWrappedTool("process", execute);
|
||||
const params = { action: "poll", sessionId: "sess-crit" };
|
||||
const { tool, params } = createNoProgressProcessFixture("sess-crit");
|
||||
|
||||
for (let i = 0; i < CRITICAL_THRESHOLD; i += 1) {
|
||||
await tool.execute(`poll-${i}`, params, undefined, undefined);
|
||||
@@ -297,12 +312,10 @@ describe("before_tool_call loop detection behavior", () => {
|
||||
).rejects.toThrow("CRITICAL");
|
||||
|
||||
const loopEvent = emitted.at(-1);
|
||||
expect(loopEvent?.type).toBe("tool.loop");
|
||||
expect(loopEvent?.level).toBe("critical");
|
||||
expect(loopEvent?.action).toBe("block");
|
||||
expect(loopEvent?.detector).toBe("known_poll_no_progress");
|
||||
expect(loopEvent?.count).toBe(CRITICAL_THRESHOLD);
|
||||
expect(loopEvent?.toolName).toBe("process");
|
||||
expectCriticalLoopEvent(loopEvent, {
|
||||
detector: "known_poll_no_progress",
|
||||
toolName: "process",
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user