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,151 @@
1
+ /**
2
+ * Cache-adjusted route economics — cache-aware-routing spec §4.2–4.3, WS-B.
3
+ * PURE: no store, no clock, no network. Every function here is total and
4
+ * deterministic; the whole module is the math the architect reviews pre-merge.
5
+ *
6
+ * ── THE REGRESSION PIN (load-bearing, WS-A discipline) ────────────────────
7
+ * With observed hit rate h = 0 and write rate w = 0, `effectiveInputRate`
8
+ * returns the LIST input rate BYTE-IDENTICALLY, and every per-call saving
9
+ * collapses to 0. A route with no cache activity therefore prices exactly as it
10
+ * did before this module existed. The property test locks this: the cache-aware
11
+ * lens NEVER changes a number until real cache tokens appear.
12
+ *
13
+ * ── FAIL-CLOSED RATES (dev-rule L5) ───────────────────────────────────────
14
+ * An unverified cache-read or cache-write rate degrades to the INPUT rate
15
+ * (1.0×), never a guessed premium/discount — the same posture as
16
+ * `estimateCostUsd`. So an unpriced cache component can only make caching look
17
+ * NEUTRAL, never spuriously attractive.
18
+ *
19
+ * Units: every rate is USD PER TOKEN (matching `ModelPricing.inputUsdPerTok` and
20
+ * `pricing-shape.ts` `TokenRates`), so callers pass either shape unwidened.
21
+ */
22
+ /**
23
+ * The rate components the effective-rate math needs, USD per token. A thin,
24
+ * self-contained shape so this module imports neither `ModelPricing` nor
25
+ * `pricing-shape` (both can build one) and — critically — does NOT touch the
26
+ * UNRELATED local `TokenRates` in `watch/evaluate.ts` (QA name-collision note:
27
+ * that one is a flat `{inputUsdPerTok, outputUsdPerTok}` blend input; keep them
28
+ * separate). `cacheRead`/`cacheWrite` null ⇒ fall back to `input` (L5).
29
+ */
30
+ export interface EffectiveRates {
31
+ readonly input: number;
32
+ readonly cacheRead: number | null;
33
+ readonly cacheWrite: number | null;
34
+ }
35
+ /** Observed cache activity over a trailing window — the aggregate form (spec
36
+ * §4.2): `h = Σcached/Σin`, `w = Σwrite/Σin`. Both in [0,1]; `h + w ≤ 1` holds
37
+ * because cached and write tokens are disjoint subsets of input tokens. */
38
+ export interface ObservedCacheRates {
39
+ readonly h: number;
40
+ readonly w: number;
41
+ }
42
+ /**
43
+ * Cache-adjusted effective INPUT rate (spec §4.2, aggregate form):
44
+ *
45
+ * p_eff_in = h·p_read + w·p_write + (1 − h − w)·p_in
46
+ *
47
+ * The blend of what a token of input ACTUALLY costs given the window's cache
48
+ * behavior. Clamps h,w to non-negative and their sum to ≤ 1 (defensive — a
49
+ * malformed rollup must never produce a negative uncached weight). At h = w = 0
50
+ * this is exactly `rates.input` (the regression pin).
51
+ */
52
+ export declare function effectiveInputRate(obs: ObservedCacheRates, rates: EffectiveRates): number;
53
+ /**
54
+ * Expected per-call saving from READING a warm prefix instead of paying full
55
+ * input on it (spec §4.2, steady-state form): the cached prefix tokens cost
56
+ * `p_read` rather than `p_in`, so the saving per call is
57
+ *
58
+ * E[T_read]·(p_in − p_read), E[T_read] = matchingPrefixTokens · P(hit)
59
+ *
60
+ * The one-time write premium is NOT here — it is the switch cost (§4.3). At
61
+ * P(hit) = 0, or when the read rate has degraded to the input rate (L5), this is
62
+ * 0: a candidate with no verified read discount shows no per-call saving.
63
+ */
64
+ export declare function perCallCacheSavingsUsd(matchingPrefixTokens: number, pHit: number, rates: EffectiveRates): number;
65
+ /**
66
+ * Switch cost of moving a warm workflow from `oldRates` to `newRates` (spec
67
+ * §4.3):
68
+ *
69
+ * switch_cost = prefix_tok·p_write(new) − prefix_tok·p_read(old)
70
+ *
71
+ * The new candidate must WRITE the prefix into its (cold) cache at its write
72
+ * rate; the incumbent would have READ it at its read rate. Positive ⇒ switching
73
+ * costs money up front; negative ⇒ the incumbent's read was already dearer than
74
+ * the challenger's write (rare, but real when the incumbent has no read
75
+ * discount). With `prefixTokens = 0` this is exactly 0 (the regression pin for a
76
+ * route with no cacheable prefix).
77
+ */
78
+ export declare function switchCostUsd(prefixTokens: number, newRates: EffectiveRates, oldRates: EffectiveRates): number;
79
+ /**
80
+ * Cache option value (spec §4.3): the total warmth advantage a candidate is
81
+ * expected to accrue over its remaining life — `E[remaining_calls] ×
82
+ * per_call_cache_savings`. This is the benefit side the switch cost is weighed
83
+ * against. Non-negative inputs; 0 at either factor 0.
84
+ */
85
+ export declare function cacheOptionValueUsd(remainingCalls: number, perCallSavingsUsd: number): number;
86
+ /** Floor on the denominator of `breakevenCalls` so a vanishing per-call saving
87
+ * yields a very large (but finite) break-even rather than Infinity/NaN. */
88
+ export declare const BREAKEVEN_EPSILON_USD = 1e-9;
89
+ /**
90
+ * Break-even call count (spec §4.3): `switch_cost / max(per_call_savings, ε)` —
91
+ * how many warm calls a swap must serve before its up-front switch cost is
92
+ * repaid by per-call savings. Returns `Infinity` when the switch never pays back
93
+ * (non-positive per-call saving with a positive switch cost) so callers render
94
+ * "never breaks even" rather than a misleading huge integer. A non-positive
95
+ * switch cost (free or profitable to switch) breaks even at 0 calls.
96
+ */
97
+ export declare function breakevenCalls(switchCostUsd_: number, perCallSavingsUsd: number): number;
98
+ /**
99
+ * The cache-aware verdict on a swap proposal (spec §4.3). Renders on the
100
+ * console, the `swap execute` approval prompt, and the OTLP decision span.
101
+ * • `cache_positive` — cache-adjusted advantage clears BOTH the absolute
102
+ * floor and the relative threshold; recommended.
103
+ * • `cache_marginal` — a real advantage that does not clear the hysteresis
104
+ * bar; created + labeled, NOT recommended (anti-thrash).
105
+ * • `cache_negative` — cache-adjusted, the challenger is WORSE than list
106
+ * would suggest (incumbent warm, challenger cold).
107
+ * • `no_cache_signal` — no observed cache activity to base a cache-aware
108
+ * verdict on; the ordinary list comparison stands.
109
+ */
110
+ export type CacheVerdict = "cache_positive" | "cache_marginal" | "cache_negative" | "no_cache_signal";
111
+ /**
112
+ * Hysteresis config (transaction-cost analogy, [Briefing §16]). A swap is
113
+ * `cache_positive` only when its advantage clears BOTH bars — an absolute
114
+ * per-call floor AND a relative fraction of window spend. Defaults per spec
115
+ * §4.3; lives in `WatchConfig` (same home as `thresholdPct`), which composes
116
+ * this shape rather than redefining it.
117
+ */
118
+ export interface CacheHysteresisConfig {
119
+ /** Absolute floor, USD per call-equivalent (spec default $0.03). */
120
+ readonly cacheFloorUsdPerCall: number;
121
+ /** Relative floor, PERCENT of trailing-window spend (spec default 8%). */
122
+ readonly cacheRelativeThresholdPct: number;
123
+ }
124
+ export declare const DEFAULT_CACHE_HYSTERESIS: CacheHysteresisConfig;
125
+ /** The inputs the verdict classifier weighs (all cache-ADJUSTED). */
126
+ export interface CacheVerdictInput {
127
+ /** Whether the window carries ANY cache observation (read or write) on either
128
+ * side — false ⇒ `no_cache_signal` regardless of the numbers below. */
129
+ readonly hasCacheSignal: boolean;
130
+ /** Cache-adjusted per-call advantage of the challenger over the incumbent,
131
+ * USD (incumbent_effective_per_call − challenger_effective_per_call). >0 ⇒
132
+ * challenger cheaper once warmth + switch cost are counted. */
133
+ readonly perCallAdvantageUsd: number;
134
+ /** The same advantage projected over the expected remaining calls, USD — the
135
+ * quantity weighed against the relative (window-spend) bar. */
136
+ readonly totalAdvantageUsd: number;
137
+ /** Trailing-window spend on this route, USD — the base of the relative bar. */
138
+ readonly windowSpendUsd: number;
139
+ }
140
+ /**
141
+ * Classify a swap proposal's cache-aware verdict with hysteresis (spec §4.3).
142
+ * Pure and total. The ordering is deliberate: no signal short-circuits first
143
+ * (we cannot speak to cache economics we have not observed), then a negative
144
+ * advantage is `cache_negative`, then the two-bar hysteresis gate separates
145
+ * `cache_positive` from `cache_marginal`.
146
+ */
147
+ export declare function classifyCacheVerdict(input: CacheVerdictInput, config?: CacheHysteresisConfig): CacheVerdict;
148
+ /** Human-readable one-liner for a verdict — reused by the console, the approval
149
+ * prompt, and the definitions page (WS-D) so the phrasing is single-sourced. */
150
+ export declare function describeCacheVerdict(verdict: CacheVerdict): string;
151
+ //# sourceMappingURL=effective-rate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effective-rate.d.ts","sourceRoot":"","sources":["../../src/registry/effective-rate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;2EAE2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAUzF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,oBAAoB,EAAE,MAAM,EAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,cAAc,GACpB,MAAM,CAKR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,cAAc,GACvB,MAAM,CAGR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAE7F;AAED;2EAC2E;AAC3E,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAIxF;AAID;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAEtG;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,oEAAoE;IACpE,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,0EAA0E;IAC1E,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;CAC5C;AAED,eAAO,MAAM,wBAAwB,EAAE,qBAGtC,CAAC;AAEF,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC;2EACuE;IACvE,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;mEAE+D;IAC/D,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC;mEAC+D;IAC/D,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,iBAAiB,EACxB,MAAM,GAAE,qBAAgD,GACvD,YAAY,CAOd;AAED;gFACgF;AAChF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAWlE"}
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ /**
3
+ * Cache-adjusted route economics — cache-aware-routing spec §4.2–4.3, WS-B.
4
+ * PURE: no store, no clock, no network. Every function here is total and
5
+ * deterministic; the whole module is the math the architect reviews pre-merge.
6
+ *
7
+ * ── THE REGRESSION PIN (load-bearing, WS-A discipline) ────────────────────
8
+ * With observed hit rate h = 0 and write rate w = 0, `effectiveInputRate`
9
+ * returns the LIST input rate BYTE-IDENTICALLY, and every per-call saving
10
+ * collapses to 0. A route with no cache activity therefore prices exactly as it
11
+ * did before this module existed. The property test locks this: the cache-aware
12
+ * lens NEVER changes a number until real cache tokens appear.
13
+ *
14
+ * ── FAIL-CLOSED RATES (dev-rule L5) ───────────────────────────────────────
15
+ * An unverified cache-read or cache-write rate degrades to the INPUT rate
16
+ * (1.0×), never a guessed premium/discount — the same posture as
17
+ * `estimateCostUsd`. So an unpriced cache component can only make caching look
18
+ * NEUTRAL, never spuriously attractive.
19
+ *
20
+ * Units: every rate is USD PER TOKEN (matching `ModelPricing.inputUsdPerTok` and
21
+ * `pricing-shape.ts` `TokenRates`), so callers pass either shape unwidened.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.DEFAULT_CACHE_HYSTERESIS = exports.BREAKEVEN_EPSILON_USD = void 0;
25
+ exports.effectiveInputRate = effectiveInputRate;
26
+ exports.perCallCacheSavingsUsd = perCallCacheSavingsUsd;
27
+ exports.switchCostUsd = switchCostUsd;
28
+ exports.cacheOptionValueUsd = cacheOptionValueUsd;
29
+ exports.breakevenCalls = breakevenCalls;
30
+ exports.classifyCacheVerdict = classifyCacheVerdict;
31
+ exports.describeCacheVerdict = describeCacheVerdict;
32
+ /** Resolve a possibly-null cache rate to its fail-closed fallback (the input
33
+ * rate). Centralized so every function degrades identically (L5). */
34
+ function readRate(rates) {
35
+ return rates.cacheRead ?? rates.input;
36
+ }
37
+ function writeRate(rates) {
38
+ return rates.cacheWrite ?? rates.input;
39
+ }
40
+ /**
41
+ * Cache-adjusted effective INPUT rate (spec §4.2, aggregate form):
42
+ *
43
+ * p_eff_in = h·p_read + w·p_write + (1 − h − w)·p_in
44
+ *
45
+ * The blend of what a token of input ACTUALLY costs given the window's cache
46
+ * behavior. Clamps h,w to non-negative and their sum to ≤ 1 (defensive — a
47
+ * malformed rollup must never produce a negative uncached weight). At h = w = 0
48
+ * this is exactly `rates.input` (the regression pin).
49
+ */
50
+ function effectiveInputRate(obs, rates) {
51
+ const h = Math.max(obs.h, 0);
52
+ const w = Math.max(obs.w, 0);
53
+ // Cap the combined cache weight at 1: uncached weight never goes negative.
54
+ const cacheWeight = Math.min(h + w, 1);
55
+ const scale = h + w > 0 ? cacheWeight / (h + w) : 0;
56
+ const hh = h * scale;
57
+ const ww = w * scale;
58
+ const uncachedWeight = 1 - hh - ww;
59
+ return hh * readRate(rates) + ww * writeRate(rates) + uncachedWeight * rates.input;
60
+ }
61
+ /**
62
+ * Expected per-call saving from READING a warm prefix instead of paying full
63
+ * input on it (spec §4.2, steady-state form): the cached prefix tokens cost
64
+ * `p_read` rather than `p_in`, so the saving per call is
65
+ *
66
+ * E[T_read]·(p_in − p_read), E[T_read] = matchingPrefixTokens · P(hit)
67
+ *
68
+ * The one-time write premium is NOT here — it is the switch cost (§4.3). At
69
+ * P(hit) = 0, or when the read rate has degraded to the input rate (L5), this is
70
+ * 0: a candidate with no verified read discount shows no per-call saving.
71
+ */
72
+ function perCallCacheSavingsUsd(matchingPrefixTokens, pHit, rates) {
73
+ const tokens = Math.max(matchingPrefixTokens, 0);
74
+ const hit = Math.min(Math.max(pHit, 0), 1);
75
+ const perTokenSaving = Math.max(rates.input - readRate(rates), 0);
76
+ return tokens * hit * perTokenSaving;
77
+ }
78
+ /**
79
+ * Switch cost of moving a warm workflow from `oldRates` to `newRates` (spec
80
+ * §4.3):
81
+ *
82
+ * switch_cost = prefix_tok·p_write(new) − prefix_tok·p_read(old)
83
+ *
84
+ * The new candidate must WRITE the prefix into its (cold) cache at its write
85
+ * rate; the incumbent would have READ it at its read rate. Positive ⇒ switching
86
+ * costs money up front; negative ⇒ the incumbent's read was already dearer than
87
+ * the challenger's write (rare, but real when the incumbent has no read
88
+ * discount). With `prefixTokens = 0` this is exactly 0 (the regression pin for a
89
+ * route with no cacheable prefix).
90
+ */
91
+ function switchCostUsd(prefixTokens, newRates, oldRates) {
92
+ const tokens = Math.max(prefixTokens, 0);
93
+ return tokens * writeRate(newRates) - tokens * readRate(oldRates);
94
+ }
95
+ /**
96
+ * Cache option value (spec §4.3): the total warmth advantage a candidate is
97
+ * expected to accrue over its remaining life — `E[remaining_calls] ×
98
+ * per_call_cache_savings`. This is the benefit side the switch cost is weighed
99
+ * against. Non-negative inputs; 0 at either factor 0.
100
+ */
101
+ function cacheOptionValueUsd(remainingCalls, perCallSavingsUsd) {
102
+ return Math.max(remainingCalls, 0) * Math.max(perCallSavingsUsd, 0);
103
+ }
104
+ /** Floor on the denominator of `breakevenCalls` so a vanishing per-call saving
105
+ * yields a very large (but finite) break-even rather than Infinity/NaN. */
106
+ exports.BREAKEVEN_EPSILON_USD = 1e-9;
107
+ /**
108
+ * Break-even call count (spec §4.3): `switch_cost / max(per_call_savings, ε)` —
109
+ * how many warm calls a swap must serve before its up-front switch cost is
110
+ * repaid by per-call savings. Returns `Infinity` when the switch never pays back
111
+ * (non-positive per-call saving with a positive switch cost) so callers render
112
+ * "never breaks even" rather than a misleading huge integer. A non-positive
113
+ * switch cost (free or profitable to switch) breaks even at 0 calls.
114
+ */
115
+ function breakevenCalls(switchCostUsd_, perCallSavingsUsd) {
116
+ if (switchCostUsd_ <= 0)
117
+ return 0;
118
+ if (perCallSavingsUsd <= 0)
119
+ return Number.POSITIVE_INFINITY;
120
+ return switchCostUsd_ / Math.max(perCallSavingsUsd, exports.BREAKEVEN_EPSILON_USD);
121
+ }
122
+ exports.DEFAULT_CACHE_HYSTERESIS = {
123
+ cacheFloorUsdPerCall: 0.03,
124
+ cacheRelativeThresholdPct: 8,
125
+ };
126
+ /**
127
+ * Classify a swap proposal's cache-aware verdict with hysteresis (spec §4.3).
128
+ * Pure and total. The ordering is deliberate: no signal short-circuits first
129
+ * (we cannot speak to cache economics we have not observed), then a negative
130
+ * advantage is `cache_negative`, then the two-bar hysteresis gate separates
131
+ * `cache_positive` from `cache_marginal`.
132
+ */
133
+ function classifyCacheVerdict(input, config = exports.DEFAULT_CACHE_HYSTERESIS) {
134
+ if (!input.hasCacheSignal)
135
+ return "no_cache_signal";
136
+ if (input.perCallAdvantageUsd < 0)
137
+ return "cache_negative";
138
+ const clearsFloor = input.perCallAdvantageUsd >= config.cacheFloorUsdPerCall;
139
+ const relativeBar = (config.cacheRelativeThresholdPct / 100) * Math.max(input.windowSpendUsd, 0);
140
+ const clearsRelative = input.totalAdvantageUsd >= relativeBar;
141
+ return clearsFloor && clearsRelative ? "cache_positive" : "cache_marginal";
142
+ }
143
+ /** Human-readable one-liner for a verdict — reused by the console, the approval
144
+ * prompt, and the definitions page (WS-D) so the phrasing is single-sourced. */
145
+ function describeCacheVerdict(verdict) {
146
+ switch (verdict) {
147
+ case "cache_positive":
148
+ return "cache-positive — clears the switch-cost hysteresis; recommended";
149
+ case "cache_marginal":
150
+ return "cache-marginal — a real but sub-threshold advantage; not recommended (anti-thrash)";
151
+ case "cache_negative":
152
+ return "cache-negative — the incumbent is warm and the challenger is cold; switching costs more than it saves";
153
+ case "no_cache_signal":
154
+ return "no cache signal — no observed cache activity; the list-price comparison stands";
155
+ }
156
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Registry-wired capability facts — Phase 3 spec WS6, plan §4. Replaces the
3
+ * Phase 1 "grant whatever the adapter claims" stub: routing now consumes
4
+ * declared+probed registry facts from the packaged registry.json
5
+ * (env-overridable path), with precedence
6
+ *
7
+ * capabilityOverrides (config) > probed > declared
8
+ *
9
+ * applied PER FLAG. Discrepancy-aware: a probed-false trumps a declared-true
10
+ * — the DeepSeek case (declared supports_response_schema, probed
11
+ * native_rung_rate = 0) finally routes correctly.
12
+ *
13
+ * Conservatism rules (measurement honesty):
14
+ * - grounded_native: probed can only REVOKE (a declared-true with a low
15
+ * probed grounded rate), never grant — high citation rates without
16
+ * declared search may be fabricated URLs.
17
+ * - Unprobed/undeclared dimensions (explicit caches, cache keys, flex tier,
18
+ * trace visibility) fall back to the adapter-static map, which is the
19
+ * declared layer for call-shaping facts.
20
+ */
21
+ import type { CapabilityFlag, ProviderId } from "../types/provider";
22
+ import type { RegistryEntry } from "./build";
23
+ export interface RegistryFacts {
24
+ /** Capability flags for a (provider, model), or null when the registry has
25
+ * no entry for it (caller falls back to the adapter-static map). */
26
+ flagsFor(provider: ProviderId, model: string, staticFlags: ReadonlySet<CapabilityFlag>): ReadonlySet<CapabilityFlag> | null;
27
+ }
28
+ /** Per-flag fact merge for one registry entry. `staticFlags` is the
29
+ * adapter-static (declared call-shaping) baseline. */
30
+ export declare function capabilityFactsFromEntry(entry: RegistryEntry, staticFlags: ReadonlySet<CapabilityFlag>): Set<CapabilityFlag>;
31
+ export declare function loadRegistryFacts(registryPath?: string): RegistryFacts;
32
+ //# sourceMappingURL=facts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.d.ts","sourceRoot":"","sources":["../../src/registry/facts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAY,aAAa,EAAE,MAAM,SAAS,CAAC;AAMvD,MAAM,WAAW,aAAa;IAC5B;wEACoE;IACpE,QAAQ,CACN,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,CAAC,cAAc,CAAC,GACvC,WAAW,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;CACvC;AAED;sDACsD;AACtD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,WAAW,CAAC,cAAc,CAAC,GACvC,GAAG,CAAC,cAAc,CAAC,CAsErB;AAQD,wBAAgB,iBAAiB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CA8BtE"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ /**
3
+ * Registry-wired capability facts — Phase 3 spec WS6, plan §4. Replaces the
4
+ * Phase 1 "grant whatever the adapter claims" stub: routing now consumes
5
+ * declared+probed registry facts from the packaged registry.json
6
+ * (env-overridable path), with precedence
7
+ *
8
+ * capabilityOverrides (config) > probed > declared
9
+ *
10
+ * applied PER FLAG. Discrepancy-aware: a probed-false trumps a declared-true
11
+ * — the DeepSeek case (declared supports_response_schema, probed
12
+ * native_rung_rate = 0) finally routes correctly.
13
+ *
14
+ * Conservatism rules (measurement honesty):
15
+ * - grounded_native: probed can only REVOKE (a declared-true with a low
16
+ * probed grounded rate), never grant — high citation rates without
17
+ * declared search may be fabricated URLs.
18
+ * - Unprobed/undeclared dimensions (explicit caches, cache keys, flex tier,
19
+ * trace visibility) fall back to the adapter-static map, which is the
20
+ * declared layer for call-shaping facts.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.capabilityFactsFromEntry = capabilityFactsFromEntry;
24
+ exports.loadRegistryFacts = loadRegistryFacts;
25
+ const node_fs_1 = require("node:fs");
26
+ const node_path_1 = require("node:path");
27
+ /** Same bar the registry's discrepancy detection uses. */
28
+ const GROUNDED_BAR = 0.5;
29
+ const CONFORMANCE_BAR = 0.9;
30
+ /** Per-flag fact merge for one registry entry. `staticFlags` is the
31
+ * adapter-static (declared call-shaping) baseline. */
32
+ function capabilityFactsFromEntry(entry, staticFlags) {
33
+ const flags = new Set(staticFlags);
34
+ const declared = entry.declared;
35
+ const probed = entry.probed;
36
+ // structured_native — probed native_rung_rate is the ground truth when
37
+ // sampled; else declared (adapter fact first, pricing-map flag second).
38
+ const nativeRate = probed?.schema?.native_rung_rate ?? null;
39
+ if (nativeRate !== null) {
40
+ if (nativeRate > 0)
41
+ flags.add("structured_native");
42
+ else
43
+ flags.delete("structured_native"); // the DeepSeek json_object-vs-schema gap
44
+ }
45
+ else if (declared !== null) {
46
+ const declaredNative = declared.flags.adapter_structured_native ?? declared.flags.supports_response_schema;
47
+ if (declaredNative === true)
48
+ flags.add("structured_native");
49
+ else if (declaredNative === false)
50
+ flags.delete("structured_native");
51
+ }
52
+ // json_mode — probed: a sampled schema class with a decent conform rate on
53
+ // ANY rung proves the model can emit parseable schema-shaped JSON.
54
+ const conformRate = probed?.schema?.conform_rate ?? null;
55
+ if (conformRate !== null && conformRate >= CONFORMANCE_BAR) {
56
+ flags.add("json_mode");
57
+ }
58
+ // grounded_native — probed may REVOKE a declared-true, never grant.
59
+ const groundedRate = probed?.grounding?.grounded_rate ?? null;
60
+ const declaredGrounded = declared === null
61
+ ? null
62
+ : (declared.flags.adapter_grounded_native ?? declared.flags.supports_web_search);
63
+ if (declaredGrounded === true)
64
+ flags.add("grounded_native");
65
+ else if (declaredGrounded === false)
66
+ flags.delete("grounded_native");
67
+ if (flags.has("grounded_native") &&
68
+ groundedRate !== null &&
69
+ (probed?.grounding?.samples ?? 0) > 0 &&
70
+ groundedRate < GROUNDED_BAR) {
71
+ flags.delete("grounded_native");
72
+ }
73
+ // prefix_cache_implicit — probed realized cache behavior wins when sampled.
74
+ const caching = probed?.caching ?? null;
75
+ if (caching !== null && caching.samples > 0) {
76
+ if (caching.cache_hit_rate > 0)
77
+ flags.add("prefix_cache_implicit");
78
+ else
79
+ flags.delete("prefix_cache_implicit");
80
+ }
81
+ else if (declared?.flags.supports_prompt_caching === true) {
82
+ flags.add("prefix_cache_implicit");
83
+ }
84
+ // zero_retention (G-3) — the opt-in data-governance filter. Authoritative
85
+ // source is the credential-scoped `facts` layer (claims.ts), NEVER the
86
+ // adapter-static baseline: ZDR is a policy designation, not an observable
87
+ // adapter capability. The flag is present only when a fact designates this
88
+ // endpoint zero-retention under our own (managed) account or unconditionally
89
+ // (any). A byok-only designation does NOT grant it — a customer's own key
90
+ // does not inherit our managed-account posture (the credential-scope
91
+ // compliance rule; product-plan v3.2, phase6-verification.md). Absence, a
92
+ // value:false, and a stray baseline flag all fail closed: no cited managed/any
93
+ // ZDR fact => the model is excluded from a `zero_retention` route.
94
+ const zdrFacts = entry.facts?.zero_retention;
95
+ const zdrDesignated = zdrFacts?.some((f) => f.value === true && (f.scope === "managed" || f.scope === "any")) ?? false;
96
+ if (zdrDesignated)
97
+ flags.add("zero_retention");
98
+ else
99
+ flags.delete("zero_retention");
100
+ // context_cache_explicit / prompt_cache_key / tier_flex / trace_visible:
101
+ // unprobed dimensions — the adapter-static baseline stands.
102
+ return flags;
103
+ }
104
+ /** Packaged registry.json (registry/ at the package root; dist/ and src/
105
+ * both sit one level below it). */
106
+ function packagedRegistryPath() {
107
+ return (0, node_path_1.join)(__dirname, "..", "..", "registry", "registry.json");
108
+ }
109
+ function loadRegistryFacts(registryPath) {
110
+ const path = registryPath ?? packagedRegistryPath();
111
+ let byKey = new Map();
112
+ if ((0, node_fs_1.existsSync)(path)) {
113
+ const registry = JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
114
+ byKey = new Map(registry.models.map((m) => [m.model_key, m]));
115
+ }
116
+ else if (registryPath !== undefined) {
117
+ // An EXPLICIT path that doesn't exist is a config error worth failing on;
118
+ // a missing packaged file just means static fallback (fresh checkout).
119
+ throw new Error(`registry facts file not found: ${path}`);
120
+ }
121
+ const cache = new Map();
122
+ return {
123
+ flagsFor(provider, model, staticFlags) {
124
+ const key = `${provider}/${model}`;
125
+ const entry = byKey.get(key);
126
+ if (entry === undefined)
127
+ return null;
128
+ let flags = cache.get(key);
129
+ if (flags === undefined) {
130
+ flags = capabilityFactsFromEntry(entry, staticFlags);
131
+ cache.set(key, flags);
132
+ }
133
+ return flags;
134
+ },
135
+ };
136
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Schema fingerprinting — spec §2 WS6, network-effects instrumentation.
3
+ * Pure function: JSON schema → bucketed structural features + task category
4
+ * + a stable cell key. Computed at route load; stored on every telemetry row.
5
+ * PRIVACY: the fingerprint must be irreversible — features and category only,
6
+ * never field names, titles, descriptions, or enum values.
7
+ */
8
+ export type TaskCategory = "extraction" | "generation" | "classification" | "analysis";
9
+ export interface SchemaFingerprint {
10
+ readonly depthBucket: "1-2" | "3-4" | "5+";
11
+ readonly fieldCountBucket: "1-5" | "6-20" | "21-60" | "61+";
12
+ readonly enumDensityBucket: "none" | "low" | "high";
13
+ readonly lengthFloorCount: number;
14
+ readonly arrayComplexityBucket: "none" | "flat" | "nested";
15
+ readonly category: TaskCategory;
16
+ /** Stable hash of the buckets above — the Conformance Matrix cell key. */
17
+ readonly cellKey: string;
18
+ }
19
+ export declare function fingerprintSchema(schema: object | null): SchemaFingerprint | null;
20
+ //# sourceMappingURL=fingerprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/registry/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,gBAAgB,GAAG,UAAU,CAAC;AAEvF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IACpD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC3D,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AA8GD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAgDjF"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ /**
3
+ * Schema fingerprinting — spec §2 WS6, network-effects instrumentation.
4
+ * Pure function: JSON schema → bucketed structural features + task category
5
+ * + a stable cell key. Computed at route load; stored on every telemetry row.
6
+ * PRIVACY: the fingerprint must be irreversible — features and category only,
7
+ * never field names, titles, descriptions, or enum values.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.fingerprintSchema = fingerprintSchema;
11
+ const node_crypto_1 = require("node:crypto");
12
+ const MAX_WALK_DEPTH = 12;
13
+ /** minLength at or above this marks a prose field (a deliberate length floor,
14
+ * not an id/enum constraint) — the "analysis" signal. */
15
+ const PROSE_FLOOR_MIN_LENGTH = 200;
16
+ const LOW_ENUM_RATIO = 0.2;
17
+ function isRecord(v) {
18
+ return typeof v === "object" && v !== null && !Array.isArray(v);
19
+ }
20
+ const SCALAR_TYPES = new Set(["string", "number", "integer", "boolean", "null"]);
21
+ function isScalarNode(node) {
22
+ return typeof node.type === "string" && SCALAR_TYPES.has(node.type);
23
+ }
24
+ function walk(node, depth, stats) {
25
+ if (!isRecord(node) || depth > MAX_WALK_DEPTH)
26
+ return;
27
+ if (depth > stats.maxDepth)
28
+ stats.maxDepth = depth;
29
+ if (isScalarNode(node)) {
30
+ stats.leafCount += 1;
31
+ if (Array.isArray(node.enum) || node.const !== undefined)
32
+ stats.enumLeafCount += 1;
33
+ if (node.type === "string" &&
34
+ typeof node.minLength === "number" &&
35
+ node.minLength >= PROSE_FLOOR_MIN_LENGTH) {
36
+ stats.proseFloorCount += 1;
37
+ }
38
+ return;
39
+ }
40
+ const properties = node.properties;
41
+ if (isRecord(properties)) {
42
+ for (const child of Object.values(properties)) {
43
+ stats.fieldCount += 1;
44
+ walk(child, depth + 1, stats);
45
+ }
46
+ }
47
+ const items = node.items;
48
+ if (items !== undefined) {
49
+ const itemNodes = Array.isArray(items) ? items : [items];
50
+ for (const item of itemNodes) {
51
+ if (isRecord(item) && isScalarNode(item)) {
52
+ stats.hasFlatArray = true;
53
+ walk(item, depth + 1, stats);
54
+ }
55
+ else {
56
+ stats.hasNestedArray = true;
57
+ walk(item, depth + 1, stats);
58
+ }
59
+ }
60
+ }
61
+ if (isRecord(node.additionalProperties))
62
+ walk(node.additionalProperties, depth + 1, stats);
63
+ for (const combinator of ["anyOf", "oneOf", "allOf"]) {
64
+ const branches = node[combinator];
65
+ if (Array.isArray(branches)) {
66
+ // Combinator branches describe the SAME position — no depth increase.
67
+ for (const branch of branches)
68
+ walk(branch, depth, stats);
69
+ }
70
+ }
71
+ }
72
+ function bucketDepth(depth) {
73
+ if (depth <= 2)
74
+ return "1-2";
75
+ if (depth <= 4)
76
+ return "3-4";
77
+ return "5+";
78
+ }
79
+ function bucketFieldCount(count) {
80
+ if (count <= 5)
81
+ return "1-5";
82
+ if (count <= 20)
83
+ return "6-20";
84
+ if (count <= 60)
85
+ return "21-60";
86
+ return "61+";
87
+ }
88
+ function bucketEnumDensity(ratio) {
89
+ if (ratio === 0)
90
+ return "none";
91
+ if (ratio < LOW_ENUM_RATIO)
92
+ return "low";
93
+ return "high";
94
+ }
95
+ function categorize(stats, enumDensity) {
96
+ // Order matters (v0 heuristic, spec WS6): a deliberate prose floor is the
97
+ // strongest signal (analysis) → enum dominance (classification) → shallow
98
+ // typed scalars (extraction) → everything else (generation).
99
+ if (stats.proseFloorCount > 0)
100
+ return "analysis";
101
+ if (enumDensity === "high")
102
+ return "classification";
103
+ if (stats.maxDepth <= 2 && !stats.hasNestedArray && stats.leafCount > 0)
104
+ return "extraction";
105
+ return "generation";
106
+ }
107
+ function fingerprintSchema(schema) {
108
+ if (schema === null)
109
+ return null;
110
+ const stats = {
111
+ maxDepth: 0,
112
+ fieldCount: 0,
113
+ leafCount: 0,
114
+ enumLeafCount: 0,
115
+ proseFloorCount: 0,
116
+ hasFlatArray: false,
117
+ hasNestedArray: false,
118
+ };
119
+ walk(schema, 1, stats);
120
+ const enumRatio = stats.leafCount === 0 ? 0 : stats.enumLeafCount / stats.leafCount;
121
+ const enumDensityBucket = bucketEnumDensity(enumRatio);
122
+ const arrayComplexityBucket = stats.hasNestedArray
123
+ ? "nested"
124
+ : stats.hasFlatArray
125
+ ? "flat"
126
+ : "none";
127
+ const category = categorize(stats, enumDensityBucket);
128
+ const depthBucket = bucketDepth(stats.maxDepth);
129
+ const fieldCountBucket = bucketFieldCount(stats.fieldCount);
130
+ const cellKey = (0, node_crypto_1.createHash)("sha256")
131
+ .update(JSON.stringify([
132
+ depthBucket,
133
+ fieldCountBucket,
134
+ enumDensityBucket,
135
+ stats.proseFloorCount,
136
+ arrayComplexityBucket,
137
+ category,
138
+ ]))
139
+ .digest("hex")
140
+ .slice(0, 16);
141
+ return {
142
+ depthBucket,
143
+ fieldCountBucket,
144
+ enumDensityBucket,
145
+ lengthFloorCount: stats.proseFloorCount,
146
+ arrayComplexityBucket,
147
+ category,
148
+ cellKey,
149
+ };
150
+ }