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,363 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The telemetry wire contract — Phase 6 WS2.
|
|
4
|
+
*
|
|
5
|
+
* ONE definition of what a batch of telemetry looks like, and ONE function
|
|
6
|
+
* that turns a batch plus a tenant into the exact database writes it becomes.
|
|
7
|
+
* Both transports use them:
|
|
8
|
+
*
|
|
9
|
+
* direct mode exporter → stampBatch(batch, ownTenancy) → PostgREST
|
|
10
|
+
* api mode exporter → POST /v1/ingest → server → stampBatch(batch, keyTenancy) → PostgREST
|
|
11
|
+
*
|
|
12
|
+
* telemetry-ingestion-boundary.md §4 requires that "the SDK must treat api
|
|
13
|
+
* mode and direct mode identically … one exporter interface, two transports —
|
|
14
|
+
* enforced by a shared conformance test". This module is what makes that
|
|
15
|
+
* enforceable rather than aspirational: the conformance test does not compare
|
|
16
|
+
* two hand-written mappers for similarity, it asserts that both paths run the
|
|
17
|
+
* SAME mapper. A drift bug has nowhere to live.
|
|
18
|
+
*
|
|
19
|
+
* ── WHY THE WIRE ROWS DO NOT CARRY A TENANT ──────────────────────────────
|
|
20
|
+
* T3: tenancy is derived from the principal, never trusted from the caller. A
|
|
21
|
+
* client that could put `org_id` on a row could put someone else's `org_id` on
|
|
22
|
+
* a row. So the wire carries the telemetry and nothing else, and the tenant is
|
|
23
|
+
* stamped by whoever holds the principal — the exporter's config in direct
|
|
24
|
+
* mode, the resolved key in api mode.
|
|
25
|
+
*
|
|
26
|
+
* The single exception is `feedback.org_id`, and it is the reason WS2 exists.
|
|
27
|
+
* A verdict recorded on OUR hosted server belongs to the org of the person who
|
|
28
|
+
* recorded it, not to the org the server runs as, and one SQLite store holds
|
|
29
|
+
* verdicts for many orgs. So a feedback row may name its own org — and the
|
|
30
|
+
* ingest endpoint VERIFIES that name against the key rather than trusting it
|
|
31
|
+
* (see `foreignOrgFeedback`). A service-role exporter needs no such check: it
|
|
32
|
+
* already holds a credential that can write any row in the database.
|
|
33
|
+
*/
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.DEFAULT_INGEST_URL = exports.INGEST_PROTOCOL_VERSION_V1 = exports.INGEST_PROTOCOL_VERSION = exports.INGEST_PATH = void 0;
|
|
36
|
+
exports.stampBatch = stampBatch;
|
|
37
|
+
exports.foreignOrgFeedback = foreignOrgFeedback;
|
|
38
|
+
const fingerprint_1 = require("../registry/fingerprint");
|
|
39
|
+
/** The path the api sink posts to. Spelled once. */
|
|
40
|
+
exports.INGEST_PATH = "/v1/ingest";
|
|
41
|
+
/** The CURRENT protocol version — the maximum the SDK can speak (ruling d).
|
|
42
|
+
* v2 = v1 + the optional runs/steps/artifacts sections. A server that does not
|
|
43
|
+
* recognise the version refuses the batch rather than guessing; the SDK sends
|
|
44
|
+
* v2 ONLY when the artifact namespace is active (spec §1.3), otherwise it keeps
|
|
45
|
+
* sending v1 batches byte-identical to before v2 existed. */
|
|
46
|
+
exports.INGEST_PROTOCOL_VERSION = 2;
|
|
47
|
+
/** The v1 baseline — batches carrying only the pre-artifact sections announce
|
|
48
|
+
* this and remain valid forever. The exporter uses it when artifacts are
|
|
49
|
+
* disabled (byte-identical to today) and for the pre-loop load-error batch. */
|
|
50
|
+
exports.INGEST_PROTOCOL_VERSION_V1 = 1;
|
|
51
|
+
/** Default ingest host — telemetry-ingestion-boundary.md §2.1. */
|
|
52
|
+
exports.DEFAULT_INGEST_URL = "https://api.modelrig.ai";
|
|
53
|
+
/**
|
|
54
|
+
* Turn a batch plus a tenant into the writes it becomes.
|
|
55
|
+
*
|
|
56
|
+
* THE conformance seam. Both transports call this; nothing else builds a
|
|
57
|
+
* telemetry row. If you are about to add a table to the export, add it here
|
|
58
|
+
* and both modes gain it at once — which is the point.
|
|
59
|
+
*/
|
|
60
|
+
function stampBatch(batch, tenancy) {
|
|
61
|
+
const writes = [];
|
|
62
|
+
const now = new Date().toISOString();
|
|
63
|
+
if (batch.routes !== undefined && batch.routes.length > 0) {
|
|
64
|
+
// Derive task identities BEFORE the routes write (spec §4, ruling a): a
|
|
65
|
+
// route implies a task. This is the derivation, not FK surgery — `routes`
|
|
66
|
+
// is untouched; the identity is a projection kept current by the same sync.
|
|
67
|
+
const seenTasks = new Set();
|
|
68
|
+
const taskRows = [];
|
|
69
|
+
for (const r of batch.routes) {
|
|
70
|
+
// Dedup by route NAME: a batch may carry several versions of one route,
|
|
71
|
+
// but they share a single task identity ((org_id, task) PK).
|
|
72
|
+
if (seenTasks.has(r.route))
|
|
73
|
+
continue;
|
|
74
|
+
seenTasks.add(r.route);
|
|
75
|
+
// Built field-by-field from the PRINCIPAL's tenancy, never spread from
|
|
76
|
+
// wire input — a client-supplied org_id must not ride in (ingest.ts:170
|
|
77
|
+
// doctrine, T3).
|
|
78
|
+
const taskRow = {
|
|
79
|
+
org_id: tenancy.org_id,
|
|
80
|
+
task: r.route,
|
|
81
|
+
source: "route-sync",
|
|
82
|
+
};
|
|
83
|
+
// spread-iff-bundle-present (the 00027 pattern): a metadata-only sync
|
|
84
|
+
// (no bundle) must NOT null-out an existing schema/fingerprint — a merge
|
|
85
|
+
// upsert touches only the columns present in the row. The fingerprint is
|
|
86
|
+
// computed server-side from the inlined schema with the SAME pure
|
|
87
|
+
// function the loader uses (fingerprintSchema); the parity golden locks
|
|
88
|
+
// the two call sites to identical output.
|
|
89
|
+
if (r.bundle !== undefined) {
|
|
90
|
+
taskRow.declared_schema = r.bundle.outputSchema ?? null;
|
|
91
|
+
taskRow.fingerprint_cell = (0, fingerprint_1.fingerprintSchema)(r.bundle.outputSchema)?.cellKey ?? null;
|
|
92
|
+
taskRow.updated_at = now;
|
|
93
|
+
}
|
|
94
|
+
taskRows.push(taskRow);
|
|
95
|
+
}
|
|
96
|
+
writes.push({
|
|
97
|
+
// merge=true: a task row is a mutable projection of the latest sync, like
|
|
98
|
+
// the routes mirror, unlike inferences. onConflict on the PK (S5).
|
|
99
|
+
table: "tasks",
|
|
100
|
+
onConflict: "org_id,task",
|
|
101
|
+
merge: true,
|
|
102
|
+
rows: taskRows,
|
|
103
|
+
});
|
|
104
|
+
writes.push({
|
|
105
|
+
table: "routes",
|
|
106
|
+
onConflict: "org_id,route,version",
|
|
107
|
+
merge: true,
|
|
108
|
+
rows: batch.routes.map((r) => ({
|
|
109
|
+
org_id: tenancy.org_id,
|
|
110
|
+
route: r.route,
|
|
111
|
+
version: r.version,
|
|
112
|
+
candidates: r.candidates,
|
|
113
|
+
capture: r.capture,
|
|
114
|
+
updated_at: now,
|
|
115
|
+
// Phase D (spec §13): the resolved bundle + its hash + the sync stamp.
|
|
116
|
+
// Written only when the batch carries a bundle, so an older SDK's
|
|
117
|
+
// metadata-only mirror leaves any existing bundle intact (a merge
|
|
118
|
+
// upsert touches only the columns present in the row). `synced_at` is
|
|
119
|
+
// the BUNDLE's timestamp — stamped iff a bundle synced — distinct from
|
|
120
|
+
// `updated_at`, the row's metadata timestamp.
|
|
121
|
+
...(r.bundle !== undefined
|
|
122
|
+
? { bundle: r.bundle, bundle_sha: r.bundle_sha ?? null, synced_at: now }
|
|
123
|
+
: {}),
|
|
124
|
+
})),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (batch.runs !== undefined && batch.runs.length > 0) {
|
|
128
|
+
writes.push({
|
|
129
|
+
// runs are a mutable projection (start → end): merge=true on the PK (S5).
|
|
130
|
+
table: "runs",
|
|
131
|
+
onConflict: "org_id,id",
|
|
132
|
+
merge: true,
|
|
133
|
+
rows: batch.runs.map((r) => ({
|
|
134
|
+
// Field-by-field from the principal's tenancy — org_id and source_id are
|
|
135
|
+
// NEVER carried on the wire (T3). source_id identifies the rig instance,
|
|
136
|
+
// exactly like inferences.
|
|
137
|
+
org_id: tenancy.org_id,
|
|
138
|
+
id: r.id,
|
|
139
|
+
source_id: tenancy.source_id,
|
|
140
|
+
pipeline: r.pipeline,
|
|
141
|
+
pipeline_version: r.pipeline_version,
|
|
142
|
+
environment: r.environment,
|
|
143
|
+
episode_key: r.episode_key,
|
|
144
|
+
started_at: r.started_at,
|
|
145
|
+
ended_at: r.ended_at,
|
|
146
|
+
status: r.status,
|
|
147
|
+
updated_at: now,
|
|
148
|
+
})),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (batch.steps !== undefined && batch.steps.length > 0) {
|
|
152
|
+
writes.push({
|
|
153
|
+
// A step is a FACT (one row per attempt): merge=false on the composite PK.
|
|
154
|
+
// A retry must not rewrite what already landed.
|
|
155
|
+
table: "steps",
|
|
156
|
+
onConflict: "org_id,run_id,step_key,attempt_no",
|
|
157
|
+
merge: false,
|
|
158
|
+
rows: batch.steps.map((s) => ({
|
|
159
|
+
org_id: tenancy.org_id,
|
|
160
|
+
run_id: s.run_id,
|
|
161
|
+
step_key: s.step_key,
|
|
162
|
+
attempt_no: s.attempt_no,
|
|
163
|
+
task: s.task,
|
|
164
|
+
provenance: s.provenance,
|
|
165
|
+
// A ground-truth step joins inferences(org_id, source_id, id); the
|
|
166
|
+
// source_id is the principal's, stamped here (not trusted from the wire).
|
|
167
|
+
// Attested steps carry no inference reference (span only) — null.
|
|
168
|
+
inference_source_id: s.provenance === "ground-truth" ? tenancy.source_id : null,
|
|
169
|
+
inference_id: s.inference_id,
|
|
170
|
+
span_trace_id: s.span_trace_id,
|
|
171
|
+
span_id: s.span_id,
|
|
172
|
+
started_at: s.started_at,
|
|
173
|
+
ended_at: s.ended_at,
|
|
174
|
+
failure_class: s.failure_class,
|
|
175
|
+
// spread-iff-present (the 00027 pattern): the attested envelope is
|
|
176
|
+
// written ONLY for attested steps (OTLP ingest, E3-Harvest). A
|
|
177
|
+
// ground-truth step carries no `attested`, so the column stays null and
|
|
178
|
+
// the 00038 CHECK holds. An SDK batch never sets it → byte-identical.
|
|
179
|
+
...(s.attested !== undefined ? { attested: s.attested } : {}),
|
|
180
|
+
})),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (batch.artifacts !== undefined && batch.artifacts.length > 0) {
|
|
184
|
+
writes.push({
|
|
185
|
+
table: "artifacts",
|
|
186
|
+
onConflict: "org_id,id",
|
|
187
|
+
merge: false, // an artifact metadata row is a fact; a retry must not rewrite it
|
|
188
|
+
rows: batch.artifacts.map((a) => ({
|
|
189
|
+
org_id: tenancy.org_id,
|
|
190
|
+
id: a.id,
|
|
191
|
+
run_id: a.run_id,
|
|
192
|
+
step_key: a.step_key,
|
|
193
|
+
attempt_no: a.attempt_no,
|
|
194
|
+
task: a.task,
|
|
195
|
+
name: a.name,
|
|
196
|
+
type: a.type,
|
|
197
|
+
version: a.version,
|
|
198
|
+
supersedes_artifact_id: a.supersedes_artifact_id,
|
|
199
|
+
declared_schema: a.declared_schema,
|
|
200
|
+
fingerprint_cell: a.fingerprint_cell,
|
|
201
|
+
content_ref: a.content_ref,
|
|
202
|
+
content_hash: a.content_hash,
|
|
203
|
+
content_bytes: a.content_bytes,
|
|
204
|
+
data_classification: a.data_classification,
|
|
205
|
+
expires_at: a.expires_at,
|
|
206
|
+
// spread-iff-present (00027 pattern): a batch without `scrub` (older SDK,
|
|
207
|
+
// custody off) leaves the column null rather than overwriting it.
|
|
208
|
+
...(a.scrub !== undefined ? { scrub: a.scrub } : {}),
|
|
209
|
+
})),
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
if (batch.artifact_edges !== undefined && batch.artifact_edges.length > 0) {
|
|
213
|
+
writes.push({
|
|
214
|
+
table: "artifact_edges",
|
|
215
|
+
onConflict: "org_id,from_artifact_id,to_artifact_id,kind",
|
|
216
|
+
merge: false,
|
|
217
|
+
rows: batch.artifact_edges.map((e) => ({
|
|
218
|
+
org_id: tenancy.org_id,
|
|
219
|
+
from_artifact_id: e.from_artifact_id,
|
|
220
|
+
to_artifact_id: e.to_artifact_id,
|
|
221
|
+
kind: e.kind,
|
|
222
|
+
})),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (batch.artifact_evaluations !== undefined && batch.artifact_evaluations.length > 0) {
|
|
226
|
+
writes.push({
|
|
227
|
+
table: "artifact_evaluations",
|
|
228
|
+
onConflict: "org_id,id",
|
|
229
|
+
merge: false,
|
|
230
|
+
rows: batch.artifact_evaluations.map((v) => ({
|
|
231
|
+
org_id: tenancy.org_id,
|
|
232
|
+
id: v.id,
|
|
233
|
+
artifact_id: v.artifact_id,
|
|
234
|
+
// Subject-one-of (00051): a run-subject row carries run_id, artifact_id
|
|
235
|
+
// null; the CHECK rejects a row that sets both or neither.
|
|
236
|
+
run_id: v.run_id ?? null,
|
|
237
|
+
evaluator: v.evaluator,
|
|
238
|
+
evaluator_kind: v.evaluator_kind,
|
|
239
|
+
score: v.score,
|
|
240
|
+
passed: v.passed,
|
|
241
|
+
label: v.label,
|
|
242
|
+
explanation: v.explanation,
|
|
243
|
+
created_by: v.created_by,
|
|
244
|
+
})),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
if (batch.eval_cases !== undefined && batch.eval_cases.length > 0) {
|
|
248
|
+
writes.push({
|
|
249
|
+
// An eval case is created once (via promote); a retry must not rewrite it.
|
|
250
|
+
// Edits/deletes are a server-side owner action, not this stream. merge=false
|
|
251
|
+
// on the PK — idempotent by doing nothing (S5).
|
|
252
|
+
table: "eval_cases",
|
|
253
|
+
onConflict: "org_id,id",
|
|
254
|
+
merge: false,
|
|
255
|
+
rows: batch.eval_cases.map((c) => ({
|
|
256
|
+
org_id: tenancy.org_id,
|
|
257
|
+
id: c.id,
|
|
258
|
+
task: c.task,
|
|
259
|
+
source_artifact_id: c.source_artifact_id,
|
|
260
|
+
corrected_artifact_id: c.corrected_artifact_id,
|
|
261
|
+
origin: c.origin,
|
|
262
|
+
note: c.note,
|
|
263
|
+
created_by: c.created_by,
|
|
264
|
+
})),
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
if (batch.manifest !== undefined) {
|
|
268
|
+
writes.push({
|
|
269
|
+
table: "rig_manifests",
|
|
270
|
+
onConflict: "org_id,source_id",
|
|
271
|
+
merge: true,
|
|
272
|
+
rows: [
|
|
273
|
+
{
|
|
274
|
+
org_id: tenancy.org_id,
|
|
275
|
+
source_id: tenancy.source_id,
|
|
276
|
+
name: batch.manifest.name,
|
|
277
|
+
dimensions: batch.manifest.dimensions,
|
|
278
|
+
contribution: batch.manifest.contribution,
|
|
279
|
+
serveability: batch.manifest.serveability,
|
|
280
|
+
// [] when the load was clean — a merge upsert then clears any stale
|
|
281
|
+
// failure a prior broken deploy left on the row (follow-up #2).
|
|
282
|
+
load_errors: batch.manifest.load_errors ?? [],
|
|
283
|
+
updated_at: now,
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (batch.inferences !== undefined && batch.inferences.length > 0) {
|
|
289
|
+
writes.push({
|
|
290
|
+
table: "inferences",
|
|
291
|
+
// 00013's tenant-first primary key. Named explicitly so a retry lands on
|
|
292
|
+
// the row it already wrote rather than on the old single-column pk.
|
|
293
|
+
onConflict: "org_id,source_id,id",
|
|
294
|
+
// An inference is a fact that happened. A retry must not be able to
|
|
295
|
+
// rewrite it — idempotent by doing nothing, not by overwriting.
|
|
296
|
+
merge: false,
|
|
297
|
+
rows: batch.inferences.map((row) => ({
|
|
298
|
+
org_id: tenancy.org_id,
|
|
299
|
+
project_id: tenancy.project_id,
|
|
300
|
+
source_id: tenancy.source_id,
|
|
301
|
+
...row,
|
|
302
|
+
})),
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
if (batch.watermarkAt !== undefined) {
|
|
306
|
+
writes.push({
|
|
307
|
+
table: "export_watermarks",
|
|
308
|
+
onConflict: "org_id,source_id",
|
|
309
|
+
merge: true,
|
|
310
|
+
rows: [
|
|
311
|
+
{
|
|
312
|
+
org_id: tenancy.org_id,
|
|
313
|
+
source_id: tenancy.source_id,
|
|
314
|
+
last_exported_ts: batch.watermarkAt,
|
|
315
|
+
},
|
|
316
|
+
],
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
if (batch.feedback !== undefined && batch.feedback.length > 0) {
|
|
320
|
+
writes.push({
|
|
321
|
+
table: "feedback",
|
|
322
|
+
onConflict: "id",
|
|
323
|
+
merge: false,
|
|
324
|
+
rows: batch.feedback.map(({ org_id, ...row }) => ({
|
|
325
|
+
// The verdict's own org wins when it has one — that is the whole of
|
|
326
|
+
// QA-P6-010's fix. Note that `source_id` is deliberately absent:
|
|
327
|
+
// `feedback.source` already means "who judged", and two columns a
|
|
328
|
+
// letter apart meaning different things is N2's cautionary tale.
|
|
329
|
+
org_id: org_id ?? tenancy.org_id,
|
|
330
|
+
project_id: tenancy.project_id,
|
|
331
|
+
...row,
|
|
332
|
+
})),
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
if (batch.envelopes !== undefined && batch.envelopes.length > 0) {
|
|
336
|
+
writes.push({
|
|
337
|
+
table: "envelopes",
|
|
338
|
+
onConflict: "org_id,envelope_key",
|
|
339
|
+
merge: true,
|
|
340
|
+
rows: batch.envelopes.map((e) => ({
|
|
341
|
+
org_id: tenancy.org_id,
|
|
342
|
+
envelope_key: e.envelope_key,
|
|
343
|
+
budget_usd: e.budget_usd,
|
|
344
|
+
spent_usd: e.spent_usd,
|
|
345
|
+
status: e.status,
|
|
346
|
+
exported_at: now,
|
|
347
|
+
})),
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
return writes;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Feedback rows naming an org other than the presented key's.
|
|
354
|
+
*
|
|
355
|
+
* Exists as its own exported function because the ingest endpoint must drop
|
|
356
|
+
* these and COUNT them, and a check that lives inline in a request handler is
|
|
357
|
+
* a check nobody can test in isolation. Returns the offending ids.
|
|
358
|
+
*/
|
|
359
|
+
function foreignOrgFeedback(rows, keyOrgId) {
|
|
360
|
+
return rows
|
|
361
|
+
.filter((r) => r.org_id !== undefined && r.org_id !== keyOrgId)
|
|
362
|
+
.map((r) => r.id);
|
|
363
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load-error console reporting — follow-up #2.
|
|
3
|
+
*
|
|
4
|
+
* When a route bundle fails to load, tell the console WHY. `loadRoutes` throws
|
|
5
|
+
* before the exporter loop exists, so the run-loop path never gets a chance to
|
|
6
|
+
* mirror the failure. This sends a one-shot manifest batch carrying
|
|
7
|
+
* `describeConfigFailure(error)` onto `rig_manifests.load_errors`, which drives
|
|
8
|
+
* /setup's "Define your first route" step to `failed` with what we looked for
|
|
9
|
+
* and what we found.
|
|
10
|
+
*
|
|
11
|
+
* Fire-and-forget, and best-effort by design: `createRig` is synchronous and
|
|
12
|
+
* re-throws (the rig genuinely cannot run), and telemetry must never change the
|
|
13
|
+
* error the caller sees. KNOWN LIMITATION: this only reaches the console once
|
|
14
|
+
* the app runs with an export configured (MODELRIG_API_KEY / direct creds); a
|
|
15
|
+
* first-timer who hasn't connected yet still gets the full diagnosis at their
|
|
16
|
+
* terminal via `renderConfigErrorForTerminal`.
|
|
17
|
+
*
|
|
18
|
+
* Lives here rather than in index.ts to keep that file under the LOC cap (P1) —
|
|
19
|
+
* the same relocation `buildTelemetrySink` made to `sinks.ts`.
|
|
20
|
+
*/
|
|
21
|
+
import type { RigConfig } from "../config";
|
|
22
|
+
import { RouteConfigError } from "../routes/loader";
|
|
23
|
+
export declare function reportLoadError(config: RigConfig, error: RouteConfigError): void;
|
|
24
|
+
//# sourceMappingURL=load-error-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-error-report.d.ts","sourceRoot":"","sources":["../../src/telemetry/load-error-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAOpD,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAoBhF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Load-error console reporting — follow-up #2.
|
|
4
|
+
*
|
|
5
|
+
* When a route bundle fails to load, tell the console WHY. `loadRoutes` throws
|
|
6
|
+
* before the exporter loop exists, so the run-loop path never gets a chance to
|
|
7
|
+
* mirror the failure. This sends a one-shot manifest batch carrying
|
|
8
|
+
* `describeConfigFailure(error)` onto `rig_manifests.load_errors`, which drives
|
|
9
|
+
* /setup's "Define your first route" step to `failed` with what we looked for
|
|
10
|
+
* and what we found.
|
|
11
|
+
*
|
|
12
|
+
* Fire-and-forget, and best-effort by design: `createRig` is synchronous and
|
|
13
|
+
* re-throws (the rig genuinely cannot run), and telemetry must never change the
|
|
14
|
+
* error the caller sees. KNOWN LIMITATION: this only reaches the console once
|
|
15
|
+
* the app runs with an export configured (MODELRIG_API_KEY / direct creds); a
|
|
16
|
+
* first-timer who hasn't connected yet still gets the full diagnosis at their
|
|
17
|
+
* terminal via `renderConfigErrorForTerminal`.
|
|
18
|
+
*
|
|
19
|
+
* Lives here rather than in index.ts to keep that file under the LOC cap (P1) —
|
|
20
|
+
* the same relocation `buildTelemetrySink` made to `sinks.ts`.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.reportLoadError = reportLoadError;
|
|
24
|
+
const node_path_1 = require("node:path");
|
|
25
|
+
const node_os_1 = require("node:os");
|
|
26
|
+
const manifest_1 = require("../routes/manifest");
|
|
27
|
+
const config_teaching_1 = require("../types/config-teaching");
|
|
28
|
+
const exporter_1 = require("./exporter");
|
|
29
|
+
const sinks_1 = require("./sinks");
|
|
30
|
+
function reportLoadError(config, error) {
|
|
31
|
+
if (config.export === undefined)
|
|
32
|
+
return;
|
|
33
|
+
const sourceId = config.export.sourceId ?? (0, node_os_1.hostname)();
|
|
34
|
+
// rig.yaml can load fine even when a route bundle can't — carry its
|
|
35
|
+
// name/dimensions/contribution so the reporting upsert doesn't blank them.
|
|
36
|
+
let manifestMeta = null;
|
|
37
|
+
try {
|
|
38
|
+
manifestMeta = (0, manifest_1.loadManifest)((0, node_path_1.dirname)(config.routesDir));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// rig.yaml is itself broken/absent; fall back to source-id naming so the
|
|
42
|
+
// row still lands and the console still learns of the failure.
|
|
43
|
+
}
|
|
44
|
+
const sink = (0, sinks_1.buildTelemetrySink)(config.export, sourceId);
|
|
45
|
+
const batch = (0, exporter_1.buildLoadErrorBatch)(sourceId, manifestMeta, [(0, config_teaching_1.describeConfigFailure)(error)]);
|
|
46
|
+
void sink.send(batch).catch((err) => {
|
|
47
|
+
console.warn(`[modelrig] could not report the route load error to the console: ` +
|
|
48
|
+
`${err instanceof Error ? err.message : String(err)}`);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OTLP mapping — E1 (spec §3, §4). PURE: no I/O, no env, no imports from the
|
|
3
|
+
* exporter/sinks/store. One `inferences` row → one OTLP/HTTP JSON span.
|
|
4
|
+
*
|
|
5
|
+
* ── THE ONE PLACE gen_ai.* NAMES LIVE ────────────────────────────────────
|
|
6
|
+
* Every OpenTelemetry semantic-convention attribute name this product emits is
|
|
7
|
+
* declared in THIS module and nowhere else (architect-review-2026-08 §2(f)).
|
|
8
|
+
* The pin is `SEMCONV_VERSION` below — bump it here and the wire changes in one
|
|
9
|
+
* edit, not scattered across the codebase. If you find a `"gen_ai.*"` string
|
|
10
|
+
* literal outside this file, it is a bug.
|
|
11
|
+
*
|
|
12
|
+
* ── WHY HAND-BUILT JSON, NOT @opentelemetry/* ────────────────────────────
|
|
13
|
+
* We are mapping completed rows, not instrumenting live code, so the SDK's
|
|
14
|
+
* tracer runtime would be dead weight (spec §2.2). The shape below is the
|
|
15
|
+
* OTLP/HTTP `ExportTraceServiceRequest` JSON encoding. Two encoding rules bite
|
|
16
|
+
* here and are easy to get wrong (plan §"risks"):
|
|
17
|
+
* • trace_id / span_id are LOWERCASE HEX strings — the documented OTLP/JSON
|
|
18
|
+
* exception to Protobuf's base64-for-bytes. NOT base64.
|
|
19
|
+
* • int64 attribute + timestamp values are DECIMAL STRINGS; doubles are
|
|
20
|
+
* numbers. `intValue`/`startTimeUnixNano` are strings on the wire.
|
|
21
|
+
*/
|
|
22
|
+
import type { TelemetryRow } from "../types/telemetry";
|
|
23
|
+
import type { CacheContext } from "../watch/evaluate";
|
|
24
|
+
/** Semantic-conventions pin (architect ruling §2(f)). The scope version on the
|
|
25
|
+
* wire and the single source of truth for which gen_ai vintage we speak. */
|
|
26
|
+
export declare const SEMCONV_VERSION = "1.41.0";
|
|
27
|
+
/** STATUS_CODE_UNSET / STATUS_CODE_ERROR (OK is never set — gen_ai convention
|
|
28
|
+
* leaves a successful span UNSET). */
|
|
29
|
+
declare const STATUS_UNSET = 0;
|
|
30
|
+
declare const STATUS_ERROR = 2;
|
|
31
|
+
export type OtlpAnyValue = {
|
|
32
|
+
readonly stringValue: string;
|
|
33
|
+
} | {
|
|
34
|
+
readonly intValue: string;
|
|
35
|
+
} | {
|
|
36
|
+
readonly doubleValue: number;
|
|
37
|
+
} | {
|
|
38
|
+
readonly boolValue: boolean;
|
|
39
|
+
};
|
|
40
|
+
export interface OtlpAttribute {
|
|
41
|
+
readonly key: string;
|
|
42
|
+
readonly value: OtlpAnyValue;
|
|
43
|
+
}
|
|
44
|
+
export interface OtlpStatus {
|
|
45
|
+
readonly code: typeof STATUS_UNSET | typeof STATUS_ERROR;
|
|
46
|
+
readonly message?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface OtlpSpanJson {
|
|
49
|
+
/** 32 lowercase hex chars (16 bytes). */
|
|
50
|
+
readonly traceId: string;
|
|
51
|
+
/** 16 lowercase hex chars (8 bytes). */
|
|
52
|
+
readonly spanId: string;
|
|
53
|
+
/** 16 lowercase hex chars — present only when a caller traceparent nests us. */
|
|
54
|
+
readonly parentSpanId?: string;
|
|
55
|
+
readonly name: string;
|
|
56
|
+
readonly kind: number;
|
|
57
|
+
readonly startTimeUnixNano: string;
|
|
58
|
+
readonly endTimeUnixNano: string;
|
|
59
|
+
readonly attributes: readonly OtlpAttribute[];
|
|
60
|
+
readonly status: OtlpStatus;
|
|
61
|
+
}
|
|
62
|
+
export interface OtlpResource {
|
|
63
|
+
readonly serviceName: string;
|
|
64
|
+
/** Optional extra resource attributes (e.g. deployment.environment). */
|
|
65
|
+
readonly attributes?: readonly OtlpAttribute[];
|
|
66
|
+
}
|
|
67
|
+
export interface ExportTraceServiceRequestJson {
|
|
68
|
+
readonly resourceSpans: ReadonlyArray<{
|
|
69
|
+
readonly resource: {
|
|
70
|
+
readonly attributes: readonly OtlpAttribute[];
|
|
71
|
+
};
|
|
72
|
+
readonly scopeSpans: ReadonlyArray<{
|
|
73
|
+
readonly scope: {
|
|
74
|
+
readonly name: string;
|
|
75
|
+
readonly version: string;
|
|
76
|
+
};
|
|
77
|
+
readonly spans: readonly OtlpSpanJson[];
|
|
78
|
+
}>;
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
/** The tag key the gateway stashes an inbound traceparent under (spec §2.5). */
|
|
82
|
+
export declare const TRACEPARENT_TAG = "otel.traceparent";
|
|
83
|
+
export interface Traceparent {
|
|
84
|
+
/** Caller's trace id — the emitted span joins this trace. */
|
|
85
|
+
readonly traceId: string;
|
|
86
|
+
/** Caller's span id — the emitted span's parent. */
|
|
87
|
+
readonly parentSpanId: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse a W3C `traceparent` value, or null when absent/malformed. The gateway
|
|
91
|
+
* (packages/modelrig-server) reuses this so the SDK and the server cannot
|
|
92
|
+
* disagree about what "well-formed" means. All-zero trace/parent ids are
|
|
93
|
+
* rejected per the W3C spec (they mean "no parent").
|
|
94
|
+
*/
|
|
95
|
+
export declare function parseTraceparent(value: string | undefined | null): Traceparent | null;
|
|
96
|
+
/**
|
|
97
|
+
* Map one telemetry row to one OTLP span (spec §3, normative). Pure and total:
|
|
98
|
+
* every field comes from the row; nulls are omitted (never emitted as empty).
|
|
99
|
+
*/
|
|
100
|
+
export declare function inferenceToSpan(row: TelemetryRow): OtlpSpanJson;
|
|
101
|
+
/**
|
|
102
|
+
* Decision-span attributes for a cache-aware routing decision (cache-aware-routing
|
|
103
|
+
* spec §5.5 — "routing must never be opaque"). Returns the `modelrig.cache.*`
|
|
104
|
+
* attribute set a caller attaches to the swap/proposal decision span so the
|
|
105
|
+
* verdict + its economics travel to any OTLP backend alongside the inference
|
|
106
|
+
* spans. Declared HERE because this module is the one place OTLP attribute names
|
|
107
|
+
* live (the pin at the top of this file).
|
|
108
|
+
*
|
|
109
|
+
* `breakeven_conformant_calls` can be `Infinity` ("never breaks even"), which is
|
|
110
|
+
* not a valid JSON number — so it is emitted as a double ONLY when finite, and a
|
|
111
|
+
* boolean `modelrig.cache.breakeven_reachable` records the never-case explicitly
|
|
112
|
+
* rather than dropping the fact.
|
|
113
|
+
*/
|
|
114
|
+
export declare function cacheDecisionSpanAttributes(ctx: CacheContext): OtlpAttribute[];
|
|
115
|
+
/**
|
|
116
|
+
* Wrap spans in the OTLP `ExportTraceServiceRequest` envelope (spec §4, pure).
|
|
117
|
+
* One resource, one scope (`modelrig` @ SEMCONV_VERSION), N spans.
|
|
118
|
+
*/
|
|
119
|
+
export declare function buildExportTraceRequest(spans: readonly OtlpSpanJson[], resource: OtlpResource): ExportTraceServiceRequestJson;
|
|
120
|
+
export {};
|
|
121
|
+
//# sourceMappingURL=otel-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel-map.d.ts","sourceRoot":"","sources":["../../src/telemetry/otel-map.ts"],"names":[],"mappings":"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"}
|