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,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The `rig_sk_` key FORMAT — Phase 6 WS2.
|
|
4
|
+
*
|
|
5
|
+
* Shared knowledge, deliberately: the SDK builds the header that presents a
|
|
6
|
+
* key, modelrig-server resolves one, and the oracle decides whether the value
|
|
7
|
+
* it was handed is a key at all. Three packages agreeing on a prefix by
|
|
8
|
+
* copying a string literal is how N1's "one name per concept" fails in
|
|
9
|
+
* practice, so the string lives here and they all import it.
|
|
10
|
+
*
|
|
11
|
+
* What is NOT here is MINTING. Generating a secret and writing its hash is the
|
|
12
|
+
* control plane's job; an SDK that could do it would imply a client could
|
|
13
|
+
* issue itself a credential, which is the shape of the thing this scheme
|
|
14
|
+
* exists to prevent. `mintApiKey` lives in modelrig-server.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.API_KEY_SCOPES = exports.API_KEY_BODY_MIN_LENGTH = exports.API_KEY_SECRET_BYTES = exports.API_KEY_PREFIX = void 0;
|
|
18
|
+
exports.hashApiKeySecret = hashApiKeySecret;
|
|
19
|
+
exports.looksLikeApiKey = looksLikeApiKey;
|
|
20
|
+
exports.redactApiKey = redactApiKey;
|
|
21
|
+
exports.parseScopes = parseScopes;
|
|
22
|
+
exports.hasScope = hasScope;
|
|
23
|
+
const node_crypto_1 = require("node:crypto");
|
|
24
|
+
/**
|
|
25
|
+
* The one place this prefix is spelled. Grep-visible on purpose: the
|
|
26
|
+
* guardrails C2 rule keys off it, and so does the exporter's sink selection.
|
|
27
|
+
*/
|
|
28
|
+
exports.API_KEY_PREFIX = "rig_sk_";
|
|
29
|
+
/** 32 bytes = 256 bits, as base64url. The minting side uses this to generate;
|
|
30
|
+
* this side uses its ENCODED length to recognise. See 00020's header for why
|
|
31
|
+
* that number carries the argument that a plain sha-256 at rest is sound. */
|
|
32
|
+
exports.API_KEY_SECRET_BYTES = 32;
|
|
33
|
+
/** base64url length of API_KEY_SECRET_BYTES — the minimum a real key's body has. */
|
|
34
|
+
exports.API_KEY_BODY_MIN_LENGTH = 43;
|
|
35
|
+
/**
|
|
36
|
+
* The granted authorities. Mirrors migration 00020's CHECK constraint (widened
|
|
37
|
+
* by 00033 for content custody) — a test pins that the two agree, because a
|
|
38
|
+
* scope that exists here and not there is a key that cannot be written, and one
|
|
39
|
+
* that exists there and not here is an authority nothing enforces.
|
|
40
|
+
*
|
|
41
|
+
* `artifact-write`/`artifact-read` (E2-C, 00033): request a content upload grant
|
|
42
|
+
* / mint a content download URL. Both are ordinary (non-elevated) machine
|
|
43
|
+
* grants — they move an org's own artifact bytes, they do not spend money or
|
|
44
|
+
* approve swaps (contrast decision/oracle-act, gated to admin/owner minters).
|
|
45
|
+
*
|
|
46
|
+
* `task-settings` (settings-plane, 00043): PATCH a task's governance settings
|
|
47
|
+
* (capture / artifacts / content / scrub). Held by a coding agent flipping
|
|
48
|
+
* settings for the user. READING settings needs no scope — any org-scoped key
|
|
49
|
+
* may read, since settings ride the already-readable task row.
|
|
50
|
+
*/
|
|
51
|
+
exports.API_KEY_SCOPES = [
|
|
52
|
+
"ingest",
|
|
53
|
+
"query",
|
|
54
|
+
"feedback",
|
|
55
|
+
"decision",
|
|
56
|
+
"oracle-act",
|
|
57
|
+
"artifact-write",
|
|
58
|
+
"artifact-read",
|
|
59
|
+
"task-settings",
|
|
60
|
+
];
|
|
61
|
+
/** sha256 of the WHOLE presented string, prefix included — so a caller cannot
|
|
62
|
+
* strip the prefix and land on a different row. */
|
|
63
|
+
function hashApiKeySecret(secret) {
|
|
64
|
+
return (0, node_crypto_1.createHash)("sha256").update(secret, "utf8").digest("hex");
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Cheap shape check, used to decide which credential branch a bearer token
|
|
68
|
+
* takes before any I/O happens.
|
|
69
|
+
*
|
|
70
|
+
* The minimum body length matters: without it the bare string `rig_sk_` would
|
|
71
|
+
* take the api-key branch and cost a database round trip per garbage request,
|
|
72
|
+
* which is a free amplification primitive on an unauthenticated surface.
|
|
73
|
+
*/
|
|
74
|
+
function looksLikeApiKey(presented) {
|
|
75
|
+
if (!presented.startsWith(exports.API_KEY_PREFIX))
|
|
76
|
+
return false;
|
|
77
|
+
const body = presented.slice(exports.API_KEY_PREFIX.length);
|
|
78
|
+
return body.length >= exports.API_KEY_BODY_MIN_LENGTH && /^[A-Za-z0-9_-]+$/.test(body);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* What a key may be called in a log line, an error, or a boot banner.
|
|
82
|
+
*
|
|
83
|
+
* Returns the placeholder form for a non-key so that a caller who reaches for
|
|
84
|
+
* this with the wrong variable prints nothing useful rather than printing the
|
|
85
|
+
* whole thing. C2's leak-gate is the belt; this is the braces.
|
|
86
|
+
*/
|
|
87
|
+
function redactApiKey(presented) {
|
|
88
|
+
const suffix = looksLikeApiKey(presented) ? presented.slice(-4) : "????";
|
|
89
|
+
return `${exports.API_KEY_PREFIX}…${suffix}`;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Narrow an untrusted scope list to the known set (T7: a jsonb/array column
|
|
93
|
+
* is not proof of shape — narrow at the boundary).
|
|
94
|
+
*
|
|
95
|
+
* Unknown entries are DROPPED, not rejected: a row written by a future
|
|
96
|
+
* migration with a scope this build predates should still authorize the
|
|
97
|
+
* scopes this build understands, rather than failing closed on everything.
|
|
98
|
+
* Returns declaration order so two equal grant sets compare equal.
|
|
99
|
+
*/
|
|
100
|
+
function parseScopes(raw) {
|
|
101
|
+
if (!Array.isArray(raw))
|
|
102
|
+
return [];
|
|
103
|
+
const present = new Set(raw.filter((s) => typeof s === "string"));
|
|
104
|
+
return exports.API_KEY_SCOPES.filter((scope) => present.has(scope));
|
|
105
|
+
}
|
|
106
|
+
/** An empty grant set authorizes nothing — stated as code so it cannot be
|
|
107
|
+
* accidentally re-derived as "no scopes means unrestricted". */
|
|
108
|
+
function hasScope(granted, required) {
|
|
109
|
+
return granted.includes(required);
|
|
110
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tenancy constants — Phase 6 WS1.
|
|
3
|
+
*
|
|
4
|
+
* Last Verified: 2026-08-04 against migration
|
|
5
|
+
* `supabase/migrations/00012_orgs_projects_memberships.sql` (S4: schema truth
|
|
6
|
+
* is the migration file; never assume an id, read the seed).
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The org that owns everything predating accounts, and the org a
|
|
10
|
+
* single-tenant deployment writes into.
|
|
11
|
+
*
|
|
12
|
+
* A fixed sentinel rather than a random uuid so that policies, migrations and
|
|
13
|
+
* code can all name it without a lookup. Seeded by 00012; a partial unique
|
|
14
|
+
* index on `orgs (is_house) where is_house` makes a second one impossible.
|
|
15
|
+
*
|
|
16
|
+
* On a SELF-HOSTED control plane this is simply "the customer's org" — their
|
|
17
|
+
* database has exactly one, and everything belongs to it. On the hosted plane
|
|
18
|
+
* it is ours, and WS2's `/v1/ingest` never uses it: there, org and project are
|
|
19
|
+
* resolved from the api key and stamped explicitly (T3 — tenancy is derived
|
|
20
|
+
* from the principal, never defaulted).
|
|
21
|
+
*/
|
|
22
|
+
export declare const HOUSE_ORG_ID = "00000000-0000-4000-8000-000000000001";
|
|
23
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/tenancy/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,yCAAyC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tenancy constants — Phase 6 WS1.
|
|
4
|
+
*
|
|
5
|
+
* Last Verified: 2026-08-04 against migration
|
|
6
|
+
* `supabase/migrations/00012_orgs_projects_memberships.sql` (S4: schema truth
|
|
7
|
+
* is the migration file; never assume an id, read the seed).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.HOUSE_ORG_ID = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* The org that owns everything predating accounts, and the org a
|
|
13
|
+
* single-tenant deployment writes into.
|
|
14
|
+
*
|
|
15
|
+
* A fixed sentinel rather than a random uuid so that policies, migrations and
|
|
16
|
+
* code can all name it without a lookup. Seeded by 00012; a partial unique
|
|
17
|
+
* index on `orgs (is_house) where is_house` makes a second one impossible.
|
|
18
|
+
*
|
|
19
|
+
* On a SELF-HOSTED control plane this is simply "the customer's org" — their
|
|
20
|
+
* database has exactly one, and everything belongs to it. On the hosted plane
|
|
21
|
+
* it is ours, and WS2's `/v1/ingest` never uses it: there, org and project are
|
|
22
|
+
* resolved from the api key and stamped explicitly (T3 — tenancy is derived
|
|
23
|
+
* from the principal, never defaulted).
|
|
24
|
+
*/
|
|
25
|
+
exports.HOUSE_ORG_ID = "00000000-0000-4000-8000-000000000001";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one secret-scrubber every emission boundary shares — C2's leak gate.
|
|
3
|
+
*
|
|
4
|
+
* ── WHY THIS MOVED HERE (WS3) ────────────────────────────────────────────
|
|
5
|
+
* `scrubSecrets` was born in `watch/run-record.ts`, scoped to the six
|
|
6
|
+
* INFRASTRUCTURE prefixes a failing cron might spill (`sk_live_`, `whsec_`,
|
|
7
|
+
* `rnd_`, a Supabase JWT). WS3 changed the threat model: the BYOK vault now
|
|
8
|
+
* decrypts CUSTOMER PROVIDER keys into data-plane memory at call time, and a
|
|
9
|
+
* decrypted key that reaches an error message, a telemetry row, an export, or
|
|
10
|
+
* a log line is precisely the leak the vault exists to prevent. So the scrubber
|
|
11
|
+
* is promoted to shared, its prefix set widened to every provider family we
|
|
12
|
+
* might hold, and it is exported from the package so the server and the SDK run
|
|
13
|
+
* the SAME gate rather than two that drift.
|
|
14
|
+
*
|
|
15
|
+
* ── PREFIX-BASED, NOT ENTROPY-BASED, ON PURPOSE ──────────────────────────
|
|
16
|
+
* A high-entropy heuristic ("looks random enough") redacts request ids, git
|
|
17
|
+
* shas, and base64 payloads — and a scrubber that eats legitimate text gets
|
|
18
|
+
* muted within a week, which is worse than none. Anchoring on known credential
|
|
19
|
+
* prefixes matches a real key and almost nothing else. The cost is that a
|
|
20
|
+
* provider inventing a brand-new prefix is invisible until added here; that is
|
|
21
|
+
* a one-line change and the correct trade.
|
|
22
|
+
*
|
|
23
|
+
* ── A NAME IS NOT A LEAK ─────────────────────────────────────────────────
|
|
24
|
+
* These patterns match secret VALUES, never their variable names. The string
|
|
25
|
+
* `MODELRIG_SUPABASE_SERVICE_ROLE_KEY` in an error is a name and stays; only a
|
|
26
|
+
* value carrying a live prefix is redacted. `publish-safety.test.ts` relies on
|
|
27
|
+
* the same distinction.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Credential prefixes that mark a key-shaped VALUE. Grep-visible on purpose —
|
|
31
|
+
* `scripts/guardrails.ts` (C2) and this module are the two places the set is
|
|
32
|
+
* spelled, and a test pins that the vault's provider families all appear here.
|
|
33
|
+
*
|
|
34
|
+
* Order does not matter; each is tried independently.
|
|
35
|
+
*/
|
|
36
|
+
export declare const KEY_SHAPED_PREFIXES: readonly string[];
|
|
37
|
+
/**
|
|
38
|
+
* Replace every key-shaped substring with `[redacted]`, leaving all other text
|
|
39
|
+
* intact. Safe to run on any string headed out of the process — failure
|
|
40
|
+
* messages, telemetry notes, export rows, log lines.
|
|
41
|
+
*/
|
|
42
|
+
export declare function scrubSecrets(text: string): string;
|
|
43
|
+
/** True if the text contains anything key-shaped. The predicate behind the
|
|
44
|
+
* build-failing leak-gate test — cheaper to read than a diff of scrubbed vs
|
|
45
|
+
* original, and it says what it means. */
|
|
46
|
+
export declare function containsKeyShapedString(text: string): boolean;
|
|
47
|
+
//# sourceMappingURL=scrub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrub.d.ts","sourceRoot":"","sources":["../../src/tenancy/scrub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAiBhD,CAAC;AAkBF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;0CAE0C;AAC1C,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The one secret-scrubber every emission boundary shares — C2's leak gate.
|
|
4
|
+
*
|
|
5
|
+
* ── WHY THIS MOVED HERE (WS3) ────────────────────────────────────────────
|
|
6
|
+
* `scrubSecrets` was born in `watch/run-record.ts`, scoped to the six
|
|
7
|
+
* INFRASTRUCTURE prefixes a failing cron might spill (`sk_live_`, `whsec_`,
|
|
8
|
+
* `rnd_`, a Supabase JWT). WS3 changed the threat model: the BYOK vault now
|
|
9
|
+
* decrypts CUSTOMER PROVIDER keys into data-plane memory at call time, and a
|
|
10
|
+
* decrypted key that reaches an error message, a telemetry row, an export, or
|
|
11
|
+
* a log line is precisely the leak the vault exists to prevent. So the scrubber
|
|
12
|
+
* is promoted to shared, its prefix set widened to every provider family we
|
|
13
|
+
* might hold, and it is exported from the package so the server and the SDK run
|
|
14
|
+
* the SAME gate rather than two that drift.
|
|
15
|
+
*
|
|
16
|
+
* ── PREFIX-BASED, NOT ENTROPY-BASED, ON PURPOSE ──────────────────────────
|
|
17
|
+
* A high-entropy heuristic ("looks random enough") redacts request ids, git
|
|
18
|
+
* shas, and base64 payloads — and a scrubber that eats legitimate text gets
|
|
19
|
+
* muted within a week, which is worse than none. Anchoring on known credential
|
|
20
|
+
* prefixes matches a real key and almost nothing else. The cost is that a
|
|
21
|
+
* provider inventing a brand-new prefix is invisible until added here; that is
|
|
22
|
+
* a one-line change and the correct trade.
|
|
23
|
+
*
|
|
24
|
+
* ── A NAME IS NOT A LEAK ─────────────────────────────────────────────────
|
|
25
|
+
* These patterns match secret VALUES, never their variable names. The string
|
|
26
|
+
* `MODELRIG_SUPABASE_SERVICE_ROLE_KEY` in an error is a name and stays; only a
|
|
27
|
+
* value carrying a live prefix is redacted. `publish-safety.test.ts` relies on
|
|
28
|
+
* the same distinction.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.KEY_SHAPED_PREFIXES = void 0;
|
|
32
|
+
exports.scrubSecrets = scrubSecrets;
|
|
33
|
+
exports.containsKeyShapedString = containsKeyShapedString;
|
|
34
|
+
/**
|
|
35
|
+
* Credential prefixes that mark a key-shaped VALUE. Grep-visible on purpose —
|
|
36
|
+
* `scripts/guardrails.ts` (C2) and this module are the two places the set is
|
|
37
|
+
* spelled, and a test pins that the vault's provider families all appear here.
|
|
38
|
+
*
|
|
39
|
+
* Order does not matter; each is tried independently.
|
|
40
|
+
*/
|
|
41
|
+
exports.KEY_SHAPED_PREFIXES = [
|
|
42
|
+
// Provider keys the BYOK vault can hold (signup-auth-boundary §BYOK).
|
|
43
|
+
"sk-", // OpenAI, Anthropic (sk-ant-), DeepSeek, most openai-compat
|
|
44
|
+
"AIza", // Google / Gemini
|
|
45
|
+
"xai-", // xAI / Grok
|
|
46
|
+
"fw_", // Fireworks
|
|
47
|
+
"tvly-", // Tavily
|
|
48
|
+
// ModelRig's own machine credential.
|
|
49
|
+
"rig_sk_",
|
|
50
|
+
// Platform / infrastructure secrets (the original run-record set).
|
|
51
|
+
"sk_live_",
|
|
52
|
+
"sk_test_",
|
|
53
|
+
"rk_live_", // Stripe restricted keys
|
|
54
|
+
"rk_test_",
|
|
55
|
+
"whsec_", // Stripe webhook signing
|
|
56
|
+
"rnd_", // Render API
|
|
57
|
+
"eyJ", // JWT (Supabase publishable / service-role) — base64url header
|
|
58
|
+
];
|
|
59
|
+
/** The body that must follow a prefix for it to count as a key: at least eight
|
|
60
|
+
* of the characters a base64url/hex secret is made of. Keeps `sk-` from eating
|
|
61
|
+
* the word "sk-" in prose while catching every real key, which is long. */
|
|
62
|
+
const KEY_BODY = "[A-Za-z0-9_\\-.]{8,}";
|
|
63
|
+
function escape(prefix) {
|
|
64
|
+
return prefix.replace(/[.*+?^${}()|[\]\\-]/g, "\\$&");
|
|
65
|
+
}
|
|
66
|
+
/** One combined pattern, rebuilt per call (regex objects carry `lastIndex`
|
|
67
|
+
* state with the `g` flag, so a shared instance is a footgun across callers). */
|
|
68
|
+
function keyPattern() {
|
|
69
|
+
const alt = exports.KEY_SHAPED_PREFIXES.map((p) => escape(p) + KEY_BODY).join("|");
|
|
70
|
+
return new RegExp(alt, "g");
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Replace every key-shaped substring with `[redacted]`, leaving all other text
|
|
74
|
+
* intact. Safe to run on any string headed out of the process — failure
|
|
75
|
+
* messages, telemetry notes, export rows, log lines.
|
|
76
|
+
*/
|
|
77
|
+
function scrubSecrets(text) {
|
|
78
|
+
return text.replace(keyPattern(), "[redacted]");
|
|
79
|
+
}
|
|
80
|
+
/** True if the text contains anything key-shaped. The predicate behind the
|
|
81
|
+
* build-failing leak-gate test — cheaper to read than a diff of scrubbed vs
|
|
82
|
+
* original, and it says what it means. */
|
|
83
|
+
function containsKeyShapedString(text) {
|
|
84
|
+
return keyPattern().test(text);
|
|
85
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Errors that teach, for LOAD-TIME config problems — onboarding-redesign §7 G2.
|
|
3
|
+
*
|
|
4
|
+
* The failure taxonomy in failures-teaching.ts classifies inference ATTEMPTS: a
|
|
5
|
+
* request that ran and went wrong. A malformed route bundle never ran — it is a
|
|
6
|
+
* `RouteConfigError`, deliberately outside that taxonomy (loader.ts §26). So
|
|
7
|
+
* the teaching table covered every way a call can fail and NOT the two things a
|
|
8
|
+
* first-time user actually hits first: a schema path that doesn't resolve, and
|
|
9
|
+
* a `{{variable}}` nobody declared. The setup flow's `failed` state and the
|
|
10
|
+
* docs' "when it doesn't work" sections both draw their copy from here, so
|
|
11
|
+
* `failed` has something precise to say exactly when it matters most.
|
|
12
|
+
*
|
|
13
|
+
* A `RouteConfigError` carries `.problems: string[]` — each a message the
|
|
14
|
+
* loader produced. This module classifies each into a SHAPE and attaches the
|
|
15
|
+
* three things a stuck author needs, in order: what it means, what to do, where
|
|
16
|
+
* to read. The completeness test makes every shape carry all three.
|
|
17
|
+
*
|
|
18
|
+
* NOTE what is deliberately NOT here: a `json: native` claim on a model that
|
|
19
|
+
* cannot hold it. The loader ACCEPTS that syntactically — it is a claim about
|
|
20
|
+
* the model, checked against the probed registry, not a config error. It loads
|
|
21
|
+
* and then behaves unlike the code it replaced, which is why the agent prompt
|
|
22
|
+
* (§3.5) states it as a constraint instead.
|
|
23
|
+
*/
|
|
24
|
+
import type { RouteConfigError } from "../routes/loader";
|
|
25
|
+
export type ConfigProblemShape = "missing_schema" | "missing_prompt" | "undeclared_variable" | "unknown_provider" | "no_candidates" | "invalid_policy" | "invalid_cache" | "invalid_structure" | "duplicate_route" | "unknown_route" | "other";
|
|
26
|
+
export interface ConfigTeaching {
|
|
27
|
+
readonly shape: ConfigProblemShape;
|
|
28
|
+
/** One sentence: what this problem MEANS, in the author's terms. */
|
|
29
|
+
readonly what: string;
|
|
30
|
+
/** The action to take — an instruction, not a diagnosis. */
|
|
31
|
+
readonly fixHint: string;
|
|
32
|
+
/** A deep link with a per-shape anchor, never a homepage. */
|
|
33
|
+
readonly docsUrl: string;
|
|
34
|
+
}
|
|
35
|
+
export declare const CONFIG_TEACHING: Readonly<Record<ConfigProblemShape, ConfigTeaching>>;
|
|
36
|
+
/** Map one loader problem string to its shape. Ordered most-specific first. */
|
|
37
|
+
export declare function classifyConfigProblem(problem: string): ConfigProblemShape;
|
|
38
|
+
export interface TeachableConfigProblem extends ConfigTeaching {
|
|
39
|
+
/** The raw loader message — this is literally "what we found". */
|
|
40
|
+
readonly problem: string;
|
|
41
|
+
}
|
|
42
|
+
/** Teach every problem a RouteConfigError carries. */
|
|
43
|
+
export declare function teachConfigError(error: RouteConfigError): {
|
|
44
|
+
readonly file: string | null;
|
|
45
|
+
readonly problems: readonly TeachableConfigProblem[];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The `failed`-state triple §3.1 asks for — what we looked for, what we found
|
|
49
|
+
* instead, and the most likely causes — for a route bundle that would not load.
|
|
50
|
+
* This is what the setup flow's `failed` state renders, and it is why that
|
|
51
|
+
* state can now describe its own absence instead of presenting as silence.
|
|
52
|
+
*/
|
|
53
|
+
export interface ConfigFailedState {
|
|
54
|
+
readonly lookedFor: string;
|
|
55
|
+
readonly found: readonly string[];
|
|
56
|
+
readonly causes: readonly string[];
|
|
57
|
+
readonly docsUrls: readonly string[];
|
|
58
|
+
}
|
|
59
|
+
export declare function describeConfigFailure(error: RouteConfigError): ConfigFailedState;
|
|
60
|
+
/** Terminal-friendly rendering — parity with renderFailureForTerminal. */
|
|
61
|
+
export declare function renderConfigErrorForTerminal(error: RouteConfigError): string;
|
|
62
|
+
//# sourceMappingURL=config-teaching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-teaching.d.ts","sourceRoot":"","sources":["../../src/types/config-teaching.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,kBAAkB,GAC1B,gBAAgB,GAChB,gBAAgB,GAChB,qBAAqB,GACrB,kBAAkB,GAClB,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,mBAAmB,GACnB,iBAAiB,GACjB,eAAe,GACf,OAAO,CAAC;AAEZ,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAID,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAgHhF,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAezE;AAED,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,sBAAsB,EAAE,CAAC;CACtD,CAWA;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAUhF;AAED,0EAA0E;AAC1E,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAQ5E"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Errors that teach, for LOAD-TIME config problems — onboarding-redesign §7 G2.
|
|
4
|
+
*
|
|
5
|
+
* The failure taxonomy in failures-teaching.ts classifies inference ATTEMPTS: a
|
|
6
|
+
* request that ran and went wrong. A malformed route bundle never ran — it is a
|
|
7
|
+
* `RouteConfigError`, deliberately outside that taxonomy (loader.ts §26). So
|
|
8
|
+
* the teaching table covered every way a call can fail and NOT the two things a
|
|
9
|
+
* first-time user actually hits first: a schema path that doesn't resolve, and
|
|
10
|
+
* a `{{variable}}` nobody declared. The setup flow's `failed` state and the
|
|
11
|
+
* docs' "when it doesn't work" sections both draw their copy from here, so
|
|
12
|
+
* `failed` has something precise to say exactly when it matters most.
|
|
13
|
+
*
|
|
14
|
+
* A `RouteConfigError` carries `.problems: string[]` — each a message the
|
|
15
|
+
* loader produced. This module classifies each into a SHAPE and attaches the
|
|
16
|
+
* three things a stuck author needs, in order: what it means, what to do, where
|
|
17
|
+
* to read. The completeness test makes every shape carry all three.
|
|
18
|
+
*
|
|
19
|
+
* NOTE what is deliberately NOT here: a `json: native` claim on a model that
|
|
20
|
+
* cannot hold it. The loader ACCEPTS that syntactically — it is a claim about
|
|
21
|
+
* the model, checked against the probed registry, not a config error. It loads
|
|
22
|
+
* and then behaves unlike the code it replaced, which is why the agent prompt
|
|
23
|
+
* (§3.5) states it as a constraint instead.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.CONFIG_TEACHING = void 0;
|
|
27
|
+
exports.classifyConfigProblem = classifyConfigProblem;
|
|
28
|
+
exports.teachConfigError = teachConfigError;
|
|
29
|
+
exports.describeConfigFailure = describeConfigFailure;
|
|
30
|
+
exports.renderConfigErrorForTerminal = renderConfigErrorForTerminal;
|
|
31
|
+
const DOCS_BASE = "https://modelrig.dev/route-bundles.html";
|
|
32
|
+
exports.CONFIG_TEACHING = {
|
|
33
|
+
missing_schema: {
|
|
34
|
+
shape: "missing_schema",
|
|
35
|
+
what: "The bundle's `schema:` names a JSON Schema file, and there is no file at that path relative " +
|
|
36
|
+
"to the bundle. The route can't validate output it can't find the shape for, so it never loads.",
|
|
37
|
+
fixHint: "Create the schema file at the exact path the bundle names (paths resolve relative to the " +
|
|
38
|
+
"bundle's own directory), or set `schema: null` if this task is genuinely free-form.",
|
|
39
|
+
docsUrl: `${DOCS_BASE}#missing_schema`,
|
|
40
|
+
},
|
|
41
|
+
missing_prompt: {
|
|
42
|
+
shape: "missing_prompt",
|
|
43
|
+
what: "The bundle's `prompt.system:` names a template file that isn't at that path. A route with no " +
|
|
44
|
+
"prompt has nothing to send, so it fails at load rather than at the first call.",
|
|
45
|
+
fixHint: "Create the prompt file at the path the bundle names (relative to the bundle), or point " +
|
|
46
|
+
"`prompt.system` at where the file actually is.",
|
|
47
|
+
docsUrl: `${DOCS_BASE}#missing_prompt`,
|
|
48
|
+
},
|
|
49
|
+
undeclared_variable: {
|
|
50
|
+
shape: "undeclared_variable",
|
|
51
|
+
what: "The prompt template references a `{{variable}}` that `prompt.variables` doesn't declare. " +
|
|
52
|
+
"Undeclared references are rejected at load so a typo can't silently ship an empty slot.",
|
|
53
|
+
fixHint: "Add the variable to `prompt.variables`, or fix the reference in the template if it's a typo. " +
|
|
54
|
+
"Every `{{name}}` in the template (and in `grounding.query`) must appear in the declared list.",
|
|
55
|
+
docsUrl: `${DOCS_BASE}#undeclared_variable`,
|
|
56
|
+
},
|
|
57
|
+
unknown_provider: {
|
|
58
|
+
shape: "unknown_provider",
|
|
59
|
+
what: "A candidate names a provider the SDK has no adapter for, so nothing could ever serve that " +
|
|
60
|
+
"candidate.",
|
|
61
|
+
fixHint: "Use a provider the SDK ships an adapter for (gemini, openai, deepseek, anthropic, grok), and " +
|
|
62
|
+
"pick the model from the probed registry rather than from memory.",
|
|
63
|
+
docsUrl: `${DOCS_BASE}#unknown_provider`,
|
|
64
|
+
},
|
|
65
|
+
no_candidates: {
|
|
66
|
+
shape: "no_candidates",
|
|
67
|
+
what: "The route declares no candidates, so it has nothing it is allowed to serve — the candidate " +
|
|
68
|
+
"set is the upper bound, and an empty one bounds it to nothing.",
|
|
69
|
+
fixHint: "List at least one `{provider, model}` under `candidates:`. Every model the route may ever " +
|
|
70
|
+
"use has to be named here; nothing outside this list can serve it.",
|
|
71
|
+
docsUrl: `${DOCS_BASE}#no_candidates`,
|
|
72
|
+
},
|
|
73
|
+
invalid_policy: {
|
|
74
|
+
shape: "invalid_policy",
|
|
75
|
+
what: "A value under `policy` is out of range — a retry count, a timeout, the tier, or the json " +
|
|
76
|
+
"mode — so the route's behaviour would be undefined.",
|
|
77
|
+
fixHint: "Check the policy block against the reference: retries are non-negative integers keyed by a " +
|
|
78
|
+
"retryable failure class, `timeout_ms` is a positive integer, `tier` is standard|flex|priority, " +
|
|
79
|
+
"`json` is native|json_mode.",
|
|
80
|
+
docsUrl: `${DOCS_BASE}#invalid_policy`,
|
|
81
|
+
},
|
|
82
|
+
invalid_cache: {
|
|
83
|
+
shape: "invalid_cache",
|
|
84
|
+
what: "The bundle's `cache:` is set to a value the loader doesn't accept. Request-path caching has " +
|
|
85
|
+
'exactly one setting in v1 — `cache: auto` — which lets the SDK opt each provider into its ' +
|
|
86
|
+
"native prompt cache (and stamp a stable-prefix fingerprint for savings tracking).",
|
|
87
|
+
fixHint: 'Set `cache: auto` to turn on request-path caching for this route, or remove the `cache:` line ' +
|
|
88
|
+
"to leave it off. Gemini candidates need no opt-in — they cache implicitly and are skipped " +
|
|
89
|
+
"automatically even on an `auto` route.",
|
|
90
|
+
docsUrl: `${DOCS_BASE}#invalid_cache`,
|
|
91
|
+
},
|
|
92
|
+
invalid_structure: {
|
|
93
|
+
shape: "invalid_structure",
|
|
94
|
+
what: "The bundle isn't a well-formed route: it's not valid YAML, not a mapping, or missing the " +
|
|
95
|
+
"`route`/`version` a bundle must carry.",
|
|
96
|
+
fixHint: "Open the file and check it parses as YAML and has a non-empty `route:` and an integer " +
|
|
97
|
+
"`version:` at the top level. Copy the starter bundle if in doubt.",
|
|
98
|
+
docsUrl: `${DOCS_BASE}#invalid_structure`,
|
|
99
|
+
},
|
|
100
|
+
duplicate_route: {
|
|
101
|
+
shape: "duplicate_route",
|
|
102
|
+
what: "Two bundles in the routes directory declare the same `route:` name, so which one wins would " +
|
|
103
|
+
"be ambiguous.",
|
|
104
|
+
fixHint: "Give each route a unique name, or delete the duplicate bundle. Route names are the keys your " +
|
|
105
|
+
"code calls by, so they must be one-to-one with files.",
|
|
106
|
+
docsUrl: `${DOCS_BASE}#duplicate_route`,
|
|
107
|
+
},
|
|
108
|
+
unknown_route: {
|
|
109
|
+
shape: "unknown_route",
|
|
110
|
+
what: "Something asked to run a route no bundle defines — usually a name typo, or a bundle that " +
|
|
111
|
+
"isn't in the routes directory the SDK is reading.",
|
|
112
|
+
fixHint: "Check the route name against the bundles present, and confirm MODELRIG_ROUTES_DIR points at " +
|
|
113
|
+
"the directory that holds them.",
|
|
114
|
+
docsUrl: `${DOCS_BASE}#unknown_route`,
|
|
115
|
+
},
|
|
116
|
+
other: {
|
|
117
|
+
shape: "other",
|
|
118
|
+
what: "The route bundle is invalid in a way the loader reported but this table hasn't shaped yet.",
|
|
119
|
+
fixHint: "Read the exact problem the loader printed — it names the field — and check that field against " +
|
|
120
|
+
"the route-bundle reference.",
|
|
121
|
+
docsUrl: `${DOCS_BASE}#route-bundles`,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
/** Map one loader problem string to its shape. Ordered most-specific first. */
|
|
125
|
+
function classifyConfigProblem(problem) {
|
|
126
|
+
const p = problem.toLowerCase();
|
|
127
|
+
if (/schema file not found/.test(p))
|
|
128
|
+
return "missing_schema";
|
|
129
|
+
if (/prompt\.system file not found/.test(p))
|
|
130
|
+
return "missing_prompt";
|
|
131
|
+
if (/references undeclared variable/.test(p))
|
|
132
|
+
return "undeclared_variable";
|
|
133
|
+
if (/is not a known provider/.test(p))
|
|
134
|
+
return "unknown_provider";
|
|
135
|
+
if (/candidates must be a non-empty list|candidates\[.*\] must be/.test(p))
|
|
136
|
+
return "no_candidates";
|
|
137
|
+
if (/^policy|policy\.|policy /.test(p))
|
|
138
|
+
return "invalid_policy";
|
|
139
|
+
if (/^cache .*is not supported/.test(p))
|
|
140
|
+
return "invalid_cache";
|
|
141
|
+
if (/invalid yaml|must be a yaml mapping|^route must be|^version must be/.test(p)) {
|
|
142
|
+
return "invalid_structure";
|
|
143
|
+
}
|
|
144
|
+
if (/duplicate route/.test(p))
|
|
145
|
+
return "duplicate_route";
|
|
146
|
+
if (/unknown route|routes directory not found/.test(p))
|
|
147
|
+
return "unknown_route";
|
|
148
|
+
return "other";
|
|
149
|
+
}
|
|
150
|
+
/** Teach every problem a RouteConfigError carries. */
|
|
151
|
+
function teachConfigError(error) {
|
|
152
|
+
// A bundle-level error (bad YAML, not a mapping) has no `.problems` entries;
|
|
153
|
+
// its own message is the problem.
|
|
154
|
+
const raw = error.problems.length > 0 ? error.problems : [error.message];
|
|
155
|
+
return {
|
|
156
|
+
file: error.file,
|
|
157
|
+
problems: raw.map((problem) => {
|
|
158
|
+
const teaching = exports.CONFIG_TEACHING[classifyConfigProblem(problem)];
|
|
159
|
+
return { ...teaching, problem };
|
|
160
|
+
}),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function describeConfigFailure(error) {
|
|
164
|
+
const taught = teachConfigError(error);
|
|
165
|
+
return {
|
|
166
|
+
lookedFor: error.file
|
|
167
|
+
? `a route bundle that loads at ${error.file}`
|
|
168
|
+
: "a route bundle that loads",
|
|
169
|
+
found: taught.problems.map((p) => p.problem),
|
|
170
|
+
causes: taught.problems.map((p) => p.fixHint),
|
|
171
|
+
docsUrls: [...new Set(taught.problems.map((p) => p.docsUrl))],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/** Terminal-friendly rendering — parity with renderFailureForTerminal. */
|
|
175
|
+
function renderConfigErrorForTerminal(error) {
|
|
176
|
+
const taught = teachConfigError(error);
|
|
177
|
+
const header = error.file ? `Route bundle did not load: ${error.file}` : "Route bundle did not load";
|
|
178
|
+
const lines = [header, ""];
|
|
179
|
+
for (const p of taught.problems) {
|
|
180
|
+
lines.push(`• ${p.problem}`, ` ${p.what}`, ` Fix: ${p.fixHint}`, ` Docs: ${p.docsUrl}`, "");
|
|
181
|
+
}
|
|
182
|
+
return lines.join("\n").trimEnd();
|
|
183
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Errors that teach — Phase 5 WS3.
|
|
3
|
+
*
|
|
4
|
+
* ONE table, not prose scattered across call sites. Every failure class here
|
|
5
|
+
* answers three questions in the order a stuck engineer asks them:
|
|
6
|
+
*
|
|
7
|
+
* 1. what happened? → `what` (plain language, no jargon-first)
|
|
8
|
+
* 2. what do I do about it? → `fixHint` (an action, not a diagnosis)
|
|
9
|
+
* 3. where do I read more? → `docsUrl` (a deep link, not a homepage)
|
|
10
|
+
*
|
|
11
|
+
* And where the fix is MECHANICAL, a fourth: `suggestedChange` — a
|
|
12
|
+
* JSON-patch-shaped hint a coding agent can apply without inventing
|
|
13
|
+
* anything. Only classes whose remedy is genuinely a config edit carry one;
|
|
14
|
+
* inventing a patch for "the model refused" would be worse than silence.
|
|
15
|
+
*
|
|
16
|
+
* The completeness test in failures-teaching.test.ts fails the build if a
|
|
17
|
+
* new FailureClass is added without an entry here, so this table cannot
|
|
18
|
+
* silently fall behind the taxonomy.
|
|
19
|
+
*/
|
|
20
|
+
import type { FailureClass, RigFailure } from "./failures";
|
|
21
|
+
/** A JSON-Patch-shaped edit (RFC 6902 subset) against the route bundle. */
|
|
22
|
+
export interface SuggestedChange {
|
|
23
|
+
readonly op: "add" | "replace" | "remove";
|
|
24
|
+
/** JSON Pointer into the route bundle YAML, e.g. "/policy/retries/network". */
|
|
25
|
+
readonly path: string;
|
|
26
|
+
readonly value?: unknown;
|
|
27
|
+
/** Why this edit is the right one — shown beside the diff. */
|
|
28
|
+
readonly because: string;
|
|
29
|
+
}
|
|
30
|
+
export interface FailureTeaching {
|
|
31
|
+
readonly class: FailureClass;
|
|
32
|
+
/** One sentence: what this class MEANS, in the reader's terms. */
|
|
33
|
+
readonly what: string;
|
|
34
|
+
/** The default action to take. Overridden by a failure's own fixHint when
|
|
35
|
+
* the site knows something more specific (a provider name, a model). */
|
|
36
|
+
readonly fixHint: string;
|
|
37
|
+
readonly docsUrl: string;
|
|
38
|
+
/** Build a mechanical edit for this failure, when one exists. */
|
|
39
|
+
readonly suggestedChange?: (failure: RigFailure) => SuggestedChange | null;
|
|
40
|
+
}
|
|
41
|
+
export declare const FAILURE_TEACHING: Readonly<Record<FailureClass, FailureTeaching>>;
|
|
42
|
+
/** The rendered teaching for one failure: the site's own fixHint wins when
|
|
43
|
+
* it has one (it knows the provider and model), the table fills the rest. */
|
|
44
|
+
export interface TeachableFailure {
|
|
45
|
+
readonly class: FailureClass;
|
|
46
|
+
readonly message: string;
|
|
47
|
+
readonly what: string;
|
|
48
|
+
readonly fixHint: string;
|
|
49
|
+
readonly docsUrl: string;
|
|
50
|
+
readonly suggestedChange: SuggestedChange | null;
|
|
51
|
+
}
|
|
52
|
+
export declare function teach(failure: RigFailure): TeachableFailure;
|
|
53
|
+
/** Terminal-friendly rendering — used by the CLI. Kept here so the CLI and
|
|
54
|
+
* the server cannot drift into two different-looking errors. */
|
|
55
|
+
export declare function renderFailureForTerminal(failure: RigFailure): string;
|
|
56
|
+
//# sourceMappingURL=failures-teaching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failures-teaching.d.ts","sourceRoot":"","sources":["../../src/types/failures-teaching.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE3D,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1C,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;4EACwE;IACxE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,eAAe,GAAG,IAAI,CAAC;CAC5E;AAID,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,CA+I5E,CAAC;AAiBF;6EAC6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;CAClD;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,UAAU,GAAG,gBAAgB,CAU3D;AAED;gEACgE;AAChE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAapE"}
|