(
recentErrors: Array<{ name: string; code: string }>,
threshold = 3,
)
| 165 | * the offending tool + error code when it crosses `threshold`, else null. |
| 166 | */ |
| 167 | export function detectErrorLoop( |
| 168 | recentErrors: Array<{ name: string; code: string }>, |
| 169 | threshold = 3, |
| 170 | ): { name: string; code: string; count: number } | null { |
| 171 | if (recentErrors.length < threshold) return null; |
| 172 | const counts = new Map<string, number>(); |
| 173 | for (const e of recentErrors) { |
| 174 | const key = `${e.name}|${e.code}`; |
| 175 | counts.set(key, (counts.get(key) ?? 0) + 1); |
| 176 | } |
| 177 | for (const [key, count] of counts) { |
| 178 | if (count >= threshold) { |
| 179 | const [name, code] = key.split('|'); |
| 180 | return { name: name!, code: code!, count }; |
| 181 | } |
| 182 | } |
| 183 | return null; |
| 184 | } |
| 185 | |
| 186 | export function detectStuckLoop(recentToolCalls: Array<{ name: string; argsHash: string }>): boolean { |
| 187 | const n = recentToolCalls.length; |
no test coverage detected