@odla-ai/harness 0.9.1 → 0.9.2
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/{chunk-HDIR4MM5.js → chunk-5LRYJKUI.js} +3 -3
- package/dist/chunk-FAN2R3GW.js +166 -0
- package/dist/chunk-FAN2R3GW.js.map +1 -0
- package/dist/{chunk-CIKYMC67.js → chunk-OZBJNTML.js} +4 -4
- package/dist/{chunk-4EPJJMFG.js → chunk-Q4NL5XO3.js} +142 -214
- package/dist/chunk-Q4NL5XO3.js.map +1 -0
- package/dist/{chunk-I43KTCJ2.js → chunk-U324RQ4N.js} +1 -1
- package/dist/{chunk-I43KTCJ2.js.map → chunk-U324RQ4N.js.map} +1 -1
- package/dist/{chunk-VGNIDRKM.js → chunk-VDY5V7ZG.js} +2 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +4 -4
- package/dist/code-runtime-cli.cjs +243 -160
- package/dist/code-runtime-cli.cjs.map +1 -1
- package/dist/code-runtime-cli.js +6 -5
- package/dist/code-runtime-cli.js.map +1 -1
- package/dist/index.cjs +172 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +246 -159
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +39 -6
- package/dist/node.d.ts +39 -6
- package/dist/node.js +10 -5
- package/dist/node.js.map +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/{types-BazqxWK8.d.cts → types-_8y8vBDI.d.cts} +5 -1
- package/dist/{types-BazqxWK8.d.ts → types-_8y8vBDI.d.ts} +5 -1
- package/package.json +1 -1
- package/dist/chunk-4EPJJMFG.js.map +0 -1
- /package/dist/{chunk-HDIR4MM5.js.map → chunk-5LRYJKUI.js.map} +0 -0
- /package/dist/{chunk-CIKYMC67.js.map → chunk-OZBJNTML.js.map} +0 -0
- /package/dist/{chunk-VGNIDRKM.js.map → chunk-VDY5V7ZG.js.map} +0 -0
package/dist/node.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(node_exports, {
|
|
|
33
33
|
V2_SYSTEM_PROMPT: () => V2_SYSTEM_PROMPT,
|
|
34
34
|
V3_SYSTEM_PROMPT: () => V3_SYSTEM_PROMPT,
|
|
35
35
|
applyCodePatch: () => applyCodePatch,
|
|
36
|
+
applyPatchDialectToDiff: () => applyPatchDialectToDiff,
|
|
36
37
|
assertCodeBuildRecipe: () => assertCodeBuildRecipe,
|
|
37
38
|
assertDisjointPlan: () => assertDisjointPlan,
|
|
38
39
|
assertPinnedImage: () => assertPinnedImage,
|
|
@@ -50,6 +51,7 @@ __export(node_exports, {
|
|
|
50
51
|
describePatchFailure: () => describePatchFailure,
|
|
51
52
|
digestStagedWorkspace: () => digestStagedWorkspace,
|
|
52
53
|
feedbackIsActionable: () => feedbackIsActionable,
|
|
54
|
+
hasContextFreeHunk: () => hasContextFreeHunk,
|
|
53
55
|
hazardFromAttempt: () => hazardFromAttempt,
|
|
54
56
|
installedDependencies: () => installedDependencies,
|
|
55
57
|
integrateSubGoals: () => integrateSubGoals,
|
|
@@ -999,7 +1001,7 @@ async function parseSource(value) {
|
|
|
999
1001
|
}
|
|
1000
1002
|
function parseReview(value) {
|
|
1001
1003
|
const review = record2(record2(value)?.review);
|
|
1002
|
-
if (!review || !["approved", "rejected"].includes(String(review.verdict)) || typeof review.reviewDigest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(review.reviewDigest) || typeof review.provider !== "string" || !review.provider || typeof review.model !== "string" || !review.model || !Number.isSafeInteger(review.policyVersion) || Number(review.policyVersion) < 1) throw invalid("review");
|
|
1004
|
+
if (!review || !["approved", "rejected"].includes(String(review.verdict)) || typeof review.reviewDigest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(review.reviewDigest) || typeof review.provider !== "string" || !review.provider || typeof review.model !== "string" || !review.model || !Number.isSafeInteger(review.policyVersion) || Number(review.policyVersion) < 1 || !Number.isSafeInteger(review.score) || Number(review.score) < 0 || Number(review.score) > 100 || typeof review.summary !== "string" || !Array.isArray(review.findings) || review.findings.length > 12) throw invalid("review");
|
|
1003
1005
|
return review;
|
|
1004
1006
|
}
|
|
1005
1007
|
function parseCandidate(value) {
|
|
@@ -1306,10 +1308,41 @@ var SECRET = /^(?:\.env(?:\..+)?|\.dev\.vars|credentials(?:\..+)?\.json|dev-toke
|
|
|
1306
1308
|
var PATH = /^[A-Za-z0-9_@+.,-]+(?:\/[A-Za-z0-9_@+.,-]+)*$/;
|
|
1307
1309
|
var FORBIDDEN = /^(?:GIT binary patch|Binary files |rename (?:from|to) |copy (?:from|to) |similarity index |old mode |new mode |deleted file mode 160000|new file mode 160000)/m;
|
|
1308
1310
|
function stripPatchEnvelope(patch2) {
|
|
1309
|
-
if (!/^\*\*\* (?:Begin|End) Patch\s*$/m.test(patch2)) return patch2;
|
|
1311
|
+
if (!/^\*\*\* (?:Begin|End) Patch\s*$/m.test(patch2)) return applyPatchDialectToDiff(patch2);
|
|
1310
1312
|
const kept = patch2.split("\n").filter((line) => !/^\*\*\* (?:Begin|End) Patch\s*$/.test(line));
|
|
1311
1313
|
const stripped = kept.join("\n");
|
|
1312
|
-
|
|
1314
|
+
if (/^diff --git /m.test(stripped)) return stripped;
|
|
1315
|
+
const translated = applyPatchDialectToDiff(stripped);
|
|
1316
|
+
return translated === stripped ? patch2 : translated;
|
|
1317
|
+
}
|
|
1318
|
+
function applyPatchDialectToDiff(patch2) {
|
|
1319
|
+
if (!/^\*\*\* (?:Update|Add|Delete) File: /m.test(patch2)) return patch2;
|
|
1320
|
+
const out = [];
|
|
1321
|
+
let open = false;
|
|
1322
|
+
for (const line of patch2.split("\n")) {
|
|
1323
|
+
const file = /^\*\*\* (Update|Add|Delete) File: (.+?)\s*$/.exec(line);
|
|
1324
|
+
if (file) {
|
|
1325
|
+
const [, verb, raw] = file;
|
|
1326
|
+
const path = raw.trim();
|
|
1327
|
+
if (!PATH.test(path)) return patch2;
|
|
1328
|
+
out.push(`diff --git a/${path} b/${path}`);
|
|
1329
|
+
if (verb === "Add") out.push("new file mode 100644", "--- /dev/null", `+++ b/${path}`);
|
|
1330
|
+
else if (verb === "Delete") out.push(`--- a/${path}`, "+++ /dev/null");
|
|
1331
|
+
else out.push(`--- a/${path}`, `+++ b/${path}`);
|
|
1332
|
+
open = true;
|
|
1333
|
+
continue;
|
|
1334
|
+
}
|
|
1335
|
+
if (/^\*\*\* /.test(line)) continue;
|
|
1336
|
+
if (!open) continue;
|
|
1337
|
+
if (/^@@/.test(line)) {
|
|
1338
|
+
out.push("@@ -1 +1 @@");
|
|
1339
|
+
continue;
|
|
1340
|
+
}
|
|
1341
|
+
out.push(line);
|
|
1342
|
+
}
|
|
1343
|
+
if (!open) return patch2;
|
|
1344
|
+
return `${out.join("\n").replace(/\n+$/, "")}
|
|
1345
|
+
`;
|
|
1313
1346
|
}
|
|
1314
1347
|
function validateCodePatch(rawPatch, maxBytes) {
|
|
1315
1348
|
const patch2 = stripPatchEnvelope(rawPatch);
|
|
@@ -1362,17 +1395,20 @@ function resolveCodePath(workspaceDir, path) {
|
|
|
1362
1395
|
if (target !== root && !target.startsWith(`${root}${import_node_path6.sep}`)) throw new TypeError("path escapes the staged workspace");
|
|
1363
1396
|
return target;
|
|
1364
1397
|
}
|
|
1398
|
+
function hasContextFreeHunk(patch2) {
|
|
1399
|
+
const bodies = patch2.split(/^@@.*$/m).slice(1);
|
|
1400
|
+
return bodies.some((body) => !body.split("\n").some((line) => line.startsWith(" ") && line.trim().length > 0));
|
|
1401
|
+
}
|
|
1365
1402
|
function describePatchFailure(patch2, detail) {
|
|
1366
1403
|
const hunks = patch2.split("\n").filter((line) => line.startsWith("@@"));
|
|
1367
|
-
const
|
|
1368
|
-
const contextless = bodies.some((body) => !body.split("\n").some((line) => line.startsWith(" ") && line.trim().length > 0));
|
|
1369
|
-
const hint = hunks.length > 0 && contextless ? " A hunk has no context lines; include at least one unchanged line above or below each change." : "";
|
|
1404
|
+
const hint = hunks.length > 0 && hasContextFreeHunk(patch2) ? " A hunk has no context lines; include at least one unchanged line above or below each change." : "";
|
|
1370
1405
|
return `patch did not apply: ${detail}${hint}`;
|
|
1371
1406
|
}
|
|
1372
1407
|
async function applyCodePatch(workspaceDir, rawPatch, paths2) {
|
|
1373
1408
|
const patch2 = stripPatchEnvelope(rawPatch);
|
|
1374
|
-
|
|
1375
|
-
await gitApply(workspaceDir, patch2,
|
|
1409
|
+
const zero = hasContextFreeHunk(patch2);
|
|
1410
|
+
await gitApply(workspaceDir, patch2, true, zero);
|
|
1411
|
+
await gitApply(workspaceDir, patch2, false, zero);
|
|
1376
1412
|
for (const path of paths2) {
|
|
1377
1413
|
try {
|
|
1378
1414
|
const info = await (0, import_promises6.lstat)(resolveCodePath(workspaceDir, path));
|
|
@@ -1384,9 +1420,16 @@ async function applyCodePatch(workspaceDir, rawPatch, paths2) {
|
|
|
1384
1420
|
}
|
|
1385
1421
|
}
|
|
1386
1422
|
}
|
|
1387
|
-
function gitApply(cwd, patch2, check) {
|
|
1423
|
+
function gitApply(cwd, patch2, check, unidiffZero = false) {
|
|
1388
1424
|
return new Promise((accept, reject) => {
|
|
1389
|
-
const args = [
|
|
1425
|
+
const args = [
|
|
1426
|
+
"apply",
|
|
1427
|
+
"--recount",
|
|
1428
|
+
...unidiffZero ? ["--unidiff-zero"] : [],
|
|
1429
|
+
"--whitespace=nowarn",
|
|
1430
|
+
...check ? ["--check"] : [],
|
|
1431
|
+
"-"
|
|
1432
|
+
];
|
|
1390
1433
|
const child = (0, import_node_child_process4.spawn)("git", args, {
|
|
1391
1434
|
cwd,
|
|
1392
1435
|
shell: false,
|
|
@@ -1794,9 +1837,9 @@ async function prepareRuntimeCheckpoint(input) {
|
|
|
1794
1837
|
if (evidence.receipt.outcome === "passed") {
|
|
1795
1838
|
verification = evidence.receipt;
|
|
1796
1839
|
review = await input.review(patch2, verification);
|
|
1797
|
-
note = review
|
|
1840
|
+
note = describeReview(review);
|
|
1798
1841
|
} else {
|
|
1799
|
-
note =
|
|
1842
|
+
note = describeGateFailure(evidence);
|
|
1800
1843
|
}
|
|
1801
1844
|
} catch (cause) {
|
|
1802
1845
|
note = `Candidate verification or review failed closed: ${message(cause)}`;
|
|
@@ -1821,6 +1864,23 @@ async function prepareRuntimeCheckpoint(input) {
|
|
|
1821
1864
|
});
|
|
1822
1865
|
return { checkpoint, verification, review, note };
|
|
1823
1866
|
}
|
|
1867
|
+
function describeReview(review) {
|
|
1868
|
+
const findings = review.findings.map((finding) => ` - [${finding.severity}] ${finding.detail}`).join("\n");
|
|
1869
|
+
const head = review.verdict === "approved" ? `Clean verification and independent review passed (score ${review.score}/100).` : `Clean verification passed; independent review REJECTED this candidate (score ${review.score}/100). Address the findings and checkpoint again.`;
|
|
1870
|
+
return [head, review.summary, findings].filter(Boolean).join("\n").slice(0, 4e3);
|
|
1871
|
+
}
|
|
1872
|
+
function describeGateFailure(evidence) {
|
|
1873
|
+
const failed = evidence.receipt.recipes.filter((recipe2) => recipe2.status !== "passed");
|
|
1874
|
+
const detail = failed.map((recipe2) => {
|
|
1875
|
+
const log = evidence.logs.find((entry) => entry.recipeId === recipe2.recipeId);
|
|
1876
|
+
const output = `${log?.stdout ?? ""}
|
|
1877
|
+
${log?.stderr ?? ""}`.trim();
|
|
1878
|
+
return `${recipe2.recipeId}=${recipe2.status}${output ? `
|
|
1879
|
+
${output.slice(0, 1500)}` : ""}`;
|
|
1880
|
+
}).join("\n\n");
|
|
1881
|
+
return `Clean verification failed. Fix this and checkpoint again:
|
|
1882
|
+
${detail}`.slice(0, 4e3);
|
|
1883
|
+
}
|
|
1824
1884
|
var message = (value) => (value instanceof Error ? value.message : String(value)).slice(0, 500);
|
|
1825
1885
|
|
|
1826
1886
|
// src/code-runtime-checkpoint-manager.ts
|
|
@@ -2465,6 +2525,166 @@ function createCodeRuntimeInference(options) {
|
|
|
2465
2525
|
};
|
|
2466
2526
|
}
|
|
2467
2527
|
|
|
2528
|
+
// src/code-tool-presentation.ts
|
|
2529
|
+
var text = (value, maximum) => {
|
|
2530
|
+
if (typeof value !== "string") return void 0;
|
|
2531
|
+
const bounded = value.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, " ").trim();
|
|
2532
|
+
return bounded ? bounded.slice(0, maximum) : void 0;
|
|
2533
|
+
};
|
|
2534
|
+
var integer2 = (value) => Number.isSafeInteger(value) && Number(value) >= 0 ? Number(value) : void 0;
|
|
2535
|
+
var record4 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2536
|
+
var excerpt = (value, tail = false) => {
|
|
2537
|
+
if (typeof value !== "string") return void 0;
|
|
2538
|
+
const safe = value.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, " ");
|
|
2539
|
+
const source = (tail ? safe.slice(-1e4) : safe.slice(0, 1e4)).trim();
|
|
2540
|
+
if (!source) return void 0;
|
|
2541
|
+
const lines = source.split("\n").filter((line) => line.trim()).map((line) => line.slice(0, 240));
|
|
2542
|
+
const selected = tail ? lines.slice(-10) : lines.slice(0, 10);
|
|
2543
|
+
return text(selected.join("\n"), 2400);
|
|
2544
|
+
};
|
|
2545
|
+
var paths = (value) => {
|
|
2546
|
+
if (!Array.isArray(value)) return void 0;
|
|
2547
|
+
const items = value.flatMap((item) => {
|
|
2548
|
+
const path = text(item, 1024);
|
|
2549
|
+
return path ? [path] : [];
|
|
2550
|
+
}).slice(0, 12);
|
|
2551
|
+
return items.length ? items : void 0;
|
|
2552
|
+
};
|
|
2553
|
+
function patchStats(value) {
|
|
2554
|
+
if (typeof value !== "string") return {};
|
|
2555
|
+
let additions = 0;
|
|
2556
|
+
let deletions = 0;
|
|
2557
|
+
for (const line of value.slice(0, 262144).split("\n")) {
|
|
2558
|
+
if (line.startsWith("+++") || line.startsWith("---")) continue;
|
|
2559
|
+
if (line.startsWith("+")) additions += 1;
|
|
2560
|
+
else if (line.startsWith("-")) deletions += 1;
|
|
2561
|
+
}
|
|
2562
|
+
return { ...additions ? { additions } : {}, ...deletions ? { deletions } : {} };
|
|
2563
|
+
}
|
|
2564
|
+
function searchResults(value) {
|
|
2565
|
+
if (typeof value !== "string") return void 0;
|
|
2566
|
+
const results = value.split("\n").flatMap((line) => {
|
|
2567
|
+
const match = /^([^:\n]{1,1024}):(\d+):\s?(.*)$/.exec(line);
|
|
2568
|
+
if (!match) return [];
|
|
2569
|
+
const lineNumber = Number(match[2]);
|
|
2570
|
+
const itemText = text(match[3], 240);
|
|
2571
|
+
if (!Number.isSafeInteger(lineNumber) || lineNumber < 1) return [];
|
|
2572
|
+
return [{ path: match[1], line: lineNumber, ...itemText ? { text: itemText } : {} }];
|
|
2573
|
+
}).slice(0, 5);
|
|
2574
|
+
return results.length ? results : void 0;
|
|
2575
|
+
}
|
|
2576
|
+
function codeToolRequestPresentation(request) {
|
|
2577
|
+
const input = request.input;
|
|
2578
|
+
if (request.tool === "sandbox.read") {
|
|
2579
|
+
const path = text(input.path, 1024);
|
|
2580
|
+
if (!path) return void 0;
|
|
2581
|
+
const startLine = integer2(input.startLine);
|
|
2582
|
+
const endLine = integer2(input.endLine);
|
|
2583
|
+
return { kind: "read", path, ...startLine ? { startLine } : {}, ...endLine ? { endLine } : {} };
|
|
2584
|
+
}
|
|
2585
|
+
if (request.tool === "sandbox.list") {
|
|
2586
|
+
const scope = text(input.prefix, 1024);
|
|
2587
|
+
return { kind: "list", ...scope ? { scope } : {} };
|
|
2588
|
+
}
|
|
2589
|
+
if (request.tool === "sandbox.search" || request.tool === "sandbox.overview" || request.tool === "sandbox.where_is" || request.tool === "sandbox.who_imports" || request.tool === "sandbox.who_touches") {
|
|
2590
|
+
const query = text(input.query, 512);
|
|
2591
|
+
const scope = request.tool === "sandbox.search" ? text(input.prefix, 1024) : void 0;
|
|
2592
|
+
if (request.tool === "sandbox.search" && !query) return void 0;
|
|
2593
|
+
return { kind: "query", ...query ? { query } : {}, ...scope ? { scope } : {} };
|
|
2594
|
+
}
|
|
2595
|
+
if (request.tool === "sandbox.apply_patch") {
|
|
2596
|
+
return { kind: "patch", ...patchStats(input.patch) };
|
|
2597
|
+
}
|
|
2598
|
+
const recipeId = text(input.recipeId, 120);
|
|
2599
|
+
return recipeId ? { kind: "recipe", recipeId } : void 0;
|
|
2600
|
+
}
|
|
2601
|
+
function codeToolResultPresentation(request, response2) {
|
|
2602
|
+
const started = codeToolRequestPresentation(request);
|
|
2603
|
+
if (!started || !response2.ok) return started;
|
|
2604
|
+
const details = record4(response2.details);
|
|
2605
|
+
if (started.kind === "read") {
|
|
2606
|
+
return {
|
|
2607
|
+
...started,
|
|
2608
|
+
...integer2(details?.startLine) ? { startLine: integer2(details?.startLine) } : {},
|
|
2609
|
+
...integer2(details?.endLine) ? { endLine: integer2(details?.endLine) } : {},
|
|
2610
|
+
...excerpt(response2.content) ? { excerpt: excerpt(response2.content) } : {}
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2613
|
+
if (started.kind === "list") {
|
|
2614
|
+
const listed = response2.content.split("\n").filter((line) => line && !line.startsWith("\u2026") && !line.startsWith("Workspace ")).map((line) => text(line, 1024)).filter((line) => Boolean(line)).slice(0, 8);
|
|
2615
|
+
return {
|
|
2616
|
+
...started,
|
|
2617
|
+
...integer2(details?.count) !== void 0 ? { count: integer2(details?.count) } : {},
|
|
2618
|
+
...listed.length ? { paths: listed } : {}
|
|
2619
|
+
};
|
|
2620
|
+
}
|
|
2621
|
+
if (started.kind === "query") {
|
|
2622
|
+
const results = request.tool === "sandbox.search" ? searchResults(response2.content) : void 0;
|
|
2623
|
+
const resultExcerpt = request.tool === "sandbox.search" ? void 0 : excerpt(response2.content);
|
|
2624
|
+
return {
|
|
2625
|
+
...started,
|
|
2626
|
+
...integer2(details?.count) !== void 0 ? { count: integer2(details?.count) } : {},
|
|
2627
|
+
...results ? { results } : {},
|
|
2628
|
+
...resultExcerpt ? { excerpt: resultExcerpt } : {}
|
|
2629
|
+
};
|
|
2630
|
+
}
|
|
2631
|
+
if (started.kind === "patch") {
|
|
2632
|
+
return { ...started, ...paths(details?.paths) ? { paths: paths(details?.paths) } : {} };
|
|
2633
|
+
}
|
|
2634
|
+
const output = response2.content.replace(/^Recipe [^\n]*\.?\s*/u, "");
|
|
2635
|
+
return {
|
|
2636
|
+
...started,
|
|
2637
|
+
...integer2(details?.exitCode) !== void 0 ? { exitCode: integer2(details?.exitCode) } : {},
|
|
2638
|
+
...typeof details?.timedOut === "boolean" ? { timedOut: details.timedOut } : {},
|
|
2639
|
+
...typeof details?.outputLimitExceeded === "boolean" ? { outputLimitExceeded: details.outputLimitExceeded } : {},
|
|
2640
|
+
...excerpt(output, true) ? { excerpt: excerpt(output, true) } : {}
|
|
2641
|
+
};
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
// src/code-runtime-observer.ts
|
|
2645
|
+
var MAX_FAILURE_REASON = 240;
|
|
2646
|
+
function toolFailureReason(response2) {
|
|
2647
|
+
if (response2.ok) return void 0;
|
|
2648
|
+
const supplied = response2.details?.failureReason;
|
|
2649
|
+
const reason = typeof supplied === "string" && supplied || DEFAULT_FAILURE_REASON[response2.content] || response2.content || "tool request failed; inspect the tool input and workspace state";
|
|
2650
|
+
return reason.slice(0, MAX_FAILURE_REASON);
|
|
2651
|
+
}
|
|
2652
|
+
var DEFAULT_FAILURE_REASON = {
|
|
2653
|
+
"tool denied by CaMeL policy": "tool denied by CaMeL policy",
|
|
2654
|
+
"review sessions are read-only": "review session is read-only; workspace changes are not permitted"
|
|
2655
|
+
};
|
|
2656
|
+
function observedBroker(input) {
|
|
2657
|
+
const now = input.now ?? Date.now;
|
|
2658
|
+
return {
|
|
2659
|
+
execute: async (context, request) => {
|
|
2660
|
+
const startedAt = now();
|
|
2661
|
+
const operationId = input.operationIdFor(request.requestId);
|
|
2662
|
+
const startedPresentation = codeToolRequestPresentation(request);
|
|
2663
|
+
await input.emit({
|
|
2664
|
+
type: "tool",
|
|
2665
|
+
phase: "started",
|
|
2666
|
+
tool: request.tool,
|
|
2667
|
+
operationId,
|
|
2668
|
+
...startedPresentation ? { presentation: startedPresentation } : {}
|
|
2669
|
+
});
|
|
2670
|
+
const response2 = await input.broker.execute(context, request);
|
|
2671
|
+
const completedPresentation = codeToolResultPresentation(request, response2);
|
|
2672
|
+
const failureReason = toolFailureReason(response2);
|
|
2673
|
+
await input.emit({
|
|
2674
|
+
type: "tool",
|
|
2675
|
+
phase: "completed",
|
|
2676
|
+
tool: request.tool,
|
|
2677
|
+
ok: response2.ok,
|
|
2678
|
+
durationMs: now() - startedAt,
|
|
2679
|
+
operationId,
|
|
2680
|
+
...failureReason ? { failureReason } : {},
|
|
2681
|
+
...completedPresentation ? { presentation: completedPresentation } : {}
|
|
2682
|
+
});
|
|
2683
|
+
return response2;
|
|
2684
|
+
}
|
|
2685
|
+
};
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2468
2688
|
// src/code-tool-policy.ts
|
|
2469
2689
|
var import_camel = require("@odla-ai/camel");
|
|
2470
2690
|
var import_policy = require("@odla-ai/camel/policy");
|
|
@@ -2703,8 +2923,14 @@ function optionalInteger(value) {
|
|
|
2703
2923
|
if (!Number.isSafeInteger(value) || value < 1) throw new TypeError("line bounds must be positive integers");
|
|
2704
2924
|
return value;
|
|
2705
2925
|
}
|
|
2926
|
+
var DEFAULT_FAILURE_REASON2 = {
|
|
2927
|
+
"tool denied by CaMeL policy": "tool denied by CaMeL policy",
|
|
2928
|
+
"review sessions are read-only": "review session is read-only; workspace changes are not permitted"
|
|
2929
|
+
};
|
|
2706
2930
|
function response(request, ok, content, details) {
|
|
2707
|
-
return { requestId: request.requestId, ok, content, ...details ? { details } : {} };
|
|
2931
|
+
if (ok) return { requestId: request.requestId, ok, content, ...details ? { details } : {} };
|
|
2932
|
+
const failureReason = typeof details?.failureReason === "string" && details.failureReason || DEFAULT_FAILURE_REASON2[content] || content || "tool request failed; inspect the tool input and workspace state";
|
|
2933
|
+
return { requestId: request.requestId, ok, content, details: { ...details, failureReason } };
|
|
2708
2934
|
}
|
|
2709
2935
|
|
|
2710
2936
|
// src/code-tool-reads.ts
|
|
@@ -3505,122 +3731,6 @@ async function appendCodeRuntimeEvent(control, command, event, refs) {
|
|
|
3505
3731
|
var digestRuntimeValue = (value) => `sha256:${(0, import_node_crypto4.createHash)("sha256").update(value).digest("hex")}`;
|
|
3506
3732
|
var runtimeErrorMessage = (value) => value instanceof Error ? value.message : String(value);
|
|
3507
3733
|
|
|
3508
|
-
// src/code-tool-presentation.ts
|
|
3509
|
-
var text = (value, maximum) => {
|
|
3510
|
-
if (typeof value !== "string") return void 0;
|
|
3511
|
-
const bounded = value.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, " ").trim();
|
|
3512
|
-
return bounded ? bounded.slice(0, maximum) : void 0;
|
|
3513
|
-
};
|
|
3514
|
-
var integer2 = (value) => Number.isSafeInteger(value) && Number(value) >= 0 ? Number(value) : void 0;
|
|
3515
|
-
var record4 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
3516
|
-
var excerpt = (value, tail = false) => {
|
|
3517
|
-
if (typeof value !== "string") return void 0;
|
|
3518
|
-
const safe = value.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, " ");
|
|
3519
|
-
const source = (tail ? safe.slice(-1e4) : safe.slice(0, 1e4)).trim();
|
|
3520
|
-
if (!source) return void 0;
|
|
3521
|
-
const lines = source.split("\n").filter((line) => line.trim()).map((line) => line.slice(0, 240));
|
|
3522
|
-
const selected = tail ? lines.slice(-10) : lines.slice(0, 10);
|
|
3523
|
-
return text(selected.join("\n"), 2400);
|
|
3524
|
-
};
|
|
3525
|
-
var paths = (value) => {
|
|
3526
|
-
if (!Array.isArray(value)) return void 0;
|
|
3527
|
-
const items = value.flatMap((item) => {
|
|
3528
|
-
const path = text(item, 1024);
|
|
3529
|
-
return path ? [path] : [];
|
|
3530
|
-
}).slice(0, 12);
|
|
3531
|
-
return items.length ? items : void 0;
|
|
3532
|
-
};
|
|
3533
|
-
function patchStats(value) {
|
|
3534
|
-
if (typeof value !== "string") return {};
|
|
3535
|
-
let additions = 0;
|
|
3536
|
-
let deletions = 0;
|
|
3537
|
-
for (const line of value.slice(0, 262144).split("\n")) {
|
|
3538
|
-
if (line.startsWith("+++") || line.startsWith("---")) continue;
|
|
3539
|
-
if (line.startsWith("+")) additions += 1;
|
|
3540
|
-
else if (line.startsWith("-")) deletions += 1;
|
|
3541
|
-
}
|
|
3542
|
-
return { ...additions ? { additions } : {}, ...deletions ? { deletions } : {} };
|
|
3543
|
-
}
|
|
3544
|
-
function searchResults(value) {
|
|
3545
|
-
if (typeof value !== "string") return void 0;
|
|
3546
|
-
const results = value.split("\n").flatMap((line) => {
|
|
3547
|
-
const match = /^([^:\n]{1,1024}):(\d+):\s?(.*)$/.exec(line);
|
|
3548
|
-
if (!match) return [];
|
|
3549
|
-
const lineNumber = Number(match[2]);
|
|
3550
|
-
const itemText = text(match[3], 240);
|
|
3551
|
-
if (!Number.isSafeInteger(lineNumber) || lineNumber < 1) return [];
|
|
3552
|
-
return [{ path: match[1], line: lineNumber, ...itemText ? { text: itemText } : {} }];
|
|
3553
|
-
}).slice(0, 5);
|
|
3554
|
-
return results.length ? results : void 0;
|
|
3555
|
-
}
|
|
3556
|
-
function codeToolRequestPresentation(request) {
|
|
3557
|
-
const input = request.input;
|
|
3558
|
-
if (request.tool === "sandbox.read") {
|
|
3559
|
-
const path = text(input.path, 1024);
|
|
3560
|
-
if (!path) return void 0;
|
|
3561
|
-
const startLine = integer2(input.startLine);
|
|
3562
|
-
const endLine = integer2(input.endLine);
|
|
3563
|
-
return { kind: "read", path, ...startLine ? { startLine } : {}, ...endLine ? { endLine } : {} };
|
|
3564
|
-
}
|
|
3565
|
-
if (request.tool === "sandbox.list") {
|
|
3566
|
-
const scope = text(input.prefix, 1024);
|
|
3567
|
-
return { kind: "list", ...scope ? { scope } : {} };
|
|
3568
|
-
}
|
|
3569
|
-
if (request.tool === "sandbox.search" || request.tool === "sandbox.overview" || request.tool === "sandbox.where_is" || request.tool === "sandbox.who_imports" || request.tool === "sandbox.who_touches") {
|
|
3570
|
-
const query = text(input.query, 512);
|
|
3571
|
-
const scope = request.tool === "sandbox.search" ? text(input.prefix, 1024) : void 0;
|
|
3572
|
-
if (request.tool === "sandbox.search" && !query) return void 0;
|
|
3573
|
-
return { kind: "query", ...query ? { query } : {}, ...scope ? { scope } : {} };
|
|
3574
|
-
}
|
|
3575
|
-
if (request.tool === "sandbox.apply_patch") {
|
|
3576
|
-
return { kind: "patch", ...patchStats(input.patch) };
|
|
3577
|
-
}
|
|
3578
|
-
const recipeId = text(input.recipeId, 120);
|
|
3579
|
-
return recipeId ? { kind: "recipe", recipeId } : void 0;
|
|
3580
|
-
}
|
|
3581
|
-
function codeToolResultPresentation(request, response2) {
|
|
3582
|
-
const started = codeToolRequestPresentation(request);
|
|
3583
|
-
if (!started || !response2.ok) return started;
|
|
3584
|
-
const details = record4(response2.details);
|
|
3585
|
-
if (started.kind === "read") {
|
|
3586
|
-
return {
|
|
3587
|
-
...started,
|
|
3588
|
-
...integer2(details?.startLine) ? { startLine: integer2(details?.startLine) } : {},
|
|
3589
|
-
...integer2(details?.endLine) ? { endLine: integer2(details?.endLine) } : {},
|
|
3590
|
-
...excerpt(response2.content) ? { excerpt: excerpt(response2.content) } : {}
|
|
3591
|
-
};
|
|
3592
|
-
}
|
|
3593
|
-
if (started.kind === "list") {
|
|
3594
|
-
const listed = response2.content.split("\n").filter((line) => line && !line.startsWith("\u2026") && !line.startsWith("Workspace ")).map((line) => text(line, 1024)).filter((line) => Boolean(line)).slice(0, 8);
|
|
3595
|
-
return {
|
|
3596
|
-
...started,
|
|
3597
|
-
...integer2(details?.count) !== void 0 ? { count: integer2(details?.count) } : {},
|
|
3598
|
-
...listed.length ? { paths: listed } : {}
|
|
3599
|
-
};
|
|
3600
|
-
}
|
|
3601
|
-
if (started.kind === "query") {
|
|
3602
|
-
const results = request.tool === "sandbox.search" ? searchResults(response2.content) : void 0;
|
|
3603
|
-
const resultExcerpt = request.tool === "sandbox.search" ? void 0 : excerpt(response2.content);
|
|
3604
|
-
return {
|
|
3605
|
-
...started,
|
|
3606
|
-
...integer2(details?.count) !== void 0 ? { count: integer2(details?.count) } : {},
|
|
3607
|
-
...results ? { results } : {},
|
|
3608
|
-
...resultExcerpt ? { excerpt: resultExcerpt } : {}
|
|
3609
|
-
};
|
|
3610
|
-
}
|
|
3611
|
-
if (started.kind === "patch") {
|
|
3612
|
-
return { ...started, ...paths(details?.paths) ? { paths: paths(details?.paths) } : {} };
|
|
3613
|
-
}
|
|
3614
|
-
const output = response2.content.replace(/^Recipe [^\n]*\.?\s*/u, "");
|
|
3615
|
-
return {
|
|
3616
|
-
...started,
|
|
3617
|
-
...integer2(details?.exitCode) !== void 0 ? { exitCode: integer2(details?.exitCode) } : {},
|
|
3618
|
-
...typeof details?.timedOut === "boolean" ? { timedOut: details.timedOut } : {},
|
|
3619
|
-
...typeof details?.outputLimitExceeded === "boolean" ? { outputLimitExceeded: details.outputLimitExceeded } : {},
|
|
3620
|
-
...excerpt(output, true) ? { excerpt: excerpt(output, true) } : {}
|
|
3621
|
-
};
|
|
3622
|
-
}
|
|
3623
|
-
|
|
3624
3734
|
// src/code-runtime-acknowledgement-gate.ts
|
|
3625
3735
|
function codeRuntimeAcknowledgementGate(signal) {
|
|
3626
3736
|
let settle;
|
|
@@ -3927,36 +4037,11 @@ var TheseusRuntimeEngine = class {
|
|
|
3927
4037
|
}
|
|
3928
4038
|
/** Report every brokered effect as it starts and finishes. */
|
|
3929
4039
|
#observed(command, active, broker) {
|
|
3930
|
-
return {
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
await this.#event(
|
|
3936
|
-
command,
|
|
3937
|
-
{
|
|
3938
|
-
type: "tool",
|
|
3939
|
-
phase: "started",
|
|
3940
|
-
tool: request.tool,
|
|
3941
|
-
operationId,
|
|
3942
|
-
...startedPresentation ? { presentation: startedPresentation } : {}
|
|
3943
|
-
},
|
|
3944
|
-
active.conversationRefs
|
|
3945
|
-
).catch(() => void 0);
|
|
3946
|
-
const response2 = await broker.execute(context, request);
|
|
3947
|
-
const completedPresentation = codeToolResultPresentation(request, response2);
|
|
3948
|
-
await this.#event(command, {
|
|
3949
|
-
type: "tool",
|
|
3950
|
-
phase: "completed",
|
|
3951
|
-
tool: request.tool,
|
|
3952
|
-
ok: response2.ok,
|
|
3953
|
-
durationMs: Date.now() - startedAt,
|
|
3954
|
-
operationId,
|
|
3955
|
-
...completedPresentation ? { presentation: completedPresentation } : {}
|
|
3956
|
-
}, active.conversationRefs).catch(() => void 0);
|
|
3957
|
-
return response2;
|
|
3958
|
-
}
|
|
3959
|
-
};
|
|
4040
|
+
return observedBroker({
|
|
4041
|
+
broker,
|
|
4042
|
+
operationIdFor: (requestId) => digestRuntimeValue(`${command.commandId}:${requestId}`),
|
|
4043
|
+
emit: (event) => this.#event(command, event, active.conversationRefs).catch(() => void 0)
|
|
4044
|
+
});
|
|
3960
4045
|
}
|
|
3961
4046
|
async #checkpoint(command) {
|
|
3962
4047
|
const active = this.#active.get(command.sessionId);
|
|
@@ -4300,6 +4385,7 @@ async function installedDependencies(repoRoot) {
|
|
|
4300
4385
|
V2_SYSTEM_PROMPT,
|
|
4301
4386
|
V3_SYSTEM_PROMPT,
|
|
4302
4387
|
applyCodePatch,
|
|
4388
|
+
applyPatchDialectToDiff,
|
|
4303
4389
|
assertCodeBuildRecipe,
|
|
4304
4390
|
assertDisjointPlan,
|
|
4305
4391
|
assertPinnedImage,
|
|
@@ -4317,6 +4403,7 @@ async function installedDependencies(repoRoot) {
|
|
|
4317
4403
|
describePatchFailure,
|
|
4318
4404
|
digestStagedWorkspace,
|
|
4319
4405
|
feedbackIsActionable,
|
|
4406
|
+
hasContextFreeHunk,
|
|
4320
4407
|
hazardFromAttempt,
|
|
4321
4408
|
installedDependencies,
|
|
4322
4409
|
integrateSubGoals,
|