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.
- package/CHANGELOG.md +94 -0
- package/LICENSE +201 -0
- package/README.md +145 -8
- package/data/PROVENANCE.md +19 -0
- package/data/pricing-manual.json +22 -0
- package/data/pricing-map.json +46362 -0
- package/data/pricing-overlay.json +419 -0
- package/dist/adapters/anthropic.d.ts +90 -0
- package/dist/adapters/anthropic.d.ts.map +1 -0
- package/dist/adapters/anthropic.js +296 -0
- package/dist/adapters/build-adapters.d.ts +11 -0
- package/dist/adapters/build-adapters.d.ts.map +1 -0
- package/dist/adapters/build-adapters.js +45 -0
- package/dist/adapters/deepseek.d.ts +47 -0
- package/dist/adapters/deepseek.d.ts.map +1 -0
- package/dist/adapters/deepseek.js +216 -0
- package/dist/adapters/gemini.d.ts +44 -0
- package/dist/adapters/gemini.d.ts.map +1 -0
- package/dist/adapters/gemini.js +262 -0
- package/dist/adapters/grok.d.ts +53 -0
- package/dist/adapters/grok.d.ts.map +1 -0
- package/dist/adapters/grok.js +232 -0
- package/dist/adapters/openai-compat.d.ts +80 -0
- package/dist/adapters/openai-compat.d.ts.map +1 -0
- package/dist/adapters/openai-compat.js +244 -0
- package/dist/adapters/openai-stream.d.ts +58 -0
- package/dist/adapters/openai-stream.d.ts.map +1 -0
- package/dist/adapters/openai-stream.js +120 -0
- package/dist/adapters/openai.d.ts +55 -0
- package/dist/adapters/openai.d.ts.map +1 -0
- package/dist/adapters/openai.js +281 -0
- package/dist/adapters/sampling.d.ts +28 -0
- package/dist/adapters/sampling.d.ts.map +1 -0
- package/dist/adapters/sampling.js +34 -0
- package/dist/adapters/tool-mapping.d.ts +92 -0
- package/dist/adapters/tool-mapping.d.ts.map +1 -0
- package/dist/adapters/tool-mapping.js +143 -0
- package/dist/artifacts/artifact.d.ts +137 -0
- package/dist/artifacts/artifact.d.ts.map +1 -0
- package/dist/artifacts/artifact.js +377 -0
- package/dist/artifacts/content-uploader.d.ts +87 -0
- package/dist/artifacts/content-uploader.d.ts.map +1 -0
- package/dist/artifacts/content-uploader.js +124 -0
- package/dist/artifacts/index.d.ts +63 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +80 -0
- package/dist/artifacts/run-context.d.ts +129 -0
- package/dist/artifacts/run-context.d.ts.map +1 -0
- package/dist/artifacts/run-context.js +208 -0
- package/dist/artifacts/scrub.d.ts +60 -0
- package/dist/artifacts/scrub.d.ts.map +1 -0
- package/dist/artifacts/scrub.js +139 -0
- package/dist/artifacts/step.d.ts +26 -0
- package/dist/artifacts/step.d.ts.map +1 -0
- package/dist/artifacts/step.js +37 -0
- package/dist/artifacts/taint.d.ts +63 -0
- package/dist/artifacts/taint.d.ts.map +1 -0
- package/dist/artifacts/taint.js +76 -0
- package/dist/bakeoff/cache-sim.d.ts +99 -0
- package/dist/bakeoff/cache-sim.d.ts.map +1 -0
- package/dist/bakeoff/cache-sim.js +126 -0
- package/dist/bakeoff/engine.d.ts +52 -0
- package/dist/bakeoff/engine.d.ts.map +1 -0
- package/dist/bakeoff/engine.js +163 -0
- package/dist/bakeoff/eval-cases.d.ts +96 -0
- package/dist/bakeoff/eval-cases.d.ts.map +1 -0
- package/dist/bakeoff/eval-cases.js +105 -0
- package/dist/bakeoff/replay.d.ts +52 -0
- package/dist/bakeoff/replay.d.ts.map +1 -0
- package/dist/bakeoff/replay.js +94 -0
- package/dist/bakeoff/report.d.ts +41 -0
- package/dist/bakeoff/report.d.ts.map +1 -0
- package/dist/bakeoff/report.js +142 -0
- package/dist/bakeoff/samples.d.ts +77 -0
- package/dist/bakeoff/samples.d.ts.map +1 -0
- package/dist/bakeoff/samples.js +148 -0
- package/dist/bakeoff/stats.d.ts +13 -0
- package/dist/bakeoff/stats.d.ts.map +1 -0
- package/dist/bakeoff/stats.js +48 -0
- package/dist/bakeoff/types.d.ts +37 -0
- package/dist/bakeoff/types.d.ts.map +1 -0
- package/dist/bakeoff/types.js +10 -0
- package/dist/cli.d.ts +25 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +590 -0
- package/dist/config.d.ts +204 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +252 -0
- package/dist/deprecations.d.ts +32 -0
- package/dist/deprecations.d.ts.map +1 -0
- package/dist/deprecations.js +59 -0
- package/dist/feedback/coverage.d.ts +32 -0
- package/dist/feedback/coverage.d.ts.map +1 -0
- package/dist/feedback/coverage.js +95 -0
- package/dist/feedback/feedback.d.ts +35 -0
- package/dist/feedback/feedback.d.ts.map +1 -0
- package/dist/feedback/feedback.js +39 -0
- package/dist/gateway/http-protocol.d.ts +175 -0
- package/dist/gateway/http-protocol.d.ts.map +1 -0
- package/dist/gateway/http-protocol.js +105 -0
- package/dist/index.d.ts +242 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +576 -0
- package/dist/init/finder.d.ts +94 -0
- package/dist/init/finder.d.ts.map +1 -0
- package/dist/init/finder.js +343 -0
- package/dist/init/init-cli.d.ts +10 -0
- package/dist/init/init-cli.d.ts.map +1 -0
- package/dist/init/init-cli.js +86 -0
- package/dist/init/observe-cli.d.ts +19 -0
- package/dist/init/observe-cli.d.ts.map +1 -0
- package/dist/init/observe-cli.js +73 -0
- package/dist/init/observe.d.ts +81 -0
- package/dist/init/observe.d.ts.map +1 -0
- package/dist/init/observe.js +245 -0
- package/dist/init/run.d.ts +99 -0
- package/dist/init/run.d.ts.map +1 -0
- package/dist/init/run.js +281 -0
- package/dist/init/signatures.d.ts +39 -0
- package/dist/init/signatures.d.ts.map +1 -0
- package/dist/init/signatures.js +116 -0
- package/dist/matrix/aggregate.d.ts +89 -0
- package/dist/matrix/aggregate.d.ts.map +1 -0
- package/dist/matrix/aggregate.js +186 -0
- package/dist/query/grammar.d.ts +35 -0
- package/dist/query/grammar.d.ts.map +1 -0
- package/dist/query/grammar.js +279 -0
- package/dist/query/run.d.ts +8 -0
- package/dist/query/run.d.ts.map +1 -0
- package/dist/query/run.js +21 -0
- package/dist/registry/build.d.ts +219 -0
- package/dist/registry/build.d.ts.map +1 -0
- package/dist/registry/build.js +313 -0
- package/dist/registry/cache-policy.d.ts +94 -0
- package/dist/registry/cache-policy.d.ts.map +1 -0
- package/dist/registry/cache-policy.js +238 -0
- package/dist/registry/call-notes.d.ts +11 -0
- package/dist/registry/call-notes.d.ts.map +1 -0
- package/dist/registry/call-notes.js +110 -0
- package/dist/registry/claims.d.ts +63 -0
- package/dist/registry/claims.d.ts.map +1 -0
- package/dist/registry/claims.js +107 -0
- package/dist/registry/effective-rate.d.ts +151 -0
- package/dist/registry/effective-rate.d.ts.map +1 -0
- package/dist/registry/effective-rate.js +156 -0
- package/dist/registry/facts.d.ts +32 -0
- package/dist/registry/facts.d.ts.map +1 -0
- package/dist/registry/facts.js +136 -0
- package/dist/registry/fingerprint.d.ts +20 -0
- package/dist/registry/fingerprint.d.ts.map +1 -0
- package/dist/registry/fingerprint.js +150 -0
- package/dist/registry/parity.d.ts +52 -0
- package/dist/registry/parity.d.ts.map +1 -0
- package/dist/registry/parity.js +82 -0
- package/dist/registry/pricing-shape.d.ts +113 -0
- package/dist/registry/pricing-shape.d.ts.map +1 -0
- package/dist/registry/pricing-shape.js +123 -0
- package/dist/registry/pricing.d.ts +43 -0
- package/dist/registry/pricing.d.ts.map +1 -0
- package/dist/registry/pricing.js +127 -0
- package/dist/registry/rows.d.ts +16 -0
- package/dist/registry/rows.d.ts.map +1 -0
- package/dist/registry/rows.js +57 -0
- package/dist/registry/seed.d.ts +43 -0
- package/dist/registry/seed.d.ts.map +1 -0
- package/dist/registry/seed.js +97 -0
- package/dist/registry/select.d.ts +68 -0
- package/dist/registry/select.d.ts.map +1 -0
- package/dist/registry/select.js +141 -0
- package/dist/registry/staleness.d.ts +18 -0
- package/dist/registry/staleness.d.ts.map +1 -0
- package/dist/registry/staleness.js +39 -0
- package/dist/rigindex/bootstrap.d.ts +36 -0
- package/dist/rigindex/bootstrap.d.ts.map +1 -0
- package/dist/rigindex/bootstrap.js +97 -0
- package/dist/rigindex/fit.d.ts +24 -0
- package/dist/rigindex/fit.d.ts.map +1 -0
- package/dist/rigindex/fit.js +76 -0
- package/dist/rigindex/gates.d.ts +52 -0
- package/dist/rigindex/gates.d.ts.map +1 -0
- package/dist/rigindex/gates.js +109 -0
- package/dist/rigindex/graph.d.ts +31 -0
- package/dist/rigindex/graph.d.ts.map +1 -0
- package/dist/rigindex/graph.js +120 -0
- package/dist/rigindex/index.d.ts +23 -0
- package/dist/rigindex/index.d.ts.map +1 -0
- package/dist/rigindex/index.js +112 -0
- package/dist/rigindex/types.d.ts +76 -0
- package/dist/rigindex/types.d.ts.map +1 -0
- package/dist/rigindex/types.js +8 -0
- package/dist/routes/cache-lint.d.ts +41 -0
- package/dist/routes/cache-lint.d.ts.map +1 -0
- package/dist/routes/cache-lint.js +81 -0
- package/dist/routes/draft.d.ts +83 -0
- package/dist/routes/draft.d.ts.map +1 -0
- package/dist/routes/draft.js +135 -0
- package/dist/routes/loader.d.ts +63 -0
- package/dist/routes/loader.d.ts.map +1 -0
- package/dist/routes/loader.js +574 -0
- package/dist/routes/manifest.d.ts +24 -0
- package/dist/routes/manifest.d.ts.map +1 -0
- package/dist/routes/manifest.js +118 -0
- package/dist/routes/resolved-bundle.d.ts +79 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -0
- package/dist/routes/resolved-bundle.js +148 -0
- package/dist/routes/sampling-config.d.ts +32 -0
- package/dist/routes/sampling-config.d.ts.map +1 -0
- package/dist/routes/sampling-config.js +91 -0
- package/dist/routes/serveability.d.ts +52 -0
- package/dist/routes/serveability.d.ts.map +1 -0
- package/dist/routes/serveability.js +73 -0
- package/dist/routes/template.d.ts +18 -0
- package/dist/routes/template.d.ts.map +1 -0
- package/dist/routes/template.js +94 -0
- package/dist/run/ajv.d.ts +22 -0
- package/dist/run/ajv.d.ts.map +1 -0
- package/dist/run/ajv.js +32 -0
- package/dist/run/cache-handle.d.ts +58 -0
- package/dist/run/cache-handle.d.ts.map +1 -0
- package/dist/run/cache-handle.js +54 -0
- package/dist/run/cache-stamp.d.ts +65 -0
- package/dist/run/cache-stamp.d.ts.map +1 -0
- package/dist/run/cache-stamp.js +0 -0
- package/dist/run/capture-write.d.ts +33 -0
- package/dist/run/capture-write.d.ts.map +1 -0
- package/dist/run/capture-write.js +55 -0
- package/dist/run/cost.d.ts +26 -0
- package/dist/run/cost.d.ts.map +1 -0
- package/dist/run/cost.js +41 -0
- package/dist/run/dispatch.d.ts +99 -0
- package/dist/run/dispatch.d.ts.map +1 -0
- package/dist/run/dispatch.js +191 -0
- package/dist/run/envelope.d.ts +21 -0
- package/dist/run/envelope.d.ts.map +1 -0
- package/dist/run/envelope.js +45 -0
- package/dist/run/grounding.d.ts +56 -0
- package/dist/run/grounding.d.ts.map +1 -0
- package/dist/run/grounding.js +89 -0
- package/dist/run/raw.d.ts +88 -0
- package/dist/run/raw.d.ts.map +1 -0
- package/dist/run/raw.js +286 -0
- package/dist/run/record-attempt.d.ts +40 -0
- package/dist/run/record-attempt.d.ts.map +1 -0
- package/dist/run/record-attempt.js +99 -0
- package/dist/run/repair.d.ts +36 -0
- package/dist/run/repair.d.ts.map +1 -0
- package/dist/run/repair.js +61 -0
- package/dist/run/resolve.d.ts +99 -0
- package/dist/run/resolve.d.ts.map +1 -0
- package/dist/run/resolve.js +203 -0
- package/dist/run/retry.d.ts +19 -0
- package/dist/run/retry.d.ts.map +1 -0
- package/dist/run/retry.js +50 -0
- package/dist/run/run.d.ts +55 -0
- package/dist/run/run.d.ts.map +1 -0
- package/dist/run/run.js +540 -0
- package/dist/run/stream.d.ts +49 -0
- package/dist/run/stream.d.ts.map +1 -0
- package/dist/run/stream.js +87 -0
- package/dist/run/validate.d.ts +15 -0
- package/dist/run/validate.d.ts.map +1 -0
- package/dist/run/validate.js +55 -0
- package/dist/savings/cache-ledger.d.ts +108 -0
- package/dist/savings/cache-ledger.d.ts.map +1 -0
- package/dist/savings/cache-ledger.js +174 -0
- package/dist/savings/cache-reconcile.d.ts +64 -0
- package/dist/savings/cache-reconcile.d.ts.map +1 -0
- package/dist/savings/cache-reconcile.js +59 -0
- package/dist/savings/cache-stats.d.ts +63 -0
- package/dist/savings/cache-stats.d.ts.map +1 -0
- package/dist/savings/cache-stats.js +108 -0
- package/dist/savings/emit.d.ts +38 -0
- package/dist/savings/emit.d.ts.map +1 -0
- package/dist/savings/emit.js +100 -0
- package/dist/savings/odometer.d.ts +32 -0
- package/dist/savings/odometer.d.ts.map +1 -0
- package/dist/savings/odometer.js +70 -0
- package/dist/savings/swap-execute.d.ts +58 -0
- package/dist/savings/swap-execute.d.ts.map +1 -0
- package/dist/savings/swap-execute.js +130 -0
- package/dist/savings/swaps-client.d.ts +55 -0
- package/dist/savings/swaps-client.d.ts.map +1 -0
- package/dist/savings/swaps-client.js +95 -0
- package/dist/settings/api-fetcher.d.ts +39 -0
- package/dist/settings/api-fetcher.d.ts.map +1 -0
- package/dist/settings/api-fetcher.js +92 -0
- package/dist/settings/index.d.ts +10 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +15 -0
- package/dist/settings/task-settings.d.ts +91 -0
- package/dist/settings/task-settings.d.ts.map +1 -0
- package/dist/settings/task-settings.js +116 -0
- package/dist/status.d.ts +77 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +113 -0
- package/dist/telemetry/artifact-store.d.ts +48 -0
- package/dist/telemetry/artifact-store.d.ts.map +1 -0
- package/dist/telemetry/artifact-store.js +189 -0
- package/dist/telemetry/cache-miss-streak.d.ts +79 -0
- package/dist/telemetry/cache-miss-streak.d.ts.map +1 -0
- package/dist/telemetry/cache-miss-streak.js +99 -0
- package/dist/telemetry/capture.d.ts +31 -0
- package/dist/telemetry/capture.d.ts.map +1 -0
- package/dist/telemetry/capture.js +81 -0
- package/dist/telemetry/exporter-setup.d.ts +28 -0
- package/dist/telemetry/exporter-setup.d.ts.map +1 -0
- package/dist/telemetry/exporter-setup.js +34 -0
- package/dist/telemetry/exporter.d.ts +137 -0
- package/dist/telemetry/exporter.d.ts.map +1 -0
- package/dist/telemetry/exporter.js +510 -0
- package/dist/telemetry/health.d.ts +76 -0
- package/dist/telemetry/health.d.ts.map +1 -0
- package/dist/telemetry/health.js +92 -0
- package/dist/telemetry/ingest-protocol.d.ts +310 -0
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -0
- package/dist/telemetry/ingest-protocol.js +363 -0
- package/dist/telemetry/load-error-report.d.ts +24 -0
- package/dist/telemetry/load-error-report.d.ts.map +1 -0
- package/dist/telemetry/load-error-report.js +50 -0
- package/dist/telemetry/otel-map.d.ts +121 -0
- package/dist/telemetry/otel-map.d.ts.map +1 -0
- package/dist/telemetry/otel-map.js +224 -0
- package/dist/telemetry/otel-normalize.d.ts +104 -0
- package/dist/telemetry/otel-normalize.d.ts.map +1 -0
- package/dist/telemetry/otel-normalize.js +530 -0
- package/dist/telemetry/otlp-emitter.d.ts +52 -0
- package/dist/telemetry/otlp-emitter.d.ts.map +1 -0
- package/dist/telemetry/otlp-emitter.js +144 -0
- package/dist/telemetry/otlp-proto.d.ts +29 -0
- package/dist/telemetry/otlp-proto.d.ts.map +1 -0
- package/dist/telemetry/otlp-proto.js +266 -0
- package/dist/telemetry/sinks.d.ts +90 -0
- package/dist/telemetry/sinks.d.ts.map +1 -0
- package/dist/telemetry/sinks.js +180 -0
- package/dist/telemetry/store.d.ts +65 -0
- package/dist/telemetry/store.d.ts.map +1 -0
- package/dist/telemetry/store.js +547 -0
- package/dist/tenancy/api-key-format.d.ts +77 -0
- package/dist/tenancy/api-key-format.d.ts.map +1 -0
- package/dist/tenancy/api-key-format.js +110 -0
- package/dist/tenancy/constants.d.ts +23 -0
- package/dist/tenancy/constants.d.ts.map +1 -0
- package/dist/tenancy/constants.js +25 -0
- package/dist/tenancy/scrub.d.ts +47 -0
- package/dist/tenancy/scrub.d.ts.map +1 -0
- package/dist/tenancy/scrub.js +85 -0
- package/dist/types/config-teaching.d.ts +62 -0
- package/dist/types/config-teaching.d.ts.map +1 -0
- package/dist/types/config-teaching.js +183 -0
- package/dist/types/failures-teaching.d.ts +56 -0
- package/dist/types/failures-teaching.d.ts.map +1 -0
- package/dist/types/failures-teaching.js +177 -0
- package/dist/types/failures.d.ts +27 -0
- package/dist/types/failures.d.ts.map +1 -0
- package/dist/types/failures.js +41 -0
- package/dist/types/provider.d.ts +200 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/provider.js +40 -0
- package/dist/types/route.d.ts +205 -0
- package/dist/types/route.d.ts.map +1 -0
- package/dist/types/route.js +6 -0
- package/dist/types/telemetry.d.ts +206 -0
- package/dist/types/telemetry.d.ts.map +1 -0
- package/dist/types/telemetry.js +6 -0
- package/dist/validate-cli.d.ts +12 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate-cli.js +57 -0
- package/dist/verify/capture.d.ts +66 -0
- package/dist/verify/capture.d.ts.map +1 -0
- package/dist/verify/capture.js +180 -0
- package/dist/verify/cli-run.d.ts +23 -0
- package/dist/verify/cli-run.d.ts.map +1 -0
- package/dist/verify/cli-run.js +57 -0
- package/dist/verify/diff.d.ts +48 -0
- package/dist/verify/diff.d.ts.map +1 -0
- package/dist/verify/diff.js +157 -0
- package/dist/verify/index.d.ts +17 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +24 -0
- package/dist/verify/report.d.ts +14 -0
- package/dist/verify/report.d.ts.map +1 -0
- package/dist/verify/report.js +88 -0
- package/dist/verify/types.d.ts +101 -0
- package/dist/verify/types.d.ts.map +1 -0
- package/dist/verify/types.js +17 -0
- package/dist/verify/verify.d.ts +29 -0
- package/dist/verify/verify.d.ts.map +1 -0
- package/dist/verify/verify.js +148 -0
- package/dist/watch/budget.d.ts +19 -0
- package/dist/watch/budget.d.ts.map +1 -0
- package/dist/watch/budget.js +35 -0
- package/dist/watch/evaluate.d.ts +225 -0
- package/dist/watch/evaluate.d.ts.map +1 -0
- package/dist/watch/evaluate.js +155 -0
- package/dist/watch/monitor.d.ts +116 -0
- package/dist/watch/monitor.d.ts.map +1 -0
- package/dist/watch/monitor.js +199 -0
- package/dist/watch/proposals.d.ts +89 -0
- package/dist/watch/proposals.d.ts.map +1 -0
- package/dist/watch/proposals.js +197 -0
- package/dist/watch/run-record.d.ts +64 -0
- package/dist/watch/run-record.d.ts.map +1 -0
- package/dist/watch/run-record.js +86 -0
- package/dist/watch/run-reported.d.ts +20 -0
- package/dist/watch/run-reported.d.ts.map +1 -0
- package/dist/watch/run-reported.js +53 -0
- package/dist/watch/run.d.ts +73 -0
- package/dist/watch/run.d.ts.map +1 -0
- package/dist/watch/run.js +83 -0
- package/dist/watch/state-store.d.ts +48 -0
- package/dist/watch/state-store.d.ts.map +1 -0
- package/dist/watch/state-store.js +86 -0
- package/dist/watch/state.d.ts +21 -0
- package/dist/watch/state.d.ts.map +1 -0
- package/dist/watch/state.js +93 -0
- package/package.json +56 -14
- package/registry/LICENSE +20 -0
- package/registry/leaderboard.json +3639 -0
- package/registry/registry.json +7263 -0
- package/index.js +0 -3
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* parity-50 — addendum A1 / provider-coverage-plan §3. The honest coverage
|
|
3
|
+
* KPI: how much of OpenRouter's top-50-by-usage list is PROBED (not merely
|
|
4
|
+
* listed) in our registry. A model counts as probed when ANY of its mapped
|
|
5
|
+
* registry keys carries probed schema samples — same weights on any host.
|
|
6
|
+
* Gaps are named on the leaderboard ("not yet probed"), never invisible.
|
|
7
|
+
*/
|
|
8
|
+
import type { Registry } from "./build";
|
|
9
|
+
export interface ParityListEntry {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly registry_keys: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
export interface ParityGap {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly status: "not yet probed" | "not in registry";
|
|
16
|
+
}
|
|
17
|
+
export interface ParityReport {
|
|
18
|
+
readonly total: number;
|
|
19
|
+
readonly probed: number;
|
|
20
|
+
readonly listedUnprobed: number;
|
|
21
|
+
readonly missing: number;
|
|
22
|
+
readonly probedPct: number;
|
|
23
|
+
readonly gaps: readonly ParityGap[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Normalize a model key for the parity join. The parity list is a hand-curated
|
|
27
|
+
* monthly snapshot; the registry is machine-generated from probe result files.
|
|
28
|
+
* Two keys that differ only by CASE or surrounding whitespace name the same
|
|
29
|
+
* model, so we match modulo those — a benign rename (e.g. `Qwen` vs `qwen` in a
|
|
30
|
+
* host catalog) must not silently drop coverage and force another manual
|
|
31
|
+
* id_repair. This is deliberately conservative: it collapses case/whitespace
|
|
32
|
+
* only, never leaf variants, so distinct ids (`grok/grok-4-2` vs `grok/grok-4.3`)
|
|
33
|
+
* stay distinct and an unprobed model is never falsely counted as probed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function normalizeParityKey(key: string): string;
|
|
36
|
+
export declare function computeParity(list: readonly ParityListEntry[], registry: Registry): ParityReport;
|
|
37
|
+
/** Does the registry contain at least one model with probed schema samples?
|
|
38
|
+
* The precondition for the zero-coverage gate below: a 0 coverage number is
|
|
39
|
+
* only suspicious when there IS probed data that failed to join. */
|
|
40
|
+
export declare function registryHasProbedModels(registry: Registry): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Mechanical zero-coverage gate — makes the parity-list ↔ registry join
|
|
43
|
+
* regression un-forgettable. If parity coverage computes 0 probed WHILE the
|
|
44
|
+
* registry actually contains probed models, the join is broken (an id/namespace
|
|
45
|
+
* mismatch between the curated list and the machine-generated registry, exactly
|
|
46
|
+
* the failure the id_repair_note documents), and a leaderboard rendered from it
|
|
47
|
+
* would publish 0% coverage as if it were true. Throw rather than render that.
|
|
48
|
+
* A legitimately-empty registry (no probed models yet) computes 0 and is fine.
|
|
49
|
+
* Call this wherever computeParity feeds a rendered/published surface.
|
|
50
|
+
*/
|
|
51
|
+
export declare function assertParityCoverageSane(report: ParityReport, registry: Registry): void;
|
|
52
|
+
//# sourceMappingURL=parity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parity.d.ts","sourceRoot":"","sources":["../../src/registry/parity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;CACrC;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,eAAe,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAG,YAAY,CA4BhG;AAED;;oEAEoE;AACpE,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAEnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAUvF"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* parity-50 — addendum A1 / provider-coverage-plan §3. The honest coverage
|
|
4
|
+
* KPI: how much of OpenRouter's top-50-by-usage list is PROBED (not merely
|
|
5
|
+
* listed) in our registry. A model counts as probed when ANY of its mapped
|
|
6
|
+
* registry keys carries probed schema samples — same weights on any host.
|
|
7
|
+
* Gaps are named on the leaderboard ("not yet probed"), never invisible.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.normalizeParityKey = normalizeParityKey;
|
|
11
|
+
exports.computeParity = computeParity;
|
|
12
|
+
exports.registryHasProbedModels = registryHasProbedModels;
|
|
13
|
+
exports.assertParityCoverageSane = assertParityCoverageSane;
|
|
14
|
+
/**
|
|
15
|
+
* Normalize a model key for the parity join. The parity list is a hand-curated
|
|
16
|
+
* monthly snapshot; the registry is machine-generated from probe result files.
|
|
17
|
+
* Two keys that differ only by CASE or surrounding whitespace name the same
|
|
18
|
+
* model, so we match modulo those — a benign rename (e.g. `Qwen` vs `qwen` in a
|
|
19
|
+
* host catalog) must not silently drop coverage and force another manual
|
|
20
|
+
* id_repair. This is deliberately conservative: it collapses case/whitespace
|
|
21
|
+
* only, never leaf variants, so distinct ids (`grok/grok-4-2` vs `grok/grok-4.3`)
|
|
22
|
+
* stay distinct and an unprobed model is never falsely counted as probed.
|
|
23
|
+
*/
|
|
24
|
+
function normalizeParityKey(key) {
|
|
25
|
+
return key.trim().toLowerCase();
|
|
26
|
+
}
|
|
27
|
+
function computeParity(list, registry) {
|
|
28
|
+
const byKey = new Map(registry.models.map((m) => [normalizeParityKey(m.model_key), m]));
|
|
29
|
+
let probed = 0;
|
|
30
|
+
let listedUnprobed = 0;
|
|
31
|
+
let missing = 0;
|
|
32
|
+
const gaps = [];
|
|
33
|
+
for (const entry of list) {
|
|
34
|
+
const matches = entry.registry_keys
|
|
35
|
+
.map((k) => byKey.get(normalizeParityKey(k)))
|
|
36
|
+
.filter((m) => m !== undefined);
|
|
37
|
+
if (matches.some((m) => (m.probed?.schema?.samples ?? 0) > 0)) {
|
|
38
|
+
probed += 1;
|
|
39
|
+
}
|
|
40
|
+
else if (matches.length > 0) {
|
|
41
|
+
listedUnprobed += 1;
|
|
42
|
+
gaps.push({ name: entry.name, status: "not yet probed" });
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
missing += 1;
|
|
46
|
+
gaps.push({ name: entry.name, status: "not in registry" });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
total: list.length,
|
|
51
|
+
probed,
|
|
52
|
+
listedUnprobed,
|
|
53
|
+
missing,
|
|
54
|
+
probedPct: list.length === 0 ? 0 : probed / list.length,
|
|
55
|
+
gaps,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Does the registry contain at least one model with probed schema samples?
|
|
59
|
+
* The precondition for the zero-coverage gate below: a 0 coverage number is
|
|
60
|
+
* only suspicious when there IS probed data that failed to join. */
|
|
61
|
+
function registryHasProbedModels(registry) {
|
|
62
|
+
return registry.models.some((m) => (m.probed?.schema?.samples ?? 0) > 0);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Mechanical zero-coverage gate — makes the parity-list ↔ registry join
|
|
66
|
+
* regression un-forgettable. If parity coverage computes 0 probed WHILE the
|
|
67
|
+
* registry actually contains probed models, the join is broken (an id/namespace
|
|
68
|
+
* mismatch between the curated list and the machine-generated registry, exactly
|
|
69
|
+
* the failure the id_repair_note documents), and a leaderboard rendered from it
|
|
70
|
+
* would publish 0% coverage as if it were true. Throw rather than render that.
|
|
71
|
+
* A legitimately-empty registry (no probed models yet) computes 0 and is fine.
|
|
72
|
+
* Call this wherever computeParity feeds a rendered/published surface.
|
|
73
|
+
*/
|
|
74
|
+
function assertParityCoverageSane(report, registry) {
|
|
75
|
+
if (report.probed === 0 && registryHasProbedModels(registry)) {
|
|
76
|
+
throw new Error("parity-50 coverage computed 0 probed, but the registry contains probed models — " +
|
|
77
|
+
"the parity-list↔registry join is broken (likely an id/namespace mismatch between the " +
|
|
78
|
+
"curated list keys and the registry model_keys). Refusing to render a leaderboard that " +
|
|
79
|
+
"hides real coverage. Fix the registry_keys in registry/parity-50.json or the " +
|
|
80
|
+
"normalization in src/registry/parity.ts.");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-class pricing shape — spec `pricing-first-class/spec.md` §2.1.
|
|
3
|
+
*
|
|
4
|
+
* A structured, additive representation of a model's price that can carry
|
|
5
|
+
* every component a vendor publishes (serving-tier multipliers, cache-write,
|
|
6
|
+
* context-length bands, batch discounts, per-modality input rates), each with
|
|
7
|
+
* `source` + `as_of`, and — required — a `basis` string stating what the
|
|
8
|
+
* headline number *is*. It exists ALONGSIDE the flat three-component
|
|
9
|
+
* `DeclaredLayer.pricing` (which is not retired this pass — S3 order of
|
|
10
|
+
* destruction); a snapshot-only entry maps trivially via `synthesizeFromFlat`.
|
|
11
|
+
*
|
|
12
|
+
* GOVERNING RULE (dev-rule L5, spec §3): never fabricate a component you have
|
|
13
|
+
* not verified against the vendor's published number. Tier multipliers are
|
|
14
|
+
* MULTIPLIERS on `base` (1.0 = base), not absolute rates — a mis-read
|
|
15
|
+
* multiplier is worse than a missing one, so absent data degrades to
|
|
16
|
+
* `base`-only, never to a guessed tier.
|
|
17
|
+
*
|
|
18
|
+
* Units: every `TokenRates` field is USD PER TOKEN (not per-Mtok) — the same
|
|
19
|
+
* unit as `ModelPricing.inputUsdPerTok`, so synthesis is a pure passthrough.
|
|
20
|
+
*/
|
|
21
|
+
export interface TokenRates {
|
|
22
|
+
readonly input: number;
|
|
23
|
+
readonly output: number;
|
|
24
|
+
/** context-cache READ rate. */
|
|
25
|
+
readonly cache_read?: number | null;
|
|
26
|
+
/** context-cache WRITE rate (Anthropic-class 5m TTL / OpenAI 5.6+). */
|
|
27
|
+
readonly cache_write?: number | null;
|
|
28
|
+
/** 1h-TTL context-cache WRITE rate (Anthropic 2×; WS-A). Additive — absent
|
|
29
|
+
* ⇒ the 1h write bucket bills at `cache_write` (fail-closed, dev-rule L5). */
|
|
30
|
+
readonly cache_write_1h?: number | null;
|
|
31
|
+
}
|
|
32
|
+
/** MULTIPLIERS on `base` (1.0 = base), NOT absolute rates. */
|
|
33
|
+
export interface ServingTiers {
|
|
34
|
+
readonly priority?: number | null;
|
|
35
|
+
readonly fast?: number | null;
|
|
36
|
+
readonly region_us?: number | null;
|
|
37
|
+
}
|
|
38
|
+
/** A rate change that applies above a token threshold. */
|
|
39
|
+
export interface ContextBand {
|
|
40
|
+
readonly above_tokens: number;
|
|
41
|
+
readonly rates: TokenRates;
|
|
42
|
+
}
|
|
43
|
+
/** Non-text input units, USD per unit. */
|
|
44
|
+
export interface ModalityRates {
|
|
45
|
+
readonly image_per_unit?: number | null;
|
|
46
|
+
readonly audio_per_second?: number | null;
|
|
47
|
+
}
|
|
48
|
+
export interface ModelPricingV2 {
|
|
49
|
+
/** standard-tier text — the only REQUIRED rates block. */
|
|
50
|
+
readonly base: TokenRates;
|
|
51
|
+
readonly tiers?: ServingTiers | null;
|
|
52
|
+
readonly context_bands?: readonly ContextBand[] | null;
|
|
53
|
+
readonly batch_discount?: number | null;
|
|
54
|
+
readonly modality?: ModalityRates | null;
|
|
55
|
+
/** provenance: host-api / website / snapshot. */
|
|
56
|
+
readonly source: string;
|
|
57
|
+
readonly as_of: string;
|
|
58
|
+
/** What `base` represents, rendered verbatim on the surface (P5, in code). */
|
|
59
|
+
readonly basis: string;
|
|
60
|
+
}
|
|
61
|
+
/** The basis string for a snapshot-synthesized (base-only, standard, text)
|
|
62
|
+
* entry — the honest caveat when nothing richer than three components exists. */
|
|
63
|
+
export declare const SNAPSHOT_BASIS = "base \u00B7 standard tier \u00B7 text";
|
|
64
|
+
/**
|
|
65
|
+
* Map a flat three-component price (USD per token) to a `ModelPricingV2` with
|
|
66
|
+
* `base` only — `tiers`, `context_bands`, `batch`, `modality` all null. This is
|
|
67
|
+
* the fail-closed default for every model the sweep could not enrich: it
|
|
68
|
+
* asserts nothing beyond the standard text rate the flat field already carried.
|
|
69
|
+
*
|
|
70
|
+
* `asOf`/`source` are provenance the shape requires (spec §2.1 marks both
|
|
71
|
+
* required); the plan names the three rate values as the essential inputs, and
|
|
72
|
+
* the caller supplies provenance. `source` defaults to the snapshot lane.
|
|
73
|
+
*/
|
|
74
|
+
export declare function synthesizeFromFlat(input: number, output: number, cache_read: number | null, asOf: string, source?: string): ModelPricingV2;
|
|
75
|
+
export type ServingTierName = "priority" | "fast" | "region_us";
|
|
76
|
+
/**
|
|
77
|
+
* Absolute rates for a serving tier = `base × multiplier`. Returns `null` when
|
|
78
|
+
* the tier's multiplier is absent — fail-closed, so no surface can render a
|
|
79
|
+
* tier price the model never published. The multiplier scales every rate
|
|
80
|
+
* component present on `base`.
|
|
81
|
+
*/
|
|
82
|
+
export declare function tierRates(pricing: ModelPricingV2, tier: ServingTierName): TokenRates | null;
|
|
83
|
+
/** A display-ready projection of a price. `basis` is always present, so a
|
|
84
|
+
* surface built from this object can never show a number without its caveat. */
|
|
85
|
+
export interface PricingV2Display {
|
|
86
|
+
/** what the headline number IS — always present (the render caveat). */
|
|
87
|
+
readonly basis: string;
|
|
88
|
+
/** "$3.00 in · $15.00 out per Mtok" — the base rates. */
|
|
89
|
+
readonly base: string;
|
|
90
|
+
readonly cacheRead: string | null;
|
|
91
|
+
readonly cacheWrite: string | null;
|
|
92
|
+
/** 1h-TTL cache-write rate per Mtok (Anthropic 2×); null when unpublished. */
|
|
93
|
+
readonly cacheWrite1h: string | null;
|
|
94
|
+
/** absolute tier rates, base × multiplier, per Mtok. */
|
|
95
|
+
readonly tiers: readonly {
|
|
96
|
+
readonly name: ServingTierName;
|
|
97
|
+
readonly rate: string;
|
|
98
|
+
}[];
|
|
99
|
+
readonly contextBands: readonly string[];
|
|
100
|
+
readonly batch: string | null;
|
|
101
|
+
readonly modality: readonly string[];
|
|
102
|
+
readonly source: string;
|
|
103
|
+
readonly asOf: string;
|
|
104
|
+
/** vendor page URL if the `source` embeds one, for a "full terms" link. */
|
|
105
|
+
readonly vendorUrl: string | null;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Build the display projection. Every returned object carries `basis`; the
|
|
109
|
+
* base rate string is only ever produced together with it — the render-caveat
|
|
110
|
+
* guarantee lives here, in code, so no consumer can bypass it.
|
|
111
|
+
*/
|
|
112
|
+
export declare function describePricingV2(pricing: ModelPricingV2): PricingV2Display;
|
|
113
|
+
//# sourceMappingURL=pricing-shape.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing-shape.d.ts","sourceRoot":"","sources":["../../src/registry/pricing-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;kFAC8E;IAC9E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAAC;IACvD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACzC,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;iFACiF;AACjF,eAAO,MAAM,cAAc,0CAAgC,CAAC;AAE5D;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,IAAI,EAAE,MAAM,EACZ,MAAM,SAAqB,GAC1B,cAAc,CAWhB;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,MAAM,GAAG,WAAW,CAAC;AAMhE;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,GAAG,UAAU,GAAG,IAAI,CAU3F;AAED;gFACgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrF,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAqBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,gBAAgB,CAqC3E"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* First-class pricing shape — spec `pricing-first-class/spec.md` §2.1.
|
|
4
|
+
*
|
|
5
|
+
* A structured, additive representation of a model's price that can carry
|
|
6
|
+
* every component a vendor publishes (serving-tier multipliers, cache-write,
|
|
7
|
+
* context-length bands, batch discounts, per-modality input rates), each with
|
|
8
|
+
* `source` + `as_of`, and — required — a `basis` string stating what the
|
|
9
|
+
* headline number *is*. It exists ALONGSIDE the flat three-component
|
|
10
|
+
* `DeclaredLayer.pricing` (which is not retired this pass — S3 order of
|
|
11
|
+
* destruction); a snapshot-only entry maps trivially via `synthesizeFromFlat`.
|
|
12
|
+
*
|
|
13
|
+
* GOVERNING RULE (dev-rule L5, spec §3): never fabricate a component you have
|
|
14
|
+
* not verified against the vendor's published number. Tier multipliers are
|
|
15
|
+
* MULTIPLIERS on `base` (1.0 = base), not absolute rates — a mis-read
|
|
16
|
+
* multiplier is worse than a missing one, so absent data degrades to
|
|
17
|
+
* `base`-only, never to a guessed tier.
|
|
18
|
+
*
|
|
19
|
+
* Units: every `TokenRates` field is USD PER TOKEN (not per-Mtok) — the same
|
|
20
|
+
* unit as `ModelPricing.inputUsdPerTok`, so synthesis is a pure passthrough.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.SNAPSHOT_BASIS = void 0;
|
|
24
|
+
exports.synthesizeFromFlat = synthesizeFromFlat;
|
|
25
|
+
exports.tierRates = tierRates;
|
|
26
|
+
exports.describePricingV2 = describePricingV2;
|
|
27
|
+
/** The basis string for a snapshot-synthesized (base-only, standard, text)
|
|
28
|
+
* entry — the honest caveat when nothing richer than three components exists. */
|
|
29
|
+
exports.SNAPSHOT_BASIS = "base · standard tier · text";
|
|
30
|
+
/**
|
|
31
|
+
* Map a flat three-component price (USD per token) to a `ModelPricingV2` with
|
|
32
|
+
* `base` only — `tiers`, `context_bands`, `batch`, `modality` all null. This is
|
|
33
|
+
* the fail-closed default for every model the sweep could not enrich: it
|
|
34
|
+
* asserts nothing beyond the standard text rate the flat field already carried.
|
|
35
|
+
*
|
|
36
|
+
* `asOf`/`source` are provenance the shape requires (spec §2.1 marks both
|
|
37
|
+
* required); the plan names the three rate values as the essential inputs, and
|
|
38
|
+
* the caller supplies provenance. `source` defaults to the snapshot lane.
|
|
39
|
+
*/
|
|
40
|
+
function synthesizeFromFlat(input, output, cache_read, asOf, source = "litellm-snapshot") {
|
|
41
|
+
return {
|
|
42
|
+
base: { input, output, cache_read },
|
|
43
|
+
tiers: null,
|
|
44
|
+
context_bands: null,
|
|
45
|
+
batch_discount: null,
|
|
46
|
+
modality: null,
|
|
47
|
+
source,
|
|
48
|
+
as_of: asOf,
|
|
49
|
+
basis: exports.SNAPSHOT_BASIS,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function scale(rate, mult) {
|
|
53
|
+
return rate === null || rate === undefined ? null : rate * mult;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Absolute rates for a serving tier = `base × multiplier`. Returns `null` when
|
|
57
|
+
* the tier's multiplier is absent — fail-closed, so no surface can render a
|
|
58
|
+
* tier price the model never published. The multiplier scales every rate
|
|
59
|
+
* component present on `base`.
|
|
60
|
+
*/
|
|
61
|
+
function tierRates(pricing, tier) {
|
|
62
|
+
const mult = pricing.tiers?.[tier];
|
|
63
|
+
if (mult === null || mult === undefined)
|
|
64
|
+
return null;
|
|
65
|
+
return {
|
|
66
|
+
input: pricing.base.input * mult,
|
|
67
|
+
output: pricing.base.output * mult,
|
|
68
|
+
cache_read: scale(pricing.base.cache_read, mult),
|
|
69
|
+
cache_write: scale(pricing.base.cache_write, mult),
|
|
70
|
+
cache_write_1h: scale(pricing.base.cache_write_1h, mult),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const TIER_ORDER = ["priority", "fast", "region_us"];
|
|
74
|
+
/** USD-per-token → "$X.XX" per Mtok. Adaptive precision: a pricing-authority
|
|
75
|
+
* surface must not misrepresent a rate — `$0.075/M` renders as `$0.075`, not a
|
|
76
|
+
* rounded `$0.07`/`$0.08`. Shows up to 6 decimals, trailing zeros trimmed, with
|
|
77
|
+
* a 2-decimal floor for readability. */
|
|
78
|
+
function perMtok(perToken) {
|
|
79
|
+
const v = perToken * 1e6;
|
|
80
|
+
const trimmed = v.toFixed(6).replace(/\.?0+$/, "");
|
|
81
|
+
const decimals = trimmed.includes(".") ? trimmed.split(".")[1].length : 0;
|
|
82
|
+
return `$${decimals >= 2 ? trimmed : v.toFixed(2)}`;
|
|
83
|
+
}
|
|
84
|
+
function inOut(rates) {
|
|
85
|
+
return `${perMtok(rates.input)} in · ${perMtok(rates.output)} out per Mtok`;
|
|
86
|
+
}
|
|
87
|
+
const URL_RE = /https?:\/\/[^\s)]+/;
|
|
88
|
+
/**
|
|
89
|
+
* Build the display projection. Every returned object carries `basis`; the
|
|
90
|
+
* base rate string is only ever produced together with it — the render-caveat
|
|
91
|
+
* guarantee lives here, in code, so no consumer can bypass it.
|
|
92
|
+
*/
|
|
93
|
+
function describePricingV2(pricing) {
|
|
94
|
+
const tiers = [];
|
|
95
|
+
for (const name of TIER_ORDER) {
|
|
96
|
+
const rates = tierRates(pricing, name);
|
|
97
|
+
if (rates !== null)
|
|
98
|
+
tiers.push({ name, rate: inOut(rates) });
|
|
99
|
+
}
|
|
100
|
+
const contextBands = (pricing.context_bands ?? []).map((b) => `above ${b.above_tokens.toLocaleString()} tok: ${inOut(b.rates)}`);
|
|
101
|
+
const modality = [];
|
|
102
|
+
if (pricing.modality?.image_per_unit != null) {
|
|
103
|
+
modality.push(`image: $${pricing.modality.image_per_unit.toFixed(4)} per unit`);
|
|
104
|
+
}
|
|
105
|
+
if (pricing.modality?.audio_per_second != null) {
|
|
106
|
+
modality.push(`audio: $${pricing.modality.audio_per_second.toFixed(4)} per second`);
|
|
107
|
+
}
|
|
108
|
+
const urlMatch = URL_RE.exec(pricing.source);
|
|
109
|
+
return {
|
|
110
|
+
basis: pricing.basis,
|
|
111
|
+
base: inOut(pricing.base),
|
|
112
|
+
cacheRead: pricing.base.cache_read != null ? `${perMtok(pricing.base.cache_read)} per Mtok` : null,
|
|
113
|
+
cacheWrite: pricing.base.cache_write != null ? `${perMtok(pricing.base.cache_write)} per Mtok` : null,
|
|
114
|
+
cacheWrite1h: pricing.base.cache_write_1h != null ? `${perMtok(pricing.base.cache_write_1h)} per Mtok` : null,
|
|
115
|
+
tiers,
|
|
116
|
+
contextBands,
|
|
117
|
+
batch: pricing.batch_discount != null ? `${(pricing.batch_discount * 100).toFixed(0)}% off base` : null,
|
|
118
|
+
modality,
|
|
119
|
+
source: pricing.source,
|
|
120
|
+
asOf: pricing.as_of,
|
|
121
|
+
vendorUrl: urlMatch ? urlMatch[0] : null,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin pricing accessor over the vendored LiteLLM pricing snapshot
|
|
3
|
+
* (data/pricing-map.json, extracted at the pinned SHA — see
|
|
4
|
+
* upstream/litellm.pin.json). The full three-layer registry is Phase 2;
|
|
5
|
+
* Phase 1 needs only cost-per-token lookups for envelopes, prefer:[cost]
|
|
6
|
+
* ordering, and telemetry cost estimates.
|
|
7
|
+
*
|
|
8
|
+
* Data source: model_prices_and_context_window.json,
|
|
9
|
+
* Copyright (c) 2023 Berri AI, MIT License (https://github.com/BerriAI/litellm).
|
|
10
|
+
*/
|
|
11
|
+
import type { ProviderId } from "../types/provider";
|
|
12
|
+
import type { ModelPricingV2 } from "./pricing-shape";
|
|
13
|
+
export interface ModelPricing {
|
|
14
|
+
readonly inputUsdPerTok: number;
|
|
15
|
+
readonly outputUsdPerTok: number;
|
|
16
|
+
readonly cachedInputUsdPerTok: number | null;
|
|
17
|
+
/** Cache-CREATION (write) rate, USD/tok (WS-A). From LiteLLM
|
|
18
|
+
* `cache_creation_input_token_cost`. null ⇒ unverified: cache writes bill at
|
|
19
|
+
* the input rate (1.0×), never a guessed premium (dev-rule L5). */
|
|
20
|
+
readonly cacheWriteUsdPerTok: number | null;
|
|
21
|
+
/** 1h-TTL cache-write rate, USD/tok (Anthropic 2×; WS-A). From LiteLLM
|
|
22
|
+
* `cache_creation_input_token_cost_above_1hr`. null ⇒ the 1h portion falls
|
|
23
|
+
* back to `cacheWriteUsdPerTok` (then to input) — fail-closed. */
|
|
24
|
+
readonly cacheWrite1hUsdPerTok: number | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function getPricing(provider: ProviderId, model: string): ModelPricing | null;
|
|
27
|
+
/**
|
|
28
|
+
* The richer `ModelPricingV2` a vendor overlay/manual entry carries, if any —
|
|
29
|
+
* resolved by the SAME key precedence as {@link getPricing} (snapshot wins on a
|
|
30
|
+
* shared key, and the snapshot never carries `pricing_v2`, so a shared key
|
|
31
|
+
* yields null → the caller synthesizes from the flat rate). Returns null when
|
|
32
|
+
* no richer shape is on file. Never guesses: absence is `base`-only downstream.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getPricingV2(provider: ProviderId, model: string): ModelPricingV2 | null;
|
|
35
|
+
export declare function estimateCostUsd(pricing: ModelPricing, tokensIn: number, tokensOut: number, tokensCached: number,
|
|
36
|
+
/** Cache-CREATION (write) tokens — a subset of tokensIn, WS-A (spec §4.1).
|
|
37
|
+
* Defaults to 0: with a zero write the whole expression collapses to the
|
|
38
|
+
* pre-WS-A formula BYTE-IDENTICALLY (the regression pin), so every existing
|
|
39
|
+
* caller and stored cost is unchanged. */
|
|
40
|
+
tokensCacheWrite?: number,
|
|
41
|
+
/** 1h-TTL portion of the write (bills at the higher multiplier when known). */
|
|
42
|
+
tokensCacheWrite1h?: number): number;
|
|
43
|
+
//# sourceMappingURL=pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/registry/pricing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C;;uEAEmE;IACnE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C;;sEAEkE;IAClE,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/C;AAyDD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CA6BnF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAYvF;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM;AACpB;;;0CAG0C;AAC1C,gBAAgB,SAAI;AACpB,+EAA+E;AAC/E,kBAAkB,SAAI,GACrB,MAAM,CAsBR"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Thin pricing accessor over the vendored LiteLLM pricing snapshot
|
|
4
|
+
* (data/pricing-map.json, extracted at the pinned SHA — see
|
|
5
|
+
* upstream/litellm.pin.json). The full three-layer registry is Phase 2;
|
|
6
|
+
* Phase 1 needs only cost-per-token lookups for envelopes, prefer:[cost]
|
|
7
|
+
* ordering, and telemetry cost estimates.
|
|
8
|
+
*
|
|
9
|
+
* Data source: model_prices_and_context_window.json,
|
|
10
|
+
* Copyright (c) 2023 Berri AI, MIT License (https://github.com/BerriAI/litellm).
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.getPricing = getPricing;
|
|
14
|
+
exports.getPricingV2 = getPricingV2;
|
|
15
|
+
exports.estimateCostUsd = estimateCostUsd;
|
|
16
|
+
const node_fs_1 = require("node:fs");
|
|
17
|
+
const node_path_1 = require("node:path");
|
|
18
|
+
/** LiteLLM key prefixes per provider, most-specific first. Verified against
|
|
19
|
+
* the snapshot (see data/PROVENANCE.md): Gemini API entries live under
|
|
20
|
+
* "gemini/" (bare ids resolve to Vertex pricing — different product), OpenAI
|
|
21
|
+
* under bare ids, DeepSeek under both. */
|
|
22
|
+
const KEY_PREFIXES = {
|
|
23
|
+
gemini: ["gemini/"],
|
|
24
|
+
openai: ["", "openai/"],
|
|
25
|
+
deepseek: ["deepseek/", ""],
|
|
26
|
+
anthropic: ["anthropic/", ""],
|
|
27
|
+
grok: ["xai/"],
|
|
28
|
+
// A1 hosts: DeepInfra models keep their org path ("Qwen/QwQ-32B");
|
|
29
|
+
// Fireworks pricing keys carry the accounts/… wire prefix.
|
|
30
|
+
deepinfra: ["deepinfra/"],
|
|
31
|
+
fireworks: ["fireworks_ai/accounts/fireworks/models/", "fireworks_ai/"],
|
|
32
|
+
};
|
|
33
|
+
let cachedMap = null;
|
|
34
|
+
/** Host-swept gap-filler (scripts/pricing-sweep.ts): prices for models the
|
|
35
|
+
* pinned LiteLLM snapshot has not caught up to. Merged BENEATH the snapshot —
|
|
36
|
+
* the snapshot wins on any shared key (stability); the overlay only fills gaps.
|
|
37
|
+
* Absent file ⇒ no overlay, unchanged behaviour. */
|
|
38
|
+
function loadOverlay(dataDir) {
|
|
39
|
+
const path = (0, node_path_1.join)(dataDir, "pricing-overlay.json");
|
|
40
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
41
|
+
return {};
|
|
42
|
+
const parsed = JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
|
|
43
|
+
return parsed.prices ?? {};
|
|
44
|
+
}
|
|
45
|
+
function loadMap() {
|
|
46
|
+
if (cachedMap === null) {
|
|
47
|
+
const dataDir = (0, node_path_1.join)(__dirname, "..", "..", "data");
|
|
48
|
+
const snapshot = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(dataDir, "pricing-map.json"), "utf8"));
|
|
49
|
+
cachedMap = { ...loadOverlay(dataDir), ...snapshot };
|
|
50
|
+
}
|
|
51
|
+
return cachedMap;
|
|
52
|
+
}
|
|
53
|
+
function getPricing(provider, model) {
|
|
54
|
+
if (model === "")
|
|
55
|
+
return null;
|
|
56
|
+
const map = loadMap();
|
|
57
|
+
for (const prefix of KEY_PREFIXES[provider]) {
|
|
58
|
+
const entry = map[`${prefix}${model}`];
|
|
59
|
+
if (entry !== undefined &&
|
|
60
|
+
typeof entry.input_cost_per_token === "number" &&
|
|
61
|
+
typeof entry.output_cost_per_token === "number") {
|
|
62
|
+
return {
|
|
63
|
+
inputUsdPerTok: entry.input_cost_per_token,
|
|
64
|
+
outputUsdPerTok: entry.output_cost_per_token,
|
|
65
|
+
cachedInputUsdPerTok: typeof entry.cache_read_input_token_cost === "number"
|
|
66
|
+
? entry.cache_read_input_token_cost
|
|
67
|
+
: null,
|
|
68
|
+
cacheWriteUsdPerTok: typeof entry.cache_creation_input_token_cost === "number"
|
|
69
|
+
? entry.cache_creation_input_token_cost
|
|
70
|
+
: null,
|
|
71
|
+
cacheWrite1hUsdPerTok: typeof entry.cache_creation_input_token_cost_above_1hr === "number"
|
|
72
|
+
? entry.cache_creation_input_token_cost_above_1hr
|
|
73
|
+
: null,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The richer `ModelPricingV2` a vendor overlay/manual entry carries, if any —
|
|
81
|
+
* resolved by the SAME key precedence as {@link getPricing} (snapshot wins on a
|
|
82
|
+
* shared key, and the snapshot never carries `pricing_v2`, so a shared key
|
|
83
|
+
* yields null → the caller synthesizes from the flat rate). Returns null when
|
|
84
|
+
* no richer shape is on file. Never guesses: absence is `base`-only downstream.
|
|
85
|
+
*/
|
|
86
|
+
function getPricingV2(provider, model) {
|
|
87
|
+
if (model === "")
|
|
88
|
+
return null;
|
|
89
|
+
const map = loadMap();
|
|
90
|
+
for (const prefix of KEY_PREFIXES[provider]) {
|
|
91
|
+
const entry = map[`${prefix}${model}`];
|
|
92
|
+
if (entry !== undefined && typeof entry.input_cost_per_token === "number") {
|
|
93
|
+
// Resolve on the same entry getPricing would pick; only that entry's
|
|
94
|
+
// pricing_v2 counts (a later-prefix match must not shadow it).
|
|
95
|
+
return entry.pricing_v2 ?? null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function estimateCostUsd(pricing, tokensIn, tokensOut, tokensCached,
|
|
101
|
+
/** Cache-CREATION (write) tokens — a subset of tokensIn, WS-A (spec §4.1).
|
|
102
|
+
* Defaults to 0: with a zero write the whole expression collapses to the
|
|
103
|
+
* pre-WS-A formula BYTE-IDENTICALLY (the regression pin), so every existing
|
|
104
|
+
* caller and stored cost is unchanged. */
|
|
105
|
+
tokensCacheWrite = 0,
|
|
106
|
+
/** 1h-TTL portion of the write (bills at the higher multiplier when known). */
|
|
107
|
+
tokensCacheWrite1h = 0) {
|
|
108
|
+
// Providers report tokensCached and tokensCacheWrite as subsets of tokensIn;
|
|
109
|
+
// bill each at its rate, the remainder at the input rate, never negatively.
|
|
110
|
+
const cached = Math.min(Math.max(tokensCached, 0), Math.max(tokensIn, tokensCached));
|
|
111
|
+
const write = Math.max(tokensCacheWrite, 0);
|
|
112
|
+
const write1h = Math.min(Math.max(tokensCacheWrite1h, 0), write);
|
|
113
|
+
// uncached subtracts BOTH cache buckets. With write === 0 this is exactly the
|
|
114
|
+
// former `max(tokensIn − cached, 0)`, so a zero-write call is unchanged.
|
|
115
|
+
const uncachedIn = Math.max(tokensIn - cached - write, 0);
|
|
116
|
+
const cachedRate = pricing.cachedInputUsdPerTok ?? pricing.inputUsdPerTok;
|
|
117
|
+
// L5 fail-closed: an unverified write rate degrades to the INPUT rate (1.0×),
|
|
118
|
+
// never a guessed premium; the 1h rate degrades to the 5m write rate, then to
|
|
119
|
+
// input. Below-min / non-cache-write callers pass 0 and touch none of this.
|
|
120
|
+
const writeRate = pricing.cacheWriteUsdPerTok ?? pricing.inputUsdPerTok;
|
|
121
|
+
const write1hRate = pricing.cacheWrite1hUsdPerTok ?? writeRate;
|
|
122
|
+
return (uncachedIn * pricing.inputUsdPerTok +
|
|
123
|
+
cached * cachedRate +
|
|
124
|
+
(write - write1h) * writeRate +
|
|
125
|
+
write1h * write1hRate +
|
|
126
|
+
Math.max(tokensOut, 0) * pricing.outputUsdPerTok);
|
|
127
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry → selection rows. One projection, used by every surface that
|
|
3
|
+
* asks a capability question from the FILES (the CLI, `modelrig init`, the
|
|
4
|
+
* docs build). The console projects from its Supabase mirror and the oracle
|
|
5
|
+
* from its own loader, but all three land on the same `ModelSelectRow`
|
|
6
|
+
* shape so the three cannot answer differently.
|
|
7
|
+
*/
|
|
8
|
+
import type { ModelSelectRow } from "./select";
|
|
9
|
+
/**
|
|
10
|
+
* Load selection rows from registry.json (+ leaderboard.json for effective
|
|
11
|
+
* cost). Returns [] rather than throwing when the registry is absent or
|
|
12
|
+
* unreadable — a repo without a built registry should still get drafts,
|
|
13
|
+
* carrying the incumbent alone.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadRegistryRows(registryPath?: string): ModelSelectRow[];
|
|
16
|
+
//# sourceMappingURL=rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/registry/rows.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAyC/C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE,CA2BxE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Registry → selection rows. One projection, used by every surface that
|
|
4
|
+
* asks a capability question from the FILES (the CLI, `modelrig init`, the
|
|
5
|
+
* docs build). The console projects from its Supabase mirror and the oracle
|
|
6
|
+
* from its own loader, but all three land on the same `ModelSelectRow`
|
|
7
|
+
* shape so the three cannot answer differently.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.loadRegistryRows = loadRegistryRows;
|
|
11
|
+
const node_fs_1 = require("node:fs");
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
function packagedRegistryDir() {
|
|
14
|
+
// dist/ and src/ both sit one level under the package root.
|
|
15
|
+
return (0, node_path_1.join)(__dirname, "..", "..", "registry");
|
|
16
|
+
}
|
|
17
|
+
function readJson(path) {
|
|
18
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
19
|
+
return null;
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load selection rows from registry.json (+ leaderboard.json for effective
|
|
29
|
+
* cost). Returns [] rather than throwing when the registry is absent or
|
|
30
|
+
* unreadable — a repo without a built registry should still get drafts,
|
|
31
|
+
* carrying the incumbent alone.
|
|
32
|
+
*/
|
|
33
|
+
function loadRegistryRows(registryPath) {
|
|
34
|
+
const registryFile = registryPath ?? (0, node_path_1.join)(packagedRegistryDir(), "registry.json");
|
|
35
|
+
const registry = readJson(registryFile);
|
|
36
|
+
if (registry === null)
|
|
37
|
+
return [];
|
|
38
|
+
const dir = registryFile.slice(0, Math.max(registryFile.lastIndexOf("/"), 0));
|
|
39
|
+
const leaderboard = readJson((0, node_path_1.join)(dir, "leaderboard.json")) ?? [];
|
|
40
|
+
const effective = new Map(leaderboard.map((r) => [r.model_key, r.effective_usd_per_1k_conformant ?? null]));
|
|
41
|
+
return (registry.models ?? []).map((entry) => {
|
|
42
|
+
const [provider] = entry.model_key.split("/");
|
|
43
|
+
return {
|
|
44
|
+
key: entry.model_key,
|
|
45
|
+
provider: provider ?? entry.model_key,
|
|
46
|
+
inputUsdPerMtok: entry.declared?.pricing?.input_usd_per_mtok ?? null,
|
|
47
|
+
outputUsdPerMtok: entry.declared?.pricing?.output_usd_per_mtok ?? null,
|
|
48
|
+
conformRate: entry.probed?.schema?.conform_rate ?? null,
|
|
49
|
+
nativeRungRate: entry.probed?.schema?.native_rung_rate ?? null,
|
|
50
|
+
groundedRate: entry.probed?.grounding?.grounded_rate ?? null,
|
|
51
|
+
cacheHitRate: entry.probed?.caching?.cache_hit_rate ?? null,
|
|
52
|
+
effectiveUsdPer1k: effective.get(entry.model_key) ?? null,
|
|
53
|
+
discrepancies: entry.discrepancies?.length ?? 0,
|
|
54
|
+
probedAsOf: entry.probed?.as_of ?? null,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
}
|