

























@@ -15,7 +15,7 @@ import {
1515runBeforeToolCallHook,
1616wrapToolWithBeforeToolCallHook,
1717} from "./pi-tools.before-tool-call.js";
18-import { CRITICAL_THRESHOLD, GLOBAL_CIRCUIT_BREAKER_THRESHOLD } from "./tool-loop-detection.js";
18+import { CRITICAL_THRESHOLD } from "./tool-loop-detection.js";
1919import type { AnyAgentTool } from "./tools/common.js";
2020import { callGatewayTool } from "./tools/gateway.js";
2121@@ -277,28 +277,23 @@ describe("before_tool_call loop detection behavior", () => {
277277}
278278});
279279280-it("keeps generic repeated calls warn-only below global breaker", async () => {
280+it("keeps generic repeated calls unblocked below critical threshold", async () => {
281281const { tool, params } = createGenericReadRepeatFixture();
282282283-for (let i = 0; i < CRITICAL_THRESHOLD + 5; i += 1) {
283+for (let i = 0; i < CRITICAL_THRESHOLD; i += 1) {
284284await expectUnblockedToolExecution(tool, `read-${i}`, params);
285285}
286286});
287287288-it("blocks generic repeated no-progress calls at global breaker threshold", async () => {
288+it("blocks generic repeated no-progress calls at critical threshold", async () => {
289289const { tool, params } = createGenericReadRepeatFixture();
290290291-for (let i = 0; i < GLOBAL_CIRCUIT_BREAKER_THRESHOLD; i += 1) {
291+for (let i = 0; i < CRITICAL_THRESHOLD; i += 1) {
292292await expectUnblockedToolExecution(tool, `read-${i}`, params);
293293}
294294295-const result = await tool.execute(
296-`read-${GLOBAL_CIRCUIT_BREAKER_THRESHOLD}`,
297-params,
298-undefined,
299-undefined,
300-);
301-expectToolLoopBlockedResult(result, "global circuit breaker");
295+const result = await tool.execute(`read-${CRITICAL_THRESHOLD}`, params, undefined, undefined);
296+expectToolLoopBlockedResult(result, "identical outcomes");
302297});
303298304299it("does not carry loop history across run ids", async () => {
@@ -316,27 +311,27 @@ describe("before_tool_call loop detection behavior", () => {
316311runId: "heartbeat-2",
317312});
318313319-for (let i = 0; i < GLOBAL_CIRCUIT_BREAKER_THRESHOLD; i += 1) {
314+for (let i = 0; i < CRITICAL_THRESHOLD; i += 1) {
320315await expectUnblockedToolExecution(firstRunTool, `old-run-${i}`, params);
321316}
322317323318await expectUnblockedToolExecution(secondRunTool, "new-run-0", params);
324319});
325320326-it("coalesces repeated generic warning events into threshold buckets", async () => {
327-await withToolLoopEvents(
328-async (emitted) => {
329-const { tool, params } = createGenericReadRepeatFixture();
321+it("escalates generic repeat diagnostics from warning to critical", async () => {
322+await withToolLoopEvents(async (emitted) => {
323+const { tool, params } = createGenericReadRepeatFixture();
330324331- for (let i = 0; i < 21; i += 1) {
332- await tool.execute(`read-bucket-${i}`, params, undefined, undefined);
333- }
325+for (let i = 0; i < 21; i += 1) {
326+await tool.execute(`read-bucket-${i}`, params, undefined, undefined);
327+}
334328335-const genericWarns = emitted.filter((evt) => evt.detector === "generic_repeat");
336-expect(genericWarns.map((evt) => evt.count)).toEqual([10, 20]);
337-},
338-(evt) => evt.level === "warning",
339-);
329+const genericEvents = emitted.filter((evt) => evt.detector === "generic_repeat");
330+expect(genericEvents.map((evt) => [evt.level, evt.count])).toEqual([
331+["warning", 10],
332+["critical", 20],
333+]);
334+});
340335});
341336342337it("emits structured warning diagnostic events for ping-pong loops", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。