diff --git a/src/features/background-agent/loop-detector.ts b/src/features/background-agent/loop-detector.ts index af93dee2a..a7ee3a883 100644 --- a/src/features/background-agent/loop-detector.ts +++ b/src/features/background-agent/loop-detector.ts @@ -44,7 +44,9 @@ export function recordToolCall( ): ToolCallWindow { const previous = window?.toolSignatures ?? [] const signature = createToolCallSignature(toolName, toolInput) - const toolSignatures = [...previous, signature].slice(-settings.windowSize) + const toolSignatures = previous.length >= settings.windowSize + ? [...previous.slice(1), signature] + : [...previous, signature] return { toolSignatures, diff --git a/src/features/background-agent/manager-circuit-breaker.test.ts b/src/features/background-agent/manager-circuit-breaker.test.ts index ddff2ec61..8bb1426e7 100644 --- a/src/features/background-agent/manager-circuit-breaker.test.ts +++ b/src/features/background-agent/manager-circuit-breaker.test.ts @@ -233,7 +233,7 @@ describe("BackgroundManager circuit breaker", () => { expect(task.status).toBe("running") expect(task.progress?.toolCalls).toBe(1) - expect(task.progress?.countedToolPartIDs).toEqual(["tool-1"]) + expect(task.progress?.countedToolPartIDs).toEqual(new Set(["tool-1"])) }) }) diff --git a/src/features/background-agent/manager.ts b/src/features/background-agent/manager.ts index 5a0e3c678..b43ba96a6 100644 --- a/src/features/background-agent/manager.ts +++ b/src/features/background-agent/manager.ts @@ -57,6 +57,7 @@ import { detectRepetitiveToolUse, recordToolCall, resolveCircuitBreakerSettings, + type CircuitBreakerSettings, } from "./loop-detector" import { createSubagentDepthLimitError, @@ -152,6 +153,7 @@ export class BackgroundManager { private preStartDescendantReservations: Set private enableParentSessionNotifications: boolean readonly taskHistory = new TaskHistory() + private cachedCircuitBreakerSettings?: CircuitBreakerSettings constructor( ctx: PluginInput, @@ -918,7 +920,7 @@ export class BackgroundManager { task.progress.toolCalls += 1 task.progress.lastTool = partInfo.tool - const circuitBreaker = resolveCircuitBreakerSettings(this.config) + const circuitBreaker = this.cachedCircuitBreakerSettings ?? (this.cachedCircuitBreakerSettings = resolveCircuitBreakerSettings(this.config)) if (partInfo.tool) { task.progress.toolCallWindow = recordToolCall( task.progress.toolCallWindow, diff --git a/src/features/background-agent/types.ts b/src/features/background-agent/types.ts index be57d5a7d..3bb7141e2 100644 --- a/src/features/background-agent/types.ts +++ b/src/features/background-agent/types.ts @@ -19,7 +19,7 @@ export interface TaskProgress { toolCalls: number lastTool?: string toolCallWindow?: ToolCallWindow - countedToolPartIDs?: string[] + countedToolPartIDs?: Set lastUpdate: Date lastMessage?: string lastMessageAt?: Date