@miller-tech/uap 1.130.1 → 1.131.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,7 +20,10 @@ function maxPhases() {
20
20
  const raw = Number(process.env.UAP_DELIVER_MAX_PHASES);
21
21
  if (Number.isFinite(raw) && raw >= MIN_PHASES)
22
22
  return Math.min(Math.floor(raw), MAX_PHASES_HARD_CEILING);
23
- return 8;
23
+ // (#4a) Default 8→10: a huge mission was being squeezed into ≤8 phases, each
24
+ // then too big for a rail. Still bounded by the hard ceiling; env overrides up
25
+ // to 20 for the largest missions.
26
+ return 10;
24
27
  }
25
28
  /** Only instructions this long are epic-shaped enough to auto-decompose. */
26
29
  const AUTO_DECOMPOSE_MIN_CHARS = 200;
@@ -1 +1 @@
1
- {"version":3,"file":"decompose.js","sourceRoot":"","sources":["../../src/delivery/decompose.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decompose.js","sourceRoot":"","sources":["../../src/delivery/decompose.ts"],"names":[],"mappings":"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"}
@@ -62,8 +62,27 @@ export interface EpicControllerConfig {
62
62
  * treated as "not accepted" so the controller retries rather than wedging.
63
63
  */
64
64
  checkAcceptance?: (epic: Epic, result: EpicRunResult) => boolean | Promise<boolean>;
65
- /** Max fresh-session attempts per epic before it is declared failed. Default 2. */
65
+ /** Max fresh-session attempts per epic before it is declared failed. Default 3. */
66
66
  maxAttemptsPerEpic?: number;
67
+ /**
68
+ * (#4c) Max recursive split levels when an epic can't be delivered whole.
69
+ * Default 1 (one level: an over-budget epic splits into sub-epics, which
70
+ * never re-split). deliver raises this for LARGE missions so a genuinely huge
71
+ * epic recursively shrinks — a sub-epic that still can't land is split again,
72
+ * one level shallower — until each piece fits a rail, instead of failing the
73
+ * whole mission at the first split. Bounded: the depth counter decrements to
74
+ * 0, and each `splitEpic` planner can decline (return null) to stop early.
75
+ */
76
+ splitDepth?: number;
77
+ /**
78
+ * (#5) When true, split a failed epic on ANY exhausted-attempts failure, not
79
+ * only on context-budget exhaustion — turning "epic failed, mission
80
+ * incomplete" into "re-plan it into smaller pieces and try those." Default
81
+ * false (budget exhaustion only, preserving the conservative path). deliver
82
+ * enables it for large missions so give-up becomes auto-escalation. Still
83
+ * bounded by `splitDepth` and by the planner's option to decline the split.
84
+ */
85
+ splitOnAnyFailure?: boolean;
67
86
  /** Progress hook. */
68
87
  onEpic?: (epic: Epic, outcome: EpicOutcome) => void;
69
88
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"epic-controller.d.ts","sourceRoot":"","sources":["../../src/delivery/epic-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,4EAA4E;AAC5E,MAAM,WAAW,IAAK,SAAQ,aAAa;IACzC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;;OAKG;IACH,OAAO,EAAE,CACP,IAAI,EAAE,IAAI,EACV,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,KACrE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5B;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpF,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB;IACrB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACpD;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;IACzE;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAID;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAoI1F"}
1
+ {"version":3,"file":"epic-controller.d.ts","sourceRoot":"","sources":["../../src/delivery/epic-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,4EAA4E;AAC5E,MAAM,WAAW,IAAK,SAAQ,aAAa;IACzC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;;OAKG;IACH,OAAO,EAAE,CACP,IAAI,EAAE,IAAI,EACV,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,KACrE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5B;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpF,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,qBAAqB;IACrB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACpD;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;IACzE;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAID;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgJ1F"}
@@ -22,7 +22,7 @@
22
22
  */
23
23
  import { topoOrder } from './decompose.js';
24
24
  import { CONTEXT_BUDGET_MARKER } from './context-budget.js';
25
- const DEFAULT_MAX_ATTEMPTS = 2;
25
+ const DEFAULT_MAX_ATTEMPTS = 3;
26
26
  /**
27
27
  * Run the epic sequence. Epics execute in dependency order; an epic whose
28
28
  * dependency failed is skipped (never build an epic on an unfinished one). Each
@@ -85,14 +85,24 @@ export async function runEpics(config) {
85
85
  : `attempt ${attempts} failed to deliver: ${result.summary}`;
86
86
  }
87
87
  }
88
- // Rail sizing: an epic that failed because its sessions outgrew the
89
- // context budget is too big for one rail re-plan it as smaller
90
- // sub-epics and run them in place (one split level; sub-epics inherit
91
- // the prior summaries but never split again).
92
- if (!accepted && config.splitEpic && (lastFailure ?? '').includes(CONTEXT_BUDGET_MARKER)) {
88
+ // Rail sizing + auto-escalation: an epic that exhausted its attempts is
89
+ // re-planned as smaller sub-epics and run in place, rather than failing the
90
+ // whole mission. Fires on context-budget exhaustion always, and on ANY
91
+ // failure when splitOnAnyFailure is set (#5). Recurses up to `splitDepth`
92
+ // levels (#4c): sub-epics inherit the prior summaries and may split again
93
+ // one level shallower until each piece fits a rail. Default depth 1 keeps
94
+ // the conservative one-level behavior.
95
+ const depthRemaining = config.splitDepth ?? 1;
96
+ const budgetExhausted = (lastFailure ?? '').includes(CONTEXT_BUDGET_MARKER);
97
+ const splitFn = config.splitEpic;
98
+ const shouldSplit = !accepted &&
99
+ !!splitFn &&
100
+ depthRemaining > 0 &&
101
+ (budgetExhausted || config.splitOnAnyFailure === true);
102
+ if (shouldSplit && splitFn) {
93
103
  let subs = null;
94
104
  try {
95
- subs = await config.splitEpic(epic, lastFailure);
105
+ subs = await splitFn(epic, lastFailure);
96
106
  }
97
107
  catch {
98
108
  subs = null; // fail-soft: an unplannable split just keeps the failure
@@ -113,7 +123,7 @@ export async function runEpics(config) {
113
123
  const subResult = await runEpics({
114
124
  ...config,
115
125
  epics: chained,
116
- splitEpic: undefined, // one level only a sub-epic that still overflows fails
126
+ splitDepth: depthRemaining - 1, // recurse one level shallower (#4c); 0 no re-split
117
127
  initialPriorSummaries: [...priorSummaries],
118
128
  });
119
129
  epicTurns += subResult.turns; // flows into totalTurns below
@@ -124,9 +134,10 @@ export async function runEpics(config) {
124
134
  // project gates, i.e. the epic's goal is delivered.
125
135
  const finalPieceGreen = subResult.outcomes.length > 0 && subResult.outcomes[subResult.outcomes.length - 1].accepted;
126
136
  accepted = subResult.success || finalPieceGreen;
137
+ const splitReason = budgetExhausted ? 'context auto-size' : 'auto-escalation';
127
138
  lastSummary = accepted
128
- ? `split into ${chained.length} sub-epics (context auto-size): ${subResult.outcomes.map((o) => o.summary).join('; ')}`
129
- : `split into ${chained.length} sub-epics after context-budget exhaustion; failed: ${subResult.failed.join(', ')}`;
139
+ ? `split into ${chained.length} sub-epics (${splitReason}): ${subResult.outcomes.map((o) => o.summary).join('; ')}`
140
+ : `split into ${chained.length} sub-epics (${splitReason}); failed: ${subResult.failed.join(', ')}`;
130
141
  }
131
142
  }
132
143
  totalTurns += epicTurns;
@@ -1 +1 @@
1
- {"version":3,"file":"epic-controller.js","sourceRoot":"","sources":["../../src/delivery/epic-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"epic-controller.js","sourceRoot":"","sources":["../../src/delivery/epic-controller.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"persistence-profile.d.ts","sourceRoot":"","sources":["../../src/delivery/persistence-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,OAAO,GAAG,UAAU,GAAG,YAAY,CAAC;AAC/E,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,oBAAoB,CAAC;IAChC,iFAAiF;IACjF,cAAc,EAAE,OAAO,CAAC;IACxB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,cAAc,EAAE,OAAO,CAAC;CACzB;AAmBD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAMhE;AAeD,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACxD;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,GAAG,GAAE,iBAAsB,GAC1B,kBAAkB,CAqBpB"}
1
+ {"version":3,"file":"persistence-profile.d.ts","sourceRoot":"","sources":["../../src/delivery/persistence-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,OAAO,GAAG,UAAU,GAAG,YAAY,CAAC;AAC/E,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,oBAAoB,CAAC;IAChC,iFAAiF;IACjF,cAAc,EAAE,OAAO,CAAC;IACxB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,cAAc,EAAE,OAAO,CAAC;CACzB;AAsBD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAMhE;AAeD,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACxD;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,GAAG,GAAE,iBAAsB,GAC1B,kBAAkB,CAoCpB"}
@@ -18,8 +18,11 @@ const PROFILES = {
18
18
  light: { intensity: 'light', stopHookBlocks: true, maxBlocks: 3, stagnationLimit: 2, injectAutonomy: false },
19
19
  // Opus/Sonnet/GPT — nudge past premature-done; moderate blocking.
20
20
  moderate: { intensity: 'moderate', stopHookBlocks: true, maxBlocks: 6, stagnationLimit: 3, injectAutonomy: true },
21
- // qwen / small local — firmly drive; more blocks tolerated, tighter stagnation.
22
- aggressive: { intensity: 'aggressive', stopHookBlocks: true, maxBlocks: 9, stagnationLimit: 3, injectAutonomy: true },
21
+ // qwen / small local — firmly drive; more blocks tolerated. (#4d) maxBlocks
22
+ // 9→12 and stagnationLimit 3→4 give a huge multi-epic build more runway
23
+ // before give-up, now that #2 (state carryover) and #3 (force-write) keep the
24
+ // model making real progress across resets. Still finite — anti-spin holds.
25
+ aggressive: { intensity: 'aggressive', stopHookBlocks: true, maxBlocks: 12, stagnationLimit: 4, injectAutonomy: true },
23
26
  };
24
27
  const OFF_PROFILE = {
25
28
  intensity: 'off',
@@ -73,6 +76,20 @@ export function resolvePersistenceProfile(modelId, cfg = {}) {
73
76
  }
74
77
  }
75
78
  }
79
+ // (#4d) Env caps: raise the hands-free runway for a huge mission without
80
+ // weakening per-family defaults. Applied last so an explicit operator value
81
+ // wins. Only meaningful when the profile blocks; both stay finite (clamped
82
+ // to 50) so the "never spin forever" guarantee holds.
83
+ if (profile.stopHookBlocks) {
84
+ const envBlocks = Number(process.env.UAP_HANDSFREE_MAX_BLOCKS);
85
+ const envStag = Number(process.env.UAP_HANDSFREE_STAGNATION_LIMIT);
86
+ if (Number.isFinite(envBlocks) && envBlocks >= 1) {
87
+ profile = { ...profile, maxBlocks: Math.min(Math.floor(envBlocks), 50) };
88
+ }
89
+ if (Number.isFinite(envStag) && envStag >= 1) {
90
+ profile = { ...profile, stagnationLimit: Math.min(Math.floor(envStag), 50) };
91
+ }
92
+ }
76
93
  return profile;
77
94
  }
78
95
  //# sourceMappingURL=persistence-profile.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"persistence-profile.js","sourceRoot":"","sources":["../../src/delivery/persistence-profile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"persistence-profile.js","sourceRoot":"","sources":["../../src/delivery/persistence-profile.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miller-tech/uap",
3
- "version": "1.130.1",
3
+ "version": "1.131.0",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -4645,6 +4645,7 @@ def _maybe_inject_recon_convergence(
4645
4645
  openai_body["messages"] = msgs
4646
4646
 
4647
4647
  restored: list[str] = []
4648
+ stripped: list[str] = []
4648
4649
  if escalate:
4649
4650
  # Strip tools entirely so the only possible response is terminal prose.
4650
4651
  openai_body.pop("tools", None)
@@ -4691,11 +4692,44 @@ def _maybe_inject_recon_convergence(
4691
4692
  present.add(name.lower())
4692
4693
  restored.append(name)
4693
4694
 
4695
+ # FORCE-WRITE (hard tier): a nudge that leaves BOTH read and write tools
4696
+ # available lets the model keep picking a read — the live failure mode
4697
+ # (no_write_streak climbing to 45+ while write tools were re-injected but
4698
+ # tool_choice stayed 'auto', so the model just read again). At the hard
4699
+ # tier, remove the exploration path (read-only class + escape hatches) so
4700
+ # the only actions left are write/deliver, and force tool_choice=required
4701
+ # so a write MUST happen this turn. Floor-guarded: if stripping would
4702
+ # leave no write path, leave the toolset untouched (never strand — the
4703
+ # firm tier keeps reads, the escalate tier strips everything). Bounded:
4704
+ # if the model still produces no write, the streak keeps climbing and the
4705
+ # next fire escalates to the terminal-summary tier above.
4706
+ if hard:
4707
+ tools_now = openai_body.get("tools") or []
4708
+ deny = {c.lower() for c in _READ_ONLY_TOOL_CLASS} | {
4709
+ e.lower() for e in _EXPLORATION_ESCAPE_TOOLS
4710
+ }
4711
+ write_lower = {w.lower() for w in _WRITE_TOOL_CLASS}
4712
+
4713
+ def _rc_name(t: dict) -> str:
4714
+ return ((t.get("function", {}) or {}).get("name", "") or "").lower()
4715
+
4716
+ kept = [t for t in tools_now if _rc_name(t) not in deny]
4717
+ if kept and any(_rc_name(t) in write_lower for t in kept):
4718
+ stripped = [
4719
+ ((t.get("function", {}) or {}).get("name", "") or "")
4720
+ for t in tools_now
4721
+ if _rc_name(t) in deny
4722
+ ]
4723
+ if stripped:
4724
+ openai_body["tools"] = kept
4725
+ openai_body["tool_choice"] = "required"
4726
+ openai_body.pop("grammar", None)
4727
+
4694
4728
  logger.warning(
4695
4729
  "RECON CONVERGENCE: injected %s directive (no_write_streak=%d, hard_fires=%d, "
4696
- "ctx=%.0f%%, tool_choice=%s, restored_write_tools=%s)",
4730
+ "ctx=%.0f%%, tool_choice=%s, restored_write_tools=%s, stripped_read_tools=%s)",
4697
4731
  tier, streak, monitor.recon_hard_fires, util * 100,
4698
- openai_body.get("tool_choice", "stripped"), restored or "none",
4732
+ openai_body.get("tool_choice", "stripped"), restored or "none", stripped or "none",
4699
4733
  )
4700
4734
 
4701
4735
 
@@ -8151,6 +8185,94 @@ async def _apply_malformed_tool_guardrail(
8151
8185
  )
8152
8186
 
8153
8187
 
8188
+ def _extract_state_carryover(messages: list[dict], max_files: int = 20) -> str | None:
8189
+ """Reconstruct mission state (plan + files written) from a conversation that
8190
+ is about to be pruned by the contamination breaker, so the reset does not
8191
+ throw away what the build has planned and done.
8192
+
8193
+ The contamination/attractor reset keeps only the first user turn (+ a short
8194
+ tail), dropping the middle of the conversation — which is where the TodoWrite
8195
+ plan and the file-write actions live. On a huge build that drop destroys
8196
+ mission state: the model then re-explores from scratch, regrows the history,
8197
+ overflows again, and thrashes. The client's on-disk ledger is not visible to
8198
+ the proxy, but the plan and the writes ARE in the message stream, so
8199
+ reconstruct a compact carryover from them and re-inject it after the reset.
8200
+
8201
+ Returns a carryover block, or None when no state is found (fresh session).
8202
+ """
8203
+ write_lower = {w.lower() for w in _WRITE_TOOL_CLASS}
8204
+ plan_tools = {
8205
+ "todowrite", "taskcreate", "taskupdate", "task_create", "task_update",
8206
+ "todo_write", "update_todo_list",
8207
+ }
8208
+ latest_plan: list[str] = []
8209
+ files: list[str] = []
8210
+ seen: set[str] = set()
8211
+ for m in messages:
8212
+ if not isinstance(m, dict) or m.get("role") != "assistant":
8213
+ continue
8214
+ content = m.get("content")
8215
+ if not isinstance(content, list):
8216
+ continue
8217
+ for block in content:
8218
+ if not isinstance(block, dict) or block.get("type") != "tool_use":
8219
+ continue
8220
+ name = (block.get("name") or "").lower()
8221
+ inp = block.get("input") if isinstance(block.get("input"), dict) else {}
8222
+ if name in plan_tools:
8223
+ todos = inp.get("todos") or inp.get("tasks") or inp.get("items")
8224
+ if isinstance(todos, list):
8225
+ rendered = []
8226
+ for t in todos:
8227
+ if not isinstance(t, dict):
8228
+ continue
8229
+ text = (
8230
+ t.get("content") or t.get("title")
8231
+ or t.get("task") or t.get("description") or ""
8232
+ ).strip()
8233
+ if not text:
8234
+ continue
8235
+ status = (t.get("status") or t.get("state") or "").strip().lower()
8236
+ mark = {
8237
+ "completed": "x", "done": "x", "complete": "x",
8238
+ "in_progress": "~", "in-progress": "~", "active": "~",
8239
+ }.get(status, " ")
8240
+ rendered.append(f" [{mark}] {text}")
8241
+ if rendered:
8242
+ latest_plan = rendered # keep the MOST RECENT plan only
8243
+ elif name in write_lower:
8244
+ path = (
8245
+ inp.get("file_path") or inp.get("path")
8246
+ or inp.get("target") or inp.get("filename") or inp.get("task")
8247
+ )
8248
+ if isinstance(path, str) and path.strip() and path not in seen:
8249
+ seen.add(path)
8250
+ files.append(path.strip())
8251
+ if not latest_plan and not files:
8252
+ return None
8253
+ parts = [
8254
+ "[STATE CARRYOVER — preserved across the reset; do NOT restart from "
8255
+ "scratch or re-explore what is already done]"
8256
+ ]
8257
+ if latest_plan:
8258
+ parts.append(
8259
+ "Your current plan (most recent TodoWrite) — resume the first "
8260
+ "unfinished item ([ ] = todo, [~] = in progress, [x] = done):"
8261
+ )
8262
+ parts.extend(latest_plan[:40])
8263
+ if files:
8264
+ shown = files[-max_files:]
8265
+ omitted = len(files) - len(shown)
8266
+ head_note = f" (showing last {len(shown)} of {len(files)})" if omitted > 0 else ""
8267
+ parts.append(f"Files you have already written/edited this session{head_note}:")
8268
+ parts.extend(f" - {p}" for p in shown)
8269
+ parts.append(
8270
+ "Continue the plan from where it stands. Take the next concrete action "
8271
+ "toward the first unfinished item now."
8272
+ )
8273
+ return "\n".join(parts)
8274
+
8275
+
8154
8276
  def _maybe_apply_session_contamination_breaker(
8155
8277
  anthropic_body: dict, monitor: SessionMonitor, session_id: str
8156
8278
  ) -> dict:
@@ -8283,7 +8405,11 @@ def _maybe_apply_session_contamination_breaker(
8283
8405
  "Just call the tool."
8284
8406
  ),
8285
8407
  }
8286
- new_messages = head + [reset_marker]
8408
+ carry = _extract_state_carryover(messages)
8409
+ new_messages = (
8410
+ head + [reset_marker, {"role": "user", "content": carry}]
8411
+ if carry else head + [reset_marker]
8412
+ )
8287
8413
  monitor.attractor_correction_active = True
8288
8414
  log_reason = "attractor"
8289
8415
  else:
@@ -8296,7 +8422,9 @@ def _maybe_apply_session_contamination_breaker(
8296
8422
  "Continue from the recent context and emit valid tool calls with strict JSON arguments only.]"
8297
8423
  ),
8298
8424
  }
8299
- new_messages = head + [reset_marker] + tail
8425
+ carry = _extract_state_carryover(messages)
8426
+ carry_msgs = [{"role": "user", "content": carry}] if carry else []
8427
+ new_messages = head + [reset_marker] + carry_msgs + tail
8300
8428
  log_reason = "standard"
8301
8429
 
8302
8430
  updated_body = dict(anthropic_body)
@@ -0,0 +1,162 @@
1
+ """Tests for the huge-project hands-free fixes:
2
+
3
+ #3 FORCE-WRITE: at the hard recon-convergence tier the proxy strips the
4
+ exploration tools (read-only class + escape hatches) and forces
5
+ tool_choice='required' so the model MUST write instead of reading again.
6
+ #2 STATE CARRYOVER: the contamination breaker reconstructs the plan + files
7
+ written from the message stream and re-injects them after the reset, so a
8
+ prune no longer destroys mission state.
9
+ """
10
+ import importlib.util
11
+ import unittest
12
+ from pathlib import Path
13
+
14
+ proxy_path = Path(__file__).resolve().parents[3] / "tools" / "agents" / "scripts" / "anthropic_proxy.py"
15
+ spec = importlib.util.spec_from_file_location("anthropic_proxy", proxy_path)
16
+ ap = importlib.util.module_from_spec(spec)
17
+ spec.loader.exec_module(ap)
18
+
19
+
20
+ def _tool(name):
21
+ return {"type": "function", "function": {"name": name, "parameters": {}}}
22
+
23
+
24
+ def _names(tools):
25
+ return {(t.get("function", {}) or {}).get("name", "") for t in tools}
26
+
27
+
28
+ class ForceWriteHardTierTest(unittest.TestCase):
29
+ """#3: hard tier removes read/exploration tools and forces a write."""
30
+
31
+ def _hard_monitor(self):
32
+ m = ap.SessionMonitor(context_window=132096)
33
+ m.consecutive_no_write_turns = (
34
+ int(ap.PROXY_RECON_HARD_MULTIPLIER * ap.PROXY_RECON_CONVERGENCE_THRESHOLD) + 1
35
+ )
36
+ return m
37
+
38
+ def test_strips_reads_and_forces_required(self):
39
+ m = self._hard_monitor()
40
+ tools = [_tool("Read"), _tool("Grep"), _tool("Bash"), _tool("Write"), _tool("Edit")]
41
+ body = {"messages": [{"role": "user", "content": "reading"}], "tools": list(tools)}
42
+ ap._maybe_inject_recon_convergence(body, m, full_tools=tools)
43
+ remaining = _names(body["tools"])
44
+ self.assertNotIn("Read", remaining)
45
+ self.assertNotIn("Grep", remaining)
46
+ self.assertNotIn("Bash", remaining) # exploration escape hatch also stripped
47
+ self.assertIn("Write", remaining)
48
+ self.assertIn("Edit", remaining)
49
+ self.assertEqual(body.get("tool_choice"), "required")
50
+
51
+ def test_keeps_deliver_when_writes_are_gated(self):
52
+ m = self._hard_monitor()
53
+ tools = [_tool("Read"), _tool("Bash"), _tool("deliver")]
54
+ body = {"messages": [{"role": "user", "content": "reading"}], "tools": list(tools)}
55
+ ap._maybe_inject_recon_convergence(body, m, full_tools=tools)
56
+ remaining = _names(body["tools"])
57
+ self.assertIn("deliver", remaining) # deliver is a write path — survives
58
+ self.assertNotIn("Read", remaining)
59
+ self.assertEqual(body.get("tool_choice"), "required")
60
+
61
+ def test_floor_invariant_no_write_path_left_untouched(self):
62
+ """If stripping reads would leave NO write path, do not strip (never
63
+ strand). Falls back to the hard tier's 'auto' release."""
64
+ m = self._hard_monitor()
65
+ tools = [_tool("Read"), _tool("Grep")] # read-only, no write tool
66
+ body = {"messages": [{"role": "user", "content": "reading"}], "tools": list(tools)}
67
+ ap._maybe_inject_recon_convergence(body, m, full_tools=tools)
68
+ remaining = _names(body["tools"])
69
+ self.assertIn("Read", remaining) # untouched — no write path to force toward
70
+ self.assertNotEqual(body.get("tool_choice"), "required")
71
+
72
+ def test_firm_tier_does_not_force_write(self):
73
+ """The firm tier (below the hard multiplier) must keep reads available."""
74
+ m = ap.SessionMonitor(context_window=132096)
75
+ m.consecutive_no_write_turns = ap.PROXY_RECON_CONVERGENCE_THRESHOLD # firm
76
+ tools = [_tool("Read"), _tool("Write")]
77
+ body = {"messages": [{"role": "user", "content": "reading"}],
78
+ "tools": list(tools), "tool_choice": "required"}
79
+ ap._maybe_inject_recon_convergence(body, m, full_tools=tools)
80
+ self.assertIn("Read", _names(body["tools"])) # reads still allowed at firm
81
+ self.assertEqual(body.get("tool_choice"), "auto")
82
+
83
+
84
+ class StateCarryoverExtractTest(unittest.TestCase):
85
+ """#2: _extract_state_carryover reconstructs plan + files from the stream."""
86
+
87
+ def _convo(self):
88
+ return [
89
+ {"role": "user", "content": "build the app"},
90
+ {"role": "assistant", "content": [
91
+ {"type": "tool_use", "name": "TodoWrite", "input": {"todos": [
92
+ {"content": "scaffold project", "status": "completed"},
93
+ {"content": "add auth", "status": "in_progress"},
94
+ {"content": "write tests", "status": "pending"},
95
+ ]}},
96
+ ]},
97
+ {"role": "assistant", "content": [
98
+ {"type": "tool_use", "name": "Write", "input": {"file_path": "src/index.ts"}},
99
+ ]},
100
+ {"role": "assistant", "content": [
101
+ {"type": "tool_use", "name": "Edit", "input": {"file_path": "src/auth.ts"}},
102
+ ]},
103
+ ]
104
+
105
+ def test_extracts_plan_and_files(self):
106
+ out = ap._extract_state_carryover(self._convo())
107
+ self.assertIsNotNone(out)
108
+ self.assertIn("STATE CARRYOVER", out)
109
+ self.assertIn("scaffold project", out)
110
+ self.assertIn("add auth", out)
111
+ self.assertIn("[x] scaffold project", out)
112
+ self.assertIn("[~] add auth", out)
113
+ self.assertIn("src/index.ts", out)
114
+ self.assertIn("src/auth.ts", out)
115
+
116
+ def test_returns_none_on_fresh_session(self):
117
+ convo = [{"role": "user", "content": "hi"},
118
+ {"role": "assistant", "content": [
119
+ {"type": "tool_use", "name": "Read", "input": {"file_path": "x"}}]}]
120
+ self.assertIsNone(ap._extract_state_carryover(convo))
121
+
122
+ def test_keeps_most_recent_plan_only(self):
123
+ convo = self._convo()
124
+ convo.append({"role": "assistant", "content": [
125
+ {"type": "tool_use", "name": "TodoWrite", "input": {"todos": [
126
+ {"content": "final polish", "status": "pending"}]}}]})
127
+ out = ap._extract_state_carryover(convo)
128
+ self.assertIn("final polish", out)
129
+ self.assertNotIn("scaffold project", out) # superseded by the later plan
130
+
131
+
132
+ class ContaminationBreakerPreservesStateTest(unittest.TestCase):
133
+ """#2 end-to-end: a standard contamination reset re-injects the carryover."""
134
+
135
+ def test_standard_reset_includes_carryover(self):
136
+ m = ap.SessionMonitor(context_window=132096)
137
+ m.malformed_tool_streak = max(1, ap.PROXY_SESSION_CONTAMINATION_THRESHOLD)
138
+ keep = max(2, ap.PROXY_SESSION_CONTAMINATION_KEEP_LAST)
139
+ filler = [{"role": "user", "content": f"m{i}"} for i in range(keep + 4)]
140
+ messages = (
141
+ [{"role": "user", "content": "build the app"}]
142
+ + [{"role": "assistant", "content": [
143
+ {"type": "tool_use", "name": "TodoWrite", "input": {"todos": [
144
+ {"content": "step one", "status": "completed"},
145
+ {"content": "step two", "status": "pending"}]}}]}]
146
+ + [{"role": "assistant", "content": [
147
+ {"type": "tool_use", "name": "Write", "input": {"file_path": "app/main.py"}}]}]
148
+ + filler
149
+ )
150
+ body = {"messages": messages, "tools": [_tool("Write")]}
151
+ out = ap._maybe_apply_session_contamination_breaker(body, m, "fp:test")
152
+ blob = "\n".join(
153
+ b if isinstance(b, str) else str(b)
154
+ for msg in out["messages"] for b in [msg.get("content", "")]
155
+ )
156
+ self.assertIn("STATE CARRYOVER", blob)
157
+ self.assertIn("app/main.py", blob)
158
+ self.assertIn("step two", blob)
159
+
160
+
161
+ if __name__ == "__main__":
162
+ unittest.main()