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,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini ProviderAdapter — plan step 5 (the hardest port).
|
|
3
|
+
* Transformation logic ported from apps/api/src/services/gemini-provider.ts:
|
|
4
|
+
* grounding tool passthrough, explicit context-cache passthrough (cache name
|
|
5
|
+
* via AdapterRequest.cache.key), thinking level, flex tier + capacity-shed
|
|
6
|
+
* classification, responseJsonSchema, served-tier extraction.
|
|
7
|
+
* NOT ported (by design): logging, pricing tables (registry owns pricing),
|
|
8
|
+
* env reads, the analyst-persona system instruction (route templates own
|
|
9
|
+
* prompt content), and especially the model fallback chain — silent model
|
|
10
|
+
* substitution is an invariant violation here; a failed model fails typed.
|
|
11
|
+
*
|
|
12
|
+
* Portions may be derived from LiteLLM (https://github.com/BerriAI/litellm),
|
|
13
|
+
* Copyright (c) 2023 Berri AI, MIT License — retain this notice if LiteLLM's
|
|
14
|
+
* gemini transformation logic is consulted during the port.
|
|
15
|
+
*/
|
|
16
|
+
import type { AdapterRequest, CapabilityFlag, ProviderAdapter } from "../types/provider";
|
|
17
|
+
import type { FailureClass } from "../types/failures";
|
|
18
|
+
export interface GeminiAdapterConfig {
|
|
19
|
+
readonly apiKey: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function geminiSupports(feature: CapabilityFlag, model: string): boolean;
|
|
22
|
+
export interface ClassifiedFailure {
|
|
23
|
+
readonly cls: FailureClass;
|
|
24
|
+
readonly fixHint?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Map a Gemini SDK/API error message into the failure taxonomy. Ported from
|
|
28
|
+
* classifyGeminiError + classifyGeminiFallbackReason; branch ORDER is
|
|
29
|
+
* load-bearing — auth before INVALID_ARGUMENT (a bad key surfaces as 400
|
|
30
|
+
* INVALID_ARGUMENT "API key not valid"), quota before generic 429 capacity.
|
|
31
|
+
*/
|
|
32
|
+
export declare function classifyGeminiFailure(message: string): ClassifiedFailure;
|
|
33
|
+
/** The candidate-independent part of an AdapterRequest (also what the pure
|
|
34
|
+
* shaping helpers take, so unit tests never need a branded CandidateRef). */
|
|
35
|
+
export type ShapingInput = Omit<AdapterRequest, "candidate">;
|
|
36
|
+
export interface GeminiShapedRequest {
|
|
37
|
+
readonly model: string;
|
|
38
|
+
readonly contents: string;
|
|
39
|
+
readonly config: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
/** Pure request shaping — everything except the abort signal. */
|
|
42
|
+
export declare function buildGeminiRequest(model: string, req: ShapingInput): GeminiShapedRequest;
|
|
43
|
+
export declare function createGeminiAdapter(config: GeminiAdapterConfig): ProviderAdapter;
|
|
44
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EACV,cAAc,EAGd,cAAc,EACd,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,mBAAmB,CAAC;AAKlE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAkCD,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAG9E;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAyCxE;AAED;6EAC6E;AAC7E,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AAE7D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,mBAAmB,CA2CxF;AA0BD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,eAAe,CAmJhF"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Gemini ProviderAdapter — plan step 5 (the hardest port).
|
|
4
|
+
* Transformation logic ported from apps/api/src/services/gemini-provider.ts:
|
|
5
|
+
* grounding tool passthrough, explicit context-cache passthrough (cache name
|
|
6
|
+
* via AdapterRequest.cache.key), thinking level, flex tier + capacity-shed
|
|
7
|
+
* classification, responseJsonSchema, served-tier extraction.
|
|
8
|
+
* NOT ported (by design): logging, pricing tables (registry owns pricing),
|
|
9
|
+
* env reads, the analyst-persona system instruction (route templates own
|
|
10
|
+
* prompt content), and especially the model fallback chain — silent model
|
|
11
|
+
* substitution is an invariant violation here; a failed model fails typed.
|
|
12
|
+
*
|
|
13
|
+
* Portions may be derived from LiteLLM (https://github.com/BerriAI/litellm),
|
|
14
|
+
* Copyright (c) 2023 Berri AI, MIT License — retain this notice if LiteLLM's
|
|
15
|
+
* gemini transformation logic is consulted during the port.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.geminiSupports = geminiSupports;
|
|
19
|
+
exports.classifyGeminiFailure = classifyGeminiFailure;
|
|
20
|
+
exports.buildGeminiRequest = buildGeminiRequest;
|
|
21
|
+
exports.createGeminiAdapter = createGeminiAdapter;
|
|
22
|
+
const genai_1 = require("@google/genai");
|
|
23
|
+
const tool_mapping_1 = require("./tool-mapping");
|
|
24
|
+
const sampling_1 = require("./sampling");
|
|
25
|
+
/** Models that accept thinkingConfig — passing it to 2.x models 400s.
|
|
26
|
+
* Ported from the production THINKING_CAPABLE_MODELS set. */
|
|
27
|
+
const THINKING_CAPABLE_MODELS = new Set([
|
|
28
|
+
"gemini-3.1-pro-preview",
|
|
29
|
+
"gemini-3.0-pro-preview",
|
|
30
|
+
"gemini-3.1-flash-preview",
|
|
31
|
+
]);
|
|
32
|
+
/** Gemini-3 default. Google STRONGLY recommends temperature=1.0 for all
|
|
33
|
+
* Gemini 3 models and warns that values below 1.0 can cause looping / degraded
|
|
34
|
+
* output — concentrated on complex reasoning/math tasks, not simple
|
|
35
|
+
* classification (verified 2026-08-20 against ai.google.dev/gemini-api/docs/gemini-3;
|
|
36
|
+
* the source pipeline ran gemini-3.1-pro at 0.1 for CLASSIFICATION without
|
|
37
|
+
* looping, which the reasoning-task carve-out explains). It is a recommendation,
|
|
38
|
+
* not a hard API cap: the accepted range stays 0–2. This is the DEFAULT the
|
|
39
|
+
* adapter sends when a route declares no `sampling.temperature`; a declared
|
|
40
|
+
* value overrides it and is sent as-is (CE-6), with a load-time warning emitted
|
|
41
|
+
* for a sub-1.0 value on a Gemini-3 candidate (routes/loader.ts). */
|
|
42
|
+
const GEMINI_TEMPERATURE = 1.0;
|
|
43
|
+
const DEFAULT_MAX_OUTPUT_TOKENS = 64000; // thinking tokens count against this
|
|
44
|
+
const TOP_P = 0.95;
|
|
45
|
+
const TOP_K = 40;
|
|
46
|
+
const GEMINI_CAPABILITIES = new Set([
|
|
47
|
+
"structured_native",
|
|
48
|
+
"json_mode",
|
|
49
|
+
"grounded_native",
|
|
50
|
+
"context_cache_explicit",
|
|
51
|
+
"prefix_cache_implicit",
|
|
52
|
+
"tier_flex",
|
|
53
|
+
]);
|
|
54
|
+
function geminiSupports(feature, model) {
|
|
55
|
+
void model; // Phase 1 static stub: flags are family-wide for the 2.5/3.x models in use
|
|
56
|
+
return GEMINI_CAPABILITIES.has(feature);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Map a Gemini SDK/API error message into the failure taxonomy. Ported from
|
|
60
|
+
* classifyGeminiError + classifyGeminiFallbackReason; branch ORDER is
|
|
61
|
+
* load-bearing — auth before INVALID_ARGUMENT (a bad key surfaces as 400
|
|
62
|
+
* INVALID_ARGUMENT "API key not valid"), quota before generic 429 capacity.
|
|
63
|
+
*/
|
|
64
|
+
function classifyGeminiFailure(message) {
|
|
65
|
+
const msg = message.toLowerCase();
|
|
66
|
+
if (/cachedcontent|cached_content/.test(msg)) {
|
|
67
|
+
return { cls: "cache_invalid", fixHint: "recreate the context cache and retry without it if it keeps failing" };
|
|
68
|
+
}
|
|
69
|
+
if (/\b40[13]\b|api[_ ]key|permission_denied|unauthenticated/.test(msg)) {
|
|
70
|
+
// F2: a dead key must not burn backoff retries — config_auth is
|
|
71
|
+
// non-retryable and the run loop advances to the next candidate.
|
|
72
|
+
return { cls: "config_auth", fixHint: "check the Gemini API key/credentials configured for this rig" };
|
|
73
|
+
}
|
|
74
|
+
if (/quota|\brpm\b|\btpm\b|rate limit/.test(msg)) {
|
|
75
|
+
return { cls: "capacity_shed" };
|
|
76
|
+
}
|
|
77
|
+
if (/\b50[234]\b/.test(msg) ||
|
|
78
|
+
/service unavailable|preempted|sheddable|overloaded|bad gateway|gateway timeout/.test(msg) ||
|
|
79
|
+
/\b429\b|resource has been exhausted|serving capacity/.test(msg)) {
|
|
80
|
+
return { cls: "capacity_shed" };
|
|
81
|
+
}
|
|
82
|
+
if (/abort|cancel|timeout|etimedout/.test(msg)) {
|
|
83
|
+
return { cls: "timeout" };
|
|
84
|
+
}
|
|
85
|
+
if (/fetch failed|econnreset|econnrefused|enotfound|eai_again|epipe|eproto|err_tls/.test(msg)) {
|
|
86
|
+
return { cls: "network" };
|
|
87
|
+
}
|
|
88
|
+
if (/\b404\b|not found/.test(msg)) {
|
|
89
|
+
return {
|
|
90
|
+
cls: "network",
|
|
91
|
+
fixHint: "the candidate model was not found — fix the model id in the route's candidate list",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (/invalid_argument|invalid argument/.test(msg)) {
|
|
95
|
+
return {
|
|
96
|
+
cls: "network",
|
|
97
|
+
fixHint: "request shape rejected (often a response schema over Gemini's complexity ceiling) — another candidate may accept it",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return { cls: "network" };
|
|
101
|
+
}
|
|
102
|
+
/** Pure request shaping — everything except the abort signal. */
|
|
103
|
+
function buildGeminiRequest(model, req) {
|
|
104
|
+
const usingCache = req.cache?.key !== undefined && req.cache.key !== "";
|
|
105
|
+
// CE-6: a declared sampling field OVERRIDES the ported constant; absent, the
|
|
106
|
+
// constant stands (byte-identical to pre-CE-6). topK stays internal (gemini-only,
|
|
107
|
+
// not on the customer surface — spec §1 non-goals).
|
|
108
|
+
const config = {
|
|
109
|
+
temperature: req.sampling?.temperature ?? GEMINI_TEMPERATURE,
|
|
110
|
+
maxOutputTokens: (0, sampling_1.effectiveMaxOutputTokens)(req, DEFAULT_MAX_OUTPUT_TOKENS),
|
|
111
|
+
topP: req.sampling?.topP ?? TOP_P,
|
|
112
|
+
topK: TOP_K,
|
|
113
|
+
...(THINKING_CAPABLE_MODELS.has(model) ? { thinkingConfig: { thinkingLevel: "high" } } : {}),
|
|
114
|
+
};
|
|
115
|
+
if (req.outputSchema !== null) {
|
|
116
|
+
config.responseMimeType = "application/json";
|
|
117
|
+
config.responseJsonSchema = req.outputSchema;
|
|
118
|
+
}
|
|
119
|
+
// cachedContent excludes systemInstruction and tools — the API rejects
|
|
120
|
+
// requests setting both (they are baked into the cache at creation time,
|
|
121
|
+
// including the googleSearch tool for cached grounded steps).
|
|
122
|
+
if (usingCache) {
|
|
123
|
+
config.cachedContent = req.cache?.key;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
if (req.systemPrompt !== "") {
|
|
127
|
+
config.systemInstruction = req.systemPrompt;
|
|
128
|
+
}
|
|
129
|
+
if (req.grounding === true) {
|
|
130
|
+
config.tools = [{ googleSearch: {} }];
|
|
131
|
+
}
|
|
132
|
+
else if (req.tools !== undefined && req.tools.length > 0) {
|
|
133
|
+
// Caller-supplied tools (spec §4.4) → Gemini functionDeclarations.
|
|
134
|
+
// Grounding wins the single `tools` slot when both are asked for.
|
|
135
|
+
config.tools = (0, tool_mapping_1.toGeminiTools)(req.tools);
|
|
136
|
+
const toolConfig = (0, tool_mapping_1.toGeminiToolConfig)(req.toolChoice);
|
|
137
|
+
if (toolConfig !== undefined)
|
|
138
|
+
config.toolConfig = toolConfig;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (req.requestedTier === "flex") {
|
|
142
|
+
config.serviceTier = "flex";
|
|
143
|
+
}
|
|
144
|
+
return { model, contents: req.userPrompt, config };
|
|
145
|
+
}
|
|
146
|
+
/** Best-effort served-tier extraction (ported): response.serviceTier, then
|
|
147
|
+
* usageMetadata.trafficType (Vertex path), else assume the requested tier —
|
|
148
|
+
* production bills flex when a flex request was accepted without a tier echo. */
|
|
149
|
+
function extractServedTier(rawServiceTier, trafficType, requested) {
|
|
150
|
+
if (rawServiceTier === "flex" || trafficType === "ON_DEMAND_FLEX")
|
|
151
|
+
return "flex";
|
|
152
|
+
if (rawServiceTier === "standard" || rawServiceTier === "default" || trafficType === "ON_DEMAND") {
|
|
153
|
+
return "standard";
|
|
154
|
+
}
|
|
155
|
+
if (rawServiceTier === "priority" || trafficType === "ON_DEMAND_PRIORITY")
|
|
156
|
+
return "priority";
|
|
157
|
+
return requested;
|
|
158
|
+
}
|
|
159
|
+
function createGeminiAdapter(config) {
|
|
160
|
+
const ai = new genai_1.GoogleGenAI({ apiKey: config.apiKey });
|
|
161
|
+
return {
|
|
162
|
+
id: "gemini",
|
|
163
|
+
supports: geminiSupports,
|
|
164
|
+
supportsTools: () => true,
|
|
165
|
+
async call(req) {
|
|
166
|
+
const model = req.candidate.model;
|
|
167
|
+
const abortController = new AbortController();
|
|
168
|
+
const timeoutId = setTimeout(() => abortController.abort(), req.timeoutMs);
|
|
169
|
+
// F1: post-response failures (refusal/empty/truncation) still billed
|
|
170
|
+
// tokens — they attach the response usage so the run loop accounts them.
|
|
171
|
+
const fail = (cls, message, fixHint, usage) => ({
|
|
172
|
+
ok: false,
|
|
173
|
+
failure: {
|
|
174
|
+
class: cls,
|
|
175
|
+
message,
|
|
176
|
+
provider: "gemini",
|
|
177
|
+
model,
|
|
178
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
179
|
+
},
|
|
180
|
+
...(usage !== undefined ? { usage } : {}),
|
|
181
|
+
});
|
|
182
|
+
try {
|
|
183
|
+
const shaped = buildGeminiRequest(model, req);
|
|
184
|
+
const dispatchedAt = Date.now();
|
|
185
|
+
const response = await ai.models.generateContent({
|
|
186
|
+
model: shaped.model,
|
|
187
|
+
contents: shaped.contents,
|
|
188
|
+
config: { ...shaped.config, abortSignal: abortController.signal },
|
|
189
|
+
});
|
|
190
|
+
// TTFB (Phase 4 WS3): generateContent is non-streaming — the first
|
|
191
|
+
// body byte genuinely arrives with the whole body, so TTFB = total.
|
|
192
|
+
const ttfbMs = Date.now() - dispatchedAt;
|
|
193
|
+
const usageMetadata = (response.usageMetadata ?? {});
|
|
194
|
+
const respWithTier = response;
|
|
195
|
+
const servedTier = extractServedTier(respWithTier.serviceTier, usageMetadata.trafficType, req.requestedTier);
|
|
196
|
+
const tokensIn = usageMetadata.promptTokenCount ?? 0;
|
|
197
|
+
// Thinking tokens are billed as output and count against
|
|
198
|
+
// maxOutputTokens — include them in tokensOut for honest accounting.
|
|
199
|
+
const tokensOut = (usageMetadata.candidatesTokenCount ?? 0) + (usageMetadata.thoughtsTokenCount ?? 0);
|
|
200
|
+
const tokensCached = usageMetadata.cachedContentTokenCount ?? 0;
|
|
201
|
+
const usage = { tokensIn, tokensOut, tokensCached, servedTier, ttfbMs };
|
|
202
|
+
const candidates = response.candidates;
|
|
203
|
+
const finishReason = candidates?.[0]?.finishReason;
|
|
204
|
+
// Tool-call turn (spec §4.4): collect functionCall parts. When present,
|
|
205
|
+
// surface normalized calls and skip the text/empty/truncation guards.
|
|
206
|
+
// Read any accompanying text from the parts (not the `response.text`
|
|
207
|
+
// getter, which can throw/warn on a functionCall-only response).
|
|
208
|
+
if (req.tools !== undefined && req.tools.length > 0) {
|
|
209
|
+
const parts = candidates?.[0]?.content?.parts ?? [];
|
|
210
|
+
const fnCalls = parts
|
|
211
|
+
.map((p) => p.functionCall)
|
|
212
|
+
.filter((fc) => fc !== undefined && fc !== null);
|
|
213
|
+
const toolCalls = (0, tool_mapping_1.geminiFunctionCallsToToolCalls)(fnCalls);
|
|
214
|
+
if (toolCalls !== undefined) {
|
|
215
|
+
const toolText = parts
|
|
216
|
+
.map((p) => p.text)
|
|
217
|
+
.filter((t) => typeof t === "string")
|
|
218
|
+
.join("");
|
|
219
|
+
return { ok: true, text: toolText, usage, toolCalls };
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (finishReason === "SAFETY" || finishReason === "PROHIBITED_CONTENT") {
|
|
223
|
+
return fail("refusal", `Gemini blocked output via safety filter (finishReason=${finishReason})`, undefined, usage);
|
|
224
|
+
}
|
|
225
|
+
if (finishReason === "RECITATION") {
|
|
226
|
+
return fail("refusal", "Gemini blocked output via recitation filter (finishReason=RECITATION)", undefined, usage);
|
|
227
|
+
}
|
|
228
|
+
const text = response.text ?? "";
|
|
229
|
+
if (text.trim().length === 0) {
|
|
230
|
+
return fail("content_invalid", `empty response from Gemini (finishReason=${finishReason ?? "none"})`, undefined, usage);
|
|
231
|
+
}
|
|
232
|
+
if (finishReason === "MAX_TOKENS" && req.outputSchema !== null) {
|
|
233
|
+
// A truncated structured emission is mid-object and unparseable.
|
|
234
|
+
return fail("content_invalid", "Gemini structured output truncated (finishReason=MAX_TOKENS)", "raise maxOutputTokens for this route or reduce thinking budget", usage);
|
|
235
|
+
}
|
|
236
|
+
return { ok: true, text, usage };
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
240
|
+
// An abort we triggered is our timeout regardless of message text.
|
|
241
|
+
if (abortController.signal.aborted) {
|
|
242
|
+
return fail("timeout", `Gemini call exceeded timeoutMs=${req.timeoutMs}: ${message}`);
|
|
243
|
+
}
|
|
244
|
+
const { cls, fixHint } = classifyGeminiFailure(message);
|
|
245
|
+
return {
|
|
246
|
+
ok: false,
|
|
247
|
+
failure: {
|
|
248
|
+
class: cls,
|
|
249
|
+
message,
|
|
250
|
+
provider: "gemini",
|
|
251
|
+
model,
|
|
252
|
+
cause: error,
|
|
253
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
finally {
|
|
258
|
+
clearTimeout(timeoutId);
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grok (xAI) ProviderAdapter — provider expansion 2026-08-02 (Matt: "add
|
|
3
|
+
* Grok to the testing asap"). OpenAI-compatible API at api.x.ai/v1 with
|
|
4
|
+
* native strict json_schema structured outputs and automatic prompt caching
|
|
5
|
+
* (cached tokens surface in prompt_tokens_details, deepseek-style). No
|
|
6
|
+
* service tiers. Reasoning models keep their trace server-side — only
|
|
7
|
+
* delta.content is accumulated, mirroring the deepseek reasoner rule.
|
|
8
|
+
*
|
|
9
|
+
* Portions may be derived from LiteLLM (https://github.com/BerriAI/litellm),
|
|
10
|
+
* Copyright (c) 2023 Berri AI, MIT License — retain this notice if LiteLLM's
|
|
11
|
+
* xai transformation logic is consulted during the port.
|
|
12
|
+
*/
|
|
13
|
+
import type { CapabilityFlag, ProviderAdapter } from "../types/provider";
|
|
14
|
+
import type { ClassifiedFailure, ShapingInput } from "./gemini";
|
|
15
|
+
import type { OpenAIWireTool, OpenAIWireToolChoice } from "./tool-mapping";
|
|
16
|
+
export interface GrokAdapterConfig {
|
|
17
|
+
readonly apiKey: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function grokSupports(feature: CapabilityFlag, _model: string): boolean;
|
|
20
|
+
export declare function classifyGrokFailure(message: string): ClassifiedFailure;
|
|
21
|
+
interface ChatMessage {
|
|
22
|
+
readonly role: "system" | "user";
|
|
23
|
+
readonly content: string;
|
|
24
|
+
}
|
|
25
|
+
export interface GrokShapedParams {
|
|
26
|
+
readonly model: string;
|
|
27
|
+
readonly max_tokens: number;
|
|
28
|
+
readonly messages: readonly ChatMessage[];
|
|
29
|
+
readonly stream: true;
|
|
30
|
+
readonly stream_options: {
|
|
31
|
+
readonly include_usage: true;
|
|
32
|
+
};
|
|
33
|
+
/** CE-6 declared sampling — present only when the route/raw asks for them. */
|
|
34
|
+
readonly temperature?: number;
|
|
35
|
+
readonly top_p?: number;
|
|
36
|
+
/** Prompt-cache routing hint (WS-C) — the stable-prefix fingerprint the run
|
|
37
|
+
* loop stamps; xAI keeps a warm cache keyed to it (writes free today). */
|
|
38
|
+
readonly prompt_cache_key?: string;
|
|
39
|
+
readonly response_format?: {
|
|
40
|
+
readonly type: "json_schema";
|
|
41
|
+
readonly json_schema: {
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly schema: object;
|
|
44
|
+
readonly strict: true;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
readonly tools?: readonly OpenAIWireTool[];
|
|
48
|
+
readonly tool_choice?: OpenAIWireToolChoice;
|
|
49
|
+
}
|
|
50
|
+
export declare function buildGrokParams(model: string, req: ShapingInput): GrokShapedParams;
|
|
51
|
+
export declare function createGrokAdapter(config: GrokAdapterConfig): ProviderAdapter;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=grok.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grok.d.ts","sourceRoot":"","sources":["../../src/adapters/grok.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAMhG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAKD,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAc7E;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAsBtE;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;8EAC0E;IAC1E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE;QACzB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;SAAE,CAAC;KACjG,CAAC;IACF,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,gBAAgB,CAsClF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,eAAe,CAgK5E"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Grok (xAI) ProviderAdapter — provider expansion 2026-08-02 (Matt: "add
|
|
4
|
+
* Grok to the testing asap"). OpenAI-compatible API at api.x.ai/v1 with
|
|
5
|
+
* native strict json_schema structured outputs and automatic prompt caching
|
|
6
|
+
* (cached tokens surface in prompt_tokens_details, deepseek-style). No
|
|
7
|
+
* service tiers. Reasoning models keep their trace server-side — only
|
|
8
|
+
* delta.content is accumulated, mirroring the deepseek reasoner rule.
|
|
9
|
+
*
|
|
10
|
+
* Portions may be derived from LiteLLM (https://github.com/BerriAI/litellm),
|
|
11
|
+
* Copyright (c) 2023 Berri AI, MIT License — retain this notice if LiteLLM's
|
|
12
|
+
* xai transformation logic is consulted during the port.
|
|
13
|
+
*/
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.grokSupports = grokSupports;
|
|
19
|
+
exports.classifyGrokFailure = classifyGrokFailure;
|
|
20
|
+
exports.buildGrokParams = buildGrokParams;
|
|
21
|
+
exports.createGrokAdapter = createGrokAdapter;
|
|
22
|
+
const openai_1 = __importDefault(require("openai"));
|
|
23
|
+
const tool_mapping_1 = require("./tool-mapping");
|
|
24
|
+
const openai_stream_1 = require("./openai-stream");
|
|
25
|
+
const sampling_1 = require("./sampling");
|
|
26
|
+
const GROK_BASE_URL = "https://api.x.ai/v1";
|
|
27
|
+
const DEFAULT_MAX_TOKENS = 32000;
|
|
28
|
+
function grokSupports(feature, _model) {
|
|
29
|
+
switch (feature) {
|
|
30
|
+
case "structured_native":
|
|
31
|
+
case "json_mode":
|
|
32
|
+
case "prefix_cache_implicit":
|
|
33
|
+
case "prompt_cache_key": // prompt_cache_key routing hint (WS-C) — cache-policy registry truth
|
|
34
|
+
return true;
|
|
35
|
+
case "grounded_native": // Live Search exists but is not wired — probes may grant later
|
|
36
|
+
case "context_cache_explicit":
|
|
37
|
+
case "tier_flex":
|
|
38
|
+
case "trace_visible":
|
|
39
|
+
case "zero_retention": // never a static adapter attestation — set only from the credential-scoped registry facts (claims.ts)
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function classifyGrokFailure(message) {
|
|
44
|
+
const msg = message.toLowerCase();
|
|
45
|
+
if (/\b429\b|rate limit|\brate\b/.test(msg))
|
|
46
|
+
return { cls: "capacity_shed" };
|
|
47
|
+
if (/\b50[023]\b|service unavailable|overloaded/.test(msg))
|
|
48
|
+
return { cls: "capacity_shed" };
|
|
49
|
+
if (/timeout|etimedout|abort/.test(msg))
|
|
50
|
+
return { cls: "timeout" };
|
|
51
|
+
if (/econnreset|econnrefused|enotfound|fetch failed|network/.test(msg))
|
|
52
|
+
return { cls: "network" };
|
|
53
|
+
if (/\b401\b|api key|incorrect api key/.test(msg)) {
|
|
54
|
+
// F2: non-retryable — a dead key never burns backoff retries.
|
|
55
|
+
return { cls: "config_auth", fixHint: "check the xAI API key configured for this rig" };
|
|
56
|
+
}
|
|
57
|
+
if (/credit|spending limit|insufficient_quota|billing/.test(msg)) {
|
|
58
|
+
// xAI 403 "used all available credits / monthly spending limit" —
|
|
59
|
+
// account-level hard stop observed 2026-08-03; retries are pure waste.
|
|
60
|
+
return { cls: "config_auth", fixHint: "the xAI account is out of credits or over its spending limit" };
|
|
61
|
+
}
|
|
62
|
+
if (/does not exist|not found|\bmodel\b.*invalid/.test(msg)) {
|
|
63
|
+
return {
|
|
64
|
+
cls: "network",
|
|
65
|
+
fixHint: "the candidate model was not found — fix the model id in the route's candidate list",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return { cls: "network" };
|
|
69
|
+
}
|
|
70
|
+
function buildGrokParams(model, req) {
|
|
71
|
+
const messages = [
|
|
72
|
+
...(req.systemPrompt !== "" ? [{ role: "system", content: req.systemPrompt }] : []),
|
|
73
|
+
{ role: "user", content: req.userPrompt },
|
|
74
|
+
];
|
|
75
|
+
return {
|
|
76
|
+
model,
|
|
77
|
+
max_tokens: (0, sampling_1.effectiveMaxOutputTokens)(req, DEFAULT_MAX_TOKENS),
|
|
78
|
+
messages,
|
|
79
|
+
stream: true,
|
|
80
|
+
stream_options: { include_usage: true },
|
|
81
|
+
...(0, sampling_1.openAISamplingFields)(req),
|
|
82
|
+
// Prompt caching (WS-C): the run loop stamps `cache.key` (the stable-prefix
|
|
83
|
+
// fingerprint) for prompt_cache_key providers; pass it through as xAI's hint.
|
|
84
|
+
...(req.cache?.key !== undefined && req.cache.key !== ""
|
|
85
|
+
? { prompt_cache_key: req.cache.key }
|
|
86
|
+
: {}),
|
|
87
|
+
...(req.outputSchema !== null
|
|
88
|
+
? {
|
|
89
|
+
response_format: {
|
|
90
|
+
type: "json_schema",
|
|
91
|
+
json_schema: {
|
|
92
|
+
name: "modelrig_route_output",
|
|
93
|
+
schema: req.outputSchema,
|
|
94
|
+
strict: true,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
: {}),
|
|
99
|
+
...(req.tools !== undefined && req.tools.length > 0
|
|
100
|
+
? {
|
|
101
|
+
tools: (0, tool_mapping_1.toOpenAITools)(req.tools),
|
|
102
|
+
...((0, tool_mapping_1.toOpenAIToolChoice)(req.toolChoice) !== undefined
|
|
103
|
+
? { tool_choice: (0, tool_mapping_1.toOpenAIToolChoice)(req.toolChoice) }
|
|
104
|
+
: {}),
|
|
105
|
+
}
|
|
106
|
+
: {}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function createGrokAdapter(config) {
|
|
110
|
+
return {
|
|
111
|
+
id: "grok",
|
|
112
|
+
supports: grokSupports,
|
|
113
|
+
supportsTools: () => true,
|
|
114
|
+
async call(req) {
|
|
115
|
+
const model = req.candidate.model;
|
|
116
|
+
// F1: post-stream failures still billed tokens — attach usage.
|
|
117
|
+
const fail = (cls, message, fixHint, usage) => ({
|
|
118
|
+
ok: false,
|
|
119
|
+
failure: {
|
|
120
|
+
class: cls,
|
|
121
|
+
message,
|
|
122
|
+
provider: "grok",
|
|
123
|
+
model,
|
|
124
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
125
|
+
},
|
|
126
|
+
...(usage !== undefined ? { usage } : {}),
|
|
127
|
+
});
|
|
128
|
+
try {
|
|
129
|
+
const client = new openai_1.default({
|
|
130
|
+
apiKey: config.apiKey,
|
|
131
|
+
baseURL: GROK_BASE_URL,
|
|
132
|
+
timeout: req.timeoutMs,
|
|
133
|
+
});
|
|
134
|
+
const params = buildGrokParams(model, req);
|
|
135
|
+
const stream = await client.chat.completions.create(params);
|
|
136
|
+
let text = "";
|
|
137
|
+
let promptTokens = 0;
|
|
138
|
+
let completionTokens = 0;
|
|
139
|
+
let cachedTokens = 0;
|
|
140
|
+
let cacheWriteTokens = 0;
|
|
141
|
+
let finishReason = null;
|
|
142
|
+
const toolCallAcc = (0, tool_mapping_1.createOpenAIToolCallAccumulator)();
|
|
143
|
+
// Only delta.content is accumulated — a reasoning model's trace must
|
|
144
|
+
// never leak into the JSON buffer (deepseek reasoner rule applied).
|
|
145
|
+
for await (const chunk of stream) {
|
|
146
|
+
const choice = chunk.choices[0];
|
|
147
|
+
if (choice?.delta?.content)
|
|
148
|
+
text += choice.delta.content;
|
|
149
|
+
toolCallAcc.push(choice?.delta?.tool_calls);
|
|
150
|
+
if (choice?.finish_reason)
|
|
151
|
+
finishReason = choice.finish_reason;
|
|
152
|
+
if (chunk.usage) {
|
|
153
|
+
promptTokens = chunk.usage.prompt_tokens ?? 0;
|
|
154
|
+
completionTokens = chunk.usage.completion_tokens ?? 0;
|
|
155
|
+
cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
156
|
+
cacheWriteTokens = chunk.usage.input_tokens_details?.cache_write_tokens ?? 0;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// xAI has no service tiers — served is always standard. prompt_tokens
|
|
160
|
+
// already INCLUDES cached → tokensIn is subset-correct.
|
|
161
|
+
const usage = {
|
|
162
|
+
tokensIn: promptTokens,
|
|
163
|
+
tokensOut: completionTokens,
|
|
164
|
+
tokensCached: cachedTokens,
|
|
165
|
+
tokensCacheWrite: cacheWriteTokens,
|
|
166
|
+
servedTier: "standard",
|
|
167
|
+
};
|
|
168
|
+
// Tool-call turn (spec §4.4): surface normalized calls, skip the
|
|
169
|
+
// empty/truncation content guards below.
|
|
170
|
+
const toolCalls = toolCallAcc.finalize();
|
|
171
|
+
if (toolCalls !== undefined) {
|
|
172
|
+
return { ok: true, text, usage, toolCalls };
|
|
173
|
+
}
|
|
174
|
+
if (text.trim().length === 0) {
|
|
175
|
+
return fail("content_invalid", `empty response from Grok (finish_reason=${finishReason ?? "none"})`, undefined, usage);
|
|
176
|
+
}
|
|
177
|
+
if (finishReason === "length" && req.outputSchema !== null) {
|
|
178
|
+
return fail("content_invalid", "Grok structured output truncated (finish_reason=length)", "raise maxOutputTokens for this route", usage);
|
|
179
|
+
}
|
|
180
|
+
return { ok: true, text, usage };
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
184
|
+
const { cls, fixHint } = classifyGrokFailure(message);
|
|
185
|
+
return {
|
|
186
|
+
ok: false,
|
|
187
|
+
failure: {
|
|
188
|
+
class: cls,
|
|
189
|
+
message,
|
|
190
|
+
provider: "grok",
|
|
191
|
+
model,
|
|
192
|
+
cause: error,
|
|
193
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
async *stream(req) {
|
|
199
|
+
const model = req.candidate.model;
|
|
200
|
+
try {
|
|
201
|
+
const client = new openai_1.default({ apiKey: config.apiKey, baseURL: GROK_BASE_URL, timeout: req.timeoutMs });
|
|
202
|
+
const params = buildGrokParams(model, req);
|
|
203
|
+
const dispatchedAt = Date.now();
|
|
204
|
+
const stream = await client.chat.completions.create(params);
|
|
205
|
+
// xAI has no service tiers — served is always standard.
|
|
206
|
+
yield* (0, openai_stream_1.streamOpenAIDialect)(stream, req, dispatchedAt, {
|
|
207
|
+
provider: "grok",
|
|
208
|
+
cachedTokenSource: "details",
|
|
209
|
+
mapServedTier: () => "standard",
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
214
|
+
const { cls, fixHint } = classifyGrokFailure(message);
|
|
215
|
+
yield {
|
|
216
|
+
kind: "final",
|
|
217
|
+
result: {
|
|
218
|
+
ok: false,
|
|
219
|
+
failure: {
|
|
220
|
+
class: cls,
|
|
221
|
+
message,
|
|
222
|
+
provider: "grok",
|
|
223
|
+
model,
|
|
224
|
+
cause: error,
|
|
225
|
+
...(fixHint !== undefined ? { fixHint } : {}),
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|