{"version":3,"file":"todo-loop-guard.d.ts","sourceRoot":"","sources":["../../../src/core/tools/todo-loop-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,uBAAuB,CAAK;IAEpC;;;;OAIG;IACH,eAAe,IAAI,OAAO,CAGzB;IAED;;OAEG;IACH,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEjD;IAED;;OAEG;IACH,qBAAqB,IAAI,IAAI,CAE5B;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAEZ;IAED,0BAA0B,IAAI,MAAM,CAEnC;IAED,eAAe,IAAI,OAAO,CAEzB;CACD","sourcesContent":["/**\n * Guard against duplicate todo_write calls within a single user turn.\n *\n * - The first write after the per-turn lock is active is blocked and returns a\n *   paired TODO_WRITE_ALREADY_APPLIED rejection result.\n * - The second equivalent duplicate terminates the active agent run locally with\n *   REPEATED_TOOL_CALL_LOOP. The tool layer throws for this case.\n *\n * Counts reset on non-todo tool success or a new user message.\n */\nexport class TodoLoopGuard {\n\tprivate duplicateRejectionCount = 0;\n\n\t/**\n\t * Record a todo_write attempt that was already rejected by the per-turn lock.\n\t * Returns whether the call may return a rejection result (first duplicate)\n\t * or must terminate the run (second equivalent duplicate).\n\t */\n\trecordDuplicate(): boolean {\n\t\tthis.duplicateRejectionCount++;\n\t\treturn this.duplicateRejectionCount <= 1;\n\t}\n\n\t/**\n\t * Reset loop guard after a successful non-todo tool call.\n\t */\n\tresetOnNonTodoToolSuccess(_toolName: string): void {\n\t\tthis.duplicateRejectionCount = 0;\n\t}\n\n\t/**\n\t * Reset loop guard when a new user message arrives.\n\t */\n\tresetOnNewUserMessage(): void {\n\t\tthis.duplicateRejectionCount = 0;\n\t}\n\n\t/**\n\t * Reset loop guard manually.\n\t */\n\treset(): void {\n\t\tthis.duplicateRejectionCount = 0;\n\t}\n\n\tgetDuplicateRejectionCount(): number {\n\t\treturn this.duplicateRejectionCount;\n\t}\n\n\tisDuplicateLoop(): boolean {\n\t\treturn this.duplicateRejectionCount >= 2;\n\t}\n}\n"]}