@miller-tech/uap 1.135.1 → 1.136.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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/delivery/acceptance-judge.d.ts +1 -1
- package/dist/delivery/acceptance-judge.d.ts.map +1 -1
- package/dist/delivery/acceptance-judge.js +125 -17
- package/dist/delivery/acceptance-judge.js.map +1 -1
- package/package.json +1 -1
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/tools/agents/scripts/anthropic_proxy.py +121 -0
- package/tools/agents/tests/test_mandate_deliver.py +101 -0
- package/web/dash/charts.js +267 -0
- package/web/dash/core.js +17 -77
- package/web/dash/styles.css +19 -0
- package/web/dash/tab-agents.js +21 -0
- package/web/dash/tab-orchestration.js +21 -0
- package/web/dash/tab-overview.js +21 -0
- package/web/dash/tab-tasks.js +21 -0
- package/web/dashboard.html +1 -0
|
@@ -41,7 +41,7 @@ export interface AcceptanceOptions {
|
|
|
41
41
|
maxChars?: number;
|
|
42
42
|
}
|
|
43
43
|
/** Bounded walk gathering source-file evidence (path-labelled, truncated). */
|
|
44
|
-
export declare function gatherEvidence(projectRoot: string, maxFiles?: number, maxChars?: number): string;
|
|
44
|
+
export declare function gatherEvidence(projectRoot: string, maxFiles?: number, maxChars?: number, spec?: string): string;
|
|
45
45
|
/**
|
|
46
46
|
* Extract the first PARSEABLE balanced top-level JSON object from model text.
|
|
47
47
|
* If a balanced object fails to parse (e.g. a stray `{…}` fragment in the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acceptance-judge.d.ts","sourceRoot":"","sources":["../../src/delivery/acceptance-judge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,QAAQ,EAAE,YAAY,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"acceptance-judge.d.ts","sourceRoot":"","sources":["../../src/delivery/acceptance-judge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,QAAQ,EAAE,YAAY,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiDD,8EAA8E;AAC9E,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,QAAQ,SAAoB,EAC5B,QAAQ,SAAoB,EAC5B,IAAI,CAAC,EAAE,MAAM,GACZ,MAAM,CAoIR;AAyBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAiC9E;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAyC1F;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CASvE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,EACb,iBAAiB,CAAC,EAAE,MAAM,OAAO,GAChC;IACD,KAAK,CACH,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC7D;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAChF,CAqCA"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* the logic is fully unit-testable with a mock.
|
|
14
14
|
*/
|
|
15
15
|
import { lstatSync, readdirSync, readFileSync } from 'fs';
|
|
16
|
-
import { join, relative } from 'path';
|
|
16
|
+
import { join, relative, dirname } from 'path';
|
|
17
17
|
const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', 'out', 'coverage', '.uap', '.uap-deliver', 'agents', '.worktrees']);
|
|
18
18
|
const SRC_EXT = /\.(js|mjs|cjs|ts|tsx|jsx|html|css|json|py|go|rs|java|rb|md|txt)$/i;
|
|
19
19
|
/** Never ship likely-secret files into the LLM prompt (esp. for remote endpoints). */
|
|
@@ -45,8 +45,26 @@ function evidencePriority(name) {
|
|
|
45
45
|
return 1;
|
|
46
46
|
return 2; // md, txt, misc data
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Path-like tokens the spec explicitly names (files or directories). These are
|
|
50
|
+
* what the judge is being asked to verify, so they get guaranteed evidence
|
|
51
|
+
* slots: at repo scale the alphabetical candidate walk fills its pool long
|
|
52
|
+
* before late-alphabet directories — observed live 2026-07-11, a mission whose
|
|
53
|
+
* whole deliverable lived under web/dash/ was judged 0/4 with "no such file"
|
|
54
|
+
* while every file sat on disk, because web/ never entered the candidate pool.
|
|
55
|
+
*/
|
|
56
|
+
function specReferencedPaths(spec) {
|
|
57
|
+
const out = new Set();
|
|
58
|
+
for (const m of spec.matchAll(/[\w.@-]+(?:\/[\w.@*-]+)+/g)) {
|
|
59
|
+
// Strip trailing punctuation from prose (e.g. "web/dash/styles.css —").
|
|
60
|
+
const p = m[0].replace(/[.,;:)]+$/, '');
|
|
61
|
+
if (!p.includes('//') && !p.startsWith('http'))
|
|
62
|
+
out.add(p);
|
|
63
|
+
}
|
|
64
|
+
return [...out];
|
|
65
|
+
}
|
|
48
66
|
/** Bounded walk gathering source-file evidence (path-labelled, truncated). */
|
|
49
|
-
export function gatherEvidence(projectRoot, maxFiles = DEFAULT_MAX_FILES, maxChars = DEFAULT_MAX_CHARS) {
|
|
67
|
+
export function gatherEvidence(projectRoot, maxFiles = DEFAULT_MAX_FILES, maxChars = DEFAULT_MAX_CHARS, spec) {
|
|
50
68
|
const root = projectRoot;
|
|
51
69
|
// Collect a generous candidate pool FIRST, then priority-order and cut to
|
|
52
70
|
// maxFiles — so neither walk order nor a data-heavy directory can starve
|
|
@@ -58,7 +76,9 @@ export function gatherEvidence(projectRoot, maxFiles = DEFAULT_MAX_FILES, maxCha
|
|
|
58
76
|
return;
|
|
59
77
|
let entries;
|
|
60
78
|
try {
|
|
61
|
-
|
|
79
|
+
// Sorted: readdir returns filesystem hash order, which made evidence
|
|
80
|
+
// content (and therefore judge verdicts) vary between machines/runs.
|
|
81
|
+
entries = readdirSync(dir).sort();
|
|
62
82
|
}
|
|
63
83
|
catch {
|
|
64
84
|
return;
|
|
@@ -85,26 +105,114 @@ export function gatherEvidence(projectRoot, maxFiles = DEFAULT_MAX_FILES, maxCha
|
|
|
85
105
|
}
|
|
86
106
|
}
|
|
87
107
|
};
|
|
108
|
+
// Spec-referenced paths first: exact files at priority -1 (uncuttable),
|
|
109
|
+
// spec-named directories walked before the root walk so their contents make
|
|
110
|
+
// the candidate pool even in huge repos. In BOTH cases the parent directory
|
|
111
|
+
// is walked too: specs routinely reference files in template form
|
|
112
|
+
// ("web/dash/tab-<name>.js") whose literal token never resolves, and the
|
|
113
|
+
// siblings of a named file are usually the rest of the deliverable —
|
|
114
|
+
// observed live 2026-07-11: 8 tab files sat next to the spec-named
|
|
115
|
+
// styles.css yet were judged "not present" (4/7 MET instead of 7/7).
|
|
116
|
+
if (spec) {
|
|
117
|
+
const dirsToWalk = new Set();
|
|
118
|
+
for (const rel of specReferencedPaths(spec)) {
|
|
119
|
+
if (rel.includes('..'))
|
|
120
|
+
continue; // stay inside projectRoot
|
|
121
|
+
const abs = join(root, rel);
|
|
122
|
+
let st;
|
|
123
|
+
try {
|
|
124
|
+
st = lstatSync(abs);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Token doesn't resolve (template form / not created yet) — its
|
|
128
|
+
// parent directory is still the best evidence lead.
|
|
129
|
+
const parent = dirname(abs);
|
|
130
|
+
if (parent.startsWith(root) && parent !== root)
|
|
131
|
+
dirsToWalk.add(parent);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (st.isFile() && SRC_EXT.test(abs) && !SECRET_FILE_RE.test(abs) && st.size <= 200_000) {
|
|
135
|
+
files.push({ abs, prio: -1 });
|
|
136
|
+
const parent = dirname(abs);
|
|
137
|
+
if (parent.startsWith(root) && parent !== root)
|
|
138
|
+
dirsToWalk.add(parent);
|
|
139
|
+
}
|
|
140
|
+
else if (st.isDirectory()) {
|
|
141
|
+
dirsToWalk.add(abs);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
for (const d of dirsToWalk) {
|
|
145
|
+
try {
|
|
146
|
+
if (lstatSync(d).isDirectory())
|
|
147
|
+
walk(d, 1);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
/* parent doesn't exist either — nothing to walk */
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
88
154
|
walk(root, 0);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
155
|
+
// Dedupe (a spec-referenced file can also be found by a walk) keeping the
|
|
156
|
+
// best (lowest) priority per path.
|
|
157
|
+
const best = new Map();
|
|
158
|
+
for (const f of files) {
|
|
159
|
+
const cur = best.get(f.abs);
|
|
160
|
+
if (!cur || f.prio < cur.prio)
|
|
161
|
+
best.set(f.abs, f);
|
|
162
|
+
}
|
|
163
|
+
const deduped = [...best.values()];
|
|
164
|
+
deduped.sort((a, b) => a.prio - b.prio); // stable: insertion order preserved within a class
|
|
165
|
+
const chosen = deduped.slice(0, maxFiles);
|
|
166
|
+
// Two-pass assembly. The old single pass `break`-ed when the char budget
|
|
167
|
+
// ran out, so a few large early files silently erased every file after
|
|
168
|
+
// them — the judge then reported those files as "not present" (observed
|
|
169
|
+
// live 2026-07-11: four 9-20K spec-named modules exhausted the 60K budget
|
|
170
|
+
// and eight 600-byte sibling stubs vanished from evidence; which files
|
|
171
|
+
// starved even varied with readdir hash order). Pass 1 guarantees EVERY
|
|
172
|
+
// chosen file a head (existence + its opening lines — enough to verify
|
|
173
|
+
// "file X exists and registers Y"); pass 2 spends the remaining budget
|
|
174
|
+
// extending files in priority order.
|
|
175
|
+
const contents = new Map();
|
|
93
176
|
for (const f of chosen) {
|
|
94
|
-
if (used >= maxChars)
|
|
95
|
-
break;
|
|
96
|
-
let content;
|
|
97
177
|
try {
|
|
98
|
-
|
|
178
|
+
contents.set(f.abs, readFileSync(f.abs, 'utf-8'));
|
|
99
179
|
}
|
|
100
180
|
catch {
|
|
101
|
-
|
|
181
|
+
/* unreadable — skip */
|
|
102
182
|
}
|
|
103
|
-
|
|
183
|
+
}
|
|
184
|
+
const HEAD_CHARS = 600;
|
|
185
|
+
const granted = new Map();
|
|
186
|
+
let used = 0;
|
|
187
|
+
for (const f of chosen) {
|
|
188
|
+
const content = contents.get(f.abs);
|
|
189
|
+
if (content === undefined || used >= maxChars)
|
|
190
|
+
continue;
|
|
191
|
+
const head = Math.min(content.length, HEAD_CHARS, maxChars - used);
|
|
192
|
+
granted.set(f.abs, head);
|
|
193
|
+
used += head;
|
|
194
|
+
}
|
|
195
|
+
for (const f of chosen) {
|
|
196
|
+
const content = contents.get(f.abs);
|
|
197
|
+
if (content === undefined || used >= maxChars)
|
|
198
|
+
continue;
|
|
104
199
|
const perFileCap = f.prio === 2 ? DATA_FILE_CHARS : PER_FILE_CHARS;
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
200
|
+
const cur = granted.get(f.abs) ?? 0;
|
|
201
|
+
const extra = Math.min(content.length, perFileCap) - cur;
|
|
202
|
+
if (extra <= 0)
|
|
203
|
+
continue;
|
|
204
|
+
const grant = Math.min(extra, maxChars - used);
|
|
205
|
+
granted.set(f.abs, cur + grant);
|
|
206
|
+
used += grant;
|
|
207
|
+
}
|
|
208
|
+
let out = '';
|
|
209
|
+
for (const f of chosen) {
|
|
210
|
+
const content = contents.get(f.abs);
|
|
211
|
+
const take = granted.get(f.abs) ?? 0;
|
|
212
|
+
if (content === undefined || take <= 0)
|
|
213
|
+
continue;
|
|
214
|
+
const rel = relative(root, f.abs);
|
|
215
|
+
out += `\n=== ${rel} ===\n${content.slice(0, take)}\n`;
|
|
108
216
|
}
|
|
109
217
|
return out.trim();
|
|
110
218
|
}
|
|
@@ -182,7 +290,7 @@ export function extractJsonObject(text) {
|
|
|
182
290
|
* never wedge delivery on its own nondeterminism.
|
|
183
291
|
*/
|
|
184
292
|
export async function runAcceptanceGate(opts) {
|
|
185
|
-
const evidence = opts.evidence ?? gatherEvidence(opts.projectRoot, opts.maxFiles, opts.maxChars);
|
|
293
|
+
const evidence = opts.evidence ?? gatherEvidence(opts.projectRoot, opts.maxFiles, opts.maxChars, opts.spec);
|
|
186
294
|
if (!evidence.trim()) {
|
|
187
295
|
return { passed: true, score: 1, criteria: [], parseError: 'no source evidence found' };
|
|
188
296
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acceptance-judge.js","sourceRoot":"","sources":["../../src/delivery/acceptance-judge.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"acceptance-judge.js","sourceRoot":"","sources":["../../src/delivery/acceptance-judge.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -1349,6 +1349,7 @@ class SessionMonitor:
|
|
|
1349
1349
|
stuck_break_fires: int = 0 # monotonic count of forced stuck-breaks
|
|
1350
1350
|
deferral_streak: int = 0 # consecutive no-tool turns deferring the work (Fix A)
|
|
1351
1351
|
deferral_break_fires: int = 0 # monotonic count of forced deferral-breaks (Fix A)
|
|
1352
|
+
mandate_deliver_fires: int = 0 # monotonic count of forced deliver-routings (mandate)
|
|
1352
1353
|
tool_starvation_streak: int = 0 # Consecutive forced turns with no tool_calls produced
|
|
1353
1354
|
last_request_msg_count: int = 0 # Message count of the previous request (compaction-boundary detection)
|
|
1354
1355
|
malformed_tool_streak: int = 0 # consecutive malformed pseudo tool payloads
|
|
@@ -4601,6 +4602,121 @@ def _maybe_inject_deferral_break(openai_body: dict, monitor: "SessionMonitor") -
|
|
|
4601
4602
|
)
|
|
4602
4603
|
|
|
4603
4604
|
|
|
4605
|
+
# MANDATE-DELIVER guardrail: delivery-enforcement blocks a direct source edit and
|
|
4606
|
+
# tells the model to "call the `deliver` tool", but the enforcer's route:deliver
|
|
4607
|
+
# signal is only honored by harnesses that understand it -- weak local models see
|
|
4608
|
+
# the text and flail (RECON deadlock). This makes the routing BINDING for ANY
|
|
4609
|
+
# model: on detecting the enforcer's block marker in the just-returned turn AND a
|
|
4610
|
+
# deliver-class tool in the request, pin tool_choice to that tool so the next turn
|
|
4611
|
+
# MUST call deliver. PROXY_MANDATE_DELIVER=off disables.
|
|
4612
|
+
PROXY_MANDATE_DELIVER = os.environ.get("PROXY_MANDATE_DELIVER", "on").lower() not in {
|
|
4613
|
+
"0", "off", "false", "no",
|
|
4614
|
+
}
|
|
4615
|
+
# Enforcer-block-SPECIFIC phrases only (src/policies/enforcers/delivery_enforcement.py).
|
|
4616
|
+
# Deliberately NOT matching the reactor's STANDING "route through deliver" guidance
|
|
4617
|
+
# (which is injected every turn) -- only the actual block event must trigger.
|
|
4618
|
+
_DELIVER_BLOCK_RE = re.compile(
|
|
4619
|
+
r"BLOCKED: do not edit|do NOT retry this edit|\"route\"\s*:\s*\"deliver\"",
|
|
4620
|
+
re.IGNORECASE,
|
|
4621
|
+
)
|
|
4622
|
+
|
|
4623
|
+
|
|
4624
|
+
def _deliver_tool_name(tools) -> "str | None":
|
|
4625
|
+
"""Name of a deliver-class tool in the request (exact `deliver` or an
|
|
4626
|
+
MCP-namespaced `..._deliver`), or None when the agent has no deliver tool."""
|
|
4627
|
+
if not isinstance(tools, list):
|
|
4628
|
+
return None
|
|
4629
|
+
for t in tools:
|
|
4630
|
+
name = ((t.get("function", {}) or {}).get("name", "") or "")
|
|
4631
|
+
low = name.lower()
|
|
4632
|
+
if low == "deliver" or low.endswith("__deliver") or low.endswith("_deliver") or (
|
|
4633
|
+
"deliver" in low and "delivery" not in low
|
|
4634
|
+
):
|
|
4635
|
+
return name
|
|
4636
|
+
return None
|
|
4637
|
+
|
|
4638
|
+
|
|
4639
|
+
def _recent_text_has_block(messages) -> bool:
|
|
4640
|
+
"""True when a user/tool message in the current turn's tail carries the
|
|
4641
|
+
delivery-enforcement block marker (a direct edit was just gated)."""
|
|
4642
|
+
if not isinstance(messages, list):
|
|
4643
|
+
return False
|
|
4644
|
+
for m in reversed(messages[-4:]):
|
|
4645
|
+
role = m.get("role")
|
|
4646
|
+
if role == "assistant":
|
|
4647
|
+
break # older blocks belong to a prior, already-handled turn
|
|
4648
|
+
if role not in ("user", "tool"):
|
|
4649
|
+
continue
|
|
4650
|
+
content = m.get("content")
|
|
4651
|
+
text = ""
|
|
4652
|
+
if isinstance(content, str):
|
|
4653
|
+
text = content
|
|
4654
|
+
elif isinstance(content, list):
|
|
4655
|
+
parts = []
|
|
4656
|
+
for c in content:
|
|
4657
|
+
if isinstance(c, dict):
|
|
4658
|
+
parts.append(c.get("text") or c.get("content") or "")
|
|
4659
|
+
else:
|
|
4660
|
+
parts.append(str(c))
|
|
4661
|
+
text = " ".join(parts)
|
|
4662
|
+
if text and _DELIVER_BLOCK_RE.search(text):
|
|
4663
|
+
return True
|
|
4664
|
+
return False
|
|
4665
|
+
|
|
4666
|
+
|
|
4667
|
+
def _assistant_already_called_deliver(messages, deliver_name: str) -> bool:
|
|
4668
|
+
"""True if the MOST RECENT assistant turn already called the deliver tool --
|
|
4669
|
+
then we must NOT re-force (let the tool result return); prevents a force loop."""
|
|
4670
|
+
if not isinstance(messages, list):
|
|
4671
|
+
return False
|
|
4672
|
+
for m in reversed(messages):
|
|
4673
|
+
if m.get("role") != "assistant":
|
|
4674
|
+
continue
|
|
4675
|
+
for tc in (m.get("tool_calls") or []):
|
|
4676
|
+
if ((tc.get("function", {}) or {}).get("name", "") or "").lower() == deliver_name.lower():
|
|
4677
|
+
return True
|
|
4678
|
+
return False # only inspect the latest assistant turn
|
|
4679
|
+
return False
|
|
4680
|
+
|
|
4681
|
+
|
|
4682
|
+
def _maybe_inject_mandate_deliver(openai_body: dict, monitor: "SessionMonitor") -> None:
|
|
4683
|
+
"""MANDATORY deliver-routing: when a direct source edit was just blocked by
|
|
4684
|
+
delivery-enforcement, force the next turn to call the `deliver` tool for ANY
|
|
4685
|
+
model. Pins tool_choice to the deliver tool + injects a terse directive.
|
|
4686
|
+
Runs before the softer guards so the pin stands. PROXY_MANDATE_DELIVER=off."""
|
|
4687
|
+
if not PROXY_MANDATE_DELIVER:
|
|
4688
|
+
return
|
|
4689
|
+
deliver_name = _deliver_tool_name(openai_body.get("tools"))
|
|
4690
|
+
if not deliver_name:
|
|
4691
|
+
return # cannot mandate a tool the agent does not have
|
|
4692
|
+
messages = openai_body.get("messages")
|
|
4693
|
+
if not _recent_text_has_block(messages):
|
|
4694
|
+
return
|
|
4695
|
+
if _assistant_already_called_deliver(messages, deliver_name):
|
|
4696
|
+
return # deliver is already in flight -- don't loop on it
|
|
4697
|
+
openai_body["tool_choice"] = {"type": "function", "function": {"name": deliver_name}}
|
|
4698
|
+
monitor.mandate_deliver_fires += 1
|
|
4699
|
+
directive = (
|
|
4700
|
+
"\n\nMANDATORY: your direct source edit was BLOCKED by delivery-enforcement. "
|
|
4701
|
+
"You MUST call the `" + deliver_name + "` tool now with a one-line description "
|
|
4702
|
+
"of the change. Do NOT retry the edit, do NOT claim the file is written, do "
|
|
4703
|
+
"NOT explain -- call `" + deliver_name + "` this turn. Deliver writes the "
|
|
4704
|
+
"files and verifies them against the gates."
|
|
4705
|
+
)
|
|
4706
|
+
msgs = openai_body.get("messages")
|
|
4707
|
+
if not isinstance(msgs, list):
|
|
4708
|
+
msgs = []
|
|
4709
|
+
if msgs and msgs[0].get("role") == "system":
|
|
4710
|
+
msgs[0]["content"] = (msgs[0].get("content") or "") + directive
|
|
4711
|
+
else:
|
|
4712
|
+
msgs.insert(0, {"role": "system", "content": directive.strip()})
|
|
4713
|
+
openai_body["messages"] = msgs
|
|
4714
|
+
logger.warning(
|
|
4715
|
+
"MANDATE-DELIVER: pinned tool_choice to deliver (tool=%s, fires=%d)",
|
|
4716
|
+
deliver_name, monitor.mandate_deliver_fires,
|
|
4717
|
+
)
|
|
4718
|
+
|
|
4719
|
+
|
|
4604
4720
|
def _maybe_inject_recon_convergence(
|
|
4605
4721
|
openai_body: dict,
|
|
4606
4722
|
monitor: "SessionMonitor",
|
|
@@ -5415,6 +5531,11 @@ def build_openai_request(
|
|
|
5415
5531
|
# session wandering in exploration without producing a write is nudged
|
|
5416
5532
|
# toward its deliverable regardless of tool-turn phase. Passed the full
|
|
5417
5533
|
# pre-narrowing toolset so it can restore a dropped write tool.
|
|
5534
|
+
# MANDATE-DELIVER: a just-blocked direct edit MUST route to the deliver tool
|
|
5535
|
+
# (makes the enforcer's route:deliver signal binding for any model). Runs first
|
|
5536
|
+
# so the forced tool_choice pins before the softer guards.
|
|
5537
|
+
_maybe_inject_mandate_deliver(openai_body, monitor)
|
|
5538
|
+
|
|
5418
5539
|
_maybe_inject_recon_convergence(openai_body, monitor, full_openai_tools)
|
|
5419
5540
|
|
|
5420
5541
|
_maybe_inject_stuck_break(openai_body, monitor)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""MANDATE-DELIVER guardrail: when delivery-enforcement blocks a direct source
|
|
3
|
+
edit, the proxy must force the next turn to call the `deliver` tool for ANY model
|
|
4
|
+
(pin tool_choice), so weak models can't ignore the routing and deadlock."""
|
|
5
|
+
|
|
6
|
+
import importlib.util
|
|
7
|
+
import os
|
|
8
|
+
import unittest
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _load_proxy():
|
|
13
|
+
p = Path(__file__).resolve().parents[1] / "scripts" / "anthropic_proxy.py"
|
|
14
|
+
spec = importlib.util.spec_from_file_location("anthropic_proxy", p)
|
|
15
|
+
assert spec is not None and spec.loader is not None
|
|
16
|
+
m = importlib.util.module_from_spec(spec)
|
|
17
|
+
spec.loader.exec_module(m)
|
|
18
|
+
return m
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
proxy = _load_proxy()
|
|
22
|
+
|
|
23
|
+
DELIVER_TOOL = {"type": "function", "function": {"name": "deliver", "parameters": {}}}
|
|
24
|
+
READ_TOOL = {"type": "function", "function": {"name": "read", "parameters": {}}}
|
|
25
|
+
BLOCK_MSG = (
|
|
26
|
+
"BLOCKED: do not edit 'src/foo.ts' directly. To create or change code, call "
|
|
27
|
+
"the `deliver` tool (or run: uap deliver \"...\"). Do NOT retry this edit."
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _body(messages, tools=None, tool_choice="auto"):
|
|
32
|
+
return {
|
|
33
|
+
"tools": DELIVER_TOOL if tools is None else tools,
|
|
34
|
+
"messages": messages,
|
|
35
|
+
"tool_choice": tool_choice,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class MandateDeliverTest(unittest.TestCase):
|
|
40
|
+
def setUp(self):
|
|
41
|
+
self.mon = proxy.SessionMonitor()
|
|
42
|
+
|
|
43
|
+
def test_forces_deliver_on_block(self):
|
|
44
|
+
b = _body([
|
|
45
|
+
{"role": "assistant", "content": "editing", "tool_calls": [{"function": {"name": "edit"}}]},
|
|
46
|
+
{"role": "tool", "content": BLOCK_MSG},
|
|
47
|
+
], tools=[DELIVER_TOOL])
|
|
48
|
+
proxy._maybe_inject_mandate_deliver(b, self.mon)
|
|
49
|
+
self.assertEqual(b["tool_choice"], {"type": "function", "function": {"name": "deliver"}})
|
|
50
|
+
self.assertEqual(self.mon.mandate_deliver_fires, 1)
|
|
51
|
+
self.assertTrue(any("MANDATORY" in (m.get("content") or "") for m in b["messages"]))
|
|
52
|
+
|
|
53
|
+
def test_no_block_no_change(self):
|
|
54
|
+
b = _body([{"role": "user", "content": "hi"}], tools=[DELIVER_TOOL], tool_choice="auto")
|
|
55
|
+
proxy._maybe_inject_mandate_deliver(b, self.mon)
|
|
56
|
+
self.assertEqual(b["tool_choice"], "auto")
|
|
57
|
+
self.assertEqual(self.mon.mandate_deliver_fires, 0)
|
|
58
|
+
|
|
59
|
+
def test_reactor_standing_guidance_does_not_trigger(self):
|
|
60
|
+
# The reactor injects this EVERY turn — it must NOT be treated as a block.
|
|
61
|
+
b = _body([{"role": "user", "content": "Use the `deliver` tool to write code — direct Edit/Write is gated and will be blocked."}], tools=[DELIVER_TOOL])
|
|
62
|
+
proxy._maybe_inject_mandate_deliver(b, self.mon)
|
|
63
|
+
self.assertEqual(self.mon.mandate_deliver_fires, 0)
|
|
64
|
+
|
|
65
|
+
def test_no_deliver_tool_no_change(self):
|
|
66
|
+
b = _body([{"role": "tool", "content": BLOCK_MSG}], tools=[READ_TOOL])
|
|
67
|
+
proxy._maybe_inject_mandate_deliver(b, self.mon)
|
|
68
|
+
self.assertEqual(self.mon.mandate_deliver_fires, 0)
|
|
69
|
+
|
|
70
|
+
def test_already_called_deliver_no_reforce(self):
|
|
71
|
+
b = _body([
|
|
72
|
+
{"role": "assistant", "content": "", "tool_calls": [{"function": {"name": "deliver"}}]},
|
|
73
|
+
{"role": "tool", "content": BLOCK_MSG},
|
|
74
|
+
], tools=[DELIVER_TOOL])
|
|
75
|
+
proxy._maybe_inject_mandate_deliver(b, self.mon)
|
|
76
|
+
self.assertEqual(self.mon.mandate_deliver_fires, 0)
|
|
77
|
+
|
|
78
|
+
def test_mcp_namespaced_deliver_tool(self):
|
|
79
|
+
mcp_deliver = {"type": "function", "function": {"name": "mcp__uap-router__deliver", "parameters": {}}}
|
|
80
|
+
b = _body([{"role": "tool", "content": BLOCK_MSG}], tools=[mcp_deliver])
|
|
81
|
+
proxy._maybe_inject_mandate_deliver(b, self.mon)
|
|
82
|
+
self.assertEqual(b["tool_choice"], {"type": "function", "function": {"name": "mcp__uap-router__deliver"}})
|
|
83
|
+
|
|
84
|
+
def test_disabled_by_env(self):
|
|
85
|
+
old = os.environ.get("PROXY_MANDATE_DELIVER")
|
|
86
|
+
os.environ["PROXY_MANDATE_DELIVER"] = "off"
|
|
87
|
+
try:
|
|
88
|
+
p2 = _load_proxy()
|
|
89
|
+
mon = p2.SessionMonitor()
|
|
90
|
+
b = _body([{"role": "tool", "content": BLOCK_MSG}], tools=[DELIVER_TOOL])
|
|
91
|
+
p2._maybe_inject_mandate_deliver(b, mon)
|
|
92
|
+
self.assertEqual(mon.mandate_deliver_fires, 0)
|
|
93
|
+
finally:
|
|
94
|
+
if old is None:
|
|
95
|
+
os.environ.pop("PROXY_MANDATE_DELIVER", None)
|
|
96
|
+
else:
|
|
97
|
+
os.environ["PROXY_MANDATE_DELIVER"] = old
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if __name__ == "__main__":
|
|
101
|
+
unittest.main()
|