(limit = 2000)
| 129 | |
| 130 | /** Read the failure log (most recent `limit` events, to bound memory). */ |
| 131 | export async function readFailures(limit = 2000): Promise<FailureEvent[]> { |
| 132 | try { |
| 133 | const raw = await fs.readFile(failuresPath(), 'utf-8'); |
| 134 | const lines = raw.split('\n').filter(l => l.trim()); |
| 135 | const slice = lines.slice(-limit); |
| 136 | return slice.map(l => { try { return JSON.parse(l) as FailureEvent; } catch { return null; } }).filter(Boolean) as FailureEvent[]; |
| 137 | } catch { |
| 138 | return []; |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | /** Convenience: read → detect → build the injectable block. Used by the agent loop. */ |
| 143 | export async function loadLessonsBlock(opts: DetectOpts & { topK?: number } = { ...DEFAULT_DETECT }): Promise<string> { |
no test coverage detected