@tangle-network/agent-eval 0.123.8 → 0.125.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +29 -4
  2. package/dist/analyst/index.d.ts +5 -0
  3. package/dist/analyst/index.js +4 -4
  4. package/dist/benchmarks/index.js +4 -4
  5. package/dist/campaign/index.d.ts +20 -1
  6. package/dist/campaign/index.js +4 -4
  7. package/dist/{chunk-ZU3QWGZE.js → chunk-A62YMFWA.js} +89 -8
  8. package/dist/chunk-A62YMFWA.js.map +1 -0
  9. package/dist/{chunk-BUR5R4R4.js → chunk-A6GT67HT.js} +3 -3
  10. package/dist/{chunk-EEHHBAWH.js → chunk-DT7OXY3C.js} +2 -2
  11. package/dist/{chunk-PDHIOKRE.js → chunk-EQUK3RFS.js} +8 -4
  12. package/dist/chunk-EQUK3RFS.js.map +1 -0
  13. package/dist/{chunk-V7HQGZBT.js → chunk-GID26AN4.js} +2 -2
  14. package/dist/{chunk-27UXRPIQ.js → chunk-HM6V7F3M.js} +2 -2
  15. package/dist/chunk-IPYXE555.js +594 -0
  16. package/dist/chunk-IPYXE555.js.map +1 -0
  17. package/dist/chunk-LKKT3IVV.js +1644 -0
  18. package/dist/chunk-LKKT3IVV.js.map +1 -0
  19. package/dist/chunk-M7AH34KV.js +155 -0
  20. package/dist/chunk-M7AH34KV.js.map +1 -0
  21. package/dist/chunk-MAX3TN3C.js +249 -0
  22. package/dist/chunk-MAX3TN3C.js.map +1 -0
  23. package/dist/{chunk-QVGVJQMR.js → chunk-PMITBABE.js} +7 -5
  24. package/dist/{chunk-QVGVJQMR.js.map → chunk-PMITBABE.js.map} +1 -1
  25. package/dist/{chunk-J3LHTAAB.js → chunk-QOTFXW5L.js} +1 -47
  26. package/dist/chunk-QOTFXW5L.js.map +1 -0
  27. package/dist/chunk-RZTMDUO7.js +49 -0
  28. package/dist/chunk-RZTMDUO7.js.map +1 -0
  29. package/dist/chunk-VBQ3CRKH.js +291 -0
  30. package/dist/chunk-VBQ3CRKH.js.map +1 -0
  31. package/dist/{chunk-RQ5TP2TV.js → chunk-W5B3ZGP3.js} +3 -3
  32. package/dist/cli.js +13 -2
  33. package/dist/cli.js.map +1 -1
  34. package/dist/contract/index.d.ts +7 -0
  35. package/dist/contract/index.js +4 -4
  36. package/dist/index.d.ts +833 -82
  37. package/dist/index.js +61 -121
  38. package/dist/index.js.map +1 -1
  39. package/dist/openapi.json +1 -1
  40. package/dist/pipelines/index.js +4 -2
  41. package/dist/pipelines/index.js.map +1 -1
  42. package/dist/rl.d.ts +3 -0
  43. package/dist/rl.js +2 -2
  44. package/dist/rollout/index.d.ts +1061 -0
  45. package/dist/rollout/index.js +109 -0
  46. package/dist/rollout/index.js.map +1 -0
  47. package/dist/supervisor-run/index.d.ts +857 -0
  48. package/dist/supervisor-run/index.js +64 -0
  49. package/dist/supervisor-run/index.js.map +1 -0
  50. package/dist/wire/index.d.ts +3 -0
  51. package/dist/wire/index.js +2 -2
  52. package/docs/rollout.md +48 -0
  53. package/package.json +11 -1
  54. package/dist/chunk-J3LHTAAB.js.map +0 -1
  55. package/dist/chunk-PDHIOKRE.js.map +0 -1
  56. package/dist/chunk-ZU3QWGZE.js.map +0 -1
  57. /package/dist/{chunk-BUR5R4R4.js.map → chunk-A6GT67HT.js.map} +0 -0
  58. /package/dist/{chunk-EEHHBAWH.js.map → chunk-DT7OXY3C.js.map} +0 -0
  59. /package/dist/{chunk-V7HQGZBT.js.map → chunk-GID26AN4.js.map} +0 -0
  60. /package/dist/{chunk-27UXRPIQ.js.map → chunk-HM6V7F3M.js.map} +0 -0
  61. /package/dist/{chunk-RQ5TP2TV.js.map → chunk-W5B3ZGP3.js.map} +0 -0
