@odla-ai/harness 0.2.0 → 0.3.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/{chunk-5FFR7U4L.js → chunk-U2OFMIAW.js} +77 -1
- package/dist/chunk-U2OFMIAW.js.map +1 -0
- package/dist/code-runtime-cli.cjs +48 -0
- package/dist/code-runtime-cli.cjs.map +1 -1
- package/dist/code-runtime-cli.js +1 -1
- package/dist/node.cjs +114 -2
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +150 -2
- package/dist/node.d.ts +150 -2
- package/dist/node.js +39 -1
- package/dist/node.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-5FFR7U4L.js.map +0 -1
package/dist/code-runtime-cli.js
CHANGED
package/dist/node.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(node_exports, {
|
|
|
26
26
|
CodeRuntimeControlError: () => CodeRuntimeControlError,
|
|
27
27
|
CodeRuntimeReconciler: () => CodeRuntimeReconciler,
|
|
28
28
|
DecompositionError: () => DecompositionError,
|
|
29
|
+
MAX_MEMORY_BODY: () => MAX_MEMORY_BODY,
|
|
29
30
|
MEASURED_PREMIUM: () => MEASURED_PREMIUM,
|
|
30
31
|
SYSTEM_PROMPT_FOR: () => SYSTEM_PROMPT_FOR,
|
|
31
32
|
V1_SYSTEM_PROMPT: () => V1_SYSTEM_PROMPT,
|
|
@@ -48,17 +49,23 @@ __export(node_exports, {
|
|
|
48
49
|
describePatchFailure: () => describePatchFailure,
|
|
49
50
|
digestStagedWorkspace: () => digestStagedWorkspace,
|
|
50
51
|
feedbackIsActionable: () => feedbackIsActionable,
|
|
52
|
+
hazardFromAttempt: () => hazardFromAttempt,
|
|
51
53
|
installedDependencies: () => installedDependencies,
|
|
52
54
|
integrateSubGoals: () => integrateSubGoals,
|
|
53
55
|
isCheckpointEffectCompleted: () => isCheckpointEffectCompleted,
|
|
54
56
|
materializeCodeRuntimeSource: () => materializeCodeRuntimeSource,
|
|
55
57
|
materializeCommandWorkspace: () => materializeCommandWorkspace,
|
|
56
58
|
materializeGitTree: () => materializeGitTree,
|
|
59
|
+
outcomeCloses: () => outcomeCloses,
|
|
60
|
+
outcomeMemory: () => outcomeMemory,
|
|
57
61
|
patchPaths: () => patchPaths,
|
|
58
62
|
planReachCollisions: () => planReachCollisions,
|
|
59
63
|
prepareRuntimeCheckpoint: () => prepareRuntimeCheckpoint,
|
|
60
64
|
racedAttempt: () => racedAttempt,
|
|
65
|
+
recallAbout: () => recallAbout,
|
|
61
66
|
registeredFiles: () => registeredFiles,
|
|
67
|
+
renderMemories: () => renderMemories,
|
|
68
|
+
renderOutcome: () => renderOutcome,
|
|
62
69
|
resolveCodePath: () => resolveCodePath,
|
|
63
70
|
restoreCodeWorkspaceCheckpoint: () => restoreCodeWorkspaceCheckpoint,
|
|
64
71
|
runCodeAgent: () => runCodeAgent,
|
|
@@ -76,6 +83,7 @@ __export(node_exports, {
|
|
|
76
83
|
straySubGoalFiles: () => straySubGoalFiles,
|
|
77
84
|
stripPatchEnvelope: () => stripPatchEnvelope,
|
|
78
85
|
validateCodePatch: () => validateCodePatch,
|
|
86
|
+
validateMemory: () => validateMemory,
|
|
79
87
|
validateRelativePath: () => validateRelativePath,
|
|
80
88
|
verifyCodeCandidate: () => verifyCodeCandidate,
|
|
81
89
|
verifyContainerEngineBoundary: () => verifyContainerEngineBoundary,
|
|
@@ -2832,6 +2840,55 @@ function createCodeRuntimeToolBroker(input, lease, role) {
|
|
|
2832
2840
|
return role === "coding" ? broker : { execute: (context, request) => request.tool === "sandbox.read" ? broker.execute(context, request) : Promise.resolve({ requestId: request.requestId, ok: false, content: "review sessions are read-only" }) };
|
|
2833
2841
|
}
|
|
2834
2842
|
|
|
2843
|
+
// src/code-memory.ts
|
|
2844
|
+
var import_graph2 = require("@odla-ai/graph");
|
|
2845
|
+
var MAX_MEMORY_BODY = 4e3;
|
|
2846
|
+
function validateMemory(memory) {
|
|
2847
|
+
if (!memory.subject.includes(":")) {
|
|
2848
|
+
throw new TypeError(`memory subject must be a graph node id, got "${memory.subject}"`);
|
|
2849
|
+
}
|
|
2850
|
+
const body = memory.body.trim();
|
|
2851
|
+
if (!body) throw new TypeError("a memory needs a body");
|
|
2852
|
+
if (body.length > MAX_MEMORY_BODY) throw new TypeError("memory body exceeds its bound");
|
|
2853
|
+
if (!memory.authorId.trim()) throw new TypeError("a memory needs an author");
|
|
2854
|
+
}
|
|
2855
|
+
async function recallAbout(store, subjects, options = {}) {
|
|
2856
|
+
const limit = options.limit ?? 20;
|
|
2857
|
+
const wanted = options.graph ? [...(0, import_graph2.closure)(options.graph, subjects, {
|
|
2858
|
+
direction: "out",
|
|
2859
|
+
maxDepth: options.depth ?? 1,
|
|
2860
|
+
...options.kinds ? { kinds: options.kinds } : {}
|
|
2861
|
+
})] : [...subjects];
|
|
2862
|
+
const found = await store.recall(wanted, limit * 2);
|
|
2863
|
+
return found.filter((memory) => !memory.supersededBy).slice(0, limit);
|
|
2864
|
+
}
|
|
2865
|
+
function renderMemories(memories) {
|
|
2866
|
+
if (memories.length === 0) return "";
|
|
2867
|
+
const lines = memories.map((memory) => {
|
|
2868
|
+
const source = memory.evidence ? ` [${memory.evidence.kind}:${memory.evidence.ref}]` : " [unverified]";
|
|
2869
|
+
return `- (${memory.kind}) ${memory.subject}${source}
|
|
2870
|
+
${memory.body.replace(/\s+/g, " ").slice(0, 400)}`;
|
|
2871
|
+
});
|
|
2872
|
+
return [
|
|
2873
|
+
"What previous runs learned about this code. A hazard cost an attempt to find;",
|
|
2874
|
+
"an unverified note is one agent's opinion. Treat them accordingly.",
|
|
2875
|
+
...lines
|
|
2876
|
+
].join("\n");
|
|
2877
|
+
}
|
|
2878
|
+
function hazardFromAttempt(input) {
|
|
2879
|
+
const body = [
|
|
2880
|
+
`Attempt ${input.attempt} at "${input.goal.slice(0, 200)}" failed its proof.`,
|
|
2881
|
+
input.feedback.replace(/\s+/g, " ").slice(0, MAX_MEMORY_BODY - 300)
|
|
2882
|
+
].join(" ");
|
|
2883
|
+
return input.touched.slice(0, 10).map((path) => ({
|
|
2884
|
+
subject: path.includes(":") ? path : `file:${path}`,
|
|
2885
|
+
kind: "hazard",
|
|
2886
|
+
body,
|
|
2887
|
+
evidence: { kind: "gate", ref: input.verificationId },
|
|
2888
|
+
authorId: input.authorId
|
|
2889
|
+
}));
|
|
2890
|
+
}
|
|
2891
|
+
|
|
2835
2892
|
// src/code-goal-runner.ts
|
|
2836
2893
|
async function runGoal(spec, attempt) {
|
|
2837
2894
|
assertBudget(spec.budget);
|
|
@@ -3016,6 +3073,9 @@ function pursueRuntimeGoal(input) {
|
|
|
3016
3073
|
return { gatePassed: false, feedback: "", tokens: outcome.tokens, error: outcome.error };
|
|
3017
3074
|
}
|
|
3018
3075
|
const verdict = await input.gate(attempt);
|
|
3076
|
+
if (!verdict.passed && input.memory) {
|
|
3077
|
+
await rememberFailure(input, attempt, verdict.feedback);
|
|
3078
|
+
}
|
|
3019
3079
|
return {
|
|
3020
3080
|
gatePassed: verdict.passed,
|
|
3021
3081
|
feedback: verdict.feedback,
|
|
@@ -3026,6 +3086,25 @@ function pursueRuntimeGoal(input) {
|
|
|
3026
3086
|
}
|
|
3027
3087
|
);
|
|
3028
3088
|
}
|
|
3089
|
+
async function rememberFailure(input, attempt, feedback) {
|
|
3090
|
+
if (!input.memory || !feedback.trim()) return;
|
|
3091
|
+
try {
|
|
3092
|
+
const touched = await input.touched?.(attempt) ?? [];
|
|
3093
|
+
if (touched.length === 0) return;
|
|
3094
|
+
for (const memory of hazardFromAttempt({
|
|
3095
|
+
goal: input.spec.goal,
|
|
3096
|
+
attempt,
|
|
3097
|
+
feedback,
|
|
3098
|
+
touched,
|
|
3099
|
+
verificationId: `goal-${attempt}`,
|
|
3100
|
+
authorId: input.memory.authorId
|
|
3101
|
+
})) {
|
|
3102
|
+
validateMemory(memory);
|
|
3103
|
+
await input.memory.store.remember(memory);
|
|
3104
|
+
}
|
|
3105
|
+
} catch {
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3029
3108
|
function goalEventLine(event) {
|
|
3030
3109
|
if (event.type === "attempt_started") return `Goal attempt ${event.attempt} starting.`;
|
|
3031
3110
|
if (event.type === "attempt_failed") return `Attempt ${event.attempt} did not satisfy the proof.`;
|
|
@@ -3351,6 +3430,31 @@ var CodePiRuntimeEngine = class {
|
|
|
3351
3430
|
}
|
|
3352
3431
|
};
|
|
3353
3432
|
|
|
3433
|
+
// src/code-goal-outcome.ts
|
|
3434
|
+
function outcomeCloses(outcome) {
|
|
3435
|
+
return outcome.met && outcome.evidence !== void 0;
|
|
3436
|
+
}
|
|
3437
|
+
function renderOutcome(outcome) {
|
|
3438
|
+
const spend = outcome.costUsd === void 0 ? "cost unknown" : `$${outcome.costUsd.toFixed(4)}`;
|
|
3439
|
+
const scale = `${outcome.attempts} attempt(s), ${outcome.tokens.toLocaleString()} tokens, ${spend}`;
|
|
3440
|
+
if (!outcome.met) {
|
|
3441
|
+
return `Goal not met (${outcome.stoppedReason}) after ${scale}. Proof: ${outcome.proof}`;
|
|
3442
|
+
}
|
|
3443
|
+
if (!outcome.evidence) {
|
|
3444
|
+
return `Goal reported met after ${scale}, but no verification receipt was produced. Treat as unverified. Proof: ${outcome.proof}`;
|
|
3445
|
+
}
|
|
3446
|
+
return `Goal met after ${scale}. Verified by ${outcome.evidence.kind}:${outcome.evidence.ref}. Proof: ${outcome.proof}`;
|
|
3447
|
+
}
|
|
3448
|
+
function outcomeMemory(outcome, subject, authorId) {
|
|
3449
|
+
return {
|
|
3450
|
+
subject,
|
|
3451
|
+
kind: "outcome",
|
|
3452
|
+
body: renderOutcome(outcome),
|
|
3453
|
+
...outcome.evidence ? { evidence: outcome.evidence } : {},
|
|
3454
|
+
authorId
|
|
3455
|
+
};
|
|
3456
|
+
}
|
|
3457
|
+
|
|
3354
3458
|
// src/code-goal-race.ts
|
|
3355
3459
|
function selectWinner(outcomes) {
|
|
3356
3460
|
const ranked = [...outcomes].sort((left, right) => {
|
|
@@ -3411,7 +3515,7 @@ function racedAttempt(options) {
|
|
|
3411
3515
|
}
|
|
3412
3516
|
|
|
3413
3517
|
// src/code-goal-decompose.ts
|
|
3414
|
-
var
|
|
3518
|
+
var import_graph3 = require("@odla-ai/graph");
|
|
3415
3519
|
var import_code5 = require("@odla-ai/graph/code");
|
|
3416
3520
|
var DecompositionError = class extends Error {
|
|
3417
3521
|
constructor(message2) {
|
|
@@ -3499,7 +3603,7 @@ async function integrateSubGoals(options) {
|
|
|
3499
3603
|
}
|
|
3500
3604
|
async function planReachCollisions(plan, workspace) {
|
|
3501
3605
|
const graph = await (0, import_code5.buildCodeGraph)({ paths: workspace.paths, read: workspace.read });
|
|
3502
|
-
return (0,
|
|
3606
|
+
return (0, import_graph3.partition)(graph, plan.map((sub) => sub.files.map((file) => `${import_code5.FILE}:${file}`)), {
|
|
3503
3607
|
kinds: [import_code5.IMPORTS, import_code5.READS, import_code5.WRITES],
|
|
3504
3608
|
direction: "out"
|
|
3505
3609
|
});
|
|
@@ -3609,6 +3713,7 @@ async function installedDependencies(repoRoot) {
|
|
|
3609
3713
|
CodeRuntimeControlError,
|
|
3610
3714
|
CodeRuntimeReconciler,
|
|
3611
3715
|
DecompositionError,
|
|
3716
|
+
MAX_MEMORY_BODY,
|
|
3612
3717
|
MEASURED_PREMIUM,
|
|
3613
3718
|
SYSTEM_PROMPT_FOR,
|
|
3614
3719
|
V1_SYSTEM_PROMPT,
|
|
@@ -3631,17 +3736,23 @@ async function installedDependencies(repoRoot) {
|
|
|
3631
3736
|
describePatchFailure,
|
|
3632
3737
|
digestStagedWorkspace,
|
|
3633
3738
|
feedbackIsActionable,
|
|
3739
|
+
hazardFromAttempt,
|
|
3634
3740
|
installedDependencies,
|
|
3635
3741
|
integrateSubGoals,
|
|
3636
3742
|
isCheckpointEffectCompleted,
|
|
3637
3743
|
materializeCodeRuntimeSource,
|
|
3638
3744
|
materializeCommandWorkspace,
|
|
3639
3745
|
materializeGitTree,
|
|
3746
|
+
outcomeCloses,
|
|
3747
|
+
outcomeMemory,
|
|
3640
3748
|
patchPaths,
|
|
3641
3749
|
planReachCollisions,
|
|
3642
3750
|
prepareRuntimeCheckpoint,
|
|
3643
3751
|
racedAttempt,
|
|
3752
|
+
recallAbout,
|
|
3644
3753
|
registeredFiles,
|
|
3754
|
+
renderMemories,
|
|
3755
|
+
renderOutcome,
|
|
3645
3756
|
resolveCodePath,
|
|
3646
3757
|
restoreCodeWorkspaceCheckpoint,
|
|
3647
3758
|
runCodeAgent,
|
|
@@ -3659,6 +3770,7 @@ async function installedDependencies(repoRoot) {
|
|
|
3659
3770
|
straySubGoalFiles,
|
|
3660
3771
|
stripPatchEnvelope,
|
|
3661
3772
|
validateCodePatch,
|
|
3773
|
+
validateMemory,
|
|
3662
3774
|
validateRelativePath,
|
|
3663
3775
|
verifyCodeCandidate,
|
|
3664
3776
|
verifyContainerEngineBoundary,
|