@openpond/evals 0.11.10 → 0.11.11

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.
Files changed (33) hide show
  1. package/dist/experiments.js +169 -0
  2. package/dist/index.js +1 -0
  3. package/dist/learning/authoring.js +2 -1
  4. package/dist/learning/reward-authoring.js +3 -3
  5. package/dist/rewards.js +5 -0
  6. package/dist/types/experiments.d.ts +426 -0
  7. package/dist/types/experiments.d.ts.map +1 -0
  8. package/dist/types/index.d.ts +1 -0
  9. package/dist/types/index.d.ts.map +1 -1
  10. package/dist/types/learning/admission.d.ts +1 -0
  11. package/dist/types/learning/admission.d.ts.map +1 -1
  12. package/dist/types/learning/authoring-service.d.ts +1 -0
  13. package/dist/types/learning/authoring-service.d.ts.map +1 -1
  14. package/dist/types/learning/authoring.d.ts +4 -0
  15. package/dist/types/learning/authoring.d.ts.map +1 -1
  16. package/dist/types/learning/contracts.d.ts +4 -3
  17. package/dist/types/learning/contracts.d.ts.map +1 -1
  18. package/dist/types/learning/iteration-candidate-decision.d.ts +1 -1
  19. package/dist/types/learning/operations.d.ts +6 -0
  20. package/dist/types/learning/operations.d.ts.map +1 -1
  21. package/dist/types/learning/repository.d.ts +4 -2
  22. package/dist/types/learning/repository.d.ts.map +1 -1
  23. package/dist/types/learning/reward-authoring.d.ts.map +1 -1
  24. package/dist/types/learning/reward-calibration.d.ts +1 -0
  25. package/dist/types/learning/reward-calibration.d.ts.map +1 -1
  26. package/dist/types/learning/transport.d.ts +8 -3
  27. package/dist/types/learning/transport.d.ts.map +1 -1
  28. package/dist/types/rewards.d.ts +4 -0
  29. package/dist/types/rewards.d.ts.map +1 -1
  30. package/package.json +5 -1
  31. package/schemas/learning/v1/command-request.schema.json +248 -235
  32. package/schemas/learning/v1/draft.schema.json +4 -0
  33. package/schemas/learning/v1/reward.schema.json +4 -0
