modelrig 0.0.1 → 0.2.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 (420) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/LICENSE +201 -0
  3. package/README.md +145 -8
  4. package/data/PROVENANCE.md +19 -0
  5. package/data/pricing-manual.json +22 -0
  6. package/data/pricing-map.json +46362 -0
  7. package/data/pricing-overlay.json +419 -0
  8. package/dist/adapters/anthropic.d.ts +90 -0
  9. package/dist/adapters/anthropic.d.ts.map +1 -0
  10. package/dist/adapters/anthropic.js +296 -0
  11. package/dist/adapters/build-adapters.d.ts +11 -0
  12. package/dist/adapters/build-adapters.d.ts.map +1 -0
  13. package/dist/adapters/build-adapters.js +45 -0
  14. package/dist/adapters/deepseek.d.ts +47 -0
  15. package/dist/adapters/deepseek.d.ts.map +1 -0
  16. package/dist/adapters/deepseek.js +216 -0
  17. package/dist/adapters/gemini.d.ts +44 -0
  18. package/dist/adapters/gemini.d.ts.map +1 -0
  19. package/dist/adapters/gemini.js +262 -0
  20. package/dist/adapters/grok.d.ts +53 -0
  21. package/dist/adapters/grok.d.ts.map +1 -0
  22. package/dist/adapters/grok.js +232 -0
  23. package/dist/adapters/openai-compat.d.ts +80 -0
  24. package/dist/adapters/openai-compat.d.ts.map +1 -0
  25. package/dist/adapters/openai-compat.js +244 -0
  26. package/dist/adapters/openai-stream.d.ts +58 -0
  27. package/dist/adapters/openai-stream.d.ts.map +1 -0
  28. package/dist/adapters/openai-stream.js +120 -0
  29. package/dist/adapters/openai.d.ts +55 -0
  30. package/dist/adapters/openai.d.ts.map +1 -0
  31. package/dist/adapters/openai.js +281 -0
  32. package/dist/adapters/sampling.d.ts +28 -0
  33. package/dist/adapters/sampling.d.ts.map +1 -0
  34. package/dist/adapters/sampling.js +34 -0
  35. package/dist/adapters/tool-mapping.d.ts +92 -0
  36. package/dist/adapters/tool-mapping.d.ts.map +1 -0
  37. package/dist/adapters/tool-mapping.js +143 -0
  38. package/dist/artifacts/artifact.d.ts +137 -0
  39. package/dist/artifacts/artifact.d.ts.map +1 -0
  40. package/dist/artifacts/artifact.js +377 -0
  41. package/dist/artifacts/content-uploader.d.ts +87 -0
  42. package/dist/artifacts/content-uploader.d.ts.map +1 -0
  43. package/dist/artifacts/content-uploader.js +124 -0
  44. package/dist/artifacts/index.d.ts +63 -0
  45. package/dist/artifacts/index.d.ts.map +1 -0
  46. package/dist/artifacts/index.js +80 -0
  47. package/dist/artifacts/run-context.d.ts +129 -0
  48. package/dist/artifacts/run-context.d.ts.map +1 -0
  49. package/dist/artifacts/run-context.js +208 -0
  50. package/dist/artifacts/scrub.d.ts +60 -0
  51. package/dist/artifacts/scrub.d.ts.map +1 -0
  52. package/dist/artifacts/scrub.js +139 -0
  53. package/dist/artifacts/step.d.ts +26 -0
  54. package/dist/artifacts/step.d.ts.map +1 -0
  55. package/dist/artifacts/step.js +37 -0
  56. package/dist/artifacts/taint.d.ts +63 -0
  57. package/dist/artifacts/taint.d.ts.map +1 -0
  58. package/dist/artifacts/taint.js +76 -0
  59. package/dist/bakeoff/cache-sim.d.ts +99 -0
  60. package/dist/bakeoff/cache-sim.d.ts.map +1 -0
  61. package/dist/bakeoff/cache-sim.js +126 -0
  62. package/dist/bakeoff/engine.d.ts +52 -0
  63. package/dist/bakeoff/engine.d.ts.map +1 -0
  64. package/dist/bakeoff/engine.js +163 -0
  65. package/dist/bakeoff/eval-cases.d.ts +96 -0
  66. package/dist/bakeoff/eval-cases.d.ts.map +1 -0
  67. package/dist/bakeoff/eval-cases.js +105 -0
  68. package/dist/bakeoff/replay.d.ts +52 -0
  69. package/dist/bakeoff/replay.d.ts.map +1 -0
  70. package/dist/bakeoff/replay.js +94 -0
  71. package/dist/bakeoff/report.d.ts +41 -0
  72. package/dist/bakeoff/report.d.ts.map +1 -0
  73. package/dist/bakeoff/report.js +142 -0
  74. package/dist/bakeoff/samples.d.ts +77 -0
  75. package/dist/bakeoff/samples.d.ts.map +1 -0
  76. package/dist/bakeoff/samples.js +148 -0
  77. package/dist/bakeoff/stats.d.ts +13 -0
  78. package/dist/bakeoff/stats.d.ts.map +1 -0
  79. package/dist/bakeoff/stats.js +48 -0
  80. package/dist/bakeoff/types.d.ts +37 -0
  81. package/dist/bakeoff/types.d.ts.map +1 -0
  82. package/dist/bakeoff/types.js +10 -0
  83. package/dist/cli.d.ts +25 -0
  84. package/dist/cli.d.ts.map +1 -0
  85. package/dist/cli.js +590 -0
  86. package/dist/config.d.ts +204 -0
  87. package/dist/config.d.ts.map +1 -0
  88. package/dist/config.js +252 -0
  89. package/dist/deprecations.d.ts +32 -0
  90. package/dist/deprecations.d.ts.map +1 -0
  91. package/dist/deprecations.js +59 -0
  92. package/dist/feedback/coverage.d.ts +32 -0
  93. package/dist/feedback/coverage.d.ts.map +1 -0
  94. package/dist/feedback/coverage.js +95 -0
  95. package/dist/feedback/feedback.d.ts +35 -0
  96. package/dist/feedback/feedback.d.ts.map +1 -0
  97. package/dist/feedback/feedback.js +39 -0
  98. package/dist/gateway/http-protocol.d.ts +175 -0
  99. package/dist/gateway/http-protocol.d.ts.map +1 -0
  100. package/dist/gateway/http-protocol.js +105 -0
  101. package/dist/index.d.ts +242 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +576 -0
  104. package/dist/init/finder.d.ts +94 -0
  105. package/dist/init/finder.d.ts.map +1 -0
  106. package/dist/init/finder.js +343 -0
  107. package/dist/init/init-cli.d.ts +10 -0
  108. package/dist/init/init-cli.d.ts.map +1 -0
  109. package/dist/init/init-cli.js +86 -0
  110. package/dist/init/observe-cli.d.ts +19 -0
  111. package/dist/init/observe-cli.d.ts.map +1 -0
  112. package/dist/init/observe-cli.js +73 -0
  113. package/dist/init/observe.d.ts +81 -0
  114. package/dist/init/observe.d.ts.map +1 -0
  115. package/dist/init/observe.js +245 -0
  116. package/dist/init/run.d.ts +99 -0
  117. package/dist/init/run.d.ts.map +1 -0
  118. package/dist/init/run.js +281 -0
  119. package/dist/init/signatures.d.ts +39 -0
  120. package/dist/init/signatures.d.ts.map +1 -0
  121. package/dist/init/signatures.js +116 -0
  122. package/dist/matrix/aggregate.d.ts +89 -0
  123. package/dist/matrix/aggregate.d.ts.map +1 -0
  124. package/dist/matrix/aggregate.js +186 -0
  125. package/dist/query/grammar.d.ts +35 -0
  126. package/dist/query/grammar.d.ts.map +1 -0
  127. package/dist/query/grammar.js +279 -0
  128. package/dist/query/run.d.ts +8 -0
  129. package/dist/query/run.d.ts.map +1 -0
  130. package/dist/query/run.js +21 -0
  131. package/dist/registry/build.d.ts +219 -0
  132. package/dist/registry/build.d.ts.map +1 -0
  133. package/dist/registry/build.js +313 -0
  134. package/dist/registry/cache-policy.d.ts +94 -0
  135. package/dist/registry/cache-policy.d.ts.map +1 -0
  136. package/dist/registry/cache-policy.js +238 -0
  137. package/dist/registry/call-notes.d.ts +11 -0
  138. package/dist/registry/call-notes.d.ts.map +1 -0
  139. package/dist/registry/call-notes.js +110 -0
  140. package/dist/registry/claims.d.ts +63 -0
  141. package/dist/registry/claims.d.ts.map +1 -0
  142. package/dist/registry/claims.js +107 -0
  143. package/dist/registry/effective-rate.d.ts +151 -0
  144. package/dist/registry/effective-rate.d.ts.map +1 -0
  145. package/dist/registry/effective-rate.js +156 -0
  146. package/dist/registry/facts.d.ts +32 -0
  147. package/dist/registry/facts.d.ts.map +1 -0
  148. package/dist/registry/facts.js +136 -0
  149. package/dist/registry/fingerprint.d.ts +20 -0
  150. package/dist/registry/fingerprint.d.ts.map +1 -0
  151. package/dist/registry/fingerprint.js +150 -0
  152. package/dist/registry/parity.d.ts +52 -0
  153. package/dist/registry/parity.d.ts.map +1 -0
  154. package/dist/registry/parity.js +82 -0
  155. package/dist/registry/pricing-shape.d.ts +113 -0
  156. package/dist/registry/pricing-shape.d.ts.map +1 -0
  157. package/dist/registry/pricing-shape.js +123 -0
  158. package/dist/registry/pricing.d.ts +43 -0
  159. package/dist/registry/pricing.d.ts.map +1 -0
  160. package/dist/registry/pricing.js +127 -0
  161. package/dist/registry/rows.d.ts +16 -0
  162. package/dist/registry/rows.d.ts.map +1 -0
  163. package/dist/registry/rows.js +57 -0
  164. package/dist/registry/seed.d.ts +43 -0
  165. package/dist/registry/seed.d.ts.map +1 -0
  166. package/dist/registry/seed.js +97 -0
  167. package/dist/registry/select.d.ts +68 -0
  168. package/dist/registry/select.d.ts.map +1 -0
  169. package/dist/registry/select.js +141 -0
  170. package/dist/registry/staleness.d.ts +18 -0
  171. package/dist/registry/staleness.d.ts.map +1 -0
  172. package/dist/registry/staleness.js +39 -0
  173. package/dist/rigindex/bootstrap.d.ts +36 -0
  174. package/dist/rigindex/bootstrap.d.ts.map +1 -0
  175. package/dist/rigindex/bootstrap.js +97 -0
  176. package/dist/rigindex/fit.d.ts +24 -0
  177. package/dist/rigindex/fit.d.ts.map +1 -0
  178. package/dist/rigindex/fit.js +76 -0
  179. package/dist/rigindex/gates.d.ts +52 -0
  180. package/dist/rigindex/gates.d.ts.map +1 -0
  181. package/dist/rigindex/gates.js +109 -0
  182. package/dist/rigindex/graph.d.ts +31 -0
  183. package/dist/rigindex/graph.d.ts.map +1 -0
  184. package/dist/rigindex/graph.js +120 -0
  185. package/dist/rigindex/index.d.ts +23 -0
  186. package/dist/rigindex/index.d.ts.map +1 -0
  187. package/dist/rigindex/index.js +112 -0
  188. package/dist/rigindex/types.d.ts +76 -0
  189. package/dist/rigindex/types.d.ts.map +1 -0
  190. package/dist/rigindex/types.js +8 -0
  191. package/dist/routes/cache-lint.d.ts +41 -0
  192. package/dist/routes/cache-lint.d.ts.map +1 -0
  193. package/dist/routes/cache-lint.js +81 -0
  194. package/dist/routes/draft.d.ts +83 -0
  195. package/dist/routes/draft.d.ts.map +1 -0
  196. package/dist/routes/draft.js +135 -0
  197. package/dist/routes/loader.d.ts +63 -0
  198. package/dist/routes/loader.d.ts.map +1 -0
  199. package/dist/routes/loader.js +574 -0
  200. package/dist/routes/manifest.d.ts +24 -0
  201. package/dist/routes/manifest.d.ts.map +1 -0
  202. package/dist/routes/manifest.js +118 -0
  203. package/dist/routes/resolved-bundle.d.ts +79 -0
  204. package/dist/routes/resolved-bundle.d.ts.map +1 -0
  205. package/dist/routes/resolved-bundle.js +148 -0
  206. package/dist/routes/sampling-config.d.ts +32 -0
  207. package/dist/routes/sampling-config.d.ts.map +1 -0
  208. package/dist/routes/sampling-config.js +91 -0
  209. package/dist/routes/serveability.d.ts +52 -0
  210. package/dist/routes/serveability.d.ts.map +1 -0
  211. package/dist/routes/serveability.js +73 -0
  212. package/dist/routes/template.d.ts +18 -0
  213. package/dist/routes/template.d.ts.map +1 -0
  214. package/dist/routes/template.js +94 -0
  215. package/dist/run/ajv.d.ts +22 -0
  216. package/dist/run/ajv.d.ts.map +1 -0
  217. package/dist/run/ajv.js +32 -0
  218. package/dist/run/cache-handle.d.ts +58 -0
  219. package/dist/run/cache-handle.d.ts.map +1 -0
  220. package/dist/run/cache-handle.js +54 -0
  221. package/dist/run/cache-stamp.d.ts +65 -0
  222. package/dist/run/cache-stamp.d.ts.map +1 -0
  223. package/dist/run/cache-stamp.js +0 -0
  224. package/dist/run/capture-write.d.ts +33 -0
  225. package/dist/run/capture-write.d.ts.map +1 -0
  226. package/dist/run/capture-write.js +55 -0
  227. package/dist/run/cost.d.ts +26 -0
  228. package/dist/run/cost.d.ts.map +1 -0
  229. package/dist/run/cost.js +41 -0
  230. package/dist/run/dispatch.d.ts +99 -0
  231. package/dist/run/dispatch.d.ts.map +1 -0
  232. package/dist/run/dispatch.js +191 -0
  233. package/dist/run/envelope.d.ts +21 -0
  234. package/dist/run/envelope.d.ts.map +1 -0
  235. package/dist/run/envelope.js +45 -0
  236. package/dist/run/grounding.d.ts +56 -0
  237. package/dist/run/grounding.d.ts.map +1 -0
  238. package/dist/run/grounding.js +89 -0
  239. package/dist/run/raw.d.ts +88 -0
  240. package/dist/run/raw.d.ts.map +1 -0
  241. package/dist/run/raw.js +286 -0
  242. package/dist/run/record-attempt.d.ts +40 -0
  243. package/dist/run/record-attempt.d.ts.map +1 -0
  244. package/dist/run/record-attempt.js +99 -0
  245. package/dist/run/repair.d.ts +36 -0
  246. package/dist/run/repair.d.ts.map +1 -0
  247. package/dist/run/repair.js +61 -0
  248. package/dist/run/resolve.d.ts +99 -0
  249. package/dist/run/resolve.d.ts.map +1 -0
  250. package/dist/run/resolve.js +203 -0
  251. package/dist/run/retry.d.ts +19 -0
  252. package/dist/run/retry.d.ts.map +1 -0
  253. package/dist/run/retry.js +50 -0
  254. package/dist/run/run.d.ts +55 -0
  255. package/dist/run/run.d.ts.map +1 -0
  256. package/dist/run/run.js +540 -0
  257. package/dist/run/stream.d.ts +49 -0
  258. package/dist/run/stream.d.ts.map +1 -0
  259. package/dist/run/stream.js +87 -0
  260. package/dist/run/validate.d.ts +15 -0
  261. package/dist/run/validate.d.ts.map +1 -0
  262. package/dist/run/validate.js +55 -0
  263. package/dist/savings/cache-ledger.d.ts +108 -0
  264. package/dist/savings/cache-ledger.d.ts.map +1 -0
  265. package/dist/savings/cache-ledger.js +174 -0
  266. package/dist/savings/cache-reconcile.d.ts +64 -0
  267. package/dist/savings/cache-reconcile.d.ts.map +1 -0
  268. package/dist/savings/cache-reconcile.js +59 -0
  269. package/dist/savings/cache-stats.d.ts +63 -0
  270. package/dist/savings/cache-stats.d.ts.map +1 -0
  271. package/dist/savings/cache-stats.js +108 -0
  272. package/dist/savings/emit.d.ts +38 -0
  273. package/dist/savings/emit.d.ts.map +1 -0
  274. package/dist/savings/emit.js +100 -0
  275. package/dist/savings/odometer.d.ts +32 -0
  276. package/dist/savings/odometer.d.ts.map +1 -0
  277. package/dist/savings/odometer.js +70 -0
  278. package/dist/savings/swap-execute.d.ts +58 -0
  279. package/dist/savings/swap-execute.d.ts.map +1 -0
  280. package/dist/savings/swap-execute.js +130 -0
  281. package/dist/savings/swaps-client.d.ts +55 -0
  282. package/dist/savings/swaps-client.d.ts.map +1 -0
  283. package/dist/savings/swaps-client.js +95 -0
  284. package/dist/settings/api-fetcher.d.ts +39 -0
  285. package/dist/settings/api-fetcher.d.ts.map +1 -0
  286. package/dist/settings/api-fetcher.js +92 -0
  287. package/dist/settings/index.d.ts +10 -0
  288. package/dist/settings/index.d.ts.map +1 -0
  289. package/dist/settings/index.js +15 -0
  290. package/dist/settings/task-settings.d.ts +91 -0
  291. package/dist/settings/task-settings.d.ts.map +1 -0
  292. package/dist/settings/task-settings.js +116 -0
  293. package/dist/status.d.ts +77 -0
  294. package/dist/status.d.ts.map +1 -0
  295. package/dist/status.js +113 -0
  296. package/dist/telemetry/artifact-store.d.ts +48 -0
  297. package/dist/telemetry/artifact-store.d.ts.map +1 -0
  298. package/dist/telemetry/artifact-store.js +189 -0
  299. package/dist/telemetry/cache-miss-streak.d.ts +79 -0
  300. package/dist/telemetry/cache-miss-streak.d.ts.map +1 -0
  301. package/dist/telemetry/cache-miss-streak.js +99 -0
  302. package/dist/telemetry/capture.d.ts +31 -0
  303. package/dist/telemetry/capture.d.ts.map +1 -0
  304. package/dist/telemetry/capture.js +81 -0
  305. package/dist/telemetry/exporter-setup.d.ts +28 -0
  306. package/dist/telemetry/exporter-setup.d.ts.map +1 -0
  307. package/dist/telemetry/exporter-setup.js +34 -0
  308. package/dist/telemetry/exporter.d.ts +137 -0
  309. package/dist/telemetry/exporter.d.ts.map +1 -0
  310. package/dist/telemetry/exporter.js +510 -0
  311. package/dist/telemetry/health.d.ts +76 -0
  312. package/dist/telemetry/health.d.ts.map +1 -0
  313. package/dist/telemetry/health.js +92 -0
  314. package/dist/telemetry/ingest-protocol.d.ts +310 -0
  315. package/dist/telemetry/ingest-protocol.d.ts.map +1 -0
  316. package/dist/telemetry/ingest-protocol.js +363 -0
  317. package/dist/telemetry/load-error-report.d.ts +24 -0
  318. package/dist/telemetry/load-error-report.d.ts.map +1 -0
  319. package/dist/telemetry/load-error-report.js +50 -0
  320. package/dist/telemetry/otel-map.d.ts +121 -0
  321. package/dist/telemetry/otel-map.d.ts.map +1 -0
  322. package/dist/telemetry/otel-map.js +224 -0
  323. package/dist/telemetry/otel-normalize.d.ts +104 -0
  324. package/dist/telemetry/otel-normalize.d.ts.map +1 -0
  325. package/dist/telemetry/otel-normalize.js +530 -0
  326. package/dist/telemetry/otlp-emitter.d.ts +52 -0
  327. package/dist/telemetry/otlp-emitter.d.ts.map +1 -0
  328. package/dist/telemetry/otlp-emitter.js +144 -0
  329. package/dist/telemetry/otlp-proto.d.ts +29 -0
  330. package/dist/telemetry/otlp-proto.d.ts.map +1 -0
  331. package/dist/telemetry/otlp-proto.js +266 -0
  332. package/dist/telemetry/sinks.d.ts +90 -0
  333. package/dist/telemetry/sinks.d.ts.map +1 -0
  334. package/dist/telemetry/sinks.js +180 -0
  335. package/dist/telemetry/store.d.ts +65 -0
  336. package/dist/telemetry/store.d.ts.map +1 -0
  337. package/dist/telemetry/store.js +547 -0
  338. package/dist/tenancy/api-key-format.d.ts +77 -0
  339. package/dist/tenancy/api-key-format.d.ts.map +1 -0
  340. package/dist/tenancy/api-key-format.js +110 -0
  341. package/dist/tenancy/constants.d.ts +23 -0
  342. package/dist/tenancy/constants.d.ts.map +1 -0
  343. package/dist/tenancy/constants.js +25 -0
  344. package/dist/tenancy/scrub.d.ts +47 -0
  345. package/dist/tenancy/scrub.d.ts.map +1 -0
  346. package/dist/tenancy/scrub.js +85 -0
  347. package/dist/types/config-teaching.d.ts +62 -0
  348. package/dist/types/config-teaching.d.ts.map +1 -0
  349. package/dist/types/config-teaching.js +183 -0
  350. package/dist/types/failures-teaching.d.ts +56 -0
  351. package/dist/types/failures-teaching.d.ts.map +1 -0
  352. package/dist/types/failures-teaching.js +177 -0
  353. package/dist/types/failures.d.ts +27 -0
  354. package/dist/types/failures.d.ts.map +1 -0
  355. package/dist/types/failures.js +41 -0
  356. package/dist/types/provider.d.ts +200 -0
  357. package/dist/types/provider.d.ts.map +1 -0
  358. package/dist/types/provider.js +40 -0
  359. package/dist/types/route.d.ts +205 -0
  360. package/dist/types/route.d.ts.map +1 -0
  361. package/dist/types/route.js +6 -0
  362. package/dist/types/telemetry.d.ts +206 -0
  363. package/dist/types/telemetry.d.ts.map +1 -0
  364. package/dist/types/telemetry.js +6 -0
  365. package/dist/validate-cli.d.ts +12 -0
  366. package/dist/validate-cli.d.ts.map +1 -0
  367. package/dist/validate-cli.js +57 -0
  368. package/dist/verify/capture.d.ts +66 -0
  369. package/dist/verify/capture.d.ts.map +1 -0
  370. package/dist/verify/capture.js +180 -0
  371. package/dist/verify/cli-run.d.ts +23 -0
  372. package/dist/verify/cli-run.d.ts.map +1 -0
  373. package/dist/verify/cli-run.js +57 -0
  374. package/dist/verify/diff.d.ts +48 -0
  375. package/dist/verify/diff.d.ts.map +1 -0
  376. package/dist/verify/diff.js +157 -0
  377. package/dist/verify/index.d.ts +17 -0
  378. package/dist/verify/index.d.ts.map +1 -0
  379. package/dist/verify/index.js +24 -0
  380. package/dist/verify/report.d.ts +14 -0
  381. package/dist/verify/report.d.ts.map +1 -0
  382. package/dist/verify/report.js +88 -0
  383. package/dist/verify/types.d.ts +101 -0
  384. package/dist/verify/types.d.ts.map +1 -0
  385. package/dist/verify/types.js +17 -0
  386. package/dist/verify/verify.d.ts +29 -0
  387. package/dist/verify/verify.d.ts.map +1 -0
  388. package/dist/verify/verify.js +148 -0
  389. package/dist/watch/budget.d.ts +19 -0
  390. package/dist/watch/budget.d.ts.map +1 -0
  391. package/dist/watch/budget.js +35 -0
  392. package/dist/watch/evaluate.d.ts +225 -0
  393. package/dist/watch/evaluate.d.ts.map +1 -0
  394. package/dist/watch/evaluate.js +155 -0
  395. package/dist/watch/monitor.d.ts +116 -0
  396. package/dist/watch/monitor.d.ts.map +1 -0
  397. package/dist/watch/monitor.js +199 -0
  398. package/dist/watch/proposals.d.ts +89 -0
  399. package/dist/watch/proposals.d.ts.map +1 -0
  400. package/dist/watch/proposals.js +197 -0
  401. package/dist/watch/run-record.d.ts +64 -0
  402. package/dist/watch/run-record.d.ts.map +1 -0
  403. package/dist/watch/run-record.js +86 -0
  404. package/dist/watch/run-reported.d.ts +20 -0
  405. package/dist/watch/run-reported.d.ts.map +1 -0
  406. package/dist/watch/run-reported.js +53 -0
  407. package/dist/watch/run.d.ts +73 -0
  408. package/dist/watch/run.d.ts.map +1 -0
  409. package/dist/watch/run.js +83 -0
  410. package/dist/watch/state-store.d.ts +48 -0
  411. package/dist/watch/state-store.d.ts.map +1 -0
  412. package/dist/watch/state-store.js +86 -0
  413. package/dist/watch/state.d.ts +21 -0
  414. package/dist/watch/state.d.ts.map +1 -0
  415. package/dist/watch/state.js +93 -0
  416. package/package.json +56 -14
  417. package/registry/LICENSE +20 -0
  418. package/registry/leaderboard.json +3639 -0
  419. package/registry/registry.json +7263 -0
  420. package/index.js +0 -3
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Bake-off engine — Phase 3 spec WS5 (closed core). Replays the last N
3
+ * captures through each named variant, aggregates per-variant metrics
4
+ * (stats.ts), and assembles the BakeoffArtifact with the proposal verdict.
5
+ *
6
+ * Proposal gate (builder decision, flagged): the incumbent is the "default"
7
+ * variant when compared, else the FIRST listed variant. A challenger
8
+ * proposes when (a) its conformance CI lower bound ≥ the incumbent's CI
9
+ * lower bound, and (b) its effective $/1K-conformant is strictly lower.
10
+ * Value gates beyond mechanical conformance arrive with Phase 4 judges —
11
+ * the artifact records value_accuracy where the hook supplies it.
12
+ */
13
+ import type { CaptureStore } from "../telemetry/capture";
14
+ import type { RunDeps } from "../run/run";
15
+ import type { ArmSamples, KeepOutputsMode } from "./samples";
16
+ import type { BakeoffArtifact, VariantMetrics } from "./types";
17
+ /** Sink for retained review samples (addendum A3). The engine assembles the
18
+ * arms to persist (incumbent + winner, or all); the caller — createRig with
19
+ * the service-role config — does the truncation + PostgREST insert. Keeps
20
+ * payloads out of the engine and out of the (anon-readable) BakeoffArtifact. */
21
+ export type BakeoffSamplesSink = (input: {
22
+ readonly bakeoffId: string;
23
+ readonly route: string;
24
+ readonly arms: readonly ArmSamples[];
25
+ }) => Promise<void>;
26
+ export interface BakeoffRequest {
27
+ readonly route: string;
28
+ /** Variant names to compare; "default" = the route's base config. */
29
+ readonly variants: readonly string[];
30
+ readonly replayLastN: number;
31
+ /** Hard cap PER VARIANT replay pass (spec: replay is envelope-guarded). */
32
+ readonly envelopeUsdPerVariant: number;
33
+ /** Addendum A3: retain outputs for a value review. "winner" = incumbent +
34
+ * winning challenger; "all" = every arm. Undefined = keep nothing (the
35
+ * default pure-metrics path). Requires a samplesSink to persist. */
36
+ readonly keepOutputs?: KeepOutputsMode;
37
+ }
38
+ export declare function runBakeoff(deps: RunDeps, captures: CaptureStore, req: BakeoffRequest, samplesSink?: BakeoffSamplesSink): Promise<BakeoffArtifact>;
39
+ /** Winner among gate-passing challengers; null when nobody beats the
40
+ * incumbent. Exported for direct unit testing. */
41
+ export declare function computeProposal(requested: readonly string[], metrics: readonly VariantMetrics[]): BakeoffArtifact["proposal"];
42
+ export interface BakeoffMirrorConfig {
43
+ readonly supabaseUrl: string;
44
+ readonly serviceRoleKey: string;
45
+ readonly sourceId: string;
46
+ readonly fetchFn?: typeof fetch;
47
+ }
48
+ /** Upsert the artifact into the `bakeoffs` mirror table (console read path).
49
+ * Same PostgREST transport pattern as the telemetry exporter; captures have
50
+ * no cloud surface — ONLY aggregate metrics travel. */
51
+ export declare function mirrorBakeoff(artifact: BakeoffArtifact, config: BakeoffMirrorConfig): Promise<void>;
52
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/bakeoff/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAO1C,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/D;;;gFAGgF;AAChF,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,CAAC;CACtC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAgBpB,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC;;wEAEoE;IACpE,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC;CACxC;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,cAAc,EACnB,WAAW,CAAC,EAAE,kBAAkB,GAC/B,OAAO,CAAC,eAAe,CAAC,CA2E1B;AAED;kDACkD;AAClD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,eAAe,CAAC,UAAU,CAAC,CA4B7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACjC;AAED;;uDAEuD;AACvD,wBAAsB,aAAa,CACjC,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ /**
3
+ * Bake-off engine — Phase 3 spec WS5 (closed core). Replays the last N
4
+ * captures through each named variant, aggregates per-variant metrics
5
+ * (stats.ts), and assembles the BakeoffArtifact with the proposal verdict.
6
+ *
7
+ * Proposal gate (builder decision, flagged): the incumbent is the "default"
8
+ * variant when compared, else the FIRST listed variant. A challenger
9
+ * proposes when (a) its conformance CI lower bound ≥ the incumbent's CI
10
+ * lower bound, and (b) its effective $/1K-conformant is strictly lower.
11
+ * Value gates beyond mechanical conformance arrive with Phase 4 judges —
12
+ * the artifact records value_accuracy where the hook supplies it.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.runBakeoff = runBakeoff;
16
+ exports.computeProposal = computeProposal;
17
+ exports.mirrorBakeoff = mirrorBakeoff;
18
+ const node_crypto_1 = require("node:crypto");
19
+ const loader_1 = require("../routes/loader");
20
+ const replay_1 = require("./replay");
21
+ const stats_1 = require("./stats");
22
+ const samples_1 = require("./samples");
23
+ /** Arm metadata for the reviewer: which model/rung/scaffold served it. */
24
+ function deriveArmMeta(route, arm) {
25
+ if (arm === "default") {
26
+ return { model: route.candidates[0]?.model ?? null, rung: route.policy.json };
27
+ }
28
+ const variant = route.variants.find((v) => v.name === arm);
29
+ const model = (variant?.candidates?.[0] ?? route.candidates[0])?.model ?? null;
30
+ return {
31
+ model,
32
+ rung: variant?.json ?? route.policy.json,
33
+ ...(variant?.scaffold !== undefined ? { scaffold: true } : {}),
34
+ };
35
+ }
36
+ async function runBakeoff(deps, captures, req, samplesSink) {
37
+ if (req.variants.length === 0) {
38
+ throw new loader_1.RouteConfigError("bakeoff needs at least one variant (use \"default\" for the base config)");
39
+ }
40
+ const route = deps.routes.get(req.route);
41
+ for (const name of req.variants) {
42
+ if (name !== "default" && !route.variants.some((v) => v.name === name)) {
43
+ throw new loader_1.RouteConfigError(`route "${req.route}" has no variant "${name}" — defined: [default, ${route.variants
44
+ .map((v) => v.name)
45
+ .join(", ")}]`);
46
+ }
47
+ }
48
+ const keepOutputs = req.keepOutputs !== undefined && samplesSink !== undefined;
49
+ const bakeoffId = (0, node_crypto_1.randomUUID)();
50
+ const metrics = [];
51
+ const rawByArm = new Map();
52
+ let replayN = 0;
53
+ for (const variant of req.variants) {
54
+ const samples = await (0, replay_1.replayVariant)(deps, captures, {
55
+ route: req.route,
56
+ variant,
57
+ lastN: req.replayLastN,
58
+ envelopeUsd: req.envelopeUsdPerVariant,
59
+ ...(keepOutputs ? { keepOutputs: true } : {}),
60
+ });
61
+ replayN = Math.max(replayN, samples.length);
62
+ metrics.push((0, stats_1.aggregateVariantMetrics)(variant, samples));
63
+ if (keepOutputs)
64
+ rawByArm.set(variant, samples);
65
+ }
66
+ const proposal = computeProposal(req.variants, metrics);
67
+ // Persist review samples (A3) — AFTER the winner is known, for the selected
68
+ // arms only. Never touches the artifact (payloads stay off the anon table).
69
+ if (keepOutputs && samplesSink !== undefined) {
70
+ const incumbentArm = req.variants.includes("default") ? "default" : req.variants[0];
71
+ const keptArms = (0, samples_1.selectArmsToKeep)(req.keepOutputs, incumbentArm, proposal?.variant ?? null, req.variants);
72
+ const arms = keptArms.map((arm) => ({
73
+ arm,
74
+ armMeta: deriveArmMeta(route, arm),
75
+ samples: (rawByArm.get(arm) ?? []).map((s) => ({
76
+ inputRef: s.captureId,
77
+ inputText: s.inputText ?? "",
78
+ outputText: s.outputText ?? null,
79
+ conform: s.conform,
80
+ costUsd: s.costUsd,
81
+ latencyMs: s.latencyMs,
82
+ })),
83
+ }));
84
+ // Best-effort: a hiccup persisting the SECONDARY review samples must not
85
+ // lose the PRIMARY metrics artifact of an expensive bake-off. Warn and
86
+ // continue; the artifact still returns, mirrors, and writes to disk.
87
+ try {
88
+ await samplesSink({ bakeoffId, route: route.route, arms });
89
+ }
90
+ catch (err) {
91
+ console.warn(`[modelrig] bake-off ${bakeoffId}: review samples not persisted ` +
92
+ `(${err instanceof Error ? err.message : String(err)}) — metrics unaffected; ` +
93
+ "re-run with --keep-outputs to retry the samples.");
94
+ }
95
+ }
96
+ return {
97
+ id: bakeoffId,
98
+ route: route.route,
99
+ routeVersion: route.version,
100
+ ranAt: new Date().toISOString(),
101
+ replayN,
102
+ variants: metrics,
103
+ proposal,
104
+ };
105
+ }
106
+ /** Winner among gate-passing challengers; null when nobody beats the
107
+ * incumbent. Exported for direct unit testing. */
108
+ function computeProposal(requested, metrics) {
109
+ const incumbentName = requested.includes("default") ? "default" : requested[0];
110
+ const incumbent = metrics.find((m) => m.variant === incumbentName);
111
+ // A1: unpriced cost columns under-count — an unpriced incumbent can't be
112
+ // compared against, and an unpriced challenger must never look cheap.
113
+ if (incumbent === undefined || incumbent.samples === 0 || incumbent.pricingMissing)
114
+ return null;
115
+ const challengers = metrics.filter((m) => m.variant !== incumbentName &&
116
+ m.samples > 0 &&
117
+ !m.pricingMissing &&
118
+ m.conformCi95[0] >= incumbent.conformCi95[0] &&
119
+ m.effectiveUsdPer1kConformant < incumbent.effectiveUsdPer1kConformant);
120
+ if (challengers.length === 0)
121
+ return null;
122
+ const winner = [...challengers].sort((a, b) => a.effectiveUsdPer1kConformant - b.effectiveUsdPer1kConformant)[0];
123
+ const savings = incumbent.effectiveUsdPer1kConformant === 0 ||
124
+ !Number.isFinite(incumbent.effectiveUsdPer1kConformant)
125
+ ? 0
126
+ : ((incumbent.effectiveUsdPer1kConformant - winner.effectiveUsdPer1kConformant) /
127
+ incumbent.effectiveUsdPer1kConformant) *
128
+ 100;
129
+ return { variant: winner.variant, vsIncumbentSavingsPct: savings };
130
+ }
131
+ /** Upsert the artifact into the `bakeoffs` mirror table (console read path).
132
+ * Same PostgREST transport pattern as the telemetry exporter; captures have
133
+ * no cloud surface — ONLY aggregate metrics travel. */
134
+ async function mirrorBakeoff(artifact, config) {
135
+ const fetchFn = config.fetchFn ?? fetch;
136
+ const base = config.supabaseUrl.replace(/\/$/, "");
137
+ const response = await fetchFn(`${base}/rest/v1/bakeoffs`, {
138
+ method: "POST",
139
+ headers: {
140
+ "content-type": "application/json",
141
+ apikey: config.serviceRoleKey,
142
+ authorization: `Bearer ${config.serviceRoleKey}`,
143
+ prefer: "resolution=merge-duplicates,return=minimal",
144
+ },
145
+ body: JSON.stringify([
146
+ {
147
+ id: artifact.id,
148
+ route: artifact.route,
149
+ route_version: artifact.routeVersion,
150
+ ran_at: artifact.ranAt,
151
+ variants: artifact.variants.map((m) => m.variant),
152
+ // JSON has no Infinity: a variant with zero conformant outputs
153
+ // serializes effectiveUsdPer1kConformant as null (console renders ∞).
154
+ matrix: JSON.parse(JSON.stringify(artifact.variants)),
155
+ replay_n: artifact.replayN,
156
+ source_id: config.sourceId,
157
+ },
158
+ ]),
159
+ });
160
+ if (!response.ok) {
161
+ throw new Error(`bakeoff mirror upsert → ${response.status} ${await response.text().catch(() => "")}`);
162
+ }
163
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Bake-off input selection from eval cases — Expansion E4 chunk A (spec §3).
3
+ *
4
+ * `bakeoff --from-eval-cases <task>` replays the promoted regression/golden cases
5
+ * for a task instead of the last-N captures. A case only holds METADATA (a source
6
+ * artifact id); the INPUT to replay lives in a LOCAL capture, reachable through
7
+ * the chain:
8
+ *
9
+ * eval_case → source artifact (run_id, step_key) → step's inference_id → capture
10
+ *
11
+ * Any link may be missing — the source artifact predates local retention, the
12
+ * route never had `capture: true`, the capture was evicted. When it is, the case
13
+ * is UNREHYDRATABLE. The load-bearing doctrine (spec §3.3): the bake-off runs on
14
+ * the rehydratable subset and NAMES every refused case with a reason — NEVER a
15
+ * silent subset. `selectEvalCaseCaptures` returns both halves so the CLI can
16
+ * print the honest-refusal report before it spends a cent.
17
+ */
18
+ import type { CaptureRow, CaptureStore } from "../telemetry/capture";
19
+ import type { ArtifactStore } from "../telemetry/artifact-store";
20
+ import type { ExportableTelemetryStore } from "../telemetry/store";
21
+ import type { EvalCaseRow } from "../types/telemetry";
22
+ import type { RunDeps } from "../run/run";
23
+ import { type BakeoffSamplesSink } from "./engine";
24
+ import type { KeepOutputsMode } from "./samples";
25
+ import type { BakeoffArtifact } from "./types";
26
+ /** The narrow store surface the selection reads — kept minimal so this module
27
+ * depends on four reads, not three whole stores. */
28
+ export interface EvalCaseSelectionDeps {
29
+ readonly readEvalCasesByTask: (task: string) => EvalCaseRow[];
30
+ readonly getArtifactById: (id: string) => {
31
+ runId: string | null;
32
+ stepKey: string | null;
33
+ } | null;
34
+ readonly getStepInferenceId: (runId: string, stepKey: string) => string | null;
35
+ readonly getCaptureByInferenceId: (inferenceId: string) => CaptureRow | null;
36
+ }
37
+ export interface RehydratedCase {
38
+ readonly caseId: string;
39
+ readonly capture: CaptureRow;
40
+ }
41
+ export interface EvalCaseRefusal {
42
+ readonly caseId: string;
43
+ readonly sourceArtifactId: string;
44
+ /** Which link of the chain broke — the honest, actionable reason. */
45
+ readonly reason: string;
46
+ }
47
+ export interface EvalCaseSelection {
48
+ readonly task: string;
49
+ /** Total eval cases found for the task (rehydratable + refused). */
50
+ readonly total: number;
51
+ readonly rehydratable: readonly RehydratedCase[];
52
+ readonly refusals: readonly EvalCaseRefusal[];
53
+ }
54
+ /**
55
+ * Partition a task's eval cases into rehydratable (with their captured input) and
56
+ * refused (named, with a reason). Pure over the injected reads — no network, no
57
+ * spend; the CLI runs this first and reports before replaying.
58
+ */
59
+ export declare function selectEvalCaseCaptures(deps: EvalCaseSelectionDeps, task: string): EvalCaseSelection;
60
+ /**
61
+ * A read-only in-memory CaptureStore over a fixed set of rehydrated captures, so
62
+ * the EXISTING bake-off engine (which reads `captures.readLast(route, n)`) runs
63
+ * over the eval-case selection with NO second actuation path (spec §3.3). Only
64
+ * `readLast` is meaningful; `getByInferenceId` is supported for symmetry; writes
65
+ * throw (this store is a replay lens, never a sink).
66
+ */
67
+ export declare function evalCaseCaptureStore(rows: readonly RehydratedCase[]): CaptureStore;
68
+ export interface EvalCaseBakeoffResult {
69
+ readonly selection: EvalCaseSelection;
70
+ /** The bake-off artifact over the rehydratable subset, or null when NOTHING
71
+ * was rehydratable (the CLI then reports the refusals and exits without spend). */
72
+ readonly artifact: BakeoffArtifact | null;
73
+ }
74
+ /**
75
+ * `bakeoff --from-eval-cases <task>` end to end: select rehydratable cases, then
76
+ * run the EXISTING bake-off engine over exactly those captured inputs (no second
77
+ * actuation path — spec §3.3). Replays every rehydratable case (replayLastN =
78
+ * the rehydratable count). Returns the selection (so the caller reports refusals)
79
+ * alongside the artifact.
80
+ */
81
+ /** The rig-side store bundle the orchestrator adapts into `EvalCaseSelectionDeps`
82
+ * — passed straight from `createRig` so `index.ts` stays a one-line delegate.
83
+ * `artifacts` is null when the namespace is off (nothing to rehydrate); `captures`
84
+ * is a thunk because the rig opens that handle lazily. */
85
+ export interface EvalCaseStores {
86
+ readonly artifacts: Pick<ArtifactStore, "readEvalCasesByTask" | "getArtifactById"> | null;
87
+ readonly telemetry: Pick<ExportableTelemetryStore, "getStepInferenceId">;
88
+ readonly captures: () => Pick<CaptureStore, "getByInferenceId">;
89
+ }
90
+ export declare function runBakeoffFromEvalCases(deps: RunDeps, stores: EvalCaseStores, req: {
91
+ readonly task: string;
92
+ readonly variants: readonly string[];
93
+ readonly envelopeUsdPerVariant: number;
94
+ readonly keepOutputs?: KeepOutputsMode;
95
+ }, samplesSink?: BakeoffSamplesSink): Promise<EvalCaseBakeoffResult>;
96
+ //# sourceMappingURL=eval-cases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-cases.d.ts","sourceRoot":"","sources":["../../src/bakeoff/eval-cases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;oDACoD;AACpD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,EAAE,CAAC;IAC9D,QAAQ,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAClG,QAAQ,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC/E,QAAQ,CAAC,uBAAuB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,UAAU,GAAG,IAAI,CAAC;CAC9E;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,SAAS,cAAc,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;CAC/C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAgCnG;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,GAAG,YAAY,CAclF;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC;uFACmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAC3C;AAED;;;;;;GAMG;AACH;;;0DAG0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,qBAAqB,GAAG,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC1F,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,wBAAwB,EAAE,oBAAoB,CAAC,CAAC;IACzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;CACjE;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC;CACxC,EACD,WAAW,CAAC,EAAE,kBAAkB,GAC/B,OAAO,CAAC,qBAAqB,CAAC,CA6BhC"}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * Bake-off input selection from eval cases — Expansion E4 chunk A (spec §3).
4
+ *
5
+ * `bakeoff --from-eval-cases <task>` replays the promoted regression/golden cases
6
+ * for a task instead of the last-N captures. A case only holds METADATA (a source
7
+ * artifact id); the INPUT to replay lives in a LOCAL capture, reachable through
8
+ * the chain:
9
+ *
10
+ * eval_case → source artifact (run_id, step_key) → step's inference_id → capture
11
+ *
12
+ * Any link may be missing — the source artifact predates local retention, the
13
+ * route never had `capture: true`, the capture was evicted. When it is, the case
14
+ * is UNREHYDRATABLE. The load-bearing doctrine (spec §3.3): the bake-off runs on
15
+ * the rehydratable subset and NAMES every refused case with a reason — NEVER a
16
+ * silent subset. `selectEvalCaseCaptures` returns both halves so the CLI can
17
+ * print the honest-refusal report before it spends a cent.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.selectEvalCaseCaptures = selectEvalCaseCaptures;
21
+ exports.evalCaseCaptureStore = evalCaseCaptureStore;
22
+ exports.runBakeoffFromEvalCases = runBakeoffFromEvalCases;
23
+ const engine_1 = require("./engine");
24
+ /**
25
+ * Partition a task's eval cases into rehydratable (with their captured input) and
26
+ * refused (named, with a reason). Pure over the injected reads — no network, no
27
+ * spend; the CLI runs this first and reports before replaying.
28
+ */
29
+ function selectEvalCaseCaptures(deps, task) {
30
+ const cases = deps.readEvalCasesByTask(task);
31
+ const rehydratable = [];
32
+ const refusals = [];
33
+ for (const c of cases) {
34
+ const refuse = (reason) => {
35
+ refusals.push({ caseId: c.id, sourceArtifactId: c.sourceArtifactId, reason });
36
+ };
37
+ const art = deps.getArtifactById(c.sourceArtifactId);
38
+ if (art === null) {
39
+ refuse("source artifact is not in the local store (promoted on another deployment, or evicted)");
40
+ continue;
41
+ }
42
+ if (art.runId === null || art.stepKey === null) {
43
+ refuse("source artifact was saved outside a step — no inference to key its input");
44
+ continue;
45
+ }
46
+ const inferenceId = deps.getStepInferenceId(art.runId, art.stepKey);
47
+ if (inferenceId === null) {
48
+ refuse("no ground-truth inference recorded for the source step");
49
+ continue;
50
+ }
51
+ const capture = deps.getCaptureByInferenceId(inferenceId);
52
+ if (capture === null) {
53
+ refuse("input not captured locally (route `capture` was off, or the capture was evicted)");
54
+ continue;
55
+ }
56
+ rehydratable.push({ caseId: c.id, capture });
57
+ }
58
+ return { task, total: cases.length, rehydratable, refusals };
59
+ }
60
+ /**
61
+ * A read-only in-memory CaptureStore over a fixed set of rehydrated captures, so
62
+ * the EXISTING bake-off engine (which reads `captures.readLast(route, n)`) runs
63
+ * over the eval-case selection with NO second actuation path (spec §3.3). Only
64
+ * `readLast` is meaningful; `getByInferenceId` is supported for symmetry; writes
65
+ * throw (this store is a replay lens, never a sink).
66
+ */
67
+ function evalCaseCaptureStore(rows) {
68
+ const captures = rows.map((r) => r.capture);
69
+ return {
70
+ record() {
71
+ throw new Error("evalCaseCaptureStore is read-only (a replay lens, not a sink)");
72
+ },
73
+ readLast(route, n) {
74
+ return captures.filter((c) => c.route === route).slice(0, n);
75
+ },
76
+ getByInferenceId(inferenceId) {
77
+ return captures.find((c) => c.inferenceId === inferenceId) ?? null;
78
+ },
79
+ close() { },
80
+ };
81
+ }
82
+ async function runBakeoffFromEvalCases(deps, stores, req, samplesSink) {
83
+ const empty = { task: req.task, total: 0, rehydratable: [], refusals: [] };
84
+ // No artifact namespace ⇒ nothing to rehydrate; honest empty selection.
85
+ if (stores.artifacts === null)
86
+ return { selection: empty, artifact: null };
87
+ const arts = stores.artifacts;
88
+ const caps = stores.captures();
89
+ const selection = selectEvalCaseCaptures({
90
+ readEvalCasesByTask: (t) => arts.readEvalCasesByTask(t),
91
+ getArtifactById: (id) => arts.getArtifactById(id),
92
+ getStepInferenceId: (r, s) => stores.telemetry.getStepInferenceId(r, s),
93
+ getCaptureByInferenceId: (i) => caps.getByInferenceId(i),
94
+ }, req.task);
95
+ if (selection.rehydratable.length === 0)
96
+ return { selection, artifact: null };
97
+ const artifact = await (0, engine_1.runBakeoff)(deps, evalCaseCaptureStore(selection.rehydratable), {
98
+ route: req.task,
99
+ variants: req.variants,
100
+ replayLastN: selection.rehydratable.length, // replay every rehydratable case
101
+ envelopeUsdPerVariant: req.envelopeUsdPerVariant,
102
+ ...(req.keepOutputs !== undefined ? { keepOutputs: req.keepOutputs } : {}),
103
+ }, samplesSink);
104
+ return { selection, artifact };
105
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Offline shadow replay — Phase 3 spec WS4/WS5. Re-runs locally captured
3
+ * inputs against candidate variants with ZERO production exposure. Replay
4
+ * dispatches are real (billed) adapter calls, but: envelope-guarded, tagged
5
+ * as replay (distinct from production telemetry), and never written to
6
+ * captures (no replay-of-replay).
7
+ *
8
+ * Builder decisions (flagged for architect review):
9
+ * - Replay rows go into the SAME local store under the `replay:<id>` TAG
10
+ * NAMESPACE (the scaffold's sanctioned option A): every replay attempt row
11
+ * carries tags {replay, replay_capture, variant} — production queries
12
+ * filter them out by tag, and per-sample cost is reconstructed from the
13
+ * same rows (base + retries + repair + search — F1-correct).
14
+ * - ReplaySampleResult gained `repairCostUsd` (additive) so the engine can
15
+ * report repair cost separately from total cost.
16
+ * - Envelope breach stops the pass typed-ly: the breaching sample is
17
+ * recorded with failureClass budget_exhausted and the PARTIAL result set
18
+ * is returned (honest Ns beat discarded spend).
19
+ */
20
+ import type { CaptureStore } from "../telemetry/capture";
21
+ import type { RunDeps } from "../run/run";
22
+ export interface ReplayRequest {
23
+ readonly route: string;
24
+ readonly variant: string;
25
+ readonly lastN: number;
26
+ readonly envelopeUsd: number;
27
+ /** Addendum A3: retain the rendered input + this arm's output on each
28
+ * sample for the human value review. Off by default (bounds memory + keeps
29
+ * the pure-metrics path clean). */
30
+ readonly keepOutputs?: boolean;
31
+ }
32
+ export interface ReplaySampleResult {
33
+ readonly captureId: string;
34
+ readonly conform: boolean;
35
+ readonly repaired: boolean;
36
+ readonly valueAccuracy: number | null;
37
+ readonly costUsd: number;
38
+ /** Portion of costUsd spent on repair calls (repaired_by rows). */
39
+ readonly repairCostUsd: number;
40
+ /** Addendum A1: any attempt row lacked pricing — costUsd under-counts and
41
+ * this sample must never rank a variant as cheap. */
42
+ readonly pricingMissing: boolean;
43
+ readonly latencyMs: number;
44
+ readonly failureClass: string | null;
45
+ /** Addendum A3 (keepOutputs only): the replayed input, verbatim. */
46
+ readonly inputText?: string;
47
+ /** Addendum A3 (keepOutputs only): this arm's output for the review, or
48
+ * null when the arm produced none (a failure). */
49
+ readonly outputText?: string | null;
50
+ }
51
+ export declare function replayVariant(deps: RunDeps, captures: CaptureStore, req: ReplayRequest): Promise<readonly ReplaySampleResult[]>;
52
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/bakeoff/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;uCAEmC;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;yDACqD;IACrD,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oEAAoE;IACpE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;sDACkD;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAsExC"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ /**
3
+ * Offline shadow replay — Phase 3 spec WS4/WS5. Re-runs locally captured
4
+ * inputs against candidate variants with ZERO production exposure. Replay
5
+ * dispatches are real (billed) adapter calls, but: envelope-guarded, tagged
6
+ * as replay (distinct from production telemetry), and never written to
7
+ * captures (no replay-of-replay).
8
+ *
9
+ * Builder decisions (flagged for architect review):
10
+ * - Replay rows go into the SAME local store under the `replay:<id>` TAG
11
+ * NAMESPACE (the scaffold's sanctioned option A): every replay attempt row
12
+ * carries tags {replay, replay_capture, variant} — production queries
13
+ * filter them out by tag, and per-sample cost is reconstructed from the
14
+ * same rows (base + retries + repair + search — F1-correct).
15
+ * - ReplaySampleResult gained `repairCostUsd` (additive) so the engine can
16
+ * report repair cost separately from total cost.
17
+ * - Envelope breach stops the pass typed-ly: the breaching sample is
18
+ * recorded with failureClass budget_exhausted and the PARTIAL result set
19
+ * is returned (honest Ns beat discarded spend).
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.replayVariant = replayVariant;
23
+ const node_crypto_1 = require("node:crypto");
24
+ const failures_1 = require("../types/failures");
25
+ const run_1 = require("../run/run");
26
+ async function replayVariant(deps, captures, req) {
27
+ const rows = captures.readLast(req.route, req.lastN);
28
+ const replayId = (0, node_crypto_1.randomUUID)();
29
+ const envelopeKey = `replay:${replayId}`;
30
+ // Zero production exposure knobs: no capture writes (no replay-of-replay),
31
+ // and the whole pass shares one hard envelope.
32
+ const replayDeps = {
33
+ ...deps,
34
+ captures: null,
35
+ envelopeBudgetUsd: req.envelopeUsd,
36
+ };
37
+ const results = [];
38
+ for (const capture of rows) {
39
+ const sampleTag = `${replayId}:${capture.inferenceId}`;
40
+ const started = Date.now();
41
+ let conform = false;
42
+ let repaired = false;
43
+ let failureClass = null;
44
+ let outputText = null;
45
+ try {
46
+ // Through the REAL run loop: the variant's template re-renders against
47
+ // the replay candidate's capability flags (never the captured prompt
48
+ // text — plan §10 replay-validity risk), repair/grounding rungs and
49
+ // retry budgets all behave exactly as production serving would.
50
+ const result = await (0, run_1.run)(replayDeps, req.route, {
51
+ input: JSON.parse(capture.variablesJson),
52
+ tags: { replay: replayId, replay_capture: sampleTag, variant: req.variant },
53
+ ...(req.variant !== "default" ? { variant: req.variant } : {}),
54
+ budget: { envelope: envelopeKey },
55
+ });
56
+ conform = result.meta.validated;
57
+ repaired = result.meta.repairedBy !== null;
58
+ if (req.keepOutputs)
59
+ outputText = JSON.stringify(result.output, null, 2);
60
+ }
61
+ catch (err) {
62
+ if (!(err instanceof failures_1.RigFailureError))
63
+ throw err;
64
+ failureClass = err.failure.class;
65
+ }
66
+ const latencyMs = Date.now() - started;
67
+ // Per-sample cost from the tagged attempt rows — base + retries + repair
68
+ // + search, exactly what telemetry billed (F1-corrected).
69
+ const attemptRows = deps.telemetry.queryByTag("replay_capture", sampleTag);
70
+ const costUsd = attemptRows.reduce((a, r) => a + r.costEstimateUsd, 0);
71
+ const repairCostUsd = attemptRows
72
+ .filter((r) => r.repairedBy !== null)
73
+ .reduce((a, r) => a + r.costEstimateUsd, 0);
74
+ const pricingMissing = attemptRows.some((r) => r.pricingMissing);
75
+ results.push({
76
+ captureId: capture.inferenceId,
77
+ conform,
78
+ repaired,
79
+ valueAccuracy: null, // golden-set hook — expected values are Phase 4's judge/goldens work
80
+ costUsd,
81
+ repairCostUsd,
82
+ pricingMissing,
83
+ latencyMs,
84
+ failureClass,
85
+ ...(req.keepOutputs
86
+ ? { inputText: capture.variablesJson, outputText }
87
+ : {}),
88
+ });
89
+ if (failureClass === "budget_exhausted") {
90
+ break; // typed stop at the envelope; partial results stand
91
+ }
92
+ }
93
+ return results;
94
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Bake-off terminal reporting — the matrix printer (moved here from cli.ts for
3
+ * the LOC cap, P1) and the `--from-eval-cases` runner (E4 chunk A) with its
4
+ * HONEST-REFUSAL report: every eval case that could not be rehydrated is NAMED
5
+ * with a reason before any bake-off runs — never a silent subset (spec §3.3).
6
+ */
7
+ import type { RigConfig } from "../config";
8
+ import type { CacheSimAssumptions } from "./cache-sim";
9
+ import type { KeepOutputsMode } from "./samples";
10
+ import type { BakeoffArtifact } from "./types";
11
+ /**
12
+ * One variant's measured-cold vs cache-adjusted input cost (cache-aware-routing
13
+ * spec §5.4). Built by the caller from `simulateCache` + the candidate's rates;
14
+ * this module only RENDERS it, so the report stays pure of pricing lookups.
15
+ */
16
+ export interface CacheAdjustedRow {
17
+ readonly variant: string;
18
+ /** Input cost the way replay actually paid it — every token at list (§5.4). */
19
+ readonly measuredColdUsd: number;
20
+ /** Input cost at production cadence — reads/writes priced per policy (§5.4). */
21
+ readonly cacheAdjustedUsd: number;
22
+ readonly assumptions: CacheSimAssumptions;
23
+ }
24
+ /**
25
+ * Render the cache-adjusted section (spec §5.4) as lines — measured-cold AND
26
+ * cache-adjusted input cost side by side, with the simulator's assumptions
27
+ * PRINTED so the numbers are never mistaken for measured savings. Pure (returns
28
+ * strings; `printMatrix` does the console I/O) so it is unit-tested directly.
29
+ * Empty input ⇒ no lines (the section is omitted entirely — back-compat).
30
+ */
31
+ export declare function formatCacheAdjustedSection(rows: readonly CacheAdjustedRow[]): string[];
32
+ export declare function printMatrix(artifact: BakeoffArtifact, cacheAdjusted?: readonly CacheAdjustedRow[]): void;
33
+ /**
34
+ * `modelrig bakeoff --from-eval-cases <task> --variants a,b,c` — replay a task's
35
+ * promoted eval cases through each variant. Prints the honest-refusal report,
36
+ * then (if anything rehydrated) runs the bake-off and persists/mirrors/prints it.
37
+ * Returns the process exit code: 0 on a run (or an empty suite), 1 when cases
38
+ * existed but NONE could be rehydrated (an actionable non-zero, not a crash).
39
+ */
40
+ export declare function runEvalCaseBakeoffCli(config: RigConfig, task: string, variants: readonly string[], envelope: number | undefined, keep: KeepOutputsMode | undefined, asJson: boolean): Promise<number>;
41
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/bakeoff/report.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAM/D;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAgCtF;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,EAAE,aAAa,GAAE,SAAS,gBAAgB,EAAO,GAAG,IAAI,CAgC5G;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,eAAe,GAAG,SAAS,EACjC,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC,CA8CjB"}