openpond-sdk 0.9.2 → 0.9.4
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/README.md +24 -0
- package/dist/chunk-62LWLACP.js +155 -0
- package/dist/chunk-62LWLACP.js.map +7 -0
- package/dist/chunk-EMANJDJR.js +393 -0
- package/dist/chunk-EMANJDJR.js.map +7 -0
- package/dist/{chunk-QABCKPW6.js → chunk-TQ5ASK7D.js} +4 -4
- package/dist/{chunk-IKTZ2CD4.js → chunk-XR6CLSCS.js} +85 -43
- package/dist/chunk-XR6CLSCS.js.map +7 -0
- package/dist/dataset-workspaces.js +3 -3
- package/dist/experiments.js +57 -0
- package/dist/experiments.js.map +7 -0
- package/dist/index.js +12 -3
- package/dist/index.js.map +2 -2
- package/dist/learning.js +3 -3
- package/dist/model-starter-attempts.js +3 -1
- package/dist/model-taskset-runs.js +21 -113
- package/dist/model-taskset-runs.js.map +4 -4
- package/dist/taskset-drafts.js +2 -2
- package/dist/taskset-packages.js +2 -2
- package/dist/types/packages/sdk/src/experiment-client.d.ts +2441 -0
- package/dist/types/packages/sdk/src/experiment-client.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/experiment-contracts.d.ts +570 -0
- package/dist/types/packages/sdk/src/experiment-contracts.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/experiment-field-mappings.d.ts +43 -0
- package/dist/types/packages/sdk/src/experiment-field-mappings.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/experiment-grading-contracts.d.ts +79 -0
- package/dist/types/packages/sdk/src/experiment-grading-contracts.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/experiment-scoring-contracts.d.ts +192 -0
- package/dist/types/packages/sdk/src/experiment-scoring-contracts.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/experiments.d.ts +7 -0
- package/dist/types/packages/sdk/src/experiments.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/harness-experiment-policy.d.ts +44 -0
- package/dist/types/packages/sdk/src/harness-experiment-policy.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/index.d.ts +2 -0
- package/dist/types/packages/sdk/src/index.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/model-starter-attempts.d.ts +123 -0
- package/dist/types/packages/sdk/src/model-starter-attempts.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/model-taskset-runs-contracts.d.ts +159 -0
- package/dist/types/packages/sdk/src/model-taskset-runs-contracts.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/model-taskset-runs.d.ts +129 -5
- package/dist/types/packages/sdk/src/model-taskset-runs.d.ts.map +1 -1
- package/package.json +6 -2
- package/dist/chunk-IKTZ2CD4.js.map +0 -7
- /package/dist/{chunk-QABCKPW6.js.map → chunk-TQ5ASK7D.js.map} +0 -0
package/README.md
CHANGED
|
@@ -14,6 +14,30 @@ npm install openpond-sdk
|
|
|
14
14
|
|
|
15
15
|
Node.js 22.14 or newer is required. This package is server-only: never expose an OpenPond API key in browser code or a `NEXT_PUBLIC_*` environment variable.
|
|
16
16
|
|
|
17
|
+
## Saved Experiments
|
|
18
|
+
|
|
19
|
+
`OpenPondExperimentsClient` from `openpond-sdk/experiments` saves immutable named
|
|
20
|
+
configuration revisions and starts separate executions. It is also available as
|
|
21
|
+
`createOpenPondClient({ apiKey, baseUrl }).experiments(teamId)`. Saving does not
|
|
22
|
+
start compute. Supply stable operation IDs for save and Start, and reuse them
|
|
23
|
+
after transport failures. A new Start operation creates another execution from
|
|
24
|
+
the exact definition reference; configuration updates require `expectedRevision`.
|
|
25
|
+
|
|
26
|
+
`get` and `list` read saved configurations; `result` reads portable retained
|
|
27
|
+
execution evidence. `compare` verifies both retained results and uses the shared
|
|
28
|
+
Evals compatibility and score-eligibility rules without starting or regrading
|
|
29
|
+
anything. Execution status and cancellation use `OpenPondModelTasksetRunsClient`.
|
|
30
|
+
Host runtime readiness, permissions and whole-execution budgets remain enforced
|
|
31
|
+
on Start. Unsupported runtime configurations fail admission before dispatch.
|
|
32
|
+
|
|
33
|
+
Released Profile, Workflow, Skill and Agent-action targets use the
|
|
34
|
+
`hosted_harness` policy with an exact `profileRepositoryId`, native `source`,
|
|
35
|
+
`packageHash` and `modelConfigurationHash`. The host resolves these pins through
|
|
36
|
+
the authorized native runtime; callers cannot replace released behavior with
|
|
37
|
+
Chat messages. Native receipt IDs belong to each execution, while the saved
|
|
38
|
+
definition retains the same task/seed population. Clients verify repository,
|
|
39
|
+
source, package, model and case identities before accepting a run.
|
|
40
|
+
|
|
17
41
|
## Next.js route handler
|
|
18
42
|
|
|
19
43
|
Sandbox and model configuration are independently optional. With only `apiKey`,
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EvaluationProjectContextSchema,
|
|
3
|
+
ModelStarterAttemptPolicySchema,
|
|
4
|
+
ModelStarterAttemptSummarySchema
|
|
5
|
+
} from "./chunk-XR6CLSCS.js";
|
|
6
|
+
import {
|
|
7
|
+
ModelProjectVersionedRefSchema,
|
|
8
|
+
canonicalJson,
|
|
9
|
+
canonicalSha256
|
|
10
|
+
} from "./chunk-TCHAWJMB.js";
|
|
11
|
+
import {
|
|
12
|
+
assertContentHash,
|
|
13
|
+
contentHash
|
|
14
|
+
} from "./chunk-QUOW6URQ.js";
|
|
15
|
+
|
|
16
|
+
// src/harness-experiment-policy.ts
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
import { ProfileEvaluationRunSourceSchema } from "@openpond/evals";
|
|
19
|
+
var Id = z.string().trim().min(1).max(240);
|
|
20
|
+
var Hash = z.string().regex(/^[a-f0-9]{64}$/);
|
|
21
|
+
var HarnessExperimentPolicySchema = z.object({
|
|
22
|
+
kind: z.literal("hosted_harness"),
|
|
23
|
+
modelId: Id,
|
|
24
|
+
reasoningEffort: z.enum(["off", "low", "medium", "high", "xhigh", "max"]).optional(),
|
|
25
|
+
profileRepositoryId: Id,
|
|
26
|
+
source: ProfileEvaluationRunSourceSchema,
|
|
27
|
+
modelConfigurationHash: Hash,
|
|
28
|
+
packageHash: Hash
|
|
29
|
+
}).strict();
|
|
30
|
+
|
|
31
|
+
// src/model-taskset-runs-contracts.ts
|
|
32
|
+
import { z as z2 } from "zod";
|
|
33
|
+
import { TasksetRunManifestSchema, TasksetRunMemberSchema, TasksetMetricResultSchema, assertTasksetMetricResult, orderTasksetRunReceipts } from "@openpond/evals/metrics";
|
|
34
|
+
import { AttemptReceiptSchema } from "@openpond/evals/runs";
|
|
35
|
+
var IdSchema = z2.string().trim().min(1).max(200);
|
|
36
|
+
var HashSchema = z2.string().regex(/^[a-f0-9]{64}$/);
|
|
37
|
+
var ModelTasksetRunPolicySchema = z2.discriminatedUnion("kind", [
|
|
38
|
+
ModelStarterAttemptPolicySchema.options[0],
|
|
39
|
+
z2.object({ kind: z2.literal("fixture") }).strict(),
|
|
40
|
+
HarnessExperimentPolicySchema
|
|
41
|
+
]);
|
|
42
|
+
var ModelTasksetRunRequestSchema = z2.object({
|
|
43
|
+
schemaVersion: z2.literal("openpond.modelTasksetRunRequest.v1"),
|
|
44
|
+
operationId: IdSchema,
|
|
45
|
+
teamId: IdSchema,
|
|
46
|
+
modelProjectId: IdSchema.nullable(),
|
|
47
|
+
name: z2.string().trim().min(1).max(200).optional(),
|
|
48
|
+
project: EvaluationProjectContextSchema.optional(),
|
|
49
|
+
taskset: ModelProjectVersionedRefSchema,
|
|
50
|
+
policy: ModelTasksetRunPolicySchema,
|
|
51
|
+
population: z2.array(TasksetRunMemberSchema).min(1).max(1e4)
|
|
52
|
+
}).strict().superRefine((value, context) => {
|
|
53
|
+
if (new Set(value.population.map((member) => member.receiptId)).size !== value.population.length) context.addIssue({ code: "custom", path: ["population"], message: "Run receipt identities must be unique." });
|
|
54
|
+
if (value.population.some((member) => member.fixtureId !== null !== (value.policy.kind === "fixture"))) context.addIssue({ code: "custom", path: ["population"], message: "Only fixture runs require a fixture identity for every member." });
|
|
55
|
+
if (value.population.some((member) => !/^(0|[1-9][0-9]*)$/.test(member.seed) || Number(member.seed) > 2147483647)) context.addIssue({ code: "custom", path: ["population"], message: "Hosted environment seeds must be integers from 0 to 2147483647." });
|
|
56
|
+
if (value.policy.kind === "hosted_harness" && value.modelProjectId !== null)
|
|
57
|
+
context.addIssue({ code: "custom", path: ["modelProjectId"], message: "A Harness target retains its released Profile binding separately from Model artifacts." });
|
|
58
|
+
if (value.policy.kind === "hosted_harness" && new Set(value.population.map((member) => canonicalJson([member.taskId, member.seed]))).size !== value.population.length)
|
|
59
|
+
context.addIssue({ code: "custom", path: ["population"], message: "Harness case identities must be unique for each task and seed." });
|
|
60
|
+
});
|
|
61
|
+
var ModelTasksetRunSummarySchema = z2.object({
|
|
62
|
+
schemaVersion: z2.literal("openpond.modelTasksetRunSummary.v1"),
|
|
63
|
+
id: IdSchema,
|
|
64
|
+
revision: z2.number().int().positive(),
|
|
65
|
+
teamId: IdSchema,
|
|
66
|
+
modelProjectId: IdSchema.nullable(),
|
|
67
|
+
name: z2.string().trim().min(1).max(200).optional(),
|
|
68
|
+
project: EvaluationProjectContextSchema.optional(),
|
|
69
|
+
operationId: IdSchema,
|
|
70
|
+
taskset: ModelProjectVersionedRefSchema,
|
|
71
|
+
policyKind: z2.enum(["hosted_chat", "fixture", "hosted_harness"]),
|
|
72
|
+
manifestHash: HashSchema,
|
|
73
|
+
status: z2.enum(["queued", "running", "cancelling", "completed", "failed", "cancelled"]),
|
|
74
|
+
totalCount: z2.number().int().min(1).max(1e4),
|
|
75
|
+
counts: z2.object({ pending: z2.number().int().nonnegative(), running: z2.number().int().nonnegative(), completed: z2.number().int().nonnegative(), failed: z2.number().int().nonnegative(), cancelled: z2.number().int().nonnegative() }).strict(),
|
|
76
|
+
createdAt: z2.iso.datetime(),
|
|
77
|
+
startedAt: z2.iso.datetime().nullable(),
|
|
78
|
+
completedAt: z2.iso.datetime().nullable(),
|
|
79
|
+
cleanupComplete: z2.boolean(),
|
|
80
|
+
resultAvailable: z2.boolean(),
|
|
81
|
+
score: z2.number().min(0).max(1).nullable(),
|
|
82
|
+
metricName: z2.string().min(1).max(240),
|
|
83
|
+
error: z2.object({ code: IdSchema, message: z2.string().max(2e3) }).strict().nullable()
|
|
84
|
+
}).strict().superRefine((value, context) => {
|
|
85
|
+
if (Object.values(value.counts).reduce((sum, count) => sum + count, 0) !== value.totalCount) context.addIssue({ code: "custom", path: ["counts"], message: "Run counts must account for the complete population." });
|
|
86
|
+
if (value.status !== "completed" && value.score !== null) context.addIssue({ code: "custom", path: ["score"], message: "Only completed evaluations publish a metric value." });
|
|
87
|
+
if (["completed", "failed", "cancelled"].includes(value.status) && (!value.completedAt || value.counts.pending || value.counts.running)) context.addIssue({ code: "custom", message: "Terminal runs require complete population accounting." });
|
|
88
|
+
if (value.status === "cancelled" && !value.cleanupComplete) context.addIssue({ code: "custom", message: "Cancelled runs require confirmed cleanup." });
|
|
89
|
+
if (value.resultAvailable && !["completed", "failed", "cancelled"].includes(value.status)) context.addIssue({ code: "custom", message: "Run results require terminal population accounting." });
|
|
90
|
+
if (value.status === "completed" && (!value.cleanupComplete || !value.resultAvailable)) context.addIssue({ code: "custom", message: "Completed evaluations require retained results and confirmed cleanup." });
|
|
91
|
+
});
|
|
92
|
+
var ModelTasksetRunDetailsSchema = z2.object({
|
|
93
|
+
summary: ModelTasksetRunSummarySchema,
|
|
94
|
+
request: ModelTasksetRunRequestSchema,
|
|
95
|
+
manifest: TasksetRunManifestSchema,
|
|
96
|
+
policySnapshot: ModelStarterAttemptSummarySchema.shape.policySnapshot
|
|
97
|
+
}).strict();
|
|
98
|
+
var ModelTasksetRunListQuerySchema = z2.object({ modelProjectId: IdSchema.optional(), projectId: EvaluationProjectContextSchema.shape.id.optional(), afterId: IdSchema.optional(), limit: z2.number().int().min(1).max(100).default(25) }).strict();
|
|
99
|
+
var ModelTasksetRunPageSchema = z2.object({ items: z2.array(ModelTasksetRunSummarySchema).max(100), nextCursor: IdSchema.nullable() }).strict();
|
|
100
|
+
var ModelTasksetRunResultSchema = z2.object({
|
|
101
|
+
schemaVersion: z2.literal("openpond.modelTasksetRunResult.v1"),
|
|
102
|
+
run: ModelTasksetRunDetailsSchema,
|
|
103
|
+
receipts: z2.array(AttemptReceiptSchema).min(1).max(1e4),
|
|
104
|
+
metric: TasksetMetricResultSchema.nullable(),
|
|
105
|
+
contentHash: HashSchema
|
|
106
|
+
}).strict();
|
|
107
|
+
function verifyHarnessExperimentManifest(request, manifest) {
|
|
108
|
+
assertContentHash(manifest, "Taskset run manifest");
|
|
109
|
+
const policy = request.policy;
|
|
110
|
+
if (policy.kind !== "hosted_harness" || manifest.execution.kind !== "harness" || canonicalJson(manifest.profileEvaluation) !== canonicalJson(policy.source) || canonicalJson(manifest.execution.harnessRelease) !== canonicalJson(policy.source.harnessRelease) || manifest.metadata.profileRepositoryId !== policy.profileRepositoryId || manifest.packageHash !== policy.packageHash || manifest.policy.kind !== "model" || manifest.policy.model.provider !== "openpond" || manifest.policy.model.model !== policy.modelId || manifest.policy.model.revision !== null || manifest.policy.model.artifactHash !== null || manifest.policy.model.tokenizerRevision !== null || manifest.policy.model.chatTemplateHash !== null || manifest.policy.configurationHash !== policy.modelConfigurationHash || manifest.tasksetRelease.id !== request.taskset.id || manifest.tasksetRelease.contentHash !== request.taskset.contentHash || canonicalJson(manifest.population) !== canonicalJson(request.population) || manifest.population.some((member) => member.receiptId !== `evaluation-${contentHash([manifest.id, member.taskId, member.seed]).slice(0, 32)}`))
|
|
111
|
+
throw new Error("Harness evaluation differs from its admitted source, package or model configuration.");
|
|
112
|
+
}
|
|
113
|
+
async function verifyModelTasksetRunDetails(value) {
|
|
114
|
+
const result = ModelTasksetRunDetailsSchema.parse(value);
|
|
115
|
+
const { summary, request, manifest, policySnapshot } = result;
|
|
116
|
+
assertContentHash(manifest, "Taskset run manifest");
|
|
117
|
+
if (manifest.contentHash !== summary.manifestHash || manifest.id !== summary.id || manifest.createdAt !== summary.createdAt || summary.teamId !== request.teamId || summary.modelProjectId !== request.modelProjectId || canonicalJson(summary.project ?? null) !== canonicalJson(request.project ?? null) || canonicalJson(manifest.metadata.project ?? null) !== canonicalJson(request.project ?? null) || (summary.name ?? null) !== (request.name ?? null) || summary.operationId !== request.operationId || summary.policyKind !== request.policy.kind || summary.totalCount !== request.population.length || summary.metricName !== manifest.metricPolicy.primaryMetric || canonicalJson(summary.taskset) !== canonicalJson(request.taskset) || manifest.tasksetRelease.id !== request.taskset.id || manifest.tasksetRelease.contentHash !== request.taskset.contentHash || canonicalJson(manifest.population) !== canonicalJson(request.population)) throw new Error("Evaluation run differs from its admitted request or manifest.");
|
|
118
|
+
if (request.policy.kind === "fixture") {
|
|
119
|
+
if (manifest.policy.kind !== "fixture" || policySnapshot !== null) throw new Error("Fixture checks cannot claim a model identity.");
|
|
120
|
+
} else if (request.policy.kind === "hosted_harness") {
|
|
121
|
+
verifyHarnessExperimentManifest(request, manifest);
|
|
122
|
+
if (policySnapshot !== null) throw new Error("Harness evaluations retain the native host model configuration.");
|
|
123
|
+
} else if (manifest.policy.kind !== "model" || !policySnapshot || policySnapshot.modelId !== request.policy.modelId || manifest.policy.model.provider !== policySnapshot.provider || manifest.policy.model.model !== policySnapshot.upstreamModelId || manifest.policy.model.revision !== null || manifest.policy.model.artifactHash !== null || manifest.policy.model.tokenizerRevision !== null || manifest.policy.model.chatTemplateHash !== null || manifest.policy.configurationHash !== await canonicalSha256({ policy: request.policy, snapshot: policySnapshot })) throw new Error("Evaluation model differs from its admitted policy.");
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
async function verifyModelTasksetRunResult(value) {
|
|
127
|
+
const result = ModelTasksetRunResultSchema.parse(value);
|
|
128
|
+
const { contentHash: actual, ...content } = result;
|
|
129
|
+
if (await canonicalSha256(content) !== actual) throw new Error("Evaluation result integrity failed.");
|
|
130
|
+
const { summary, manifest } = await verifyModelTasksetRunDetails(result.run);
|
|
131
|
+
if (!summary.resultAvailable || !["completed", "failed", "cancelled"].includes(summary.status)) throw new Error("Evaluation result is not terminal.");
|
|
132
|
+
const ordered = orderTasksetRunReceipts(manifest, result.receipts);
|
|
133
|
+
if (canonicalJson(ordered) !== canonicalJson(result.receipts)) throw new Error("Evaluation receipts differ from the admitted order.");
|
|
134
|
+
if (summary.status === "completed" !== (result.metric !== null)) throw new Error("Only completed evaluations retain a metric.");
|
|
135
|
+
if (result.metric) {
|
|
136
|
+
assertTasksetMetricResult(result.metric);
|
|
137
|
+
if (result.metric.runManifest.id !== manifest.id || result.metric.runManifest.contentHash !== manifest.contentHash || canonicalJson(result.metric.tasksetRelease) !== canonicalJson(manifest.tasksetRelease) || canonicalJson(result.metric.policy) !== canonicalJson(manifest.metricPolicy) || canonicalJson(result.metric.receiptRefs) !== canonicalJson(result.receipts.map(({ id, contentHash: contentHash2 }) => ({ id, contentHash: contentHash2 }))) || result.metric.value !== summary.score) throw new Error("Evaluation metric differs from its admitted run or receipt population.");
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export {
|
|
143
|
+
HarnessExperimentPolicySchema,
|
|
144
|
+
ModelTasksetRunPolicySchema,
|
|
145
|
+
ModelTasksetRunRequestSchema,
|
|
146
|
+
ModelTasksetRunSummarySchema,
|
|
147
|
+
ModelTasksetRunDetailsSchema,
|
|
148
|
+
ModelTasksetRunListQuerySchema,
|
|
149
|
+
ModelTasksetRunPageSchema,
|
|
150
|
+
ModelTasksetRunResultSchema,
|
|
151
|
+
verifyHarnessExperimentManifest,
|
|
152
|
+
verifyModelTasksetRunDetails,
|
|
153
|
+
verifyModelTasksetRunResult
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=chunk-62LWLACP.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/harness-experiment-policy.ts", "../src/model-taskset-runs-contracts.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from \"zod\";\nimport { ProfileEvaluationRunSourceSchema } from \"@openpond/evals\";\n\nconst Id = z.string().trim().min(1).max(240);\nconst Hash = z.string().regex(/^[a-f0-9]{64}$/);\n\n/** The host admits this released component through its native Harness engine.\n * Chat prompt/settings are owned by the released source, not replaced here. */\nexport const HarnessExperimentPolicySchema = z.object({\n kind: z.literal(\"hosted_harness\"),\n modelId: Id,\n reasoningEffort: z.enum([\"off\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"]).optional(),\n profileRepositoryId: Id,\n source: ProfileEvaluationRunSourceSchema,\n modelConfigurationHash: Hash,\n packageHash: Hash,\n}).strict();\nexport type HarnessExperimentPolicy = z.infer<typeof HarnessExperimentPolicySchema>;\n", "import { z } from \"zod\";\nimport { EvaluationProjectContextSchema } from \"./evaluation-project-context.js\";\nimport { assertContentHash, contentHash } from \"@openpond/harness\";\nimport { TasksetRunManifestSchema, TasksetRunMemberSchema, TasksetMetricResultSchema, assertTasksetMetricResult, orderTasksetRunReceipts } from \"@openpond/evals/metrics\";\nimport { AttemptReceiptSchema } from \"@openpond/evals/runs\";\nimport { ModelProjectVersionedRefSchema } from \"./model-projects.js\";\nimport { ModelStarterAttemptPolicySchema, ModelStarterAttemptSummarySchema } from \"./model-starter-attempts.js\";\nimport { canonicalJson, canonicalSha256 } from \"./protocol.js\";\nimport { HarnessExperimentPolicySchema } from \"./harness-experiment-policy.js\";\nexport { HarnessExperimentPolicySchema, type HarnessExperimentPolicy } from \"./harness-experiment-policy.js\";\n\nconst IdSchema = z.string().trim().min(1).max(200);\nconst HashSchema = z.string().regex(/^[a-f0-9]{64}$/);\nexport const ModelTasksetRunPolicySchema = z.discriminatedUnion(\"kind\", [\n ModelStarterAttemptPolicySchema.options[0],\n z.object({ kind: z.literal(\"fixture\") }).strict(),\n HarnessExperimentPolicySchema,\n]);\nexport const ModelTasksetRunRequestSchema = z.object({\n schemaVersion: z.literal(\"openpond.modelTasksetRunRequest.v1\"),\n operationId: IdSchema, teamId: IdSchema, modelProjectId: IdSchema.nullable(),\n name: z.string().trim().min(1).max(200).optional(),\n project: EvaluationProjectContextSchema.optional(),\n taskset: ModelProjectVersionedRefSchema, policy: ModelTasksetRunPolicySchema,\n population: z.array(TasksetRunMemberSchema).min(1).max(10_000),\n}).strict().superRefine((value, context) => {\n if (new Set(value.population.map(member => member.receiptId)).size !== value.population.length) context.addIssue({ code: \"custom\", path: [\"population\"], message: \"Run receipt identities must be unique.\" });\n if (value.population.some(member => (member.fixtureId !== null) !== (value.policy.kind === \"fixture\"))) context.addIssue({ code: \"custom\", path: [\"population\"], message: \"Only fixture runs require a fixture identity for every member.\" });\n if (value.population.some(member => !/^(0|[1-9][0-9]*)$/.test(member.seed) || Number(member.seed) > 2_147_483_647)) context.addIssue({ code: \"custom\", path: [\"population\"], message: \"Hosted environment seeds must be integers from 0 to 2147483647.\" });\n if (value.policy.kind === \"hosted_harness\" && value.modelProjectId !== null)\n context.addIssue({ code: \"custom\", path: [\"modelProjectId\"], message: \"A Harness target retains its released Profile binding separately from Model artifacts.\" });\n if (value.policy.kind === \"hosted_harness\"\n && new Set(value.population.map(member => canonicalJson([member.taskId, member.seed]))).size !== value.population.length)\n context.addIssue({ code: \"custom\", path: [\"population\"], message: \"Harness case identities must be unique for each task and seed.\" });\n});\nexport type ModelTasksetRunRequest = z.infer<typeof ModelTasksetRunRequestSchema>;\nexport const ModelTasksetRunSummarySchema = z.object({\n schemaVersion: z.literal(\"openpond.modelTasksetRunSummary.v1\"),\n id: IdSchema, revision: z.number().int().positive(), teamId: IdSchema, modelProjectId: IdSchema.nullable(),\n name: z.string().trim().min(1).max(200).optional(),\n project: EvaluationProjectContextSchema.optional(),\n operationId: IdSchema, taskset: ModelProjectVersionedRefSchema, policyKind: z.enum([\"hosted_chat\", \"fixture\", \"hosted_harness\"]),\n manifestHash: HashSchema,\n status: z.enum([\"queued\", \"running\", \"cancelling\", \"completed\", \"failed\", \"cancelled\"]),\n totalCount: z.number().int().min(1).max(10_000),\n counts: z.object({ pending: z.number().int().nonnegative(), running: z.number().int().nonnegative(), completed: z.number().int().nonnegative(), failed: z.number().int().nonnegative(), cancelled: z.number().int().nonnegative() }).strict(),\n createdAt: z.iso.datetime(), startedAt: z.iso.datetime().nullable(), completedAt: z.iso.datetime().nullable(),\n cleanupComplete: z.boolean(), resultAvailable: z.boolean(), score: z.number().min(0).max(1).nullable(),\n metricName: z.string().min(1).max(240),\n error: z.object({ code: IdSchema, message: z.string().max(2_000) }).strict().nullable(),\n}).strict().superRefine((value, context) => {\n if (Object.values(value.counts).reduce((sum, count) => sum + count, 0) !== value.totalCount) context.addIssue({ code: \"custom\", path: [\"counts\"], message: \"Run counts must account for the complete population.\" });\n if (value.status !== \"completed\" && value.score !== null) context.addIssue({ code: \"custom\", path: [\"score\"], message: \"Only completed evaluations publish a metric value.\" });\n if ([\"completed\", \"failed\", \"cancelled\"].includes(value.status) && (!value.completedAt || value.counts.pending || value.counts.running)) context.addIssue({ code: \"custom\", message: \"Terminal runs require complete population accounting.\" });\n if (value.status === \"cancelled\" && !value.cleanupComplete) context.addIssue({ code: \"custom\", message: \"Cancelled runs require confirmed cleanup.\" });\n if (value.resultAvailable && ![\"completed\", \"failed\", \"cancelled\"].includes(value.status)) context.addIssue({ code: \"custom\", message: \"Run results require terminal population accounting.\" });\n if (value.status === \"completed\" && (!value.cleanupComplete || !value.resultAvailable)) context.addIssue({ code: \"custom\", message: \"Completed evaluations require retained results and confirmed cleanup.\" });\n});\nexport type ModelTasksetRunSummary = z.infer<typeof ModelTasksetRunSummarySchema>;\nexport const ModelTasksetRunDetailsSchema = z.object({\n summary: ModelTasksetRunSummarySchema,\n request: ModelTasksetRunRequestSchema,\n manifest: TasksetRunManifestSchema,\n policySnapshot: ModelStarterAttemptSummarySchema.shape.policySnapshot,\n}).strict();\nexport type ModelTasksetRunDetails = z.infer<typeof ModelTasksetRunDetailsSchema>;\nexport const ModelTasksetRunListQuerySchema = z.object({ modelProjectId: IdSchema.optional(), projectId: EvaluationProjectContextSchema.shape.id.optional(), afterId: IdSchema.optional(), limit: z.number().int().min(1).max(100).default(25) }).strict();\nexport const ModelTasksetRunPageSchema = z.object({ items: z.array(ModelTasksetRunSummarySchema).max(100), nextCursor: IdSchema.nullable() }).strict();\nexport const ModelTasksetRunResultSchema = z.object({\n schemaVersion: z.literal(\"openpond.modelTasksetRunResult.v1\"),\n run: ModelTasksetRunDetailsSchema,\n receipts: z.array(AttemptReceiptSchema).min(1).max(10_000),\n metric: TasksetMetricResultSchema.nullable(),\n contentHash: HashSchema,\n}).strict();\nexport type ModelTasksetRunResult = z.infer<typeof ModelTasksetRunResultSchema>;\n\nexport function verifyHarnessExperimentManifest(request: ModelTasksetRunRequest, manifest: z.infer<typeof TasksetRunManifestSchema>) {\n assertContentHash(manifest, \"Taskset run manifest\");\n const policy = request.policy;\n if (policy.kind !== \"hosted_harness\" || manifest.execution.kind !== \"harness\"\n || canonicalJson(manifest.profileEvaluation) !== canonicalJson(policy.source)\n || canonicalJson(manifest.execution.harnessRelease) !== canonicalJson(policy.source.harnessRelease)\n || manifest.metadata.profileRepositoryId !== policy.profileRepositoryId\n || manifest.packageHash !== policy.packageHash || manifest.policy.kind !== \"model\"\n || manifest.policy.model.provider !== \"openpond\" || manifest.policy.model.model !== policy.modelId\n || manifest.policy.model.revision !== null || manifest.policy.model.artifactHash !== null\n || manifest.policy.model.tokenizerRevision !== null || manifest.policy.model.chatTemplateHash !== null\n || manifest.policy.configurationHash !== policy.modelConfigurationHash\n || manifest.tasksetRelease.id !== request.taskset.id || manifest.tasksetRelease.contentHash !== request.taskset.contentHash\n || canonicalJson(manifest.population) !== canonicalJson(request.population)\n || manifest.population.some(member => member.receiptId !== `evaluation-${contentHash([manifest.id, member.taskId, member.seed]).slice(0, 32)}`))\n throw new Error(\"Harness evaluation differs from its admitted source, package or model configuration.\");\n}\n\n/** Server artifact ownership authenticates the producer. These checks bind all\n * portable projections to the admitted request, population and policy. */\nexport async function verifyModelTasksetRunDetails(value: unknown): Promise<ModelTasksetRunDetails> {\n const result = ModelTasksetRunDetailsSchema.parse(value);\n const { summary, request, manifest, policySnapshot } = result;\n assertContentHash(manifest, \"Taskset run manifest\");\n if (manifest.contentHash !== summary.manifestHash\n || manifest.id !== summary.id || manifest.createdAt !== summary.createdAt || summary.teamId !== request.teamId || summary.modelProjectId !== request.modelProjectId\n || canonicalJson(summary.project ?? null) !== canonicalJson(request.project ?? null)\n || canonicalJson(manifest.metadata.project ?? null) !== canonicalJson(request.project ?? null)\n || (summary.name ?? null) !== (request.name ?? null)\n || summary.operationId !== request.operationId || summary.policyKind !== request.policy.kind\n || summary.totalCount !== request.population.length || summary.metricName !== manifest.metricPolicy.primaryMetric\n || canonicalJson(summary.taskset) !== canonicalJson(request.taskset)\n || manifest.tasksetRelease.id !== request.taskset.id || manifest.tasksetRelease.contentHash !== request.taskset.contentHash\n || canonicalJson(manifest.population) !== canonicalJson(request.population)) throw new Error(\"Evaluation run differs from its admitted request or manifest.\");\n if (request.policy.kind === \"fixture\") {\n if (manifest.policy.kind !== \"fixture\" || policySnapshot !== null) throw new Error(\"Fixture checks cannot claim a model identity.\");\n } else if (request.policy.kind === \"hosted_harness\") {\n verifyHarnessExperimentManifest(request, manifest);\n if (policySnapshot !== null) throw new Error(\"Harness evaluations retain the native host model configuration.\");\n } else if (manifest.policy.kind !== \"model\" || !policySnapshot || policySnapshot.modelId !== request.policy.modelId\n || manifest.policy.model.provider !== policySnapshot.provider || manifest.policy.model.model !== policySnapshot.upstreamModelId\n || manifest.policy.model.revision !== null || manifest.policy.model.artifactHash !== null || manifest.policy.model.tokenizerRevision !== null || manifest.policy.model.chatTemplateHash !== null\n || manifest.policy.configurationHash !== await canonicalSha256({ policy: request.policy, snapshot: policySnapshot })) throw new Error(\"Evaluation model differs from its admitted policy.\");\n return result;\n}\n\nexport async function verifyModelTasksetRunResult(value: unknown): Promise<ModelTasksetRunResult> {\n const result = ModelTasksetRunResultSchema.parse(value);\n const { contentHash: actual, ...content } = result;\n if (await canonicalSha256(content) !== actual) throw new Error(\"Evaluation result integrity failed.\");\n const { summary, manifest } = await verifyModelTasksetRunDetails(result.run);\n if (!summary.resultAvailable || ![\"completed\", \"failed\", \"cancelled\"].includes(summary.status)) throw new Error(\"Evaluation result is not terminal.\");\n const ordered = orderTasksetRunReceipts(manifest, result.receipts);\n if (canonicalJson(ordered) !== canonicalJson(result.receipts)) throw new Error(\"Evaluation receipts differ from the admitted order.\");\n if ((summary.status === \"completed\") !== (result.metric !== null)) throw new Error(\"Only completed evaluations retain a metric.\");\n if (result.metric) {\n assertTasksetMetricResult(result.metric);\n if (result.metric.runManifest.id !== manifest.id || result.metric.runManifest.contentHash !== manifest.contentHash\n || canonicalJson(result.metric.tasksetRelease) !== canonicalJson(manifest.tasksetRelease)\n || canonicalJson(result.metric.policy) !== canonicalJson(manifest.metricPolicy)\n || canonicalJson(result.metric.receiptRefs) !== canonicalJson(result.receipts.map(({ id, contentHash }) => ({ id, contentHash })))\n || result.metric.value !== summary.score) throw new Error(\"Evaluation metric differs from its admitted run or receipt population.\");\n }\n return result;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["z", "z", "contentHash"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ModelTasksetRunRequestSchema,
|
|
3
|
+
verifyHarnessExperimentManifest,
|
|
4
|
+
verifyModelTasksetRunDetails
|
|
5
|
+
} from "./chunk-62LWLACP.js";
|
|
6
|
+
import {
|
|
7
|
+
ImmutableReleaseRefSchema,
|
|
8
|
+
contentHash
|
|
9
|
+
} from "./chunk-QUOW6URQ.js";
|
|
10
|
+
|
|
11
|
+
// src/experiment-field-mappings.ts
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
var Segment = z.string().min(1).max(200).refine((value) => !["__proto__", "prototype", "constructor"].includes(value), "Use an ordinary field name.");
|
|
14
|
+
var Path = z.array(Segment).min(1).max(20);
|
|
15
|
+
var Slot = z.enum(["input", "output", "expectedOutput", "evaluatorContext"]);
|
|
16
|
+
var ExperimentFieldMappingSchema = z.object({
|
|
17
|
+
destination: Slot,
|
|
18
|
+
path: Path,
|
|
19
|
+
source: Slot,
|
|
20
|
+
sourcePath: z.array(Segment).max(20)
|
|
21
|
+
}).strict();
|
|
22
|
+
var ExperimentFieldMappingsSchema = z.array(ExperimentFieldMappingSchema).max(100).superRefine((mappings, context) => {
|
|
23
|
+
for (const [index, mapping] of mappings.entries()) {
|
|
24
|
+
if (mappings.slice(0, index).some((previous) => previous.destination === mapping.destination && (prefix(previous.path, mapping.path) || prefix(mapping.path, previous.path))))
|
|
25
|
+
context.addIssue({ code: "custom", path: [index, "path"], message: "Mapped destination paths must not overlap." });
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
function mapExperimentGradingFields(fields, raw) {
|
|
29
|
+
const mappings = ExperimentFieldMappingsSchema.parse(raw);
|
|
30
|
+
const mapped = structuredClone(fields);
|
|
31
|
+
for (const mapping of mappings) {
|
|
32
|
+
let value = fields[mapping.source];
|
|
33
|
+
for (const segment of mapping.sourcePath) {
|
|
34
|
+
if (!record(value) || !Object.hasOwn(value, segment)) throw new Error("The configured grader source field is unavailable.");
|
|
35
|
+
value = value[segment];
|
|
36
|
+
}
|
|
37
|
+
if (value === void 0) throw new Error("The configured grader source field is unavailable.");
|
|
38
|
+
let destination = mapped[mapping.destination];
|
|
39
|
+
if (destination === null) mapped[mapping.destination] = destination = {};
|
|
40
|
+
for (const segment of mapping.path.slice(0, -1)) {
|
|
41
|
+
const existing = Object.hasOwn(destination, segment) ? destination[segment] : void 0;
|
|
42
|
+
if (existing !== void 0 && !record(existing)) throw new Error("A grader destination path crosses a scalar field.");
|
|
43
|
+
if (existing === void 0) destination[segment] = {};
|
|
44
|
+
destination = destination[segment];
|
|
45
|
+
}
|
|
46
|
+
destination[mapping.path.at(-1)] = structuredClone(value);
|
|
47
|
+
}
|
|
48
|
+
return mapped;
|
|
49
|
+
}
|
|
50
|
+
function record(value) {
|
|
51
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
52
|
+
}
|
|
53
|
+
function prefix(left, right) {
|
|
54
|
+
return left.length <= right.length && left.every((segment, index) => segment === right[index]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/experiment-contracts.ts
|
|
58
|
+
import { FeedbackKeySchema } from "@openpond/evals/rewards";
|
|
59
|
+
import { TasksetRunManifestSchema } from "@openpond/evals/metrics";
|
|
60
|
+
import { z as z2 } from "zod";
|
|
61
|
+
var Id = z2.string().trim().min(1).max(200);
|
|
62
|
+
var Hash = z2.string().regex(/^[a-f0-9]{64}$/);
|
|
63
|
+
var ExperimentDefinitionRefSchema = z2.object({
|
|
64
|
+
id: Id,
|
|
65
|
+
revision: z2.number().int().positive(),
|
|
66
|
+
contentHash: Hash
|
|
67
|
+
}).strict();
|
|
68
|
+
var ExperimentGraderPinSchema = z2.object({
|
|
69
|
+
id: Id,
|
|
70
|
+
version: z2.string().min(1).max(200),
|
|
71
|
+
contentHash: Hash,
|
|
72
|
+
feedbackKey: FeedbackKeySchema,
|
|
73
|
+
release: ExperimentDefinitionRefSchema.nullable(),
|
|
74
|
+
mappings: ExperimentFieldMappingsSchema.optional()
|
|
75
|
+
}).strict();
|
|
76
|
+
var ExperimentGraderSelectionSchema = z2.object({ id: Id, version: z2.string().min(1).max(200), contentHash: Hash, mappings: ExperimentFieldMappingsSchema }).strict();
|
|
77
|
+
var SaveExperimentSchema = z2.object({
|
|
78
|
+
operationId: Id,
|
|
79
|
+
id: Id.optional(),
|
|
80
|
+
expectedRevision: z2.number().int().nonnegative(),
|
|
81
|
+
request: ModelTasksetRunRequestSchema,
|
|
82
|
+
maximumCostUsd: z2.number().finite().positive().max(1e4),
|
|
83
|
+
graders: z2.array(ExperimentGraderSelectionSchema).min(1).max(100).optional()
|
|
84
|
+
}).strict().superRefine((value, ctx) => {
|
|
85
|
+
if (!value.request.name) ctx.addIssue({ code: "custom", path: ["request", "name"], message: "Name this Experiment before saving it." });
|
|
86
|
+
if (Boolean(value.id) !== value.expectedRevision > 0) ctx.addIssue({ code: "custom", path: ["expectedRevision"], message: "An update requires its saved definition revision." });
|
|
87
|
+
if (Math.round(value.maximumCostUsd * 1e6) < 1) ctx.addIssue({ code: "custom", path: ["maximumCostUsd"], message: "The budget must be at least $0.000001." });
|
|
88
|
+
if (value.graders && new Set(value.graders.map((grader) => grader.id)).size !== value.graders.length) ctx.addIssue({ code: "custom", path: ["graders"], message: "Select each grader once." });
|
|
89
|
+
});
|
|
90
|
+
var DefinitionContent = z2.object({
|
|
91
|
+
schemaVersion: z2.literal("openpond.experimentDefinition.v1"),
|
|
92
|
+
id: Id,
|
|
93
|
+
teamId: Id,
|
|
94
|
+
revision: z2.number().int().positive(),
|
|
95
|
+
request: ModelTasksetRunRequestSchema,
|
|
96
|
+
maximumCostUsd: z2.number().finite().positive().max(1e4),
|
|
97
|
+
graders: z2.array(ExperimentGraderPinSchema).min(1).max(100),
|
|
98
|
+
createdAt: z2.iso.datetime(),
|
|
99
|
+
updatedAt: z2.iso.datetime()
|
|
100
|
+
}).strict();
|
|
101
|
+
var ExperimentDefinitionSchema = DefinitionContent.extend({ contentHash: Hash });
|
|
102
|
+
var StartExperimentSchema = z2.object({ operationId: Id, definition: ExperimentDefinitionRefSchema }).strict();
|
|
103
|
+
var ExperimentListQuerySchema = z2.object({
|
|
104
|
+
projectId: Id.optional(),
|
|
105
|
+
datasetHash: Hash.optional(),
|
|
106
|
+
search: z2.string().trim().max(200).optional(),
|
|
107
|
+
afterId: Id.optional(),
|
|
108
|
+
limit: z2.number().int().min(1).max(100).default(30)
|
|
109
|
+
}).strict();
|
|
110
|
+
var ExperimentExecutionContextSchema = z2.object({
|
|
111
|
+
definition: ExperimentDefinitionRefSchema,
|
|
112
|
+
maximumCostUsd: z2.number().finite().positive().max(1e4),
|
|
113
|
+
graders: z2.array(ExperimentGraderPinSchema).min(1).max(100)
|
|
114
|
+
}).strict();
|
|
115
|
+
var PrepareHarnessExperimentSchema = z2.object({
|
|
116
|
+
operationId: Id,
|
|
117
|
+
profileRepositoryId: Id,
|
|
118
|
+
definitionId: Id,
|
|
119
|
+
modelId: Id,
|
|
120
|
+
reasoningEffort: z2.enum(["off", "low", "medium", "high", "xhigh", "max"]).optional(),
|
|
121
|
+
maximumCostUsd: z2.number().finite().positive().max(1e4)
|
|
122
|
+
}).strict();
|
|
123
|
+
var PreparedHarnessExperimentSchema = z2.object({
|
|
124
|
+
request: ModelTasksetRunRequestSchema,
|
|
125
|
+
manifest: TasksetRunManifestSchema,
|
|
126
|
+
maximumCostUsd: z2.number().finite().positive().max(1e4),
|
|
127
|
+
graders: z2.array(ExperimentGraderPinSchema).min(1).max(100)
|
|
128
|
+
}).strict();
|
|
129
|
+
function verifyExperimentDefinition(value) {
|
|
130
|
+
const parsed = ExperimentDefinitionSchema.parse(value);
|
|
131
|
+
const { contentHash: actual, ...content } = parsed;
|
|
132
|
+
if (actual !== contentHash(content) || parsed.request.teamId !== parsed.teamId || !parsed.request.name)
|
|
133
|
+
throw new Error("Experiment definition differs from its immutable content.");
|
|
134
|
+
if (new Set(parsed.graders.map((item) => item.feedbackKey)).size !== parsed.graders.length)
|
|
135
|
+
throw new Error("Experiment feedback keys must be distinct.");
|
|
136
|
+
return parsed;
|
|
137
|
+
}
|
|
138
|
+
var experimentDefinitionRef = (value) => ({
|
|
139
|
+
id: value.id,
|
|
140
|
+
revision: value.revision,
|
|
141
|
+
contentHash: value.contentHash
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// src/experiment-scoring-contracts.ts
|
|
145
|
+
import { z as z3 } from "zod";
|
|
146
|
+
import { RewardReleaseRefSchema } from "@openpond/evals/rewards";
|
|
147
|
+
var Id2 = z3.string().trim().min(1).max(200);
|
|
148
|
+
var ExperimentScoringRequestSchema = z3.object({
|
|
149
|
+
operationId: Id2,
|
|
150
|
+
execution: ImmutableReleaseRefSchema,
|
|
151
|
+
graders: z3.array(RewardReleaseRefSchema).min(1).max(100),
|
|
152
|
+
maximumCostUsd: z3.number().finite().min(1e-6).max(1e4),
|
|
153
|
+
mappings: z3.array(z3.object({ graderId: Id2, fields: ExperimentFieldMappingsSchema }).strict()).max(100).optional()
|
|
154
|
+
}).strict().superRefine((value, context) => {
|
|
155
|
+
if (new Set(value.graders.map((grader) => grader.id)).size !== value.graders.length)
|
|
156
|
+
context.addIssue({ code: "custom", path: ["graders"], message: "Select each grader once." });
|
|
157
|
+
if (value.mappings && (new Set(value.mappings.map((mapping) => mapping.graderId)).size !== value.mappings.length || value.mappings.some((mapping) => !value.graders.some((grader) => grader.id === mapping.graderId))))
|
|
158
|
+
context.addIssue({ code: "custom", path: ["mappings"], message: "Map each selected grader at most once." });
|
|
159
|
+
});
|
|
160
|
+
var ScoringPassContent = z3.object({
|
|
161
|
+
schemaVersion: z3.literal("openpond.experimentScoringPass.v1"),
|
|
162
|
+
id: Id2,
|
|
163
|
+
teamId: Id2,
|
|
164
|
+
revision: z3.number().int().positive(),
|
|
165
|
+
request: ExperimentScoringRequestSchema,
|
|
166
|
+
graders: z3.array(ExperimentGraderPinSchema).min(1).max(100),
|
|
167
|
+
status: z3.enum(["queued", "running", "cancelling", "completed", "failed", "cancelled"]),
|
|
168
|
+
totalCount: z3.number().int().min(1).max(1e4),
|
|
169
|
+
counts: z3.object({
|
|
170
|
+
pending: z3.number().int().nonnegative(),
|
|
171
|
+
running: z3.number().int().nonnegative(),
|
|
172
|
+
scored: z3.number().int().nonnegative(),
|
|
173
|
+
unavailable: z3.number().int().nonnegative(),
|
|
174
|
+
failed: z3.number().int().nonnegative(),
|
|
175
|
+
cancelled: z3.number().int().nonnegative()
|
|
176
|
+
}).strict(),
|
|
177
|
+
resultAvailable: z3.boolean(),
|
|
178
|
+
createdAt: z3.iso.datetime(),
|
|
179
|
+
startedAt: z3.iso.datetime().nullable(),
|
|
180
|
+
completedAt: z3.iso.datetime().nullable(),
|
|
181
|
+
error: z3.object({ code: Id2, message: z3.string().max(2e3) }).strict().nullable()
|
|
182
|
+
}).strict();
|
|
183
|
+
var ExperimentScoringPassSchema = ScoringPassContent.extend({ contentHash: z3.string().regex(/^[a-f0-9]{64}$/) });
|
|
184
|
+
function verifyExperimentScoringPass(value) {
|
|
185
|
+
const pass = ExperimentScoringPassSchema.parse(value);
|
|
186
|
+
const { contentHash: actual, ...content } = pass;
|
|
187
|
+
if (contentHash(content) !== actual || Object.values(pass.counts).reduce((sum, count) => sum + count, 0) !== pass.totalCount)
|
|
188
|
+
throw new Error("Scoring pass integrity or population accounting failed.");
|
|
189
|
+
const terminal = ["completed", "failed", "cancelled"].includes(pass.status);
|
|
190
|
+
if (terminal && (!pass.completedAt || pass.counts.pending || pass.counts.running) || !terminal && (pass.completedAt !== null || pass.resultAvailable) || pass.status === "completed" && !pass.resultAvailable)
|
|
191
|
+
throw new Error("Scoring pass lifecycle differs from its retained result.");
|
|
192
|
+
if (pass.graders.length !== pass.request.graders.length || new Set(pass.graders.map((grader) => grader.feedbackKey)).size !== pass.graders.length || pass.graders.some((grader, index) => contentHash(grader.release) !== contentHash(pass.request.graders[index]) || contentHash(grader.mappings ?? []) !== contentHash(pass.request.mappings?.find((mapping) => mapping.graderId === grader.release?.id)?.fields ?? [])))
|
|
193
|
+
throw new Error("Scoring pass graders differ from their exact admission.");
|
|
194
|
+
return pass;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/experiment-client.ts
|
|
198
|
+
import { z as z4 } from "zod";
|
|
199
|
+
import { compareExperiments, verifyExperimentEvidence } from "@openpond/evals/experiments";
|
|
200
|
+
var Id3 = z4.string().trim().min(1).max(200);
|
|
201
|
+
var OpenPondExperimentError = class extends Error {
|
|
202
|
+
constructor(status, code, message) {
|
|
203
|
+
super(message);
|
|
204
|
+
this.status = status;
|
|
205
|
+
this.code = code;
|
|
206
|
+
this.name = "OpenPondExperimentError";
|
|
207
|
+
}
|
|
208
|
+
status;
|
|
209
|
+
code;
|
|
210
|
+
};
|
|
211
|
+
var OpenPondExperimentsClient = class {
|
|
212
|
+
constructor(options) {
|
|
213
|
+
this.options = options;
|
|
214
|
+
const url = new URL(options.baseUrl);
|
|
215
|
+
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash || !options.apiKey.trim() || !options.teamId.trim())
|
|
216
|
+
throw new Error("A clean API origin and workspace credentials are required.");
|
|
217
|
+
this.baseUrl = url.toString().replace(/\/+$/, "");
|
|
218
|
+
}
|
|
219
|
+
options;
|
|
220
|
+
baseUrl;
|
|
221
|
+
/** Resolves a released target without saving a definition or dispatching it. */
|
|
222
|
+
async prepareHarness(value, signal) {
|
|
223
|
+
const request = PrepareHarnessExperimentSchema.parse(value);
|
|
224
|
+
const result = PreparedHarnessExperimentSchema.parse(await this.request("/harness-setup", "POST", request, signal));
|
|
225
|
+
verifyHarnessExperimentManifest(result.request, result.manifest);
|
|
226
|
+
const policy = result.request.policy;
|
|
227
|
+
if (result.request.teamId !== this.options.teamId || result.request.operationId !== request.operationId || policy.kind !== "hosted_harness" || policy.profileRepositoryId !== request.profileRepositoryId || policy.source.definitionId !== request.definitionId || policy.modelId !== request.modelId || policy.reasoningEffort !== request.reasoningEffort || result.maximumCostUsd !== request.maximumCostUsd || result.manifest.limits.maximumSpendUsd !== request.maximumCostUsd)
|
|
228
|
+
throw new Error("Harness preparation differs from its requested scope or configuration.");
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
231
|
+
async save(value, signal) {
|
|
232
|
+
const request = SaveExperimentSchema.parse(value);
|
|
233
|
+
if (request.request.teamId !== this.options.teamId) throw new Error("Experiment workspace mismatch.");
|
|
234
|
+
const result = this.definition(await this.request("", "POST", request, signal), request.id);
|
|
235
|
+
if (result.revision !== request.expectedRevision + 1 || contentHash(result.request) !== contentHash(request.request) || result.maximumCostUsd !== request.maximumCostUsd) throw new Error("Experiment save receipt differs from its submitted configuration.");
|
|
236
|
+
if (request.graders && contentHash(request.graders) !== contentHash(result.graders.map((grader) => ({ id: grader.id, version: grader.version, contentHash: grader.contentHash, mappings: grader.mappings ?? [] }))))
|
|
237
|
+
throw new Error("Experiment save receipt differs from its selected graders or mappings.");
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
async get(id, options = {}) {
|
|
241
|
+
const reference = options.reference ? ExperimentDefinitionRefSchema.parse(options.reference) : void 0;
|
|
242
|
+
if (reference && reference.id !== id) throw new Error("Experiment reference identity mismatch.");
|
|
243
|
+
const suffix = reference ? `?${new URLSearchParams({ revision: String(reference.revision), contentHash: reference.contentHash })}` : "";
|
|
244
|
+
const result = this.definition(await this.request(`/${encodeURIComponent(Id3.parse(id))}${suffix}`, "GET", void 0, options.signal), id);
|
|
245
|
+
if (options.reference && contentHash(experimentDefinitionRef(result)) !== contentHash(options.reference)) throw new Error("Experiment revision mismatch.");
|
|
246
|
+
return result;
|
|
247
|
+
}
|
|
248
|
+
async list(value = {}, signal) {
|
|
249
|
+
const query = ExperimentListQuerySchema.parse(value);
|
|
250
|
+
const params = new URLSearchParams(Object.entries(query).map(([key, value2]) => [key, String(value2)]));
|
|
251
|
+
const page = z4.object({ items: z4.array(z4.unknown()).max(100), nextCursor: Id3.nullable() }).strict().parse(await this.request(`?${params}`, "GET", void 0, signal));
|
|
252
|
+
const items = page.items.map((value2) => this.definition(value2));
|
|
253
|
+
if (items.length > query.limit || new Set(items.map((item) => item.id)).size !== items.length || items.some((item) => query.projectId && item.request.project?.id !== query.projectId || query.datasetHash && item.request.taskset.contentHash !== query.datasetHash))
|
|
254
|
+
throw new Error("Experiment page differs from its selected scope.");
|
|
255
|
+
return { items, nextCursor: page.nextCursor };
|
|
256
|
+
}
|
|
257
|
+
async start(value, signal) {
|
|
258
|
+
const request = StartExperimentSchema.parse(value);
|
|
259
|
+
const response = z4.object({ definition: z4.unknown(), run: z4.unknown() }).strict().parse(
|
|
260
|
+
await this.request(`/${encodeURIComponent(request.definition.id)}/start`, "POST", request, signal)
|
|
261
|
+
);
|
|
262
|
+
const definition = this.definition(response.definition, request.definition.id);
|
|
263
|
+
if (contentHash(experimentDefinitionRef(definition)) !== contentHash(request.definition)) throw new Error("Experiment Start revision mismatch.");
|
|
264
|
+
const result = await verifyModelTasksetRunDetails(response.run);
|
|
265
|
+
if (result.summary.teamId !== this.options.teamId || result.request.operationId !== request.operationId || contentHash(savedRequestPopulation(result.request)) !== contentHash(savedRequestPopulation({ ...definition.request, operationId: request.operationId })) || contentHash(result.manifest.metadata.experimentDefinition) !== contentHash(request.definition) || result.manifest.metadata.experimentConfigurationHash !== contentHash({ definition: request.definition, maximumCostUsd: definition.maximumCostUsd, graders: definition.graders }))
|
|
266
|
+
throw new Error("Experiment execution differs from its saved configuration.");
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
async result(executionId, signal) {
|
|
270
|
+
const value = z4.object({ executionId: Id3, passId: Id3.nullable(), manifest: z4.unknown(), result: z4.unknown() }).strict().parse(await this.request(`/executions/${encodeURIComponent(Id3.parse(executionId))}/result`, "GET", void 0, signal));
|
|
271
|
+
const evidence = verifyExperimentEvidence(value);
|
|
272
|
+
if (value.executionId !== executionId || evidence.manifest.teamId !== this.options.teamId || evidence.manifest.lineage?.execution.id !== executionId || evidence.manifest.lineage.scoringPassId !== value.passId) throw new Error("Experiment result identity mismatch.");
|
|
273
|
+
return { ...evidence, executionId, passId: value.passId };
|
|
274
|
+
}
|
|
275
|
+
async executions(definitionId, options = {}) {
|
|
276
|
+
const params = new URLSearchParams(options.afterId ? { afterId: Id3.parse(options.afterId) } : {});
|
|
277
|
+
const page = z4.object({ items: z4.array(z4.unknown()).max(30), nextCursor: Id3.nullable() }).strict().parse(
|
|
278
|
+
await this.request(`/${encodeURIComponent(Id3.parse(definitionId))}/executions?${params}`, "GET", void 0, options.signal)
|
|
279
|
+
);
|
|
280
|
+
const items = await Promise.all(page.items.map((value) => verifyModelTasksetRunDetails(value)));
|
|
281
|
+
if (items.some((item) => item.summary.teamId !== this.options.teamId || ExperimentDefinitionRefSchema.parse(item.manifest.metadata.experimentDefinition).id !== definitionId) || new Set(items.map((item) => item.summary.id)).size !== items.length)
|
|
282
|
+
throw new Error("Experiment execution page has invalid ownership or repeated identities.");
|
|
283
|
+
return { items, nextCursor: page.nextCursor };
|
|
284
|
+
}
|
|
285
|
+
async execution(id, signal) {
|
|
286
|
+
return this.executionDetails(await this.request(`/executions/${encodeURIComponent(Id3.parse(id))}`, "GET", void 0, signal), id);
|
|
287
|
+
}
|
|
288
|
+
async cancel(id, signal) {
|
|
289
|
+
return this.executionDetails(await this.request(`/executions/${encodeURIComponent(Id3.parse(id))}/cancel`, "POST", {}, signal), id);
|
|
290
|
+
}
|
|
291
|
+
/** Retry intentionally creates another execution; a transport retry reuses the same operation id. */
|
|
292
|
+
async retry(id, operationId, signal) {
|
|
293
|
+
const result = await this.executionDetails(await this.request(`/executions/${encodeURIComponent(Id3.parse(id))}/retry`, "POST", { operationId: Id3.parse(operationId) }, signal));
|
|
294
|
+
if (result.request.operationId !== operationId) throw new Error("Experiment retry operation mismatch.");
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
async score(value, signal) {
|
|
298
|
+
const request = ExperimentScoringRequestSchema.parse(value);
|
|
299
|
+
const pass = this.pass(await this.request(`/executions/${encodeURIComponent(request.execution.id)}/scoring-passes`, "POST", request, signal));
|
|
300
|
+
if (contentHash(pass.request) !== contentHash(request)) throw new Error("Scoring admission differs from its submitted inputs.");
|
|
301
|
+
return pass;
|
|
302
|
+
}
|
|
303
|
+
async scoringPass(id, signal) {
|
|
304
|
+
return this.pass(await this.request(`/scoring-passes/${encodeURIComponent(Id3.parse(id))}`, "GET", void 0, signal), id);
|
|
305
|
+
}
|
|
306
|
+
async scoringPasses(executionId, options = {}) {
|
|
307
|
+
const params = new URLSearchParams(options.afterId ? { afterId: Id3.parse(options.afterId) } : {});
|
|
308
|
+
const page = z4.object({ items: z4.array(z4.unknown()).max(30), nextCursor: Id3.nullable() }).strict().parse(
|
|
309
|
+
await this.request(`/executions/${encodeURIComponent(Id3.parse(executionId))}/scoring-passes?${params}`, "GET", void 0, options.signal)
|
|
310
|
+
);
|
|
311
|
+
const items = page.items.map((value) => this.pass(value));
|
|
312
|
+
if (items.some((item) => item.request.execution.id !== executionId) || new Set(items.map((item) => item.id)).size !== items.length)
|
|
313
|
+
throw new Error("Scoring pass page differs from its execution ownership.");
|
|
314
|
+
return { items, nextCursor: page.nextCursor };
|
|
315
|
+
}
|
|
316
|
+
async cancelScoringPass(id, signal) {
|
|
317
|
+
return this.pass(await this.request(`/scoring-passes/${encodeURIComponent(Id3.parse(id))}/cancel`, "POST", {}, signal), id);
|
|
318
|
+
}
|
|
319
|
+
async scoringResult(id, signal) {
|
|
320
|
+
const value = z4.object({ executionId: Id3, passId: Id3, manifest: z4.unknown(), result: z4.unknown() }).strict().parse(
|
|
321
|
+
await this.request(`/scoring-passes/${encodeURIComponent(Id3.parse(id))}/result`, "GET", void 0, signal)
|
|
322
|
+
);
|
|
323
|
+
const evidence = verifyExperimentEvidence(value);
|
|
324
|
+
if (value.passId !== id || evidence.manifest.teamId !== this.options.teamId || evidence.manifest.id !== id || evidence.manifest.lineage?.execution.id !== value.executionId || evidence.manifest.lineage.scoringPassId !== id)
|
|
325
|
+
throw new Error("Scoring result identity mismatch.");
|
|
326
|
+
return { ...evidence, executionId: value.executionId, passId: id };
|
|
327
|
+
}
|
|
328
|
+
async compare(baselineId, candidateId, signal) {
|
|
329
|
+
const read = (id) => id.startsWith("score_") ? this.scoringResult(id, signal) : this.result(id, signal);
|
|
330
|
+
const [baseline, candidate] = await Promise.all([read(baselineId), read(candidateId)]);
|
|
331
|
+
return { baseline, candidate, comparison: compareExperiments(baseline, candidate) };
|
|
332
|
+
}
|
|
333
|
+
definition(value, id) {
|
|
334
|
+
const result = verifyExperimentDefinition(value);
|
|
335
|
+
if (result.teamId !== this.options.teamId || id && result.id !== id) throw new Error("Experiment identity mismatch.");
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
async executionDetails(value, id) {
|
|
339
|
+
const details = await verifyModelTasksetRunDetails(value);
|
|
340
|
+
if (details.summary.teamId !== this.options.teamId || id && details.summary.id !== id) throw new Error("Experiment execution identity mismatch.");
|
|
341
|
+
return details;
|
|
342
|
+
}
|
|
343
|
+
pass(value, id) {
|
|
344
|
+
const pass = verifyExperimentScoringPass(value);
|
|
345
|
+
if (pass.teamId !== this.options.teamId || id && pass.id !== id) throw new Error("Scoring pass identity mismatch.");
|
|
346
|
+
return pass;
|
|
347
|
+
}
|
|
348
|
+
async request(path, method, body, signal) {
|
|
349
|
+
const response = await (this.options.fetch ?? fetch)(`${this.baseUrl}/v1/experiments${path}`, {
|
|
350
|
+
method,
|
|
351
|
+
signal,
|
|
352
|
+
redirect: "error",
|
|
353
|
+
headers: { Authorization: `Bearer ${this.options.apiKey}`, "X-OpenPond-Team-Id": this.options.teamId, "Content-Type": "application/json", Accept: "application/json" },
|
|
354
|
+
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
355
|
+
});
|
|
356
|
+
const value = await response.json();
|
|
357
|
+
if (!response.ok) {
|
|
358
|
+
const parsed = z4.object({ code: z4.string(), message: z4.string() }).safeParse(value);
|
|
359
|
+
throw new OpenPondExperimentError(response.status, parsed.success ? parsed.data.code : "experiment_request_failed", parsed.success ? parsed.data.message : "Experiment request failed.");
|
|
360
|
+
}
|
|
361
|
+
return value;
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
function savedRequestPopulation(request) {
|
|
365
|
+
return request.policy.kind === "hosted_harness" ? {
|
|
366
|
+
...request,
|
|
367
|
+
population: request.population.map(({ receiptId: _id, ...member }) => member)
|
|
368
|
+
} : request;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export {
|
|
372
|
+
ExperimentFieldMappingSchema,
|
|
373
|
+
ExperimentFieldMappingsSchema,
|
|
374
|
+
mapExperimentGradingFields,
|
|
375
|
+
ExperimentDefinitionRefSchema,
|
|
376
|
+
ExperimentGraderPinSchema,
|
|
377
|
+
ExperimentGraderSelectionSchema,
|
|
378
|
+
SaveExperimentSchema,
|
|
379
|
+
ExperimentDefinitionSchema,
|
|
380
|
+
StartExperimentSchema,
|
|
381
|
+
ExperimentListQuerySchema,
|
|
382
|
+
ExperimentExecutionContextSchema,
|
|
383
|
+
PrepareHarnessExperimentSchema,
|
|
384
|
+
PreparedHarnessExperimentSchema,
|
|
385
|
+
verifyExperimentDefinition,
|
|
386
|
+
experimentDefinitionRef,
|
|
387
|
+
ExperimentScoringRequestSchema,
|
|
388
|
+
ExperimentScoringPassSchema,
|
|
389
|
+
verifyExperimentScoringPass,
|
|
390
|
+
OpenPondExperimentError,
|
|
391
|
+
OpenPondExperimentsClient
|
|
392
|
+
};
|
|
393
|
+
//# sourceMappingURL=chunk-EMANJDJR.js.map
|