@openpond/evals 0.12.0 → 0.12.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/artifact-verification.js +2 -0
- package/dist/connected-evidence/sources/claude-branches.js +34 -1
- package/dist/connected-evidence/sources/claude-code.js +1 -1
- package/dist/learning/continuation-mode.js +9 -0
- package/dist/learning/contracts.js +2 -0
- package/dist/learning/correction-metrics.js +61 -0
- package/dist/learning/index.js +2 -0
- package/dist/native-conversations/collector-acquisition.js +17 -6
- package/dist/native-conversations/collector-source-cache.js +1 -1
- package/dist/native-conversations/collector-store.js +27 -2
- package/dist/native-conversations/collector.js +4 -3
- package/dist/native-conversations/history.js +28 -8
- package/dist/native-conversations/index.js +1 -0
- package/dist/native-conversations/selection.js +57 -0
- package/dist/native-conversations/supervisor.js +2 -0
- package/dist/native-conversations/titles.js +2 -2
- package/dist/tasksets.js +1 -0
- package/dist/types/artifact-verification.d.ts.map +1 -1
- package/dist/types/benchmarks.d.ts +22 -22
- package/dist/types/benchmarks.d.ts.map +1 -1
- package/dist/types/builtin-benchmarks/harness-refiner.d.ts +40 -39
- package/dist/types/builtin-benchmarks/harness-refiner.d.ts.map +1 -1
- package/dist/types/compatibility.d.ts.map +1 -1
- package/dist/types/conformance.d.ts +98 -96
- package/dist/types/conformance.d.ts.map +1 -1
- package/dist/types/connected-evidence/codex-command-observations.d.ts.map +1 -1
- package/dist/types/connected-evidence/collector-coverage-contracts.d.ts +6 -6
- package/dist/types/connected-evidence/collector-coverage-contracts.d.ts.map +1 -1
- package/dist/types/connected-evidence/contracts.d.ts +58 -58
- package/dist/types/connected-evidence/contracts.d.ts.map +1 -1
- package/dist/types/connected-evidence/git-file-contracts.d.ts.map +1 -1
- package/dist/types/connected-evidence/git-file-proof.d.ts.map +1 -1
- package/dist/types/connected-evidence/git-starting-state.d.ts.map +1 -1
- package/dist/types/connected-evidence/git.d.ts.map +1 -1
- package/dist/types/connected-evidence/imports.d.ts.map +1 -1
- package/dist/types/connected-evidence/index.d.ts.map +1 -1
- package/dist/types/connected-evidence/normalize.d.ts.map +1 -1
- package/dist/types/connected-evidence/python-correctness.d.ts +38 -38
- package/dist/types/connected-evidence/python-correctness.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/claude-branches.d.ts +1 -0
- package/dist/types/connected-evidence/sources/claude-branches.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/claude-code.d.ts +25 -25
- package/dist/types/connected-evidence/sources/claude-code.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/codex-authorization.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/codex-metadata.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/codex.d.ts +25 -25
- package/dist/types/connected-evidence/sources/codex.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/grok-build.d.ts +25 -25
- package/dist/types/connected-evidence/sources/grok-build.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/history.d.ts +44 -44
- package/dist/types/connected-evidence/sources/history.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/opencode.d.ts +25 -25
- package/dist/types/connected-evidence/sources/opencode.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/pi.d.ts +25 -25
- package/dist/types/connected-evidence/sources/pi.d.ts.map +1 -1
- package/dist/types/connected-evidence/sources/usage.d.ts.map +1 -1
- package/dist/types/connected-evidence/usage-summary.d.ts.map +1 -1
- package/dist/types/deterministic-graders.d.ts.map +1 -1
- package/dist/types/environment-execution-services-contract.d.ts +19 -19
- package/dist/types/environment-execution-services-contract.d.ts.map +1 -1
- package/dist/types/environment-execution-services.d.ts.map +1 -1
- package/dist/types/evidence/authoring.d.ts.map +1 -1
- package/dist/types/evidence/conformance.d.ts +98 -98
- package/dist/types/evidence/conformance.d.ts.map +1 -1
- package/dist/types/evidence/contracts.d.ts +183 -183
- package/dist/types/evidence/contracts.d.ts.map +1 -1
- package/dist/types/evidence/eligibility.d.ts +160 -160
- package/dist/types/evidence/eligibility.d.ts.map +1 -1
- package/dist/types/evidence/index.d.ts.map +1 -1
- package/dist/types/execution-contracts.d.ts +110 -110
- package/dist/types/execution-contracts.d.ts.map +1 -1
- package/dist/types/execution-receipts.d.ts.map +1 -1
- package/dist/types/experiments.d.ts +96 -96
- package/dist/types/experiments.d.ts.map +1 -1
- package/dist/types/graders.d.ts +35 -35
- package/dist/types/graders.d.ts.map +1 -1
- package/dist/types/harness-experiment-source.d.ts.map +1 -1
- package/dist/types/harness.d.ts.map +1 -1
- package/dist/types/human-review/comparison.d.ts +189 -189
- package/dist/types/human-review/comparison.d.ts.map +1 -1
- package/dist/types/human-review/contracts.d.ts +178 -178
- package/dist/types/human-review/contracts.d.ts.map +1 -1
- package/dist/types/human-review/execution.d.ts +53 -53
- package/dist/types/human-review/execution.d.ts.map +1 -1
- package/dist/types/human-review/handoff.d.ts +43 -43
- package/dist/types/human-review/handoff.d.ts.map +1 -1
- package/dist/types/human-review/index.d.ts.map +1 -1
- package/dist/types/human-review/local-publication.d.ts +4 -4
- package/dist/types/human-review/local-publication.d.ts.map +1 -1
- package/dist/types/human-review/repository.d.ts.map +1 -1
- package/dist/types/human-review/results.d.ts +8 -8
- package/dist/types/human-review/results.d.ts.map +1 -1
- package/dist/types/human-review/service.d.ts +292 -292
- package/dist/types/human-review/service.d.ts.map +1 -1
- package/dist/types/human-review/task-proposals.d.ts +2 -2
- package/dist/types/human-review/task-proposals.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/javascript-environment-attempt.d.ts.map +1 -1
- package/dist/types/javascript-environment-contract.d.ts +39 -39
- package/dist/types/javascript-environment-contract.d.ts.map +1 -1
- package/dist/types/javascript-environment-node.d.ts.map +1 -1
- package/dist/types/javascript-environment.d.ts +14 -14
- package/dist/types/javascript-environment.d.ts.map +1 -1
- package/dist/types/javascript-isolate-node.d.ts.map +1 -1
- package/dist/types/javascript-isolate-process-entry.d.ts.map +1 -1
- package/dist/types/javascript-isolate-process.d.ts.map +1 -1
- package/dist/types/javascript-isolate.d.ts.map +1 -1
- package/dist/types/javascript-verifier-contract.d.ts.map +1 -1
- package/dist/types/javascript-verifier-node.d.ts.map +1 -1
- package/dist/types/javascript-verifier-worker.d.ts.map +1 -1
- package/dist/types/javascript-verifier.d.ts.map +1 -1
- package/dist/types/learned-preference.d.ts +10 -10
- package/dist/types/learned-preference.d.ts.map +1 -1
- package/dist/types/learning/acceptance-group.d.ts +44 -44
- package/dist/types/learning/acceptance-group.d.ts.map +1 -1
- package/dist/types/learning/acceptance-plan.d.ts +8 -8
- package/dist/types/learning/acceptance-plan.d.ts.map +1 -1
- package/dist/types/learning/admission.d.ts +37 -36
- package/dist/types/learning/admission.d.ts.map +1 -1
- package/dist/types/learning/assets.d.ts +2 -2
- package/dist/types/learning/assets.d.ts.map +1 -1
- package/dist/types/learning/authoring-service.d.ts +11 -11
- package/dist/types/learning/authoring-service.d.ts.map +1 -1
- package/dist/types/learning/authoring.d.ts +38 -38
- package/dist/types/learning/authoring.d.ts.map +1 -1
- package/dist/types/learning/batch-service.d.ts +75 -72
- package/dist/types/learning/batch-service.d.ts.map +1 -1
- package/dist/types/learning/budgeted-reward-fixtures.d.ts.map +1 -1
- package/dist/types/learning/continuation-mode.d.ts +18 -0
- package/dist/types/learning/continuation-mode.d.ts.map +1 -0
- package/dist/types/learning/contracts.d.ts +341 -298
- package/dist/types/learning/contracts.d.ts.map +1 -1
- package/dist/types/learning/correction-metrics.d.ts +274 -0
- package/dist/types/learning/correction-metrics.d.ts.map +1 -0
- package/dist/types/learning/errors.d.ts.map +1 -1
- package/dist/types/learning/grade-judge-budget.d.ts.map +1 -1
- package/dist/types/learning/grade-worker.d.ts.map +1 -1
- package/dist/types/learning/index.d.ts +2 -0
- package/dist/types/learning/index.d.ts.map +1 -1
- package/dist/types/learning/intake-contracts.d.ts +10 -10
- package/dist/types/learning/intake-contracts.d.ts.map +1 -1
- package/dist/types/learning/intake-csv.d.ts.map +1 -1
- package/dist/types/learning/intake-history.d.ts.map +1 -1
- package/dist/types/learning/intake-service.d.ts.map +1 -1
- package/dist/types/learning/intake-text.d.ts.map +1 -1
- package/dist/types/learning/intake.d.ts.map +1 -1
- package/dist/types/learning/iteration-budget.d.ts.map +1 -1
- package/dist/types/learning/iteration-candidate-decision.d.ts +16 -16
- package/dist/types/learning/iteration-candidate-decision.d.ts.map +1 -1
- package/dist/types/learning/iteration-dispatch-commands.d.ts.map +1 -1
- package/dist/types/learning/iteration-dispatch-contracts.d.ts +4 -4
- package/dist/types/learning/iteration-dispatch-contracts.d.ts.map +1 -1
- package/dist/types/learning/iteration-dispatch-worker.d.ts.map +1 -1
- package/dist/types/learning/iteration-eligibility.d.ts +1 -1
- package/dist/types/learning/iteration-eligibility.d.ts.map +1 -1
- package/dist/types/learning/iteration-reservation-cancellation.d.ts.map +1 -1
- package/dist/types/learning/iteration-reservation-contracts.d.ts.map +1 -1
- package/dist/types/learning/iteration-reservation-service.d.ts.map +1 -1
- package/dist/types/learning/iteration-training-parent.d.ts.map +1 -1
- package/dist/types/learning/judge-budget.d.ts +1 -1
- package/dist/types/learning/judge-budget.d.ts.map +1 -1
- package/dist/types/learning/model-judge.d.ts.map +1 -1
- package/dist/types/learning/nightly-schedule.d.ts.map +1 -1
- package/dist/types/learning/operations.d.ts +352 -298
- package/dist/types/learning/operations.d.ts.map +1 -1
- package/dist/types/learning/policy-inspection.d.ts.map +1 -1
- package/dist/types/learning/rating-reward-fixture.d.ts.map +1 -1
- package/dist/types/learning/repository.d.ts +199 -184
- package/dist/types/learning/repository.d.ts.map +1 -1
- package/dist/types/learning/reward-authoring.d.ts.map +1 -1
- package/dist/types/learning/reward-calibration-closure.d.ts +248 -248
- package/dist/types/learning/reward-calibration-closure.d.ts.map +1 -1
- package/dist/types/learning/reward-calibration.d.ts +62 -62
- package/dist/types/learning/reward-calibration.d.ts.map +1 -1
- package/dist/types/learning/reward-check-budget.d.ts.map +1 -1
- package/dist/types/learning/reward-check-service.d.ts.map +1 -1
- package/dist/types/learning/reward-check-worker.d.ts.map +1 -1
- package/dist/types/learning/reward-checks.d.ts +30 -30
- package/dist/types/learning/reward-checks.d.ts.map +1 -1
- package/dist/types/learning/reward-fixture-executor.d.ts.map +1 -1
- package/dist/types/learning/schedule-contracts.d.ts +3 -3
- package/dist/types/learning/schedule-contracts.d.ts.map +1 -1
- package/dist/types/learning/schedule-service.d.ts +2 -2
- package/dist/types/learning/schedule-service.d.ts.map +1 -1
- package/dist/types/learning/schedule-worker.d.ts.map +1 -1
- package/dist/types/learning/service.d.ts +3 -3
- package/dist/types/learning/service.d.ts.map +1 -1
- package/dist/types/learning/task-queue-inspection.d.ts.map +1 -1
- package/dist/types/learning/training-handoff.d.ts +9 -9
- package/dist/types/learning/training-handoff.d.ts.map +1 -1
- package/dist/types/learning/transport.d.ts +2270 -2228
- package/dist/types/learning/transport.d.ts.map +1 -1
- package/dist/types/metric-policy.d.ts +6 -6
- package/dist/types/metric-policy.d.ts.map +1 -1
- package/dist/types/metrics-node.d.ts.map +1 -1
- package/dist/types/metrics.d.ts.map +1 -1
- package/dist/types/model-improvement-qualification.d.ts +17 -17
- package/dist/types/model-improvement-qualification.d.ts.map +1 -1
- package/dist/types/native-conversations/appimage-runtime.d.ts.map +1 -1
- package/dist/types/native-conversations/codex-window-inventory.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-acquisition.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-branches.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-calendar-gate.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-contracts.d.ts +3 -0
- package/dist/types/native-conversations/collector-contracts.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-coverage.d.ts +2 -2
- package/dist/types/native-conversations/collector-coverage.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-cron.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-destinations.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-errors.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-progress.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-schedule.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-service-files.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-snapshots.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-source-cache.d.ts +2 -2
- package/dist/types/native-conversations/collector-source-cache.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-store.d.ts.map +1 -1
- package/dist/types/native-conversations/collector-sync-requests.d.ts.map +1 -1
- package/dist/types/native-conversations/collector.d.ts.map +1 -1
- package/dist/types/native-conversations/contracts.d.ts +2 -0
- package/dist/types/native-conversations/contracts.d.ts.map +1 -1
- package/dist/types/native-conversations/database.d.ts.map +1 -1
- package/dist/types/native-conversations/discovery.d.ts.map +1 -1
- package/dist/types/native-conversations/git-assets.d.ts.map +1 -1
- package/dist/types/native-conversations/history.d.ts +2 -0
- package/dist/types/native-conversations/history.d.ts.map +1 -1
- package/dist/types/native-conversations/index.d.ts +1 -0
- package/dist/types/native-conversations/index.d.ts.map +1 -1
- package/dist/types/native-conversations/location.d.ts.map +1 -1
- package/dist/types/native-conversations/openclaw-cold-archive.d.ts.map +1 -1
- package/dist/types/native-conversations/openclaw-database.d.ts.map +1 -1
- package/dist/types/native-conversations/readiness.d.ts.map +1 -1
- package/dist/types/native-conversations/selection.d.ts +32 -0
- package/dist/types/native-conversations/selection.d.ts.map +1 -0
- package/dist/types/native-conversations/source-locations.d.ts.map +1 -1
- package/dist/types/native-conversations/supervisor.d.ts.map +1 -1
- package/dist/types/native-conversations/titles.d.ts +1 -1
- package/dist/types/native-conversations/titles.d.ts.map +1 -1
- package/dist/types/native-harness-experiment-attempt.d.ts.map +1 -1
- package/dist/types/preferences.d.ts +22 -22
- package/dist/types/preferences.d.ts.map +1 -1
- package/dist/types/prepared-process-isolation.d.ts.map +1 -1
- package/dist/types/profile-evaluation-comparisons.d.ts +18 -18
- package/dist/types/profile-evaluation-comparisons.d.ts.map +1 -1
- package/dist/types/profile-evaluation-execution.d.ts.map +1 -1
- package/dist/types/profile-evaluation-reports.d.ts +2 -2
- package/dist/types/profile-evaluation-reports.d.ts.map +1 -1
- package/dist/types/profile-evaluation-suites.d.ts.map +1 -1
- package/dist/types/profile-evaluation-target.d.ts.map +1 -1
- package/dist/types/profile-evaluations.d.ts +15 -15
- package/dist/types/profile-evaluations.d.ts.map +1 -1
- package/dist/types/profile-external-evaluation.d.ts +84 -84
- package/dist/types/profile-external-evaluation.d.ts.map +1 -1
- package/dist/types/profile-source-candidate.d.ts.map +1 -1
- package/dist/types/review-conformance.d.ts +53 -53
- package/dist/types/review-conformance.d.ts.map +1 -1
- package/dist/types/rewards.d.ts +104 -104
- package/dist/types/rewards.d.ts.map +1 -1
- package/dist/types/rollouts.d.ts +16 -16
- package/dist/types/rollouts.d.ts.map +1 -1
- package/dist/types/runs.d.ts +22 -22
- package/dist/types/runs.d.ts.map +1 -1
- package/dist/types/sql-execution-contract.d.ts +3 -3
- package/dist/types/sql-execution-contract.d.ts.map +1 -1
- package/dist/types/sql-execution-engine.d.ts.map +1 -1
- package/dist/types/sql-execution-node.d.ts.map +1 -1
- package/dist/types/sql-execution-process-entry.d.ts.map +1 -1
- package/dist/types/task-schema-validation.d.ts.map +1 -1
- package/dist/types/task-schema.d.ts.map +1 -1
- package/dist/types/task-value-validator.d.ts.map +1 -1
- package/dist/types/taskset-run-contract.d.ts +26 -26
- package/dist/types/taskset-run-contract.d.ts.map +1 -1
- package/dist/types/tasksets.d.ts +73 -69
- package/dist/types/tasksets.d.ts.map +1 -1
- package/dist/types/telemetry/index.d.ts.map +1 -1
- package/dist/types/telemetry-analysis.d.ts +6 -6
- package/dist/types/telemetry-analysis.d.ts.map +1 -1
- package/dist/types/telemetry-bundle.d.ts +42 -42
- package/dist/types/telemetry-bundle.d.ts.map +1 -1
- package/dist/types/telemetry-catalog.d.ts +67 -67
- package/dist/types/telemetry-catalog.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +44 -44
- package/dist/types/telemetry.d.ts.map +1 -1
- package/package.json +1 -1
- package/schemas/learning/v1/command-request.schema.json +44 -0
- package/schemas/learning/v1/definition.schema.json +4 -0
- package/schemas/learning/v1/evidence.schema.json +4 -0
- package/schemas/learning/v1/example-submission.schema.json +4 -0
- package/schemas/learning/v1/package.schema.json +4 -0
- package/schemas/learning/v1/policy.schema.json +40 -0
|
@@ -143,6 +143,8 @@ function structuralFailures(required, entry) {
|
|
|
143
143
|
}
|
|
144
144
|
if (entry.parseStatus === "failed")
|
|
145
145
|
failures.push(`Required output ${required.path} could not be parsed.`);
|
|
146
|
+
if (required.submissionMode === "structured_json" && (entry.schemaStatus !== "passed" || entry.parseStatus !== "passed" || entry.metadata.structuredSchemaHash !== required.schemaRef?.contentHash || entry.metadata.structuredArtifactHash !== entry.artifact?.contentHash))
|
|
147
|
+
failures.push(`Required output ${required.path} lacks bound structured validation evidence.`);
|
|
146
148
|
if (entry.schemaStatus === "failed")
|
|
147
149
|
failures.push(`Required output ${required.path} failed schema validation.`);
|
|
148
150
|
return failures;
|
|
@@ -48,5 +48,38 @@ export function claudeGraph(rows) {
|
|
|
48
48
|
return { leafId: leaf.uuid, chainHash: selected.chainHash, title: title.slice(0, 180), updatedAt: connectedTimestamp(last?.timestamp), messages: messages.length };
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
function latestLeafId() {
|
|
52
|
+
// Match Claude's session browser: walk terminal bookkeeping back to a
|
|
53
|
+
// message, then prefer the last main-chain message in file order. Wall
|
|
54
|
+
// clock timestamps and later sidechain/meta records do not choose the chat.
|
|
55
|
+
const candidates = new Set();
|
|
56
|
+
for (const leaf of leaves) {
|
|
57
|
+
let current = leaf;
|
|
58
|
+
const seen = new Set();
|
|
59
|
+
while (current) {
|
|
60
|
+
const id = current.uuid;
|
|
61
|
+
if (seen.has(id))
|
|
62
|
+
throw new Error("Claude Code branch contains a parent cycle.");
|
|
63
|
+
seen.add(id);
|
|
64
|
+
if (current.type === "user" || current.type === "assistant") {
|
|
65
|
+
candidates.add(id);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
current = typeof current.parentUuid === "string" ? byId.get(current.parentUuid) : undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
let latest, fallback;
|
|
72
|
+
for (const row of nodes) {
|
|
73
|
+
const id = row.uuid;
|
|
74
|
+
if (!candidates.has(id))
|
|
75
|
+
continue;
|
|
76
|
+
fallback = id;
|
|
77
|
+
if (!row.isSidechain && !row.teamName && !row.isMeta)
|
|
78
|
+
latest = id;
|
|
79
|
+
}
|
|
80
|
+
if (!latest && !fallback)
|
|
81
|
+
throw new Error("Claude Code transcript has no conversation message.");
|
|
82
|
+
return (latest ?? fallback);
|
|
83
|
+
}
|
|
84
|
+
return { sessionId, leaves, select, branches, latestLeafId };
|
|
52
85
|
}
|
|
@@ -30,7 +30,7 @@ export function parseClaudeSession(file, rows, leafId) {
|
|
|
30
30
|
if (block.type === "tool_use")
|
|
31
31
|
events.push(event({ ...base, id, kind: "tool_call", callId: typeof block.id === "string" ? block.id : null, content: json(block) }));
|
|
32
32
|
else if (block.type === "tool_result")
|
|
33
|
-
events.push(event({ ...base, id, kind: "tool_result", role: "tool", callId: typeof block.tool_use_id === "string" ? block.tool_use_id : null, content: json(block) }));
|
|
33
|
+
events.push(event({ ...base, id, kind: "tool_result", role: "tool", callId: typeof block.tool_use_id === "string" ? block.tool_use_id : null, content: json({ ...block, ...(row.tool_use_result !== undefined ? { nativeToolResult: row.tool_use_result } : {}) }) }));
|
|
34
34
|
else
|
|
35
35
|
events.push(event({ ...base, id, kind: "unknown", content: json(block) }));
|
|
36
36
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ReleaseHashSchema, ReleaseIdSchema } from "@openpond/harness";
|
|
3
|
+
/** A deliberate future-stage choice, independent of the original pinned
|
|
4
|
+
* optimizer/data configuration. Its Model source reference remains truthful;
|
|
5
|
+
* already reserved iterations retain their earlier immutable policy revision. */
|
|
6
|
+
export const LearningContinuationModeOverrideSchema = z.object({
|
|
7
|
+
adapterMode: z.enum(["residual_append", "shared", "sequential_merge"]),
|
|
8
|
+
sourceConfiguration: z.object({ id: ReleaseIdSchema, revision: z.number().int().positive(), etag: ReleaseHashSchema }).strict(),
|
|
9
|
+
}).strict();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LearningContinuationModeOverrideSchema } from "./continuation-mode.js";
|
|
1
2
|
import { TrainingHandoffOriginSchema } from "./training-handoff.js";
|
|
2
3
|
import { LearningDomainError } from "./errors.js";
|
|
3
4
|
import { z } from "zod";
|
|
@@ -421,6 +422,7 @@ export const LearningPolicyContentSchema = z
|
|
|
421
422
|
recipe: ImmutableReleaseRefSchema,
|
|
422
423
|
retentionEvaluation: ImmutableReleaseRefSchema,
|
|
423
424
|
replayBatches: z.array(ImmutableReleaseRefSchema).max(100),
|
|
425
|
+
continuationMode: LearningContinuationModeOverrideSchema.optional(),
|
|
424
426
|
})
|
|
425
427
|
.strict(),
|
|
426
428
|
limits: z
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ReleaseIdSchema, ReleaseHashSchema, ReleaseTimestampSchema, ImmutableReleaseRefSchema } from "@openpond/harness";
|
|
3
|
+
import { LearningRevisionRefSchema } from "./contracts.js";
|
|
4
|
+
/** Reviewed behavior identity and verifier membership are frozen before either
|
|
5
|
+
* declared evaluation starts. A failed unrelated grader is never a repeat. */
|
|
6
|
+
export const CorrectionVerificationCheckSchema = z.object({
|
|
7
|
+
id: ReleaseIdSchema,
|
|
8
|
+
role: z.enum(["replay", "transfer"]),
|
|
9
|
+
taskId: ReleaseIdSchema,
|
|
10
|
+
seeds: z.array(z.string().min(1).max(500)).min(1).max(100),
|
|
11
|
+
grader: z.object({ id: ReleaseIdSchema, revision: z.string().min(1).max(200), contentHash: ReleaseHashSchema, reward: LearningRevisionRefSchema.nullable().default(null) }).strict(),
|
|
12
|
+
failureMeaning: z.literal("corrected_mistake_repeated"),
|
|
13
|
+
}).strict();
|
|
14
|
+
export const CorrectionVerificationPlanContentSchema = z.object({
|
|
15
|
+
schemaVersion: z.literal("openpond.correctionVerificationPlan.v1"),
|
|
16
|
+
id: ReleaseIdSchema, revision: z.literal(1), teamId: ReleaseIdSchema, ownerUserId: ReleaseIdSchema, modelId: ReleaseIdSchema,
|
|
17
|
+
classification: z.literal("reviewed_model_behavior"),
|
|
18
|
+
feedback: LearningRevisionRefSchema, evidence: LearningRevisionRefSchema,
|
|
19
|
+
trainingJobId: ReleaseIdSchema, checkpoint: ImmutableReleaseRefSchema, artifact: ImmutableReleaseRefSchema,
|
|
20
|
+
taskset: LearningRevisionRefSchema,
|
|
21
|
+
checks: z.array(CorrectionVerificationCheckSchema).min(1).max(1000),
|
|
22
|
+
baselineOperationId: ReleaseIdSchema, candidateOperationId: ReleaseIdSchema,
|
|
23
|
+
criterion: z.literal("all_declared_checks_pass_after_failed_parent"),
|
|
24
|
+
receivedAt: ReleaseTimestampSchema, eligibleAt: ReleaseTimestampSchema, frozenAt: ReleaseTimestampSchema,
|
|
25
|
+
}).strict().superRefine((plan, context) => {
|
|
26
|
+
if (plan.baselineOperationId === plan.candidateOperationId)
|
|
27
|
+
context.addIssue({ code: "custom", path: ["candidateOperationId"], message: "Parent and candidate must have distinct evaluation operations." });
|
|
28
|
+
if (new Set(plan.checks.map(check => check.id)).size !== plan.checks.length)
|
|
29
|
+
context.addIssue({ code: "custom", path: ["checks"], message: "Correction check identities must be unique." });
|
|
30
|
+
for (const [index, check] of plan.checks.entries())
|
|
31
|
+
if (new Set(check.seeds).size !== check.seeds.length)
|
|
32
|
+
context.addIssue({ code: "custom", path: ["checks", index, "seeds"], message: "Seeds must be unique per correction check." });
|
|
33
|
+
});
|
|
34
|
+
export const CorrectionVerificationPlanSchema = CorrectionVerificationPlanContentSchema.safeExtend({ contentHash: ReleaseHashSchema });
|
|
35
|
+
export const CorrectionOpportunitySchema = z.object({
|
|
36
|
+
schemaVersion: z.literal("openpond.correctionOpportunity.v1"),
|
|
37
|
+
id: ReleaseIdSchema, correction: ImmutableReleaseRefSchema, source: z.enum(["evaluation", "live"]),
|
|
38
|
+
modelId: ReleaseIdSchema, trainingJobId: ReleaseIdSchema, artifactId: ReleaseIdSchema, checkpointId: ReleaseIdSchema,
|
|
39
|
+
observedAt: ReleaseTimestampSchema, occurredAt: ReleaseTimestampSchema,
|
|
40
|
+
attempt: ImmutableReleaseRefSchema,
|
|
41
|
+
classification: z.enum(["confirmed_repeat", "passed", "unscored"]),
|
|
42
|
+
checkIds: z.array(ReleaseIdSchema).min(1).max(1000),
|
|
43
|
+
}).strict();
|
|
44
|
+
export const CorrectionMetricObservationSchema = z.object({
|
|
45
|
+
schemaVersion: z.literal("openpond.correctionMetricObservation.v1"),
|
|
46
|
+
correction: ImmutableReleaseRefSchema, modelId: ReleaseIdSchema, trainingJobId: ReleaseIdSchema,
|
|
47
|
+
checkpointId: ReleaseIdSchema, artifactId: ReleaseIdSchema, receivedAt: ReleaseTimestampSchema, eligibleAt: ReleaseTimestampSchema,
|
|
48
|
+
firstBatchConsumptionAt: ReleaseTimestampSchema.nullable(), firstTrainingUseAt: ReleaseTimestampSchema.nullable(),
|
|
49
|
+
verifiedAt: ReleaseTimestampSchema.nullable(), servedAt: ReleaseTimestampSchema.nullable(),
|
|
50
|
+
baselineEvaluation: ImmutableReleaseRefSchema.nullable(), candidateEvaluation: ImmutableReleaseRefSchema.nullable(),
|
|
51
|
+
status: z.enum(["pending_exposure", "pending_verification", "baseline_not_failed", "verified", "regressed", "withdrawn"]),
|
|
52
|
+
opportunities: z.array(CorrectionOpportunitySchema).max(100_000), blockers: z.array(z.string().max(500)).max(20).default([]), observedAt: ReleaseTimestampSchema,
|
|
53
|
+
}).strict();
|
|
54
|
+
const repeat = z.object({ confirmedRepeats: z.number().int().nonnegative(), scoredRelevantOpportunities: z.number().int().nonnegative(), unscoredOpportunities: z.number().int().nonnegative(), rate: z.number().min(0).max(1).nullable() }).strict();
|
|
55
|
+
export const CorrectionMetricSummarySchema = z.object({
|
|
56
|
+
schemaVersion: z.literal("openpond.correctionMetricSummary.v1"), observedAt: ReleaseTimestampSchema,
|
|
57
|
+
scope: z.object({ teamId: ReleaseIdSchema, modelId: ReleaseIdSchema, runId: ReleaseIdSchema.nullable(), checkpointId: ReleaseIdSchema.nullable(), artifactId: ReleaseIdSchema.nullable() }).strict(),
|
|
58
|
+
window: z.object({ from: ReleaseTimestampSchema, to: ReleaseTimestampSchema }).strict(), correctionCount: z.number().int().nonnegative(),
|
|
59
|
+
adaptation: z.object({ medianSeconds: z.number().nonnegative().nullable(), resolvedCount: z.number().int().nonnegative(), pendingCount: z.number().int().nonnegative(), oldestPendingSeconds: z.number().nonnegative().nullable() }).strict(),
|
|
60
|
+
evaluation: repeat.safeExtend({ source: z.literal("evaluation") }), live: repeat.safeExtend({ source: z.literal("live") }),
|
|
61
|
+
}).strict();
|
package/dist/learning/index.js
CHANGED
|
@@ -36,3 +36,5 @@ export * from "./task-queue-inspection.js";
|
|
|
36
36
|
export * from "./acceptance-plan.js";
|
|
37
37
|
export * from "./acceptance-group.js";
|
|
38
38
|
export { TrainingHandoffOriginSchema } from "./training-handoff.js";
|
|
39
|
+
export * from "./correction-metrics.js";
|
|
40
|
+
export * from "./continuation-mode.js";
|
|
@@ -7,6 +7,7 @@ import { CollectorQueueFullError } from "./collector-snapshots.js";
|
|
|
7
7
|
import { COLLECTOR_DEFAULTS } from "./collector-contracts.js";
|
|
8
8
|
import { CollectorCoverage } from "./collector-coverage.js";
|
|
9
9
|
import { CollectorSourceCache } from "./collector-source-cache.js";
|
|
10
|
+
import { nativeSessionSelectionKey } from "./selection.js";
|
|
10
11
|
/** One pass over a frozen listing per page. Unchanged revisions are cheap; a
|
|
11
12
|
* failed source is tried again only in a later explicitly launched job. */
|
|
12
13
|
export async function acquireCollectorSource(input) {
|
|
@@ -14,23 +15,30 @@ export async function acquireCollectorSource(input) {
|
|
|
14
15
|
const cache = new CollectorSourceCache(store);
|
|
15
16
|
let cursor, processed = 0, discovered = 0;
|
|
16
17
|
const failures = [];
|
|
18
|
+
const selection = connection.selectedSessionKeys ? new Set(connection.selectedSessionKeys) : null;
|
|
19
|
+
const found = new Set();
|
|
20
|
+
let enumerated = 0;
|
|
17
21
|
do {
|
|
18
22
|
await check();
|
|
19
23
|
progress({ phase: "discovering" });
|
|
20
24
|
// File mtimes and native activity summaries are not event-time authority.
|
|
21
25
|
// Enumerate the source, then apply the consented window to native events.
|
|
22
26
|
const page = await listSessions(connection.source, { cursor, limit: 50 });
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
throw new Error("Source inventory exceeds 10,000 sessions. Select a narrower
|
|
26
|
-
|
|
27
|
+
enumerated += page.items.length;
|
|
28
|
+
if (enumerated > 10_000)
|
|
29
|
+
throw new Error("Source inventory exceeds 10,000 sessions. Select a narrower source directory.");
|
|
30
|
+
const items = page.items.filter(native => !selection || selection.has(nativeSessionSelectionKey(native)));
|
|
31
|
+
for (const native of items)
|
|
32
|
+
found.add(nativeSessionSelectionKey(native));
|
|
33
|
+
discovered += items.length;
|
|
34
|
+
for (const native of items) {
|
|
27
35
|
const scanKey = JSON.stringify([native.path, native.nativeSessionId]);
|
|
28
36
|
store.coverage.record(connection.id, { sourceKeyHash: CollectorCoverage.sourceKey(scanKey),
|
|
29
37
|
nativeRevisionHash: native.storageRevision ? contentHash([native.storageRevision, agentImportNormalizerRevision(connection.source.source)]) : null,
|
|
30
38
|
state: "reading", reason: null, unknownTimeBoundaries: 0, normalized: [] });
|
|
31
39
|
}
|
|
32
40
|
progress({ discovered });
|
|
33
|
-
for (const native of
|
|
41
|
+
for (const native of items) {
|
|
34
42
|
await check();
|
|
35
43
|
// Do not parse another transcript while any retained admission is blocked.
|
|
36
44
|
await drain();
|
|
@@ -139,7 +147,10 @@ export async function acquireCollectorSource(input) {
|
|
|
139
147
|
cursor = page.nextCursor ?? undefined;
|
|
140
148
|
} while (cursor);
|
|
141
149
|
store.progress.discovered(connection.id);
|
|
142
|
-
|
|
150
|
+
// A chosen subset cannot certify coverage of the entire source window.
|
|
151
|
+
store.coverage.finish(connection.id, selection === null);
|
|
152
|
+
if (selection && [...selection].some(key => !found.has(key)))
|
|
153
|
+
throw new Error("A selected conversation is no longer available. Review the upload selection.");
|
|
143
154
|
if (failures.length)
|
|
144
155
|
throw new Error(`${failures.length} session(s) need attention. ${failures[0]}`);
|
|
145
156
|
}
|
|
@@ -12,7 +12,7 @@ export class CollectorSourceCache {
|
|
|
12
12
|
}
|
|
13
13
|
selection(connection, until, revision) {
|
|
14
14
|
return contentHash([connection.source, connection.projectId, connection.teamId,
|
|
15
|
-
connection.apiBaseUrl, connection.account ?? null, connection.since, until, revision]);
|
|
15
|
+
connection.apiBaseUrl, connection.account ?? null, connection.since, connection.selectedSessionKeys ?? null, until, revision]);
|
|
16
16
|
}
|
|
17
17
|
read(connection, until, sessionKey, revision) {
|
|
18
18
|
const row = this.store.database.prepare("SELECT value FROM source_read_cache WHERE connection_id=? AND session_key=? AND selection_hash=?").get(connection.id, sessionKey, this.selection(connection, until, revision));
|
|
@@ -61,6 +61,20 @@ export class CollectorStore {
|
|
|
61
61
|
this.database.exec("COMMIT");
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
|
+
if (prior && JSON.stringify(prior.selectedSessionKeys) !== JSON.stringify(connection.selectedSessionKeys)) {
|
|
65
|
+
const owner = JSON.parse(this.setting("owner") || "{}");
|
|
66
|
+
if (owner.pid) {
|
|
67
|
+
let alive = true;
|
|
68
|
+
try {
|
|
69
|
+
process.kill(owner.pid, 0);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
alive = error.code !== "ESRCH";
|
|
73
|
+
}
|
|
74
|
+
if (alive)
|
|
75
|
+
throw new Error("Cancel or finish the running import before changing its conversation selection.");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
64
78
|
const identityChanged = !!prior &&
|
|
65
79
|
(prior.source.instanceId !== connection.source.instanceId ||
|
|
66
80
|
prior.projectId !== connection.projectId ||
|
|
@@ -69,7 +83,8 @@ export class CollectorStore {
|
|
|
69
83
|
prior.account !== connection.account);
|
|
70
84
|
if (identityChanged)
|
|
71
85
|
connection = { ...connection, destinations: undefined };
|
|
72
|
-
if (prior && (identityChanged || prior.since !== connection.since
|
|
86
|
+
if (prior && (identityChanged || prior.since !== connection.since ||
|
|
87
|
+
JSON.stringify(prior.selectedSessionKeys) !== JSON.stringify(connection.selectedSessionKeys))) {
|
|
73
88
|
this.database.prepare("DELETE FROM settings WHERE key=?").run(`coverage:${connection.id}`);
|
|
74
89
|
this.database.prepare("DELETE FROM coverage_sessions WHERE connection_id=?").run(connection.id);
|
|
75
90
|
// Scope changes fence queued evidence too: do not upload a wider old
|
|
@@ -81,7 +96,16 @@ export class CollectorStore {
|
|
|
81
96
|
this.database.prepare("DELETE FROM settings WHERE key=?").run(`syncAcknowledged:${connection.id}`);
|
|
82
97
|
connection = { ...connection, completedSyncRevision: 0 };
|
|
83
98
|
this.error(connection.id, null);
|
|
84
|
-
|
|
99
|
+
if (!identityChanged && prior.since === connection.since) {
|
|
100
|
+
// Preserve acknowledged boundaries when adding conversations, but
|
|
101
|
+
// reacquire every queued boundary whose snapshot is being discarded.
|
|
102
|
+
this.database.prepare(`DELETE FROM checkpoints WHERE connection_id=? AND EXISTS (
|
|
103
|
+
SELECT 1 FROM pending p, json_each(p.payload,'$.boundaryIds') b
|
|
104
|
+
WHERE p.connection_id=checkpoints.connection_id
|
|
105
|
+
AND json_extract(p.payload,'$.sessionKey')=checkpoints.session_key
|
|
106
|
+
AND b.value=checkpoints.boundary_id)`).run(connection.id);
|
|
107
|
+
}
|
|
108
|
+
for (const table of identityChanged || prior.since !== connection.since ? ["source_scans", "checkpoints", "pending"] : ["source_scans", "pending"])
|
|
85
109
|
this.database
|
|
86
110
|
.prepare(`DELETE FROM ${table} WHERE connection_id=?`)
|
|
87
111
|
.run(connection.id);
|
|
@@ -270,6 +294,7 @@ export class CollectorStore {
|
|
|
270
294
|
.get(String(row.id))?.bytes ?? 0),
|
|
271
295
|
lastAdmissionAt: this.setting(`lastAdmission:${row.id}`),
|
|
272
296
|
since: config.since,
|
|
297
|
+
selectedConversations: config.selectedSessionKeys?.length ?? null,
|
|
273
298
|
schedule,
|
|
274
299
|
nextRunAt: schedule && config.state === "active" ? nextScheduledSync(schedule) : null,
|
|
275
300
|
lastSuccessfulSyncAt: this.setting(`lastSuccess:${row.id}`),
|
|
@@ -36,7 +36,7 @@ export async function runCollector(input) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
const now = new Date();
|
|
39
|
-
selected = store.connections().filter(connection => connection.state !== "disconnected" &&
|
|
39
|
+
selected = store.connections().filter(connection => connection.state !== "disconnected" && connection.selectedSessionKeys?.length !== 0 &&
|
|
40
40
|
(!input.connectionIds || input.connectionIds.includes(connection.id)) &&
|
|
41
41
|
(input.trigger !== "scheduled" || (connection.state === "active" && scheduledSyncDue(store.schedule(connection.id), store.setting(`scheduledMinute:${connection.id}`), now))));
|
|
42
42
|
if (input.trigger === "scheduled")
|
|
@@ -173,13 +173,14 @@ export async function runCollector(input) {
|
|
|
173
173
|
for (let pass = 0; pass < 3; pass++) {
|
|
174
174
|
await check();
|
|
175
175
|
const revision = connection.revision, requested = connection.requestedSyncRevision ?? 0;
|
|
176
|
+
const selection = JSON.stringify(connection.selectedSessionKeys);
|
|
176
177
|
phase = "source";
|
|
177
178
|
new CollectorSourceCache(store).seed(connection, until, store.coverage.manifest(connection.id));
|
|
178
179
|
store.coverage.begin(connection, `${nonce}-${pass}`, run.startedAt, until);
|
|
179
180
|
const checkAcquisition = async () => {
|
|
180
181
|
await check();
|
|
181
182
|
phase = "source";
|
|
182
|
-
if (connection.revision !== revision)
|
|
183
|
+
if (connection.revision !== revision || JSON.stringify(connection.selectedSessionKeys) !== selection)
|
|
183
184
|
throw new CollectorScopeChangedError("Source settings changed during acquisition.");
|
|
184
185
|
};
|
|
185
186
|
try {
|
|
@@ -193,7 +194,7 @@ export async function runCollector(input) {
|
|
|
193
194
|
}
|
|
194
195
|
errors.set(connection.id, "source", null);
|
|
195
196
|
await drain();
|
|
196
|
-
await input.transport.publishCoverage(connection, store.coverage.finish(connection.id,
|
|
197
|
+
await input.transport.publishCoverage(connection, store.coverage.finish(connection.id, connection.selectedSessionKeys === undefined), signal);
|
|
197
198
|
connection = retained(connection);
|
|
198
199
|
if (connection.revision !== revision) {
|
|
199
200
|
if (pass === 2)
|
|
@@ -114,6 +114,8 @@ export async function listSessions(source, input = {}) {
|
|
|
114
114
|
return listDatabaseSessions(source, { ...input, limit });
|
|
115
115
|
const paths = await pathsBelow(source), candidates = [];
|
|
116
116
|
for (const path of paths) {
|
|
117
|
+
if (input.parentNativeSessionId && source.source === "claude_code" && !path.replaceAll("\\", "/").includes(`/${input.parentNativeSessionId}/subagents/`))
|
|
118
|
+
continue;
|
|
117
119
|
if (input.cursor && path <= input.cursor)
|
|
118
120
|
continue;
|
|
119
121
|
try {
|
|
@@ -193,12 +195,14 @@ export async function listSessions(source, input = {}) {
|
|
|
193
195
|
// Claude writes queue/history bookkeeping before its first message. The
|
|
194
196
|
// native session's message metadata owns cwd; encoded project-directory
|
|
195
197
|
// names are ambiguous and must never be decoded into a guessed path.
|
|
198
|
+
const claudeWorker = source.source === "claude_code" && /(?:^|[\/])subagents[\/]agent-[^\/]+\.jsonl$/u.test(path)
|
|
199
|
+
? rows.find(row => row.isSidechain === true && typeof row.agentId === "string" && `agent-${row.agentId}` === id && typeof row.sessionId === "string" && basename(dirname(dirname(path))) === row.sessionId) : undefined;
|
|
196
200
|
const claudeMessage = source.source === "claude_code"
|
|
197
|
-
? rows.find((row) => row.sessionId === id && row.type === "user" && typeof row.cwd === "string" && isAbsolute(row.cwd))
|
|
201
|
+
? rows.find((row) => row.sessionId === (claudeWorker?.sessionId ?? id) && row.type === "user" && typeof row.cwd === "string" && isAbsolute(row.cwd))
|
|
198
202
|
: undefined;
|
|
199
203
|
let cwd = claudeMessage?.cwd ?? payload.cwd;
|
|
200
204
|
let title = source.source === "claude_code"
|
|
201
|
-
? claudeConversationTitle(rows, id)
|
|
205
|
+
? claudeConversationTitle(rows, claudeWorker ? String(claudeWorker.sessionId) : id, Boolean(claudeWorker))
|
|
202
206
|
: retainedConversationTitle(payload.title, id);
|
|
203
207
|
if (source.source === "grok_build" && path.endsWith("updates.jsonl")) {
|
|
204
208
|
try {
|
|
@@ -214,6 +218,7 @@ export async function listSessions(source, input = {}) {
|
|
|
214
218
|
}
|
|
215
219
|
candidates.push({
|
|
216
220
|
nativeSessionId: id,
|
|
221
|
+
...(claudeWorker ? { parentNativeSessionId: String(claudeWorker.sessionId) } : {}),
|
|
217
222
|
sourceInstanceId: source.instanceId,
|
|
218
223
|
path,
|
|
219
224
|
title,
|
|
@@ -251,6 +256,18 @@ export async function listSessions(source, input = {}) {
|
|
|
251
256
|
nextCursor: candidates.length > limit ? candidates[limit - 1].path : null,
|
|
252
257
|
};
|
|
253
258
|
}
|
|
259
|
+
/** Revalidate worker identity after acquisition; parent sessionId is shared by siblings. */
|
|
260
|
+
function assertClaudeIdentity(session, rows) {
|
|
261
|
+
const graph = claudeGraph(rows);
|
|
262
|
+
if (graph.sessionId !== (session.parentNativeSessionId ?? session.nativeSessionId))
|
|
263
|
+
throw new Error("Native session changed identity.");
|
|
264
|
+
if (session.parentNativeSessionId) {
|
|
265
|
+
const messages = rows.filter(row => row.type === "user" || row.type === "assistant");
|
|
266
|
+
if (messages.some(row => row.isSidechain !== true || `agent-${String(row.agentId)}` !== session.nativeSessionId))
|
|
267
|
+
throw new Error("Native worker changed identity.");
|
|
268
|
+
}
|
|
269
|
+
return graph;
|
|
270
|
+
}
|
|
254
271
|
export async function inspectSessionBranches(source, session) {
|
|
255
272
|
if (source.source !== "claude_code")
|
|
256
273
|
return { revision: "", branches: [] };
|
|
@@ -259,9 +276,7 @@ export async function inspectSessionBranches(source, session) {
|
|
|
259
276
|
if (session.sourceInstanceId !== source.instanceId)
|
|
260
277
|
throw new Error("Native session belongs to another selected source.");
|
|
261
278
|
const text = await readSelectedFile(source, session.path);
|
|
262
|
-
const graph =
|
|
263
|
-
if (graph.sessionId !== session.nativeSessionId)
|
|
264
|
-
throw new Error("Native session changed identity.");
|
|
279
|
+
const graph = assertClaudeIdentity(session, connectedJsonLines({ path: basename(session.path), text }));
|
|
265
280
|
return { revision: contentHash(text), branches: graph.branches() };
|
|
266
281
|
}
|
|
267
282
|
export async function readSession(source, session, input = {}) {
|
|
@@ -290,9 +305,14 @@ export async function readSession(source, session, input = {}) {
|
|
|
290
305
|
throw new Error("Choose a branch before supplying its revision.");
|
|
291
306
|
if (source.source === "claude_code") {
|
|
292
307
|
const file = files[0];
|
|
293
|
-
const graph =
|
|
294
|
-
if (
|
|
295
|
-
|
|
308
|
+
const graph = assertClaudeIdentity(session, connectedJsonLines(file));
|
|
309
|
+
if (input.latestBranch) {
|
|
310
|
+
if (input.branchLeafId || input.expectedBranchRevision || input.branchAnchor)
|
|
311
|
+
throw new Error("Choose either the latest conversation or an explicit branch.");
|
|
312
|
+
// Desktop inspection follows the native conversation. Imports keep their
|
|
313
|
+
// existing explicit branch authority and never enable this option.
|
|
314
|
+
files = [{ ...file, text: graph.select(graph.latestLeafId()).chain.map(row => JSON.stringify(row)).join("\n") + "\n" }];
|
|
315
|
+
}
|
|
296
316
|
if (input.branchAnchor) {
|
|
297
317
|
if (input.branchLeafId || input.expectedBranchRevision)
|
|
298
318
|
throw new Error("Choose either a frozen branch snapshot or a followed branch anchor.");
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { contentHash } from "@openpond/harness";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { listSessions } from "./history.js";
|
|
4
|
+
export const NativeUploadSelectionSchema = z.object({
|
|
5
|
+
sourceInstanceId: z.string().min(1).max(500),
|
|
6
|
+
sessionKeys: z.array(z.string().regex(/^[a-f0-9]{64}$/)).min(1).max(10_000),
|
|
7
|
+
}).strict().refine(value => new Set(value.sessionKeys).size === value.sessionKeys.length, "Conversation selection contains duplicates.");
|
|
8
|
+
/** Includes the source path so duplicate native IDs cannot select a sibling file. */
|
|
9
|
+
export function nativeSessionSelectionKey(session) {
|
|
10
|
+
return contentHash(JSON.stringify([session.path, session.nativeSessionId]));
|
|
11
|
+
}
|
|
12
|
+
export async function nativeUploadInventory(source) {
|
|
13
|
+
if (!source.available || !source.capabilities.history)
|
|
14
|
+
throw new Error("The selected conversation source is unavailable.");
|
|
15
|
+
const items = [];
|
|
16
|
+
let cursor;
|
|
17
|
+
const seen = new Set();
|
|
18
|
+
do {
|
|
19
|
+
const page = await listSessions(source, { cursor, limit: 100 });
|
|
20
|
+
items.push(...page.items);
|
|
21
|
+
if (items.length > 10_000)
|
|
22
|
+
throw new Error("Choose a source with no more than 10,000 conversations.");
|
|
23
|
+
cursor = page.nextCursor ?? undefined;
|
|
24
|
+
if (cursor && seen.has(cursor))
|
|
25
|
+
throw new Error("Conversation listing did not advance. Refresh the source.");
|
|
26
|
+
if (cursor)
|
|
27
|
+
seen.add(cursor);
|
|
28
|
+
} while (cursor);
|
|
29
|
+
return items;
|
|
30
|
+
}
|
|
31
|
+
export async function validateNativeUploadSelection(source, raw) {
|
|
32
|
+
const selection = NativeUploadSelectionSchema.parse(raw);
|
|
33
|
+
if (selection.sourceInstanceId !== source.instanceId)
|
|
34
|
+
throw new Error("Conversation selection belongs to another source installation.");
|
|
35
|
+
const available = new Set((await nativeUploadInventory(source)).map(nativeSessionSelectionKey));
|
|
36
|
+
if (selection.sessionKeys.some(key => !available.has(key)))
|
|
37
|
+
throw new Error("A selected conversation is no longer available. Refresh and select it again.");
|
|
38
|
+
return selection;
|
|
39
|
+
}
|
|
40
|
+
export function nativeUploadConversationPage(connection, inventory, input) {
|
|
41
|
+
const query = (input.query ?? "").trim().toLocaleLowerCase(), range = input.range ?? "all", offset = input.offset ?? 0;
|
|
42
|
+
if (query.length > 500 || !["day", "week", "all"].includes(range) || !Number.isInteger(offset) || offset < 0 || offset > 10_000)
|
|
43
|
+
throw new Error("Invalid conversation search or page.");
|
|
44
|
+
const since = range === "all" ? 0 : Date.now() - (range === "day" ? 1 : 7) * 86400000;
|
|
45
|
+
const items = inventory.filter(item => Date.parse(item.updatedAt) >= since &&
|
|
46
|
+
(!query || [item.title, item.cwd, item.nativeSessionId].some(text => text?.toLocaleLowerCase().includes(query))))
|
|
47
|
+
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
48
|
+
const approved = connection.selectedSessionKeys ? new Set(connection.selectedSessionKeys) : null;
|
|
49
|
+
return {
|
|
50
|
+
total: items.length, nextOffset: offset + 50 < items.length ? offset + 50 : null,
|
|
51
|
+
items: items.slice(offset, offset + 50).map(item => ({
|
|
52
|
+
key: nativeSessionSelectionKey(item), title: item.title, cwd: item.cwd,
|
|
53
|
+
nativeSessionId: item.nativeSessionId, updatedAt: item.updatedAt, issue: item.issue ?? null,
|
|
54
|
+
approved: approved === null || approved.has(nativeSessionSelectionKey(item)),
|
|
55
|
+
})),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -164,6 +164,8 @@ export async function setCollectorSchedule(input, connectionId, schedule) {
|
|
|
164
164
|
const connection = store.connections().find(item => item.id === connectionId);
|
|
165
165
|
if (!connection || (schedule && connection.state === "disconnected"))
|
|
166
166
|
throw new Error("Select a connected source before scheduling imports.");
|
|
167
|
+
if (schedule && connection.selectedSessionKeys?.length === 0)
|
|
168
|
+
throw new Error("Choose conversations to upload before enabling continual imports.");
|
|
167
169
|
const owner = store.setting("scheduleOwner");
|
|
168
170
|
if (owner) {
|
|
169
171
|
const { pid } = JSON.parse(owner);
|
|
@@ -5,7 +5,7 @@ function titleText(value) {
|
|
|
5
5
|
return value.replace(/\s+/gu, " ").trim().slice(0, 160) || null;
|
|
6
6
|
}
|
|
7
7
|
/** Retained provider titles take precedence over a preview of the first real user prompt. */
|
|
8
|
-
export function claudeConversationTitle(rows, sessionId) {
|
|
8
|
+
export function claudeConversationTitle(rows, sessionId, allowSidechain = false) {
|
|
9
9
|
const owned = rows.filter((row) => row.sessionId === undefined || row.sessionId === sessionId);
|
|
10
10
|
for (const row of [...owned].reverse()) {
|
|
11
11
|
if (row.type === "custom-title") {
|
|
@@ -22,7 +22,7 @@ export function claudeConversationTitle(rows, sessionId) {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
for (const row of owned) {
|
|
25
|
-
if (row.type !== "user" || row.sessionId !== sessionId || row.isMeta || row.isSidechain)
|
|
25
|
+
if (row.type !== "user" || row.sessionId !== sessionId || row.isMeta || (row.isSidechain && !allowSidechain))
|
|
26
26
|
continue;
|
|
27
27
|
const content = object(row.message).content;
|
|
28
28
|
const title = titleText(Array.isArray(content)
|
package/dist/tasksets.js
CHANGED
|
@@ -7,6 +7,7 @@ export const RequiredOutputContractSchema = z.object({
|
|
|
7
7
|
path: z.string().trim().min(1).max(2_000).refine(safeRelativePath),
|
|
8
8
|
mediaType: z.string().trim().min(1).max(200),
|
|
9
9
|
schemaRef: ImmutableAssetRefSchema.nullable().default(null),
|
|
10
|
+
submissionMode: z.literal("structured_json").optional(),
|
|
10
11
|
maxBytes: z.number().int().positive().max(250_000_000).nullable().default(null),
|
|
11
12
|
metadata: MetadataSchema,
|
|
12
13
|
}).strict();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-verification.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"artifact-verification.d.ts","sourceRoot":"","sources":["../../src/artifact-verification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAGL,KAAK,gBAAgB,EAGrB,KAAK,sBAAsB,EAC5B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,WAAW,CAAC,EAAE,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GAAG,gBAAgB,CAwEnB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,GAAG,sBAAsB,EAAE,CAqC3B"}
|
|
@@ -2,10 +2,10 @@ import { z } from "zod";
|
|
|
2
2
|
import { type AttemptReceipt, type EvaluationResult } from "./runs.js";
|
|
3
3
|
export { harnessRefinerBenchmarkAssets, harnessRefinerBenchmarkRelease, } from "./builtin-benchmarks/harness-refiner.js";
|
|
4
4
|
export declare const BenchmarkMetricSchema: z.ZodEnum<{
|
|
5
|
+
cost_usd: "cost_usd";
|
|
5
6
|
foreground_tokens: "foreground_tokens";
|
|
6
|
-
success_rate: "success_rate";
|
|
7
7
|
latency_ms: "latency_ms";
|
|
8
|
-
|
|
8
|
+
success_rate: "success_rate";
|
|
9
9
|
}>;
|
|
10
10
|
export declare const BenchmarkRunPhaseSchema: z.ZodEnum<{
|
|
11
11
|
baseline: "baseline";
|
|
@@ -13,10 +13,10 @@ export declare const BenchmarkRunPhaseSchema: z.ZodEnum<{
|
|
|
13
13
|
}>;
|
|
14
14
|
export declare const BenchmarkProtocolSchema: z.ZodObject<{
|
|
15
15
|
split: z.ZodEnum<{
|
|
16
|
+
frozen_eval: "frozen_eval";
|
|
17
|
+
test: "test";
|
|
16
18
|
train: "train";
|
|
17
19
|
validation: "validation";
|
|
18
|
-
test: "test";
|
|
19
|
-
frozen_eval: "frozen_eval";
|
|
20
20
|
}>;
|
|
21
21
|
taskIds: z.ZodArray<z.ZodString>;
|
|
22
22
|
seeds: z.ZodArray<z.ZodString>;
|
|
@@ -36,27 +36,27 @@ export declare const BenchmarkDefinitionSchema: z.ZodObject<{
|
|
|
36
36
|
contentHash: z.ZodString;
|
|
37
37
|
}, z.core.$strict>;
|
|
38
38
|
adaptationSplit: z.ZodEnum<{
|
|
39
|
+
frozen_eval: "frozen_eval";
|
|
40
|
+
test: "test";
|
|
39
41
|
train: "train";
|
|
40
42
|
validation: "validation";
|
|
41
|
-
test: "test";
|
|
42
|
-
frozen_eval: "frozen_eval";
|
|
43
43
|
}>;
|
|
44
44
|
evaluationSplit: z.ZodEnum<{
|
|
45
|
+
frozen_eval: "frozen_eval";
|
|
46
|
+
test: "test";
|
|
45
47
|
train: "train";
|
|
46
48
|
validation: "validation";
|
|
47
|
-
test: "test";
|
|
48
|
-
frozen_eval: "frozen_eval";
|
|
49
49
|
}>;
|
|
50
50
|
primaryMetric: z.ZodEnum<{
|
|
51
|
+
cost_usd: "cost_usd";
|
|
51
52
|
foreground_tokens: "foreground_tokens";
|
|
52
|
-
success_rate: "success_rate";
|
|
53
53
|
latency_ms: "latency_ms";
|
|
54
|
-
|
|
54
|
+
success_rate: "success_rate";
|
|
55
55
|
}>;
|
|
56
56
|
qualityGate: z.ZodEnum<{
|
|
57
|
-
none: "none";
|
|
58
|
-
non_regression: "non_regression";
|
|
59
57
|
all_pass: "all_pass";
|
|
58
|
+
non_regression: "non_regression";
|
|
59
|
+
none: "none";
|
|
60
60
|
}>;
|
|
61
61
|
caseCounts: z.ZodObject<{
|
|
62
62
|
adaptation: z.ZodNumber;
|
|
@@ -80,10 +80,10 @@ export declare const BenchmarkRunRequestSchema: z.ZodObject<{
|
|
|
80
80
|
}, z.core.$strict>;
|
|
81
81
|
reasoningEffort: z.ZodNullable<z.ZodString>;
|
|
82
82
|
split: z.ZodEnum<{
|
|
83
|
+
frozen_eval: "frozen_eval";
|
|
84
|
+
test: "test";
|
|
83
85
|
train: "train";
|
|
84
86
|
validation: "validation";
|
|
85
|
-
test: "test";
|
|
86
|
-
frozen_eval: "frozen_eval";
|
|
87
87
|
}>;
|
|
88
88
|
seeds: z.ZodArray<z.ZodString>;
|
|
89
89
|
repetitions: z.ZodNumber;
|
|
@@ -119,10 +119,10 @@ export declare const BenchmarkRunSummaryContentSchema: z.ZodObject<{
|
|
|
119
119
|
reasoningEffort: z.ZodNullable<z.ZodString>;
|
|
120
120
|
protocol: z.ZodObject<{
|
|
121
121
|
split: z.ZodEnum<{
|
|
122
|
+
frozen_eval: "frozen_eval";
|
|
123
|
+
test: "test";
|
|
122
124
|
train: "train";
|
|
123
125
|
validation: "validation";
|
|
124
|
-
test: "test";
|
|
125
|
-
frozen_eval: "frozen_eval";
|
|
126
126
|
}>;
|
|
127
127
|
taskIds: z.ZodArray<z.ZodString>;
|
|
128
128
|
seeds: z.ZodArray<z.ZodString>;
|
|
@@ -175,10 +175,10 @@ export declare const BenchmarkRunSummarySchema: z.ZodObject<{
|
|
|
175
175
|
reasoningEffort: z.ZodNullable<z.ZodString>;
|
|
176
176
|
protocol: z.ZodObject<{
|
|
177
177
|
split: z.ZodEnum<{
|
|
178
|
+
frozen_eval: "frozen_eval";
|
|
179
|
+
test: "test";
|
|
178
180
|
train: "train";
|
|
179
181
|
validation: "validation";
|
|
180
|
-
test: "test";
|
|
181
|
-
frozen_eval: "frozen_eval";
|
|
182
182
|
}>;
|
|
183
183
|
taskIds: z.ZodArray<z.ZodString>;
|
|
184
184
|
seeds: z.ZodArray<z.ZodString>;
|
|
@@ -218,10 +218,10 @@ export declare const BenchmarkComparisonContentSchema: z.ZodObject<{
|
|
|
218
218
|
contentHash: z.ZodString;
|
|
219
219
|
}, z.core.$strict>;
|
|
220
220
|
primaryMetric: z.ZodEnum<{
|
|
221
|
+
cost_usd: "cost_usd";
|
|
221
222
|
foreground_tokens: "foreground_tokens";
|
|
222
|
-
success_rate: "success_rate";
|
|
223
223
|
latency_ms: "latency_ms";
|
|
224
|
-
|
|
224
|
+
success_rate: "success_rate";
|
|
225
225
|
}>;
|
|
226
226
|
qualityPassed: z.ZodBoolean;
|
|
227
227
|
baselinePassRate: z.ZodNumber;
|
|
@@ -248,10 +248,10 @@ export declare const BenchmarkComparisonSchema: z.ZodObject<{
|
|
|
248
248
|
contentHash: z.ZodString;
|
|
249
249
|
}, z.core.$strict>;
|
|
250
250
|
primaryMetric: z.ZodEnum<{
|
|
251
|
+
cost_usd: "cost_usd";
|
|
251
252
|
foreground_tokens: "foreground_tokens";
|
|
252
|
-
success_rate: "success_rate";
|
|
253
253
|
latency_ms: "latency_ms";
|
|
254
|
-
|
|
254
|
+
success_rate: "success_rate";
|
|
255
255
|
}>;
|
|
256
256
|
qualityPassed: z.ZodBoolean;
|
|
257
257
|
baselinePassRate: z.ZodNumber;
|