@@ -0,0 +1,249 @@
1
+ // src/rollout/schema.ts
2
+ var ROLLOUT_SCHEMA = "tangle.rollout.v1";
3
+ var ROLLOUT_FORMAT = ROLLOUT_SCHEMA;
4
+ var ROLLOUT_ROLES = [
5
+ "agent",
6
+ "supervisor",
7
+ "worker",
8
+ "proposer",
9
+ "judge",
10
+ "analyst"
11
+ ];
12
+ var ROLLOUT_SPLITS = [
13
+ "search",
14
+ "dev",
15
+ "holdout",
16
+ "canary",
17
+ "train"
18
+ ];
19
+ var TRAINABLE_SPLITS = ["search", "train"];
20
+ function isTrainableSplit(split) {
21
+ return TRAINABLE_SPLITS.includes(split);
22
+ }
23
+ var ROLLOUT_CAPTURES = ["mint", "settle-time", "backfill"];
24
+ var CHAT_ROLES = ["system", "user", "assistant", "tool"];
25
+ var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
26
+ var isNumberOrNull = (v) => v === null || typeof v === "number";
27
+ var isStringOrNull = (v) => v === null || typeof v === "string";
28
+ var isIntegerOrNull = (v) => v === null || Number.isInteger(v);
29
+ function validateChatMessage(value, path, errors) {
30
+ if (!isRecord(value)) {
31
+ errors.push(`${path}: not an object`);
32
+ return;
33
+ }
34
+ if (!CHAT_ROLES.includes(value.role))
35
+ errors.push(`${path}.role: invalid role ${String(value.role)}`);
36
+ if (!isStringOrNull(value.content)) errors.push(`${path}.content: must be string|null`);
37
+ if (value.reasoning_content !== void 0 && typeof value.reasoning_content !== "string") {
38
+ errors.push(`${path}.reasoning_content: must be string when present`);
39
+ }
40
+ if (value.tool_call_id !== void 0 && typeof value.tool_call_id !== "string") {
41
+ errors.push(`${path}.tool_call_id: must be string when present`);
42
+ }
43
+ if (value.role === "tool" && typeof value.tool_call_id !== "string") {
44
+ errors.push(`${path}.tool_call_id: required on role:"tool"`);
45
+ }
46
+ if (value.tool_calls !== void 0) {
47
+ if (!Array.isArray(value.tool_calls)) {
48
+ errors.push(`${path}.tool_calls: must be an array when present`);
49
+ } else {
50
+ value.tool_calls.forEach((call, i) => {
51
+ if (!isRecord(call) || typeof call.id !== "string" || call.type !== "function") {
52
+ errors.push(`${path}.tool_calls[${i}]: must be {id, type:"function", function}`);
53
+ return;
54
+ }
55
+ const fn = call.function;
56
+ if (!isRecord(fn) || typeof fn.name !== "string" || typeof fn.arguments !== "string") {
57
+ errors.push(
58
+ `${path}.tool_calls[${i}].function: must be {name: string, arguments: string}`
59
+ );
60
+ }
61
+ });
62
+ }
63
+ }
64
+ }
65
+ function validateSection(value, path, fields, errors) {
66
+ if (!isRecord(value)) {
67
+ errors.push(`${path}: not an object`);
68
+ return;
69
+ }
70
+ for (const [name, check, expect] of fields) {
71
+ if (!check(value[name])) errors.push(`${path}.${name}: expected ${expect}`);
72
+ }
73
+ }
74
+ function validateRolloutLine(value) {
75
+ const errors = [];
76
+ if (!isRecord(value)) return ["line: not an object"];
77
+ if (value.schema !== ROLLOUT_SCHEMA) errors.push(`schema: expected "${ROLLOUT_SCHEMA}"`);
78
+ if (typeof value.rollout_id !== "string" || value.rollout_id.length === 0)
79
+ errors.push("rollout_id: expected non-empty string");
80
+ if (!isStringOrNull(value.parent_rollout_id))
81
+ errors.push("parent_rollout_id: expected string|null");
82
+ if (typeof value.run_id !== "string" || value.run_id.length === 0)
83
+ errors.push("run_id: expected non-empty string");
84
+ if (value.experiment_id !== void 0 && !isStringOrNull(value.experiment_id)) {
85
+ errors.push("experiment_id: expected string|null when present");
86
+ }
87
+ if (value.candidate_id !== void 0 && !isStringOrNull(value.candidate_id)) {
88
+ errors.push("candidate_id: expected string|null when present");
89
+ }
90
+ if (!isIntegerOrNull(value.generation)) errors.push("generation: expected integer|null");
91
+ if (!isIntegerOrNull(value.candidate_index)) errors.push("candidate_index: expected integer|null");
92
+ if (!ROLLOUT_ROLES.includes(value.role))
93
+ errors.push(`role: invalid role ${String(value.role)}`);
94
+ validateSection(
95
+ value.task,
96
+ "task",
97
+ [
98
+ ["suite", (v) => typeof v === "string" && v.length > 0, "non-empty string"],
99
+ ["instance_id", (v) => typeof v === "string" && v.length > 0, "non-empty string"],
100
+ [
101
+ "split",
102
+ (v) => ROLLOUT_SPLITS.includes(v),
103
+ `one of ${ROLLOUT_SPLITS.join("|")}`
104
+ ],
105
+ ["seed", isNumberOrNull, "number|null"],
106
+ ["rep", (v) => Number.isInteger(v), "integer"]
107
+ ],
108
+ errors
109
+ );
110
+ validateSection(
111
+ value.policy,
112
+ "policy",
113
+ [
114
+ ["harness", isStringOrNull, "string|null"],
115
+ ["harness_version", isStringOrNull, "string|null"],
116
+ ["model", isStringOrNull, "string|null"],
117
+ ["provider", isStringOrNull, "string|null"],
118
+ ["profile_commit", isStringOrNull, "string|null"],
119
+ ["sampling", (v) => v === null || isRecord(v), "object|null"]
120
+ ],
121
+ errors
122
+ );
123
+ if (isRecord(value.policy)) {
124
+ for (const key of ["prompt_hash", "config_hash", "agent_profile_cell_id"]) {
125
+ if (value.policy[key] !== void 0 && !isStringOrNull(value.policy[key])) {
126
+ errors.push(`policy.${key}: expected string|null when present`);
127
+ }
128
+ }
129
+ }
130
+ if (!Array.isArray(value.messages)) {
131
+ errors.push("messages: expected array");
132
+ } else {
133
+ for (const [i, m] of value.messages.entries()) validateChatMessage(m, `messages[${i}]`, errors);
134
+ }
135
+ if (!Array.isArray(value.tool_defs)) {
136
+ errors.push("tool_defs: expected array");
137
+ } else {
138
+ value.tool_defs.forEach((d, i) => {
139
+ if (!isRecord(d) || d.type !== "function" || !isRecord(d.function) || typeof d.function.name !== "string") {
140
+ errors.push(`tool_defs[${i}]: must be {type:"function", function:{name}}`);
141
+ }
142
+ });
143
+ }
144
+ if (value.steps !== void 0) {
145
+ if (!Array.isArray(value.steps)) {
146
+ errors.push("steps: expected array when present");
147
+ } else {
148
+ value.steps.forEach((s, i) => {
149
+ if (!isRecord(s) || typeof s.kind !== "string" || typeof s.name !== "string") {
150
+ errors.push(`steps[${i}]: must be {kind: string, name: string, \u2026}`);
151
+ }
152
+ });
153
+ }
154
+ }
155
+ validateSection(
156
+ value.outcome,
157
+ "outcome",
158
+ [
159
+ ["reward", isNumberOrNull, "number|null"],
160
+ ["reward_source", isStringOrNull, "string|null"],
161
+ ["metrics", isRecord, "object"],
162
+ ["is_completed", (v) => typeof v === "boolean", "boolean"],
163
+ ["is_truncated", (v) => typeof v === "boolean", "boolean"],
164
+ ["error", isStringOrNull, "string|null"]
165
+ ],
166
+ errors
167
+ );
168
+ if (isRecord(value.outcome)) {
169
+ if (!("verdict" in value.outcome)) errors.push("outcome.verdict: field required (may be null)");
170
+ if (value.outcome.realness_gated !== void 0 && typeof value.outcome.realness_gated !== "boolean") {
171
+ errors.push("outcome.realness_gated: expected boolean when present");
172
+ }
173
+ }
174
+ validateSection(
175
+ value.cost,
176
+ "cost",
177
+ [
178
+ ["usd", isNumberOrNull, "number|null"],
179
+ ["tokens_in", isNumberOrNull, "number|null"],
180
+ ["tokens_out", isNumberOrNull, "number|null"],
181
+ ["tokens_reasoning", isNumberOrNull, "number|null"],
182
+ ["cache_read", isNumberOrNull, "number|null"],
183
+ ["cache_write", isNumberOrNull, "number|null"],
184
+ ["wall_s", isNumberOrNull, "number|null"]
185
+ ],
186
+ errors
187
+ );
188
+ validateSection(
189
+ value.artifacts,
190
+ "artifacts",
191
+ [
192
+ ["patch_path", isStringOrNull, "string|null"],
193
+ ["run_dir", isStringOrNull, "string|null"],
194
+ ["transcript_ref", isStringOrNull, "string|null"]
195
+ ],
196
+ errors
197
+ );
198
+ validateSection(
199
+ value.provenance,
200
+ "provenance",
201
+ [
202
+ [
203
+ "captured_at",
204
+ (v) => typeof v === "string" && !Number.isNaN(Date.parse(v)),
205
+ "ISO-8601 timestamp"
206
+ ],
207
+ [
208
+ "capture",
209
+ (v) => ROLLOUT_CAPTURES.includes(v),
210
+ `one of ${ROLLOUT_CAPTURES.join("|")}`
211
+ ]
212
+ ],
213
+ errors
214
+ );
215
+ if (isRecord(value.provenance) && value.provenance.gap !== void 0 && typeof value.provenance.gap !== "string") {
216
+ errors.push("provenance.gap: must be string when present");
217
+ }
218
+ if (Array.isArray(value.messages) && isRecord(value.provenance)) {
219
+ if (value.messages.length === 0 && typeof value.provenance.gap !== "string") {
220
+ errors.push("provenance.gap: required when messages is empty");
221
+ }
222
+ }
223
+ return errors;
224
+ }
225
+ function assertRolloutLine(value, context = "rollout line") {
226
+ const errors = validateRolloutLine(value);
227
+ if (errors.length > 0) {
228
+ throw new Error(`invalid ${context}:
229
+ ${errors.join("\n ")}`);
230
+ }
231
+ }
232
+ function isRolloutLine(value) {
233
+ return validateRolloutLine(value).length === 0;
234
+ }
235
+
236
+ export {
237
+ ROLLOUT_SCHEMA,
238
+ ROLLOUT_FORMAT,
239
+ ROLLOUT_ROLES,
240
+ ROLLOUT_SPLITS,
241
+ TRAINABLE_SPLITS,
242
+ isTrainableSplit,
243
+ ROLLOUT_CAPTURES,
244
+ CHAT_ROLES,
245
+ validateRolloutLine,
246
+ assertRolloutLine,
247
+ isRolloutLine
248
+ };
249
+ //# sourceMappingURL=chunk-MAX3TN3C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rollout/schema.ts"],"sourcesContent":["/**\n * `tangle.rollout.v1` — THE canonical rollout serialization, owned by\n * agent-eval. One JSONL line per agent invocation (a solo eval run, a\n * supervisor episode, a worker session, a proposer shot, a judge call, an\n * analyst pass), labeled with its task/split coordinates and a single\n * scalar reward, carrying the FULL message transcript inline.\n *\n * This schema is the reconciliation of two prior producers:\n * - agent-eval's RunRecord-joined rollout rows (PR #410): identity,\n * provenance hashes, the realness gate travelling into the reward,\n * trace-derived steps.\n * - the bench rollout-ledger (agent-runtime PR #591): the wire shape —\n * role, task.split/rep, parent_rollout_id, policy provenance, capture\n * provenance, inline canonical chat-with-tools messages.\n * Where the two conflicted, RunRecord-derived semantics won; the wire\n * field names follow the ledger (snake_case). See `docs/rollout.md` for\n * the field-by-field decision table.\n *\n * Messages are inlined — never referenced — because every harness store a\n * rollout can be recovered from is mutable or garbage-collected. A line\n * must stay a complete training/eval example on its own.\n *\n * `outcome.reward` is THE single scalar (null = no verdict exists — a\n * labeled gap, never 0). `outcome.realness_gated` is the anti-Goodhart\n * flag: a gated line must never export as a positive training example.\n */\n\nexport const ROLLOUT_SCHEMA = 'tangle.rollout.v1'\n/** @deprecated alias kept for consumers of the pre-unification constant name. */\nexport const ROLLOUT_FORMAT = ROLLOUT_SCHEMA\n\n/** `agent` = a solo evaluation run (no multi-agent topology). */\nexport type RolloutRole = 'agent' | 'supervisor' | 'worker' | 'proposer' | 'judge' | 'analyst'\nexport const ROLLOUT_ROLES: readonly RolloutRole[] = [\n 'agent',\n 'supervisor',\n 'worker',\n 'proposer',\n 'judge',\n 'analyst',\n]\n\n/**\n * Split vocabulary follows `RunRecord.splitTag` ('search' is the pool the\n * optimizer may read — the trainable split), extended with the ledger's\n * 'canary'. 'train' is a legacy alias for 'search' emitted by\n * pre-unification ledgers; it validates and counts as trainable, but new\n * producers must emit 'search'.\n */\nexport type RolloutSplit = 'search' | 'dev' | 'holdout' | 'canary' | 'train'\nexport const ROLLOUT_SPLITS: readonly RolloutSplit[] = [\n 'search',\n 'dev',\n 'holdout',\n 'canary',\n 'train',\n]\n/** Splits that may ship in training exports. Everything else is fail-closed excluded. */\nexport const TRAINABLE_SPLITS: readonly RolloutSplit[] = ['search', 'train']\n\nexport function isTrainableSplit(split: RolloutSplit): boolean {\n return TRAINABLE_SPLITS.includes(split)\n}\n\n/** 'mint' = joined live from RunRecord + trace by `mintRolloutRows`. */\nexport type RolloutCapture = 'mint' | 'settle-time' | 'backfill'\nexport const ROLLOUT_CAPTURES: readonly RolloutCapture[] = ['mint', 'settle-time', 'backfill']\n\n// ---------------------------------------------------------------------------\n// Canonical message format — OpenAI chat-with-tools, full fidelity.\n// ---------------------------------------------------------------------------\n\nexport type ChatRole = 'system' | 'user' | 'assistant' | 'tool'\nexport const CHAT_ROLES: readonly ChatRole[] = ['system', 'user', 'assistant', 'tool']\n\nexport interface ChatToolCall {\n id: string\n type: 'function'\n function: {\n name: string\n /** JSON-encoded argument object, exactly as the model emitted it. */\n arguments: string\n }\n}\n\nexport interface ChatMessage {\n role: ChatRole\n content: string | null\n /** Reasoning/thinking channel where the harness captured it (full fidelity). */\n reasoning_content?: string\n tool_calls?: ChatToolCall[]\n /** Required on role:\"tool\" — the ChatToolCall this result answers. */\n tool_call_id?: string\n name?: string\n}\n\nexport interface ToolDef {\n type: 'function'\n function: {\n name: string\n description?: string\n parameters?: Record<string, unknown>\n }\n}\n\n/**\n * Compact trace-span projection (llm/tool step) carried alongside the\n * conversation when the line was minted from a trace. Optional: lines\n * recovered from harness stores have no span structure.\n */\nexport interface RolloutStep {\n kind: string\n name: string\n /** llm: last-message summary · tool: stringified args. Scrubbed. */\n input?: string\n /** llm: output text · tool: stringified result. Scrubbed. */\n output?: string\n status?: 'ok' | 'error'\n durationMs?: number\n}\n\n// ---------------------------------------------------------------------------\n// Ledger line sections.\n// ---------------------------------------------------------------------------\n\nexport interface RolloutTask {\n /** Benchmark/suite id (e.g. \"swe-bench-verified\") or the experiment id. */\n suite: string\n instance_id: string\n split: RolloutSplit\n /** Sampling seed the campaign pinned; null = not recorded. */\n seed: number | null\n /** Replicate index (0-based). */\n rep: number\n}\n\nexport interface RolloutPolicy {\n /** Harness that drove the invocation (e.g. \"opencode\", \"claude\", \"pi-loops\"). */\n harness: string | null\n harness_version: string | null\n model: string | null\n provider: string | null\n /** Commit of the agent profile / candidate under evaluation. */\n profile_commit: string | null\n /** sha256 of the effective prompt (post-steering), when recorded. */\n prompt_hash?: string | null\n /** sha256 of the effective run config, when recorded. */\n config_hash?: string | null\n /** Canonical agent-profile cell identity, when the run carries one. */\n agent_profile_cell_id?: string | null\n /** Sampling params (temperature, top_p, max_tokens…); null = not recorded. */\n sampling: Record<string, unknown> | null\n}\n\nexport interface RolloutOutcome {\n /**\n * THE single scalar training signal — the official verdict.\n * null = no verdict exists for this invocation (a labeled gap, never 0).\n */\n reward: number | null\n /** Where the reward came from (judge id; \"/inherited\" = parent episode's). */\n reward_source: string | null\n /** Raw judge verdict record, verbatim. */\n verdict: unknown\n /** Everything that is NOT the scalar reward. */\n metrics: Record<string, unknown>\n is_completed: boolean\n is_truncated: boolean\n error: string | null\n /**\n * Anti-Goodhart flag from `RunRecord.outcome.realness.gated`: the run\n * faked its success signal. Reward is forced to 0 at mint time and the\n * line never qualifies for SFT. Optional on the wire (absent = false)\n * so pre-unification ledgers stay readable.\n */\n realness_gated?: boolean\n}\n\nexport interface RolloutCostBlock {\n usd: number | null\n tokens_in: number | null\n tokens_out: number | null\n tokens_reasoning: number | null\n cache_read: number | null\n cache_write: number | null\n wall_s: number | null\n}\n\nexport interface RolloutArtifacts {\n patch_path: string | null\n run_dir: string | null\n /** Source-of-truth transcript pointer (session id / jsonl path) for audit. */\n transcript_ref: string | null\n}\n\nexport interface RolloutProvenance {\n captured_at: string\n capture: RolloutCapture\n /** Present on gap lines: why `messages` could not be recovered. */\n gap?: string\n}\n\nexport interface RolloutLine {\n schema: typeof ROLLOUT_SCHEMA\n rollout_id: string\n /** Spawning invocation within the same episode (worker → supervisor). */\n parent_rollout_id: string | null\n run_id: string\n /** Logical experiment grouping from `RunRecord.experimentId`. Optional on\n * the wire (pre-unification ledgers lack it); null = not recorded. */\n experiment_id?: string | null\n /** Stable candidate identity from `RunRecord.candidateId`; null = not recorded. */\n candidate_id?: string | null\n /** Improvement-loop generation (-1 = baseline); null = not an improvement loop. */\n generation: number | null\n /** Improvement-loop candidate index (-1 = baseline); null = not an improvement loop. */\n candidate_index: number | null\n role: RolloutRole\n task: RolloutTask\n policy: RolloutPolicy\n /** Full transcript, inline. [] = gap line (see provenance.gap). */\n messages: ChatMessage[]\n tool_defs: ToolDef[]\n /** Trace-span projections, when minted from a trace. */\n steps?: RolloutStep[]\n outcome: RolloutOutcome\n cost: RolloutCostBlock\n artifacts: RolloutArtifacts\n provenance: RolloutProvenance\n}\n\n// ---------------------------------------------------------------------------\n// Validation — pure TS, no runtime schema dependency, mirroring the\n// run-record validator's fail-loud discipline. Returns [] when the value\n// is a valid RolloutLine; otherwise one dotted-path error per defect.\n// ---------------------------------------------------------------------------\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v)\n\nconst isNumberOrNull = (v: unknown): boolean => v === null || typeof v === 'number'\nconst isStringOrNull = (v: unknown): boolean => v === null || typeof v === 'string'\nconst isIntegerOrNull = (v: unknown): boolean => v === null || Number.isInteger(v)\n\nfunction validateChatMessage(value: unknown, path: string, errors: string[]): void {\n if (!isRecord(value)) {\n errors.push(`${path}: not an object`)\n return\n }\n if (!CHAT_ROLES.includes(value.role as ChatRole))\n errors.push(`${path}.role: invalid role ${String(value.role)}`)\n if (!isStringOrNull(value.content)) errors.push(`${path}.content: must be string|null`)\n if (value.reasoning_content !== undefined && typeof value.reasoning_content !== 'string') {\n errors.push(`${path}.reasoning_content: must be string when present`)\n }\n if (value.tool_call_id !== undefined && typeof value.tool_call_id !== 'string') {\n errors.push(`${path}.tool_call_id: must be string when present`)\n }\n if (value.role === 'tool' && typeof value.tool_call_id !== 'string') {\n errors.push(`${path}.tool_call_id: required on role:\"tool\"`)\n }\n if (value.tool_calls !== undefined) {\n if (!Array.isArray(value.tool_calls)) {\n errors.push(`${path}.tool_calls: must be an array when present`)\n } else {\n value.tool_calls.forEach((call, i) => {\n if (!isRecord(call) || typeof call.id !== 'string' || call.type !== 'function') {\n errors.push(`${path}.tool_calls[${i}]: must be {id, type:\"function\", function}`)\n return\n }\n const fn = call.function\n if (!isRecord(fn) || typeof fn.name !== 'string' || typeof fn.arguments !== 'string') {\n errors.push(\n `${path}.tool_calls[${i}].function: must be {name: string, arguments: string}`,\n )\n }\n })\n }\n }\n}\n\nfunction validateSection(\n value: unknown,\n path: string,\n fields: Array<[name: string, check: (v: unknown) => boolean, expect: string]>,\n errors: string[],\n): void {\n if (!isRecord(value)) {\n errors.push(`${path}: not an object`)\n return\n }\n for (const [name, check, expect] of fields) {\n if (!check(value[name])) errors.push(`${path}.${name}: expected ${expect}`)\n }\n}\n\nexport function validateRolloutLine(value: unknown): string[] {\n const errors: string[] = []\n if (!isRecord(value)) return ['line: not an object']\n\n if (value.schema !== ROLLOUT_SCHEMA) errors.push(`schema: expected \"${ROLLOUT_SCHEMA}\"`)\n if (typeof value.rollout_id !== 'string' || value.rollout_id.length === 0)\n errors.push('rollout_id: expected non-empty string')\n if (!isStringOrNull(value.parent_rollout_id))\n errors.push('parent_rollout_id: expected string|null')\n if (typeof value.run_id !== 'string' || value.run_id.length === 0)\n errors.push('run_id: expected non-empty string')\n if (value.experiment_id !== undefined && !isStringOrNull(value.experiment_id)) {\n errors.push('experiment_id: expected string|null when present')\n }\n if (value.candidate_id !== undefined && !isStringOrNull(value.candidate_id)) {\n errors.push('candidate_id: expected string|null when present')\n }\n if (!isIntegerOrNull(value.generation)) errors.push('generation: expected integer|null')\n if (!isIntegerOrNull(value.candidate_index)) errors.push('candidate_index: expected integer|null')\n if (!ROLLOUT_ROLES.includes(value.role as RolloutRole))\n errors.push(`role: invalid role ${String(value.role)}`)\n\n validateSection(\n value.task,\n 'task',\n [\n ['suite', (v) => typeof v === 'string' && v.length > 0, 'non-empty string'],\n ['instance_id', (v) => typeof v === 'string' && v.length > 0, 'non-empty string'],\n [\n 'split',\n (v) => ROLLOUT_SPLITS.includes(v as RolloutSplit),\n `one of ${ROLLOUT_SPLITS.join('|')}`,\n ],\n ['seed', isNumberOrNull, 'number|null'],\n ['rep', (v) => Number.isInteger(v), 'integer'],\n ],\n errors,\n )\n\n validateSection(\n value.policy,\n 'policy',\n [\n ['harness', isStringOrNull, 'string|null'],\n ['harness_version', isStringOrNull, 'string|null'],\n ['model', isStringOrNull, 'string|null'],\n ['provider', isStringOrNull, 'string|null'],\n ['profile_commit', isStringOrNull, 'string|null'],\n ['sampling', (v) => v === null || isRecord(v), 'object|null'],\n ],\n errors,\n )\n if (isRecord(value.policy)) {\n for (const key of ['prompt_hash', 'config_hash', 'agent_profile_cell_id'] as const) {\n if (value.policy[key] !== undefined && !isStringOrNull(value.policy[key])) {\n errors.push(`policy.${key}: expected string|null when present`)\n }\n }\n }\n\n if (!Array.isArray(value.messages)) {\n errors.push('messages: expected array')\n } else {\n for (const [i, m] of value.messages.entries()) validateChatMessage(m, `messages[${i}]`, errors)\n }\n\n if (!Array.isArray(value.tool_defs)) {\n errors.push('tool_defs: expected array')\n } else {\n value.tool_defs.forEach((d, i) => {\n if (\n !isRecord(d) ||\n d.type !== 'function' ||\n !isRecord(d.function) ||\n typeof d.function.name !== 'string'\n ) {\n errors.push(`tool_defs[${i}]: must be {type:\"function\", function:{name}}`)\n }\n })\n }\n\n if (value.steps !== undefined) {\n if (!Array.isArray(value.steps)) {\n errors.push('steps: expected array when present')\n } else {\n value.steps.forEach((s, i) => {\n if (!isRecord(s) || typeof s.kind !== 'string' || typeof s.name !== 'string') {\n errors.push(`steps[${i}]: must be {kind: string, name: string, …}`)\n }\n })\n }\n }\n\n validateSection(\n value.outcome,\n 'outcome',\n [\n ['reward', isNumberOrNull, 'number|null'],\n ['reward_source', isStringOrNull, 'string|null'],\n ['metrics', isRecord, 'object'],\n ['is_completed', (v) => typeof v === 'boolean', 'boolean'],\n ['is_truncated', (v) => typeof v === 'boolean', 'boolean'],\n ['error', isStringOrNull, 'string|null'],\n ],\n errors,\n )\n if (isRecord(value.outcome)) {\n if (!('verdict' in value.outcome)) errors.push('outcome.verdict: field required (may be null)')\n if (\n value.outcome.realness_gated !== undefined &&\n typeof value.outcome.realness_gated !== 'boolean'\n ) {\n errors.push('outcome.realness_gated: expected boolean when present')\n }\n }\n\n validateSection(\n value.cost,\n 'cost',\n [\n ['usd', isNumberOrNull, 'number|null'],\n ['tokens_in', isNumberOrNull, 'number|null'],\n ['tokens_out', isNumberOrNull, 'number|null'],\n ['tokens_reasoning', isNumberOrNull, 'number|null'],\n ['cache_read', isNumberOrNull, 'number|null'],\n ['cache_write', isNumberOrNull, 'number|null'],\n ['wall_s', isNumberOrNull, 'number|null'],\n ],\n errors,\n )\n\n validateSection(\n value.artifacts,\n 'artifacts',\n [\n ['patch_path', isStringOrNull, 'string|null'],\n ['run_dir', isStringOrNull, 'string|null'],\n ['transcript_ref', isStringOrNull, 'string|null'],\n ],\n errors,\n )\n\n validateSection(\n value.provenance,\n 'provenance',\n [\n [\n 'captured_at',\n (v) => typeof v === 'string' && !Number.isNaN(Date.parse(v)),\n 'ISO-8601 timestamp',\n ],\n [\n 'capture',\n (v) => ROLLOUT_CAPTURES.includes(v as RolloutCapture),\n `one of ${ROLLOUT_CAPTURES.join('|')}`,\n ],\n ],\n errors,\n )\n if (\n isRecord(value.provenance) &&\n value.provenance.gap !== undefined &&\n typeof value.provenance.gap !== 'string'\n ) {\n errors.push('provenance.gap: must be string when present')\n }\n\n // A gap line must say WHY it is a gap; a full line must not carry a gap note.\n if (Array.isArray(value.messages) && isRecord(value.provenance)) {\n if (value.messages.length === 0 && typeof value.provenance.gap !== 'string') {\n errors.push('provenance.gap: required when messages is empty')\n }\n }\n\n return errors\n}\n\nexport function assertRolloutLine(\n value: unknown,\n context = 'rollout line',\n): asserts value is RolloutLine {\n const errors = validateRolloutLine(value)\n if (errors.length > 0) {\n throw new Error(`invalid ${context}:\\n ${errors.join('\\n ')}`)\n }\n}\n\nexport function isRolloutLine(value: unknown): value is RolloutLine {\n return validateRolloutLine(value).length === 0\n}\n"],"mappings":"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","names":[]}
@@ -15,7 +15,7 @@ import {
15
15
  clamp01,
16
16
  mapConcurrent,
17
17
  validatePolicyEditCandidateRecord
18
- } from "./chunk-EEHHBAWH.js";
18
+ } from "./chunk-DT7OXY3C.js";
19
19
  import {
20
20
  detectRewardHacking
21
21
  } from "./chunk-ARU2PZFM.js";