@@ -0,0 +1,169 @@
1
+ import { z } from "zod";
2
+ import { ImmutableArtifactRefSchema, ImmutableReleaseRefSchema, ReleaseHashSchema, ReleaseIdSchema, ReleaseTimestampSchema, assertContentHash, contentHash, } from "@openpond/harness";
3
+ import { ProfileEvaluationRunSourceSchema } from "./profile-evaluations.js";
4
+ import { FeedbackKeySchema } from "./rewards.js";
5
+ const MoneySchema = z.number().finite().nonnegative();
6
+ export const ExperimentTargetSchema = z.discriminatedUnion("kind", [
7
+ z.object({
8
+ kind: z.literal("model"),
9
+ modelId: ReleaseIdSchema,
10
+ configurationHash: ReleaseHashSchema,
11
+ }).strict(),
12
+ z.object({
13
+ kind: z.literal("harness"),
14
+ source: ProfileEvaluationRunSourceSchema,
15
+ }).strict(),
16
+ ]);
17
+ export const ExperimentEvaluatorSchema = z.object({
18
+ release: ImmutableReleaseRefSchema.extend({ revision: z.number().int().positive() }).strict(),
19
+ feedbackKey: FeedbackKeySchema,
20
+ output: z.enum(["boolean", "score", "category"]),
21
+ /** Category labels are meaningful only for category output. */
22
+ categories: z.array(z.string().trim().min(1).max(120)).max(50),
23
+ }).strict().superRefine((value, context) => {
24
+ if ((value.output === "category") !== (value.categories.length > 0))
25
+ context.addIssue({ code: "custom", path: ["categories"], message: "Only category feedback declares categories." });
26
+ if (new Set(value.categories).size !== value.categories.length)
27
+ context.addIssue({ code: "custom", path: ["categories"], message: "Feedback categories must be unique." });
28
+ });
29
+ export const ExperimentCaseIdentitySchema = z.object({
30
+ caseId: ReleaseIdSchema,
31
+ seed: z.string().trim().min(1).max(500),
32
+ fixtureId: ReleaseIdSchema.nullable(),
33
+ }).strict();
34
+ export function experimentCaseKey(identity) {
35
+ const value = ExperimentCaseIdentitySchema.parse(identity);
36
+ return JSON.stringify([value.caseId, value.seed, value.fixtureId]);
37
+ }
38
+ export const ExperimentManifestContentSchema = z.object({
39
+ schemaVersion: z.literal("openpond.experimentManifest.v1"),
40
+ id: ReleaseIdSchema,
41
+ name: z.string().trim().min(1).max(500),
42
+ teamId: ReleaseIdSchema,
43
+ operationId: ReleaseIdSchema,
44
+ maximumCostUsd: MoneySchema,
45
+ dataset: ImmutableReleaseRefSchema.extend({ revision: z.number().int().positive() }).strict(),
46
+ target: ExperimentTargetSchema,
47
+ evaluators: z.array(ExperimentEvaluatorSchema).max(100),
48
+ population: z.array(ExperimentCaseIdentitySchema).min(1).max(10_000),
49
+ createdAt: ReleaseTimestampSchema,
50
+ }).strict().superRefine((value, context) => {
51
+ if (new Set(value.population.map(experimentCaseKey)).size !== value.population.length)
52
+ context.addIssue({ code: "custom", path: ["population"], message: "Experiment cases must be unique." });
53
+ if (new Set(value.evaluators.map((item) => item.feedbackKey)).size !== value.evaluators.length)
54
+ context.addIssue({ code: "custom", path: ["evaluators"], message: "Experiment feedback keys must be unique." });
55
+ });
56
+ export const ExperimentManifestSchema = ExperimentManifestContentSchema.extend({ contentHash: ReleaseHashSchema }).strict();
57
+ export const ExperimentFeedbackSchema = z.object({
58
+ feedbackKey: FeedbackKeySchema,
59
+ evaluator: ExperimentEvaluatorSchema.shape.release,
60
+ status: z.enum(["scored", "unavailable", "failed", "pending"]),
61
+ value: z.union([z.boolean(), z.number().finite(), z.string().max(120)]).nullable(),
62
+ reasoning: z.string().max(20_000).nullable(),
63
+ evidenceRefs: z.array(ImmutableArtifactRefSchema).max(1_000),
64
+ }).strict();
65
+ export const ExperimentUsageSchema = z.object({
66
+ inputTokens: z.number().int().nonnegative().nullable(),
67
+ outputTokens: z.number().int().nonnegative().nullable(),
68
+ totalTokens: z.number().int().nonnegative().nullable(),
69
+ costUsd: MoneySchema.nullable(),
70
+ latencyMs: z.number().finite().nonnegative().nullable(),
71
+ }).strict().superRefine((usage, context) => {
72
+ if (usage.inputTokens !== null && usage.outputTokens !== null && usage.totalTokens !== null
73
+ && usage.totalTokens < usage.inputTokens + usage.outputTokens)
74
+ context.addIssue({ code: "custom", path: ["totalTokens"], message: "Total tokens cannot be less than input plus output." });
75
+ });
76
+ export const ExperimentCaseResultSchema = z.object({
77
+ identity: ExperimentCaseIdentitySchema,
78
+ status: z.enum(["completed", "failed", "cancelled", "unavailable"]),
79
+ output: z.unknown().nullable(),
80
+ error: z.object({ code: ReleaseIdSchema, message: z.string().max(2_000) }).strict().nullable(),
81
+ feedback: z.array(ExperimentFeedbackSchema).max(100),
82
+ usage: ExperimentUsageSchema,
83
+ traceRef: ImmutableArtifactRefSchema.nullable(),
84
+ startedAt: ReleaseTimestampSchema.nullable(),
85
+ completedAt: ReleaseTimestampSchema.nullable(),
86
+ }).strict();
87
+ export const ExperimentResultContentSchema = z.object({
88
+ schemaVersion: z.literal("openpond.experimentResult.v1"),
89
+ manifest: ImmutableReleaseRefSchema,
90
+ status: z.enum(["completed", "failed", "cancelled"]),
91
+ cases: z.array(ExperimentCaseResultSchema).min(1).max(10_000),
92
+ completedAt: ReleaseTimestampSchema,
93
+ }).strict();
94
+ export const ExperimentResultSchema = ExperimentResultContentSchema.extend({ contentHash: ReleaseHashSchema }).strict();
95
+ export function createExperimentManifest(input) {
96
+ const value = ExperimentManifestContentSchema.parse(input);
97
+ return ExperimentManifestSchema.parse({ ...value, contentHash: contentHash(value) });
98
+ }
99
+ export function createExperimentResult(input, manifest) {
100
+ ExperimentManifestSchema.parse(manifest);
101
+ assertContentHash(manifest, "Experiment manifest");
102
+ const value = ExperimentResultContentSchema.parse(input);
103
+ if (value.manifest.id !== manifest.id || value.manifest.contentHash !== manifest.contentHash)
104
+ throw new Error("Experiment result differs from its manifest.");
105
+ const expected = new Set(manifest.population.map(experimentCaseKey));
106
+ const seen = new Set();
107
+ const evaluators = new Map(manifest.evaluators.map((item) => [item.feedbackKey, item]));
108
+ for (const result of value.cases) {
109
+ const key = experimentCaseKey(result.identity);
110
+ if (!expected.has(key) || seen.has(key))
111
+ throw new Error("Experiment result has an unexpected or repeated case.");
112
+ seen.add(key);
113
+ const feedbackKeys = new Set();
114
+ for (const feedback of result.feedback) {
115
+ const evaluator = evaluators.get(feedback.feedbackKey);
116
+ if (!evaluator || feedbackKeys.has(feedback.feedbackKey)
117
+ || feedback.evaluator.id !== evaluator.release.id
118
+ || feedback.evaluator.contentHash !== evaluator.release.contentHash
119
+ || feedback.evaluator.revision !== evaluator.release.revision)
120
+ throw new Error("Experiment feedback differs from its pinned evaluator.");
121
+ feedbackKeys.add(feedback.feedbackKey);
122
+ if (feedback.status === "scored") {
123
+ if (feedback.value === null || typeof feedback.value !== { boolean: "boolean", score: "number", category: "string" }[evaluator.output]
124
+ || (evaluator.output === "category" && !evaluator.categories.includes(feedback.value))
125
+ || (evaluator.output === "score" && (feedback.value < 0 || feedback.value > 1)))
126
+ throw new Error("Experiment feedback value violates its output contract.");
127
+ }
128
+ else if (feedback.value !== null)
129
+ throw new Error("Unscored experiment feedback cannot claim a value.");
130
+ }
131
+ }
132
+ if (seen.size !== expected.size)
133
+ throw new Error("Experiment result omits admitted cases.");
134
+ return ExperimentResultSchema.parse({ ...value, contentHash: contentHash(value) });
135
+ }
136
+ /** A comparison reads retained results; it never executes or regrades a case. */
137
+ export function compareExperiments(baseline, candidate) {
138
+ for (const pair of [baseline, candidate]) {
139
+ const { contentHash: hash, ...value } = ExperimentResultSchema.parse(pair.result);
140
+ if (contentHash(value) !== hash)
141
+ throw new Error("Experiment result integrity failed.");
142
+ createExperimentResult(value, pair.manifest);
143
+ }
144
+ const reasons = [];
145
+ if (baseline.manifest.teamId !== candidate.manifest.teamId)
146
+ reasons.push("different_workspace");
147
+ if (baseline.manifest.dataset.id !== candidate.manifest.dataset.id
148
+ || baseline.manifest.dataset.contentHash !== candidate.manifest.dataset.contentHash
149
+ || baseline.manifest.dataset.revision !== candidate.manifest.dataset.revision)
150
+ reasons.push("different_dataset_version");
151
+ if (baseline.manifest.target.kind !== candidate.manifest.target.kind)
152
+ reasons.push("different_target_kind");
153
+ if (contentHash(baseline.manifest.evaluators) !== contentHash(candidate.manifest.evaluators))
154
+ reasons.push("different_evaluators");
155
+ const left = new Map(baseline.result.cases.map((item) => [experimentCaseKey(item.identity), item]));
156
+ const right = new Map(candidate.result.cases.map((item) => [experimentCaseKey(item.identity), item]));
157
+ const keys = [...new Set([...left.keys(), ...right.keys()])].sort();
158
+ if (left.size !== right.size || keys.some((key) => !left.has(key) || !right.has(key)))
159
+ reasons.push("different_population");
160
+ return {
161
+ comparable: reasons.length === 0,
162
+ reasons,
163
+ cases: keys.map((key) => ({
164
+ identity: (left.get(key) ?? right.get(key)).identity,
165
+ baseline: left.get(key) ?? null,
166
+ candidate: right.get(key) ?? null,
167
+ })),
168
+ };
169
+ }
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export * from "./artifact-verification.js";
4
4
  export * from "./evidence/index.js";
