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,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt-stability lint — cache-aware-routing WS-C step 4 (spec §5.3,
|
|
3
|
+
* [Briefing §10]). A prefix cache only pays off when the CACHED PREFIX is
|
|
4
|
+
* stable across calls. A route template that interpolates a volatile value
|
|
5
|
+
* (a timestamp, a run id, a random nonce) high in the prompt shifts the prefix
|
|
6
|
+
* on every call, so the provider caches something that never recurs — the route
|
|
7
|
+
* pays the write premium forever and never reads a hit ("paying full price and
|
|
8
|
+
* don't know it", the §5.6 smell, caught statically here instead of after the money).
|
|
9
|
+
*
|
|
10
|
+
* v1 is a pure, conservative NAME heuristic over the declared `{{variable}}`
|
|
11
|
+
* references (the run-loop's stable prefix IS the route template — spec §5.3).
|
|
12
|
+
* It flags variables whose NAME reads volatile AND that appear before the
|
|
13
|
+
* template's stable tail. It does NOT inspect rendered values (it can't — the
|
|
14
|
+
* lint runs at load, before any input) and it never fails the load: a false
|
|
15
|
+
* positive must not block a legitimate route, so this warns. The prompt compiler
|
|
16
|
+
* + Prefix Stability Score (real per-token volatility telemetry) is the deferred
|
|
17
|
+
* successor ([Briefing Phase 5]); this is the cheap static precursor.
|
|
18
|
+
*/
|
|
19
|
+
export interface CacheLintWarning {
|
|
20
|
+
/** The offending variable name. */
|
|
21
|
+
readonly variable: string;
|
|
22
|
+
/** Character offset of the reference in the raw template. */
|
|
23
|
+
readonly index: number;
|
|
24
|
+
/** Human-readable, teach-not-scold message. */
|
|
25
|
+
readonly message: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Lint a route's raw system template for cache-hostile volatile interpolations.
|
|
29
|
+
* Pure and total. Returns one warning per volatile-named reference that sits
|
|
30
|
+
* before the stable tail; `[]` for a clean template.
|
|
31
|
+
*
|
|
32
|
+
* "Before the stable tail" (v1 approximation): a volatile reference in the first
|
|
33
|
+
* `headFraction` of the template shifts the cacheable prefix; one at the very
|
|
34
|
+
* end (after the bulk of the stable instructions) shifts only the tail and is
|
|
35
|
+
* harmless for prefix caching. We warn only on head references to keep the
|
|
36
|
+
* signal high — a `{{now}}` in a trailing "as of {{now}}" line is fine.
|
|
37
|
+
*/
|
|
38
|
+
export declare function lintCacheTemplate(template: string, opts?: {
|
|
39
|
+
readonly headFraction?: number;
|
|
40
|
+
}): CacheLintWarning[];
|
|
41
|
+
//# sourceMappingURL=cache-lint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-lint.d.ts","sourceRoot":"","sources":["../../src/routes/cache-lint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAmCH,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,gBAAgB,EAAE,CAmBpB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Prompt-stability lint — cache-aware-routing WS-C step 4 (spec §5.3,
|
|
4
|
+
* [Briefing §10]). A prefix cache only pays off when the CACHED PREFIX is
|
|
5
|
+
* stable across calls. A route template that interpolates a volatile value
|
|
6
|
+
* (a timestamp, a run id, a random nonce) high in the prompt shifts the prefix
|
|
7
|
+
* on every call, so the provider caches something that never recurs — the route
|
|
8
|
+
* pays the write premium forever and never reads a hit ("paying full price and
|
|
9
|
+
* don't know it", the §5.6 smell, caught statically here instead of after the money).
|
|
10
|
+
*
|
|
11
|
+
* v1 is a pure, conservative NAME heuristic over the declared `{{variable}}`
|
|
12
|
+
* references (the run-loop's stable prefix IS the route template — spec §5.3).
|
|
13
|
+
* It flags variables whose NAME reads volatile AND that appear before the
|
|
14
|
+
* template's stable tail. It does NOT inspect rendered values (it can't — the
|
|
15
|
+
* lint runs at load, before any input) and it never fails the load: a false
|
|
16
|
+
* positive must not block a legitimate route, so this warns. The prompt compiler
|
|
17
|
+
* + Prefix Stability Score (real per-token volatility telemetry) is the deferred
|
|
18
|
+
* successor ([Briefing Phase 5]); this is the cheap static precursor.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.lintCacheTemplate = lintCacheTemplate;
|
|
22
|
+
/** Variable names that read as per-call-volatile. Deliberately broad on the
|
|
23
|
+
* volatile side (a warning is cheap; a silently un-cached route is not) but
|
|
24
|
+
* anchored to whole \b tokens so `updated_at_note` matches yet `runtime` does
|
|
25
|
+
* not falsely trip on "run". */
|
|
26
|
+
const VOLATILE_NAME = new RegExp([
|
|
27
|
+
"\\btime(stamp)?\\b",
|
|
28
|
+
"\\bnow\\b",
|
|
29
|
+
"\\bdate(time)?\\b",
|
|
30
|
+
"run[_-]?id",
|
|
31
|
+
"request[_-]?id",
|
|
32
|
+
"trace[_-]?id",
|
|
33
|
+
"session[_-]?id",
|
|
34
|
+
"correlation[_-]?id",
|
|
35
|
+
"\\buuid\\b",
|
|
36
|
+
"\\bguid\\b",
|
|
37
|
+
"\\bnonce\\b",
|
|
38
|
+
"\\brandom\\b",
|
|
39
|
+
"\\brand\\b",
|
|
40
|
+
"\\bepoch\\b",
|
|
41
|
+
"\\bcurrent[_-]",
|
|
42
|
+
"generated[_-]?at",
|
|
43
|
+
"created[_-]?at",
|
|
44
|
+
"updated[_-]?at",
|
|
45
|
+
].join("|"), "i");
|
|
46
|
+
/** The `{{var}}` scanner from template.ts, duplicated as a global-match here so
|
|
47
|
+
* the lint can read each reference's POSITION (scanTemplateVariables dedupes to
|
|
48
|
+
* names only). Kept in sync with template.ts's VAR_TAG. */
|
|
49
|
+
const VAR_TAG = /\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
|
|
50
|
+
/**
|
|
51
|
+
* Lint a route's raw system template for cache-hostile volatile interpolations.
|
|
52
|
+
* Pure and total. Returns one warning per volatile-named reference that sits
|
|
53
|
+
* before the stable tail; `[]` for a clean template.
|
|
54
|
+
*
|
|
55
|
+
* "Before the stable tail" (v1 approximation): a volatile reference in the first
|
|
56
|
+
* `headFraction` of the template shifts the cacheable prefix; one at the very
|
|
57
|
+
* end (after the bulk of the stable instructions) shifts only the tail and is
|
|
58
|
+
* harmless for prefix caching. We warn only on head references to keep the
|
|
59
|
+
* signal high — a `{{now}}` in a trailing "as of {{now}}" line is fine.
|
|
60
|
+
*/
|
|
61
|
+
function lintCacheTemplate(template, opts = {}) {
|
|
62
|
+
const headFraction = opts.headFraction ?? 0.75;
|
|
63
|
+
const headCutoff = Math.floor(template.length * headFraction);
|
|
64
|
+
const warnings = [];
|
|
65
|
+
for (const m of template.matchAll(VAR_TAG)) {
|
|
66
|
+
const name = m[1];
|
|
67
|
+
const index = m.index;
|
|
68
|
+
if (index >= headCutoff)
|
|
69
|
+
continue; // in the stable tail — harmless
|
|
70
|
+
if (!VOLATILE_NAME.test(name))
|
|
71
|
+
continue;
|
|
72
|
+
warnings.push({
|
|
73
|
+
variable: name,
|
|
74
|
+
index,
|
|
75
|
+
message: `route template interpolates \`{{${name}}}\` before the stable prompt tail — a per-call ` +
|
|
76
|
+
`value here shifts the cacheable prefix and defeats prompt caching (the route would pay ` +
|
|
77
|
+
`full price every call). Move volatile values to the end of the prompt, or drop them.`,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return warnings;
|
|
81
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route-bundle drafting — the shared emitter behind BOTH `modelrig init`
|
|
3
|
+
* (WS2) and the oracle's `create_route` act tool (WS1).
|
|
4
|
+
*
|
|
5
|
+
* A route bundle is three files, not one: the YAML, its JSON Schema, and its
|
|
6
|
+
* system prompt. A "draft" that emitted only the YAML would not load, so
|
|
7
|
+
* this builds the whole set.
|
|
8
|
+
*
|
|
9
|
+
* PURE: it returns file contents and writes nothing. Every caller that
|
|
10
|
+
* touches the disk does so through `writeRouteDraft`, which refuses to
|
|
11
|
+
* overwrite — drafts are proposals for a human to read, never edits.
|
|
12
|
+
*
|
|
13
|
+
* The YAML is hand-emitted rather than serialized by the `yaml` package on
|
|
14
|
+
* purpose: drafts are read by humans first, and the comments explaining WHERE
|
|
15
|
+
* each candidate came from are the most valuable lines in the file.
|
|
16
|
+
*/
|
|
17
|
+
export interface DraftCandidate {
|
|
18
|
+
readonly provider: string;
|
|
19
|
+
readonly model: string;
|
|
20
|
+
/** Why this candidate is here — rendered as a trailing comment. */
|
|
21
|
+
readonly note?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface RouteDraftSpec {
|
|
24
|
+
/** Route handle, e.g. "research.growth_scenarios". */
|
|
25
|
+
readonly route: string;
|
|
26
|
+
readonly candidates: readonly DraftCandidate[];
|
|
27
|
+
/** Incumbent first is the caller's job; this records which one it was so
|
|
28
|
+
* the draft can say so out loud. */
|
|
29
|
+
readonly incumbent?: {
|
|
30
|
+
readonly provider: string;
|
|
31
|
+
readonly model: string;
|
|
32
|
+
} | null;
|
|
33
|
+
readonly systemPrompt: string;
|
|
34
|
+
readonly variables: readonly string[];
|
|
35
|
+
/** JSON Schema for the output; null drafts an unstructured route. */
|
|
36
|
+
readonly outputSchema: object | null;
|
|
37
|
+
readonly require?: readonly string[];
|
|
38
|
+
readonly prefer?: readonly string[];
|
|
39
|
+
readonly policy?: {
|
|
40
|
+
readonly timeoutMs?: number;
|
|
41
|
+
readonly tier?: string;
|
|
42
|
+
readonly json?: string;
|
|
43
|
+
readonly retries?: Readonly<Record<string, number>>;
|
|
44
|
+
};
|
|
45
|
+
readonly capture?: boolean;
|
|
46
|
+
/** Provenance lines rendered as a header comment — "found at src/x.ts:42".
|
|
47
|
+
* SD8: customer-zero provenance is labeled, never hardcoded behavior. */
|
|
48
|
+
readonly provenance?: readonly string[];
|
|
49
|
+
}
|
|
50
|
+
export interface DraftFile {
|
|
51
|
+
/** Path relative to the drafts directory. */
|
|
52
|
+
readonly path: string;
|
|
53
|
+
readonly contents: string;
|
|
54
|
+
}
|
|
55
|
+
export interface RouteDraft {
|
|
56
|
+
readonly route: string;
|
|
57
|
+
readonly files: readonly DraftFile[];
|
|
58
|
+
}
|
|
59
|
+
export declare function buildRouteDraft(spec: RouteDraftSpec): RouteDraft;
|
|
60
|
+
export interface WriteDraftResult {
|
|
61
|
+
readonly written: readonly string[];
|
|
62
|
+
/** Files that already existed and were left alone. */
|
|
63
|
+
readonly skipped: readonly string[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Write a draft into `draftsDir`. Two rules, both deliberate:
|
|
67
|
+
* - It writes ONLY under the drafts directory. Nothing here can touch the
|
|
68
|
+
* caller's source, their live routes, or the control plane (spec §4:
|
|
69
|
+
* drafts-only is permanent this phase).
|
|
70
|
+
* - It never overwrites. A second run reports what it skipped instead of
|
|
71
|
+
* silently discarding edits a human made to a draft.
|
|
72
|
+
*/
|
|
73
|
+
export declare function writeRouteDraft(draft: RouteDraft, draftsDir: string, fs: {
|
|
74
|
+
existsSync: (p: string) => boolean;
|
|
75
|
+
mkdirSync: (p: string, o: {
|
|
76
|
+
recursive: boolean;
|
|
77
|
+
}) => void;
|
|
78
|
+
writeFileSync: (p: string, c: string, e: "utf8") => void;
|
|
79
|
+
}, path: {
|
|
80
|
+
join: (...parts: string[]) => string;
|
|
81
|
+
dirname: (p: string) => string;
|
|
82
|
+
}): WriteDraftResult;
|
|
83
|
+
//# sourceMappingURL=draft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../src/routes/draft.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C;wCACoC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,qEAAqE;IACrE,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;KACrD,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;6EACyE;IACzE,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,SAAS;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;CACtC;AAmBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAgGhE;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE;IACF,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1D,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D,EACD,IAAI,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAAE,GAC7E,gBAAgB,CAclB"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Route-bundle drafting — the shared emitter behind BOTH `modelrig init`
|
|
4
|
+
* (WS2) and the oracle's `create_route` act tool (WS1).
|
|
5
|
+
*
|
|
6
|
+
* A route bundle is three files, not one: the YAML, its JSON Schema, and its
|
|
7
|
+
* system prompt. A "draft" that emitted only the YAML would not load, so
|
|
8
|
+
* this builds the whole set.
|
|
9
|
+
*
|
|
10
|
+
* PURE: it returns file contents and writes nothing. Every caller that
|
|
11
|
+
* touches the disk does so through `writeRouteDraft`, which refuses to
|
|
12
|
+
* overwrite — drafts are proposals for a human to read, never edits.
|
|
13
|
+
*
|
|
14
|
+
* The YAML is hand-emitted rather than serialized by the `yaml` package on
|
|
15
|
+
* purpose: drafts are read by humans first, and the comments explaining WHERE
|
|
16
|
+
* each candidate came from are the most valuable lines in the file.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.buildRouteDraft = buildRouteDraft;
|
|
20
|
+
exports.writeRouteDraft = writeRouteDraft;
|
|
21
|
+
/** YAML string quoting: quote unless the value is unambiguously a plain
|
|
22
|
+
* scalar. Model ids carry dots, colons and dashes — the cases that bite. */
|
|
23
|
+
function yamlString(value) {
|
|
24
|
+
if (/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(value))
|
|
25
|
+
return value;
|
|
26
|
+
return JSON.stringify(value);
|
|
27
|
+
}
|
|
28
|
+
function slug(route) {
|
|
29
|
+
return route.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
30
|
+
}
|
|
31
|
+
const DEFAULT_RETRIES = {
|
|
32
|
+
content_invalid: 2,
|
|
33
|
+
network: 4,
|
|
34
|
+
capacity_shed: 3,
|
|
35
|
+
};
|
|
36
|
+
function buildRouteDraft(spec) {
|
|
37
|
+
if (spec.route.trim() === "")
|
|
38
|
+
throw new Error("a route draft needs a route name");
|
|
39
|
+
if (spec.candidates.length === 0) {
|
|
40
|
+
throw new Error(`route draft "${spec.route}" has no candidates — a route with nothing allowed to serve it ` +
|
|
41
|
+
"cannot run. Name at least one provider/model.");
|
|
42
|
+
}
|
|
43
|
+
const name = slug(spec.route);
|
|
44
|
+
const files = [];
|
|
45
|
+
const schemaRef = spec.outputSchema === null ? null : `./schemas/${name}.schema.json`;
|
|
46
|
+
const promptRef = `./prompts/${name}.system.md`;
|
|
47
|
+
const lines = [
|
|
48
|
+
"# ModelRig route bundle — DRAFT. Nothing in your app calls this yet.",
|
|
49
|
+
"# Read it, edit it, move it up one directory into modelrig/routes/, then",
|
|
50
|
+
"# switch the call site to rig.run(\"" + spec.route + "\", …).",
|
|
51
|
+
];
|
|
52
|
+
if (spec.provenance !== undefined && spec.provenance.length > 0) {
|
|
53
|
+
lines.push("#");
|
|
54
|
+
for (const line of spec.provenance)
|
|
55
|
+
lines.push(`# ${line}`);
|
|
56
|
+
}
|
|
57
|
+
lines.push("#", "# Candidates are ordered incumbent-first: the model you already use leads,", "# so the first run reproduces today's behavior. The cheaper probed", "# alternatives below it are what a bake-off would put to the test.", "#", "# `prefer` is empty ON PURPOSE. Adding `cost` re-sorts these candidates by", "# price, which would hand the first run to the cheapest model rather than", "# to your incumbent — the opposite of a like-for-like migration. Prove a", "# cheaper model with a bake-off, then switch to it deliberately.", `route: ${yamlString(spec.route)}`, "version: 1");
|
|
58
|
+
if (schemaRef !== null)
|
|
59
|
+
lines.push(`schema: ${schemaRef}`);
|
|
60
|
+
lines.push("candidates:");
|
|
61
|
+
for (const candidate of spec.candidates) {
|
|
62
|
+
lines.push(` - provider: ${yamlString(candidate.provider)}`);
|
|
63
|
+
lines.push(` model: ${yamlString(candidate.model)}` +
|
|
64
|
+
(candidate.note !== undefined ? ` # ${candidate.note}` : ""));
|
|
65
|
+
}
|
|
66
|
+
const require = spec.require ?? (spec.outputSchema === null ? [] : ["schema_conformant"]);
|
|
67
|
+
if (require.length > 0) {
|
|
68
|
+
lines.push("require:");
|
|
69
|
+
for (const r of require)
|
|
70
|
+
lines.push(` - ${yamlString(r)}`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
lines.push("require: []");
|
|
74
|
+
}
|
|
75
|
+
// Default EMPTY, not [cost]: `prefer: [cost]` re-sorts candidates by price
|
|
76
|
+
// at resolve time, so the incumbent-first ordering above would be silently
|
|
77
|
+
// overridden and the first run would NOT reproduce today's behavior.
|
|
78
|
+
lines.push(`prefer: [${(spec.prefer ?? []).map(yamlString).join(", ")}]`);
|
|
79
|
+
lines.push("prompt:");
|
|
80
|
+
lines.push(` system: ${promptRef}`);
|
|
81
|
+
lines.push(` variables: [${spec.variables.map(yamlString).join(", ")}]` +
|
|
82
|
+
(spec.variables.length === 0 ? " # no {{variables}} detected — the prompt is static" : ""));
|
|
83
|
+
const policy = spec.policy ?? {};
|
|
84
|
+
const retries = policy.retries ?? DEFAULT_RETRIES;
|
|
85
|
+
lines.push("policy:");
|
|
86
|
+
lines.push(` retries: { ${Object.entries(retries)
|
|
87
|
+
.map(([k, v]) => `${k}: ${v}`)
|
|
88
|
+
.join(", ")} }`);
|
|
89
|
+
lines.push(` timeout_ms: ${policy.timeoutMs ?? 120000}`);
|
|
90
|
+
lines.push(` tier: ${yamlString(policy.tier ?? "standard")}`);
|
|
91
|
+
// json only means something for a schema'd route; the loader defaults it,
|
|
92
|
+
// so an unstructured draft says nothing rather than saying something wrong.
|
|
93
|
+
if (spec.outputSchema !== null || policy.json !== undefined) {
|
|
94
|
+
lines.push(` json: ${yamlString(policy.json ?? "native")}`);
|
|
95
|
+
}
|
|
96
|
+
if (spec.capture === true) {
|
|
97
|
+
lines.push("# capture: replay inputs are stored LOCALLY only — never exported.");
|
|
98
|
+
lines.push("capture: true");
|
|
99
|
+
}
|
|
100
|
+
files.push({ path: `${name}.yaml`, contents: `${lines.join("\n")}\n` });
|
|
101
|
+
if (spec.outputSchema !== null) {
|
|
102
|
+
files.push({
|
|
103
|
+
path: `schemas/${name}.schema.json`,
|
|
104
|
+
contents: `${JSON.stringify(spec.outputSchema, null, 2)}\n`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
files.push({ path: `prompts/${name}.system.md`, contents: ensureTrailingNewline(spec.systemPrompt) });
|
|
108
|
+
return { route: spec.route, files };
|
|
109
|
+
}
|
|
110
|
+
function ensureTrailingNewline(text) {
|
|
111
|
+
return text.endsWith("\n") ? text : `${text}\n`;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Write a draft into `draftsDir`. Two rules, both deliberate:
|
|
115
|
+
* - It writes ONLY under the drafts directory. Nothing here can touch the
|
|
116
|
+
* caller's source, their live routes, or the control plane (spec §4:
|
|
117
|
+
* drafts-only is permanent this phase).
|
|
118
|
+
* - It never overwrites. A second run reports what it skipped instead of
|
|
119
|
+
* silently discarding edits a human made to a draft.
|
|
120
|
+
*/
|
|
121
|
+
function writeRouteDraft(draft, draftsDir, fs, path) {
|
|
122
|
+
const written = [];
|
|
123
|
+
const skipped = [];
|
|
124
|
+
for (const file of draft.files) {
|
|
125
|
+
const full = path.join(draftsDir, file.path);
|
|
126
|
+
if (fs.existsSync(full)) {
|
|
127
|
+
skipped.push(full);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
fs.mkdirSync(path.dirname(full), { recursive: true });
|
|
131
|
+
fs.writeFileSync(full, file.contents, "utf8");
|
|
132
|
+
written.push(full);
|
|
133
|
+
}
|
|
134
|
+
return { written, skipped };
|
|
135
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routes-as-code loader — spec §3, plan step 3.
|
|
3
|
+
* Scans a routes directory for *.yaml bundles, validates structurally,
|
|
4
|
+
* resolves schema/prompt paths relative to the bundle file, freezes.
|
|
5
|
+
*/
|
|
6
|
+
import type { RouteBundle } from "../types/route";
|
|
7
|
+
/**
|
|
8
|
+
* Structured config error thrown for any invalid bundle (never a raw Error).
|
|
9
|
+
* Load-time problems are deliberately NOT RigFailures — the failure taxonomy
|
|
10
|
+
* classifies inference attempts; a malformed bundle means the rig was never
|
|
11
|
+
* runnable for that route.
|
|
12
|
+
*/
|
|
13
|
+
export declare class RouteConfigError extends Error {
|
|
14
|
+
readonly file: string | null;
|
|
15
|
+
readonly problems: readonly string[];
|
|
16
|
+
constructor(message: string, opts?: {
|
|
17
|
+
file?: string;
|
|
18
|
+
problems?: readonly string[];
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export interface LoadedRoutes {
|
|
22
|
+
get(route: string): RouteBundle;
|
|
23
|
+
list(): readonly RouteBundle[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Merge two loaded route sets into one store — a UNION, collision is a loud
|
|
27
|
+
* error. Used to fold a deployment's bundled INTERNAL infra routes (e.g. the
|
|
28
|
+
* server's run-judge@v1 / analyst-summarize@v1) into the operator's configured
|
|
29
|
+
* routes without replacing them (index.ts createRig, extraRoutesDir). The
|
|
30
|
+
* reserved `@v<n>` infra namespace never collides with customer/demo routes;
|
|
31
|
+
* if it ever did, failing at boot is correct.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Load a routes directory and OPTIONALLY union a second (deployment-bundled
|
|
35
|
+
* infra) directory into it — the one call createRig makes so the extra-routes
|
|
36
|
+
* merge does not grow index.ts. `extraDir` absent/empty ⇒ exactly loadRoutes.
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadRoutesWithExtra(routesDir: string, extraDir?: string): LoadedRoutes;
|
|
39
|
+
export declare function mergeLoadedRoutes(primary: LoadedRoutes, extra: LoadedRoutes): LoadedRoutes;
|
|
40
|
+
/** One route file's structural-validation outcome (CE-6, spec §1 / walkthrough
|
|
41
|
+
* §8.7a). `route` is the parsed handle, or null when the bundle failed before a
|
|
42
|
+
* name could be read. */
|
|
43
|
+
export interface RouteValidation {
|
|
44
|
+
readonly file: string;
|
|
45
|
+
readonly route: string | null;
|
|
46
|
+
readonly ok: boolean;
|
|
47
|
+
readonly problems: readonly string[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Structurally validate every route bundle in a directory WITHOUT requiring any
|
|
51
|
+
* provider key (CE-6 `modelrig validate`). Unlike {@link loadRoutes}, one bad
|
|
52
|
+
* bundle does NOT abort the rest — each file is loaded independently and its
|
|
53
|
+
* outcome collected, so a newbie sees every problem in one pass. Duplicate route
|
|
54
|
+
* handles across files are reported per the later file. This deliberately does
|
|
55
|
+
* NOT run the serveable-candidate gate (serveability.ts) — that needs keys and
|
|
56
|
+
* stays fail-closed for SERVING; validation only checks authoring.
|
|
57
|
+
*
|
|
58
|
+
* A missing directory is still a hard error (nothing to validate) — it throws
|
|
59
|
+
* the same teaching RouteConfigError as loadRoutes.
|
|
60
|
+
*/
|
|
61
|
+
export declare function validateRoutesDir(routesDir: string): RouteValidation[];
|
|
62
|
+
export declare function loadRoutes(routesDir: string): LoadedRoutes;
|
|
63
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/routes/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAKV,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AAMxB;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;gBAEzB,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAO;CAOxF;AAiCD,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAChC,IAAI,IAAI,SAAS,WAAW,EAAE,CAAC;CAChC;AAqZD;;;;;;;GAOG;AACH;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,CAItF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,YAAY,CAyB1F;AAED;;yBAEyB;AACzB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE,CA6CtE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CA2C1D"}
|