@@ -8,21 +8,37 @@ type Repeat = {
88
99// Corrective note for the doom-loop guard's warning turn (repeat count
1010// threshold−1): tells the model the exact call already ran unchanged, shows
11- // what else is on the wire, and points at the two escape hatches. The wire
12- // list is read lazily so tool_search activations mid-run are reflected.
11+ // what else is on the wire, and points at the escape hatches — switching to a
12+ // different tool already on the wire first, tool_search and replying to the
13+ // operator as fallback. The wire list is read lazily so tool_search
14+ // activations mid-run are reflected.
1315export function createDoomLoopCorrectiveNote (
1416 wireToolNames : ( ) => readonly string [ ] ,
1517) : ( repeat : Repeat ) => string {
1618 return ( { calls } ) => {
17- const repeated = [ ...new Set ( calls . map ( ( c ) => c . name ) ) ] . join ( ", " ) ;
18- const wire = wireToolNames ( ) . join ( ", " ) ;
19+ const looped = new Set ( calls . map ( ( c ) => c . name ) ) ;
20+ const repeated = [ ...looped ] . join ( ", " ) ;
21+ const names = wireToolNames ( ) ;
22+ const wire = names . join ( ", " ) ;
23+ // Name one non-looped tool already on the wire as the first escape, so
24+ // the model switches instead of repeating. tool_search stays a fallback
25+ // rather than the example — it is named in the fallback sentence.
26+ const example = names . find (
27+ ( name ) => ! looped . has ( name ) && name !== "tool_search" ,
28+ ) ;
29+ const escape =
30+ example === undefined
31+ ? `Do not call this batch again — call tool_search to discover a ` +
32+ `different tool, or reply to the operator describing what you need.`
33+ : `Do not call this batch again — call a different tool already on ` +
34+ `the wire instead (for example ${ example } ). If none of those fits, ` +
35+ `call tool_search to discover a different tool or reply to the ` +
36+ `operator describing what you need.` ;
1937 return (
2038 `Loop guard: this exact call (${ repeated } ) already ran with the same ` +
2139 `arguments and returned the same result — calling it again changes ` +
22- `nothing. Tools currently on the wire: ${ wire } . Do not call this batch ` +
23- `again — reply to the operator describing what you need, or call ` +
24- `tool_search to discover a different tool. The next identical repeat ` +
25- `ends this run.`
40+ `nothing. Tools currently on the wire: ${ wire } . ${ escape } The next ` +
41+ `identical repeat ends this run.`
2642 ) ;
2743 } ;
2844}
0 commit comments