5
5
  export * from "./execution-contracts.js";
6
6
  export * from "./execution-receipts.js";
7
+ export * from "./experiments.js";
7
8
  export * from "./graders.js";
8
9
  export * from "./harness.js";
9
10
  export * from "./learned-preference.js";
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { ReleaseHashSchema, ReleaseIdSchema, ReleaseTimestampSchema } from "@openpond/harness";
3
- import { RewardBindingSourceSchema, RewardReleaseRefSchema } from "../rewards.js";
3
+ import { FeedbackKeySchema, RewardBindingSourceSchema, RewardReleaseRefSchema } from "../rewards.js";
4
4
  import { LearningRevisionRefSchema } from "./contracts.js";
5
5
  /** Strings intentionally preserve incomplete JSON/code until explicit publication. */
6
6
  export const RewardFixtureAuthoringFieldsSchema = z.object({
@@ -14,6 +14,7 @@ export const RewardFixtureAuthoringFieldsSchema = z.object({
14
14
  }).strict();
15
15
  export const RewardAuthoringFieldsSchema = z.object({
16
16
  name: z.string().max(500), description: z.string().max(10_000),
17
+ feedbackKey: FeedbackKeySchema.optional(),
17
18
  kind: z.enum(["custom_verifier", "state", "content", "schema", "artifact", "runtime_event", "model_judge", "learned_model", "human"]),
18
19
  fields: z.string(), outputField: z.string(), expectedField: z.string(), expectedValue: z.string(),
19
20
  schema: z.string(), reference: z.string(), events: z.string(), code: z.string(), exportName: z.string(), timeout: z.string(),
@@ -1,4 +1,4 @@
1
- import { RewardReleaseSchema, createRewardRelease } from "../rewards.js";
1
+ import { RewardReleaseSchema, createRewardRelease, feedbackKeyForReward } from "../rewards.js";
2
2
  import { assertBoundedTaskJson } from "../task-schema.js";
3
3
  import { RewardAuthoringFieldsSchema, RewardFixtureAuthoringFieldsSchema } from "./authoring.js";
4
4
  import { createLearningTextAsset, verifyLearningTextAsset } from "./assets.js";
@@ -64,7 +64,7 @@ export function compileRewardAuthoring(input) {
64
64
  const assets = [...(asset ? [asset] : []), ...(fixtureAsset ? [fixtureAsset] : [])];
65
65
  const reward = createRewardRelease({
66
66
  schemaVersion: "openpond.rewardRelease.v1", id: input.id, revision: (base?.revision ?? 0) + 1,
67
- name: fields.name, description: fields.description, implementation,
67
+ name: fields.name, description: fields.description, feedbackKey: fields.feedbackKey ?? feedbackKeyForReward({ id: input.id }), implementation,
68
68
  rawScore: fields.kind === "learned_model" ? { minimum: authoringNumber(fields.minimum, "Minimum score"), maximum: authoringNumber(fields.maximum, "Maximum score") } : { minimum: 0, maximum: 1 },
69
69
  assets: assets.map(value => value.asset), ...(fixtureAsset ? { fixtureSetRef: fixtureAsset.asset } : {}),
70
70
  ...(calibrationCheckRef ? { calibrationCheckRef } : {}),
@@ -84,7 +84,7 @@ export function rewardAuthoringFields(reward, sourceAsset, fixtureAsset = null)
84
84
  const fixtures = reward?.fixtureSetRef && fixtureAsset ? RewardFixtureAuthoringFieldsSchema.array().max(50).parse(JSON.parse(verifyLearningTextAsset(fixtureAsset, reward.fixtureSetRef))) : [];
85
85
  const config = implementation && "config" in implementation ? implementation.config : {};
86
86
  return {
87
- name: reward?.name ?? "", description: reward?.description ?? "", kind: implementation?.kind ?? "state",
87
+ name: reward?.name ?? "", description: reward?.description ?? "", ...(reward?.feedbackKey ? { feedbackKey: reward.feedbackKey } : {}), kind: implementation?.kind ?? "state",
88
88
  fields: strings(config.fields).join(", ") || "answer", outputField: text(config.outputField) || "text", expectedField: text(config.expectedField) || "text", expectedValue: text(config.expectedValue),
89
89
  schema: JSON.stringify(config.jsonSchema ?? { type: "object", properties: { answer: { type: "string" } }, required: ["answer"] }, null, 2),
90
90
  reference: text(config.refIncludes), events: strings(config.requiredEvents).join(", "),
package/dist/rewards.js CHANGED
@@ -5,6 +5,10 @@ import { gradeEvidence, GraderEvidenceSchema } from "./graders.js";
5
5
  import { CustomVerifierGraderSpecSchema, DeterministicGraderSpecSchema, GraderSpecSchema, HumanGraderSpecSchema, ModelJudgeGraderSpecSchema } from "./tasksets.js";
6
6
  import { assertBoundedTaskJson, validateTaskSchema } from "./task-schema.js";
7
7
  const bindingFields = { id: true, version: true, weight: true, hardGate: true, rewardEligible: true, privileged: true };
8
+ export const FeedbackKeySchema = z.string().regex(/^[a-z][a-z0-9_]{0,79}$/);
9
+ export function feedbackKeyForReward(reward) {
10
+ return reward.feedbackKey ?? `reward_${contentHash(reward.id).slice(0, 24)}`;
11
+ }
8
12
  export const RewardImplementationSchema = z.union([
9
13
  DeterministicGraderSpecSchema.omit(bindingFields),
10
14
  ModelJudgeGraderSpecSchema.omit(bindingFields),
@@ -18,6 +22,7 @@ export const RewardReleaseContentSchema = z.object({
18
22
  revision: z.number().int().positive(),
19
23
  name: z.string().trim().min(1).max(500),
20
24
  description: z.string().max(10_000),
25
+ feedbackKey: FeedbackKeySchema.optional(),
21
26
  implementation: RewardImplementationSchema,
22
27
  rawScore: z.object({ minimum: z.number().finite(), maximum: z.number().finite() }).strict(),
23
28
  assets: z.array(ImmutableAssetRefSchema).max(1_000),
@@ -0,0 +1,426 @@
1
+ import { z } from "zod";
2
+ export declare const ExperimentTargetSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
+ kind: z.ZodLiteral<"model">;
4
+ modelId: z.ZodString;
5
+ configurationHash: z.ZodString;
6
+ }, z.core.$strict>, z.ZodObject<{
7
+ kind: z.ZodLiteral<"harness">;
8
+ source: z.ZodObject<{
9
+ profileId: z.ZodString;
10
+ sourceRevision: z.ZodString;
11
+ harnessRelease: z.ZodObject<{
12
+ id: z.ZodString;
13
+ contentHash: z.ZodString;
14
+ }, z.core.$strict>;
15
+ catalogHash: z.ZodString;
16
+ definitionId: z.ZodString;
17
+ definitionHash: z.ZodString;
18
+ target: z.ZodDiscriminatedUnion<[z.ZodObject<{
19
+ kind: z.ZodLiteral<"profile">;
20
+ }, z.core.$strict>, z.ZodObject<{
21
+ kind: z.ZodLiteral<"workflow">;
22
+ workflowId: z.ZodString;
23
+ }, z.core.$strict>, z.ZodObject<{
24
+ kind: z.ZodLiteral<"skill">;
25
+ skillPath: z.ZodString;
26
+ }, z.core.$strict>, z.ZodObject<{
27
+ kind: z.ZodLiteral<"agent_action">;
28
+ actionId: z.ZodString;
29
+ }, z.core.$strict>], "kind">;
30
+ environmentHash: z.ZodString;
31
+ }, z.core.$strict>;
32
+ }, z.core.$strict>], "kind">;
33
+ export declare const ExperimentEvaluatorSchema: z.ZodObject<{
34
+ release: z.ZodObject<{
35
+ id: z.ZodString;
36
+ contentHash: z.ZodString;
37
+ revision: z.ZodNumber;
38
+ }, z.core.$strict>;
39
+ feedbackKey: z.ZodString;
40
+ output: z.ZodEnum<{
41
+ boolean: "boolean";
42
+ score: "score";
43
+ category: "category";
44
+ }>;
45
+ categories: z.ZodArray<z.ZodString>;
46
+ }, z.core.$strict>;
47
+ export declare const ExperimentCaseIdentitySchema: z.ZodObject<{
48
+ caseId: z.ZodString;
49
+ seed: z.ZodString;
50
+ fixtureId: z.ZodNullable<z.ZodString>;
51
+ }, z.core.$strict>;
52
+ export type ExperimentCaseIdentity = z.infer<typeof ExperimentCaseIdentitySchema>;
53
+ export declare function experimentCaseKey(identity: ExperimentCaseIdentity): string;
54
+ export declare const ExperimentManifestContentSchema: z.ZodObject<{
55
+ schemaVersion: z.ZodLiteral<"openpond.experimentManifest.v1">;
56
+ id: z.ZodString;
57
+ name: z.ZodString;
58
+ teamId: z.ZodString;
59
+ operationId: z.ZodString;
60
+ maximumCostUsd: z.ZodNumber;
61
+ dataset: z.ZodObject<{
62
+ id: z.ZodString;
63
+ contentHash: z.ZodString;
64
+ revision: z.ZodNumber;
65
+ }, z.core.$strict>;
66
+ target: z.ZodDiscriminatedUnion<[z.ZodObject<{
67
+ kind: z.ZodLiteral<"model">;
68
+ modelId: z.ZodString;
69
+ configurationHash: z.ZodString;
70
+ }, z.core.$strict>, z.ZodObject<{
71
+ kind: z.ZodLiteral<"harness">;
72
+ source: z.ZodObject<{
73
+ profileId: z.ZodString;
74
+ sourceRevision: z.ZodString;
75
+ harnessRelease: z.ZodObject<{
76
+ id: z.ZodString;
77
+ contentHash: z.ZodString;
78
+ }, z.core.$strict>;
79
+ catalogHash: z.ZodString;
80
+ definitionId: z.ZodString;
81
+ definitionHash: z.ZodString;
82
+ target: z.ZodDiscriminatedUnion<[z.ZodObject<{
83
+ kind: z.ZodLiteral<"profile">;
84
+ }, z.core.$strict>, z.ZodObject<{
85
+ kind: z.ZodLiteral<"workflow">;
86
+ workflowId: z.ZodString;
87
+ }, z.core.$strict>, z.ZodObject<{
88
+ kind: z.ZodLiteral<"skill">;
89
+ skillPath: z.ZodString;
90
+ }, z.core.$strict>, z.ZodObject<{
91
+ kind: z.ZodLiteral<"agent_action">;
92
+ actionId: z.ZodString;
93
+ }, z.core.$strict>], "kind">;
94
+ environmentHash: z.ZodString;
95
+ }, z.core.$strict>;
96
+ }, z.core.$strict>], "kind">;
97
+ evaluators: z.ZodArray<z.ZodObject<{
98
+ release: z.ZodObject<{
99
+ id: z.ZodString;
100
+ contentHash: z.ZodString;
101
+ revision: z.ZodNumber;
102
+ }, z.core.$strict>;
103
+ feedbackKey: z.ZodString;
104
+ output: z.ZodEnum<{
105
+ boolean: "boolean";
106
+ score: "score";
107
+ category: "category";
108
+ }>;
109
+ categories: z.ZodArray<z.ZodString>;
110
+ }, z.core.$strict>>;
111
+ population: z.ZodArray<z.ZodObject<{
112
+ caseId: z.ZodString;
113
+ seed: z.ZodString;
114
+ fixtureId: z.ZodNullable<z.ZodString>;
115
+ }, z.core.$strict>>;
116
+ createdAt: z.ZodString;
117
+ }, z.core.$strict>;
118
+ export declare const ExperimentManifestSchema: z.ZodObject<{
119
+ schemaVersion: z.ZodLiteral<"openpond.experimentManifest.v1">;
120
+ id: z.ZodString;
121
+ name: z.ZodString;
122
+ teamId: z.ZodString;
123
+ operationId: z.ZodString;
124
+ maximumCostUsd: z.ZodNumber;
125
+ dataset: z.ZodObject<{
126
+ id: z.ZodString;
127
+ contentHash: z.ZodString;
128
+ revision: z.ZodNumber;
129
+ }, z.core.$strict>;
130
+ target: z.ZodDiscriminatedUnion<[z.ZodObject<{
131
+ kind: z.ZodLiteral<"model">;
132
+ modelId: z.ZodString;
133
+ configurationHash: z.ZodString;
134
+ }, z.core.$strict>, z.ZodObject<{
135
+ kind: z.ZodLiteral<"harness">;
136
+ source: z.ZodObject<{
137
+ profileId: z.ZodString;
138
+ sourceRevision: z.ZodString;
139
+ harnessRelease: z.ZodObject<{
140
+ id: z.ZodString;
141
+ contentHash: z.ZodString;
142
+ }, z.core.$strict>;
143
+ catalogHash: z.ZodString;
144
+ definitionId: z.ZodString;
145
+ definitionHash: z.ZodString;
146
+ target: z.ZodDiscriminatedUnion<[z.ZodObject<{
147
+ kind: z.ZodLiteral<"profile">;
148
+ }, z.core.$strict>, z.ZodObject<{
149
+ kind: z.ZodLiteral<"workflow">;
150
+ workflowId: z.ZodString;
151
+ }, z.core.$strict>, z.ZodObject<{
152
+ kind: z.ZodLiteral<"skill">;
153
+ skillPath: z.ZodString;
154
+ }, z.core.$strict>, z.ZodObject<{
155
+ kind: z.ZodLiteral<"agent_action">;
156
+ actionId: z.ZodString;
157
+ }, z.core.$strict>], "kind">;
158
+ environmentHash: z.ZodString;
159
+ }, z.core.$strict>;
160
+ }, z.core.$strict>], "kind">;
161
+ evaluators: z.ZodArray<z.ZodObject<{
162
+ release: z.ZodObject<{
163
+ id: z.ZodString;
164
+ contentHash: z.ZodString;
165
+ revision: z.ZodNumber;
166
+ }, z.core.$strict>;
167
+ feedbackKey: z.ZodString;
168
+ output: z.ZodEnum<{
169
+ boolean: "boolean";
170
+ score: "score";
171
+ category: "category";
172
+ }>;
173
+ categories: z.ZodArray<z.ZodString>;
174
+ }, z.core.$strict>>;
175
+ population: z.ZodArray<z.ZodObject<{
176
+ caseId: z.ZodString;
177
+ seed: z.ZodString;
178
+ fixtureId: z.ZodNullable<z.ZodString>;
179
+ }, z.core.$strict>>;
180
+ createdAt: z.ZodString;
181
+ contentHash: z.ZodString;
182
+ }, z.core.$strict>;
183
+ export type ExperimentManifest = z.infer<typeof ExperimentManifestSchema>;
184
+ export declare const ExperimentFeedbackSchema: z.ZodObject<{
185
+ feedbackKey: z.ZodString;
186
+ evaluator: z.ZodObject<{
187
+ id: z.ZodString;
188
+ contentHash: z.ZodString;
189
+ revision: z.ZodNumber;
190
+ }, z.core.$strict>;
191
+ status: z.ZodEnum<{
192
+ pending: "pending";
193
+ failed: "failed";
194
+ scored: "scored";
195
+ unavailable: "unavailable";
196
+ }>;
197
+ value: z.ZodNullable<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodString]>>;
198
+ reasoning: z.ZodNullable<z.ZodString>;
199
+ evidenceRefs: z.ZodArray<z.ZodObject<{
200
+ id: z.ZodString;
201
+ contentHash: z.ZodString;
202
+ mediaType: z.ZodDefault<z.ZodNullable<z.ZodString>>;
203
+ sizeBytes: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
204
+ }, z.core.$strict>>;
205
+ }, z.core.$strict>;
206
+ export declare const ExperimentUsageSchema: z.ZodObject<{
207
+ inputTokens: z.ZodNullable<z.ZodNumber>;
208
+ outputTokens: z.ZodNullable<z.ZodNumber>;
209
+ totalTokens: z.ZodNullable<z.ZodNumber>;
210
+ costUsd: z.ZodNullable<z.ZodNumber>;
211
+ latencyMs: z.ZodNullable<z.ZodNumber>;
212
+ }, z.core.$strict>;
213
+ export declare const ExperimentCaseResultSchema: z.ZodObject<{
214
+ identity: z.ZodObject<{
215
+ caseId: z.ZodString;
216
+ seed: z.ZodString;
217
+ fixtureId: z.ZodNullable<z.ZodString>;
218
+ }, z.core.$strict>;
219
+ status: z.ZodEnum<{
220
+ failed: "failed";
221
+ completed: "completed";
222
+ cancelled: "cancelled";
223
+ unavailable: "unavailable";
224
+ }>;
225
+ output: z.ZodNullable<z.ZodUnknown>;
226
+ error: z.ZodNullable<z.ZodObject<{
227
+ code: z.ZodString;
228
+ message: z.ZodString;
229
+ }, z.core.$strict>>;
230
+ feedback: z.ZodArray<z.ZodObject<{
231
+ feedbackKey: z.ZodString;
232
+ evaluator: z.ZodObject<{
233
+ id: z.ZodString;
234
+ contentHash: z.ZodString;
235
+ revision: z.ZodNumber;
236
+ }, z.core.$strict>;
237
+ status: z.ZodEnum<{
238
+ pending: "pending";
239
+ failed: "failed";
240
+ scored: "scored";
241
+ unavailable: "unavailable";
242
+ }>;
243
+ value: z.ZodNullable<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodString]>>;
244
+ reasoning: z.ZodNullable<z.ZodString>;
245
+ evidenceRefs: z.ZodArray<z.ZodObject<{
246
+ id: z.ZodString;
247
+ contentHash: z.ZodString;
248
+ mediaType: z.ZodDefault<z.ZodNullable<z.ZodString>>;
249
+ sizeBytes: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
250
+ }, z.core.$strict>>;
251
+ }, z.core.$strict>>;
252
+ usage: z.ZodObject<{
253
+ inputTokens: z.ZodNullable<z.ZodNumber>;
254
+ outputTokens: z.ZodNullable<z.ZodNumber>;
255
+ totalTokens: z.ZodNullable<z.ZodNumber>;
256
+ costUsd: z.ZodNullable<z.ZodNumber>;
257
+ latencyMs: z.ZodNullable<z.ZodNumber>;
258
+ }, z.core.$strict>;
259
+ traceRef: z.ZodNullable<z.ZodObject<{
260
+ id: z.ZodString;
261
+ contentHash: z.ZodString;
262
+ mediaType: z.ZodDefault<z.ZodNullable<z.ZodString>>;
263
+ sizeBytes: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
264
+ }, z.core.$strict>>;
265
+ startedAt: z.ZodNullable<z.ZodString>;
266
+ completedAt: z.ZodNullable<z.ZodString>;
267
+ }, z.core.$strict>;
268
+ export declare const ExperimentResultContentSchema: z.ZodObject<{
269
+ schemaVersion: z.ZodLiteral<"openpond.experimentResult.v1">;
270
+ manifest: z.ZodObject<{
271
+ id: z.ZodString;
272
+ contentHash: z.ZodString;
273
+ }, z.core.$strict>;
274
+ status: z.ZodEnum<{
275
+ failed: "failed";
276
+ completed: "completed";
277
+ cancelled: "cancelled";
278
+ }>;
279
+ cases: z.ZodArray<z.ZodObject<{
280
+ identity: z.ZodObject<{
281
+ caseId: z.ZodString;
282
+ seed: z.ZodString;
283
+ fixtureId: z.ZodNullable<z.ZodString>;
284
+ }, z.core.$strict>;
285
+ status: z.ZodEnum<{
286
+ failed: "failed";
287
+ completed: "completed";
288
+ cancelled: "cancelled";
289
+ unavailable: "unavailable";
290
+ }>;
291
+ output: z.ZodNullable<z.ZodUnknown>;
292
+ error: z.ZodNullable<z.ZodObject<{
293
+ code: z.ZodString;
294
+ message: z.ZodString;
295
+ }, z.core.$strict>>;
296
+ feedback: z.ZodArray<z.ZodObject<{
297
+ feedbackKey: z.ZodString;
298
+ evaluator: z.ZodObject<{
299
+ id: z.ZodString;
300
+ contentHash: z.ZodString;
301
+ revision: z.ZodNumber;
302
+ }, z.core.$strict>;
303
+ status: z.ZodEnum<{
304
+ pending: "pending";
305
+ failed: "failed";
306
+ scored: "scored";
307
+ unavailable: "unavailable";
308
+ }>;
309
+ value: z.ZodNullable<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodString]>>;
310
+ reasoning: z.ZodNullable<z.ZodString>;
311
+ evidenceRefs: z.ZodArray<z.ZodObject<{
312
+ id: z.ZodString;
313
+ contentHash: z.ZodString;
314
+ mediaType: z.ZodDefault<z.ZodNullable<z.ZodString>>;
315
+ sizeBytes: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
316
+ }, z.core.$strict>>;
317
+ }, z.core.$strict>>;
318
+ usage: z.ZodObject<{
319
+ inputTokens: z.ZodNullable<z.ZodNumber>;
320
+ outputTokens: z.ZodNullable<z.ZodNumber>;
321
+ totalTokens: z.ZodNullable<z.ZodNumber>;
322
+ costUsd: z.ZodNullable<z.ZodNumber>;
323
+ latencyMs: z.ZodNullable<z.ZodNumber>;
324
+ }, z.core.$strict>;
325
+ traceRef: z.ZodNullable<z.ZodObject<{
326
+ id: z.ZodString;
327
+ contentHash: z.ZodString;
328
+ mediaType: z.ZodDefault<z.ZodNullable<z.ZodString>>;
329
+ sizeBytes: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
330
+ }, z.core.$strict>>;
331
+ startedAt: z.ZodNullable<z.ZodString>;
332
+ completedAt: z.ZodNullable<z.ZodString>;
333
+ }, z.core.$strict>>;
334
+ completedAt: z.ZodString;
335
+ }, z.core.$strict>;
336
+ export declare const ExperimentResultSchema: z.ZodObject<{
337
+ schemaVersion: z.ZodLiteral<"openpond.experimentResult.v1">;
338
+ manifest: z.ZodObject<{
339
+ id: z.ZodString;
340
+ contentHash: z.ZodString;
341
+ }, z.core.$strict>;
342
+ status: z.ZodEnum<{
343
+ failed: "failed";
344
+ completed: "completed";
345
+ cancelled: "cancelled";
346
+ }>;
347
+ cases: z.ZodArray<z.ZodObject<{
348
+ identity: z.ZodObject<{
349
+ caseId: z.ZodString;
350
+ seed: z.ZodString;
351
+ fixtureId: z.ZodNullable<z.ZodString>;
352
+ }, z.core.$strict>;
353
+ status: z.ZodEnum<{
354
+ failed: "failed";
355
+ completed: "completed";
356
+ cancelled: "cancelled";
357
+ unavailable: "unavailable";
358
+ }>;
359
+ output: z.ZodNullable<z.ZodUnknown>;
360
+ error: z.ZodNullable<z.ZodObject<{
361
+ code: z.ZodString;
362
+ message: z.ZodString;
363
+ }, z.core.$strict>>;
364
+ feedback: z.ZodArray<z.ZodObject<{
365
+ feedbackKey: z.ZodString;
366
+ evaluator: z.ZodObject<{
367
+ id: z.ZodString;
368
+ contentHash: z.ZodString;
369
+ revision: z.ZodNumber;
370
+ }, z.core.$strict>;
371
+ status: z.ZodEnum<{
372
+ pending: "pending";
373
+ failed: "failed";
374
+ scored: "scored";
375
+ unavailable: "unavailable";
376
+ }>;
377
+ value: z.ZodNullable<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodString]>>;
378
+ reasoning: z.ZodNullable<z.ZodString>;
379
+ evidenceRefs: z.ZodArray<z.ZodObject<{
380
+ id: z.ZodString;
381
+ contentHash: z.ZodString;
382
+ mediaType: z.ZodDefault<z.ZodNullable<z.ZodString>>;
383
+ sizeBytes: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
384
+ }, z.core.$strict>>;
385
+ }, z.core.$strict>>;
386
+ usage: z.ZodObject<{
387
+ inputTokens: z.ZodNullable<z.ZodNumber>;
388
+ outputTokens: z.ZodNullable<z.ZodNumber>;
389
+ totalTokens: z.ZodNullable<z.ZodNumber>;
390
+ costUsd: z.ZodNullable<z.ZodNumber>;
391
+ latencyMs: z.ZodNullable<z.ZodNumber>;
392
+ }, z.core.$strict>;
393
+ traceRef: z.ZodNullable<z.ZodObject<{
394
+ id: z.ZodString;
395
+ contentHash: z.ZodString;
396
+ mediaType: z.ZodDefault<z.ZodNullable<z.ZodString>>;
397
+ sizeBytes: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
398
+ }, z.core.$strict>>;
399
+ startedAt: z.ZodNullable<z.ZodString>;
400
+ completedAt: z.ZodNullable<z.ZodString>;
401
+ }, z.core.$strict>>;
402
+ completedAt: z.ZodString;
403
+ contentHash: z.ZodString;
404
+ }, z.core.$strict>;
405
+ export type ExperimentResult = z.infer<typeof ExperimentResultSchema>;
406
+ export declare function createExperimentManifest(input: z.input<typeof ExperimentManifestContentSchema>): ExperimentManifest;
407
+ export declare function createExperimentResult(input: z.input<typeof ExperimentResultContentSchema>, manifest: ExperimentManifest): ExperimentResult;
408
+ export type ExperimentComparison = {
409
+ comparable: boolean;
410
+ reasons: string[];
411
+ cases: Array<{
412
+ identity: ExperimentCaseIdentity;
413
+ baseline: ExperimentCaseResult | null;
414
+ candidate: ExperimentCaseResult | null;
415
+ }>;
416
+ };
417
+ export type ExperimentCaseResult = z.infer<typeof ExperimentCaseResultSchema>;
418
+ /** A comparison reads retained results; it never executes or regrades a case. */
419
+ export declare function compareExperiments(baseline: {
420
+ manifest: ExperimentManifest;
421
+ result: ExperimentResult;
422
+ }, candidate: {
423
+ manifest: ExperimentManifest;
424
+ result: ExperimentResult;
425
+ }): ExperimentComparison;
426
+ //# sourceMappingURL=experiments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experiments.d.ts","sourceRoot":"","sources":["../../../../src/experiments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAUjC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;kBAWpC,CAAC;AAEH,eAAO,MAAM,4BAA4B;;;;kBAI9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,CAG1E;AAED,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiB1C,CAAC;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAsF,CAAC;AAC5H,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;kBAO1B,CAAC;AAEZ,eAAO,MAAM,qBAAqB;;;;;;kBAUhC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAU5B,CAAC;AAEZ,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAM/B,CAAC;AACZ,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAoF,CAAC;AACxH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,GAAG,kBAAkB,CAGnH;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,EAAE,QAAQ,EAAE,kBAAkB,GAAG,gBAAgB,CAgC3I;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,sBAAsB,CAAC;QAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACnI,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,iFAAiF;AACjF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE;IAAE,QAAQ,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,EACpE,SAAS,EAAE;IAAE,QAAQ,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GACpE,oBAAoB,CA0BtB"}