@@ -25,7 +25,7 @@ import {
25
25
  costReceiptFromLlmError,
26
26
  maximumChargeForLlmRequest,
27
27
  stripFencedJson
28
- } from "./chunk-PDHIOKRE.js";
28
+ } from "./chunk-EQUK3RFS.js";
29
29
  import {
30
30
  pairedBootstrap,
31
31
  weightedComposite
@@ -2494,7 +2494,8 @@ function gepaProposer(opts) {
2494
2494
  ],
2495
2495
  jsonMode: true,
2496
2496
  temperature: opts.temperature ?? 0.7,
2497
- maxTokens
2497
+ maxTokens,
2498
+ thinking: opts.thinking
2498
2499
  };
2499
2500
  const paid = await costLedger.runPaidCall({
2500
2501
  channel: "driver",
@@ -2542,7 +2543,8 @@ ${analyst}` : userPrompt;
2542
2543
  ],
2543
2544
  jsonMode: true,
2544
2545
  temperature: opts.temperature ?? 0.7,
2545
- maxTokens
2546
+ maxTokens,
2547
+ thinking: opts.thinking
2546
2548
  };
2547
2549
  const paid = await costLedger.runPaidCall({
2548
2550
  channel: "driver",
@@ -3836,4 +3838,4 @@ export {
3836
3838
  provenanceSpansPath,
3837
3839
  emitLoopProvenance
3838
3840
  };
3839
- //# sourceMappingURL=chunk-QVGVJQMR.js.map
3841
+ //# sourceMappingURL=chunk-PMITBABE.js.map