(p: FailurePattern)
| 89 | |
| 90 | /** Templated, DETERMINISTIC caution for a recurring failure. Never LLM-phrased. */ |
| 91 | export function buildLesson(p: FailurePattern): string { |
| 92 | const sig = p.signature.toLowerCase(); |
| 93 | const verb = (advice: string) => `When using \`${p.tool}\`: ${advice} (this failed ${p.count}× across ${p.distinctTasks} tasks).`; |
| 94 | if (/(not found|does not exist|cannot find|no such|unknown symbol|undefined)/.test(sig)) { |
| 95 | if (p.tool.startsWith('edit_symbol')) return verb('confirm the symbol exists first (grep / code-graph) — it has repeatedly not been found.'); |
| 96 | return verb('verify the target exists before calling it — the target has repeatedly not been found.'); |
| 97 | } |
| 98 | if (/(permission|denied|eacces|not permitted)/.test(sig)) return verb('check permissions / path writability before retrying.'); |
| 99 | if (/(timeout|timed out|etimedout)/.test(sig)) return verb('it has repeatedly timed out — narrow the scope or raise the timeout.'); |
| 100 | if (/(syntax|parse|unexpected token)/.test(sig)) return verb('the produced input repeatedly failed to parse — double-check syntax before submitting.'); |
| 101 | if (/(already exists|eexist)/.test(sig)) return verb('the target already exists — read/update it instead of creating.'); |
| 102 | return verb(`it has failed repeatedly with: "${p.sample.slice(0, 80)}". Check its preconditions before using it again.`); |
| 103 | } |
| 104 | |
| 105 | /** Build the system-prompt block from confirmed patterns (top-K). Empty when none. */ |
| 106 | export function buildLessonsBlock(patterns: FailurePattern[], topK = 5): string { |
no test coverage detected