@mupt-ai/dari-gateway 0.2.0 → 0.3.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/README.md +8 -4
- package/dist/bun.d.ts +2 -0
- package/dist/bun.js +4 -0
- package/dist/context/eval_catalog.d.ts +3 -0
- package/dist/context/eval_catalog.js +7 -0
- package/dist/context/interaction_fingerprint.d.ts +27 -0
- package/dist/context/interaction_fingerprint.js +519 -0
- package/dist/context/interaction_fingerprint_format.d.ts +42 -0
- package/dist/context/interaction_fingerprint_format.js +113 -0
- package/dist/context/interaction_lease_depth.d.ts +2 -0
- package/dist/context/interaction_lease_depth.js +110 -0
- package/dist/context/lease_history.d.ts +7 -0
- package/dist/context/lease_history.js +158 -0
- package/dist/context/pricing.d.ts +4 -0
- package/dist/context/pricing.js +27 -0
- package/dist/context/provider_prompt_accounting.d.ts +14 -0
- package/dist/context/provider_prompt_accounting.js +187 -0
- package/dist/context/routing_context.d.ts +40 -0
- package/dist/context/routing_context.js +211 -0
- package/dist/http/auth.d.ts +2 -0
- package/dist/http/auth.js +35 -0
- package/dist/http/errors.d.ts +19 -0
- package/dist/http/errors.js +89 -0
- package/dist/http/handler.d.ts +12 -0
- package/dist/http/handler.js +88 -0
- package/dist/http/http2_server.d.ts +6 -0
- package/dist/http/http2_server.js +103 -0
- package/dist/http/serve.d.ts +20 -0
- package/dist/http/serve.js +78 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +9 -0
- package/dist/ingress/anthropic_messages.d.ts +3 -0
- package/dist/ingress/anthropic_messages.js +122 -0
- package/dist/ingress/anthropic_models.d.ts +1 -0
- package/dist/ingress/anthropic_models.js +23 -0
- package/dist/ingress/chat_completions.d.ts +2 -0
- package/dist/ingress/chat_completions.js +44 -0
- package/dist/ingress/claude_code/request_context.d.ts +2 -0
- package/dist/ingress/claude_code/request_context.js +31 -0
- package/dist/ingress/codex.d.ts +3 -0
- package/dist/ingress/codex.js +69 -0
- package/dist/ingress/codex_models.d.ts +2 -0
- package/dist/ingress/codex_models.js +89 -0
- package/dist/ingress/json.d.ts +1 -0
- package/dist/ingress/json.js +95 -0
- package/dist/ingress/models.d.ts +1 -0
- package/dist/ingress/models.js +65 -0
- package/dist/ingress/muse_code.d.ts +2 -0
- package/dist/ingress/muse_code.js +8 -0
- package/dist/ingress/muse_models.d.ts +9 -0
- package/dist/ingress/muse_models.js +32 -0
- package/dist/interaction/capabilities.d.ts +3 -0
- package/dist/interaction/capabilities.js +24 -0
- package/dist/interaction/image.d.ts +4 -0
- package/dist/interaction/image.js +13 -0
- package/dist/interaction/portable_reasoning_state.d.ts +4 -0
- package/dist/interaction/portable_reasoning_state.js +18 -0
- package/dist/interaction/provider_continuation_state.d.ts +6 -0
- package/dist/interaction/provider_continuation_state.js +27 -0
- package/dist/interaction/tool_identity.d.ts +10 -0
- package/dist/interaction/tool_identity.js +41 -0
- package/dist/interaction/types.d.ts +204 -0
- package/dist/interaction/types.js +5 -0
- package/dist/models/catalog.d.ts +35 -0
- package/dist/models/catalog.js +232 -0
- package/dist/models/context_limits.d.ts +2 -0
- package/dist/models/context_limits.js +7 -0
- package/dist/models/execution_provider.d.ts +9 -0
- package/dist/models/execution_provider.js +17 -0
- package/dist/models/gateways.d.ts +11 -0
- package/dist/models/gateways.js +45 -0
- package/dist/models/ids.d.ts +1 -0
- package/dist/models/ids.js +15 -0
- package/dist/models/provider_defaults.d.ts +4 -0
- package/dist/models/provider_defaults.js +44 -0
- package/dist/models/runtime_overrides.d.ts +7 -0
- package/dist/models/runtime_overrides.js +226 -0
- package/dist/models/subscriptions.d.ts +8 -0
- package/dist/models/subscriptions.js +37 -0
- package/dist/observability/errors.d.ts +8 -0
- package/dist/observability/errors.js +11 -0
- package/dist/platform/platform.d.ts +156 -0
- package/dist/platform/platform.js +11 -0
- package/dist/platform/routing_contract.d.ts +2 -0
- package/dist/platform/routing_contract.js +5 -0
- package/dist/protocol/input/anthropic_messages.d.ts +2 -0
- package/dist/protocol/input/anthropic_messages.js +494 -0
- package/dist/protocol/input/chat_completions.d.ts +4 -0
- package/dist/protocol/input/chat_completions.js +214 -0
- package/dist/protocol/input/chat_completions_validation.d.ts +2 -0
- package/dist/protocol/input/chat_completions_validation.js +258 -0
- package/dist/protocol/input/openai_responses.d.ts +2 -0
- package/dist/protocol/input/openai_responses.js +666 -0
- package/dist/protocol/input/router_model.d.ts +7 -0
- package/dist/protocol/input/router_model.js +43 -0
- package/dist/protocol/output/anthropic_messages.d.ts +10 -0
- package/dist/protocol/output/anthropic_messages.js +15 -0
- package/dist/protocol/output/anthropic_messages_output.d.ts +10 -0
- package/dist/protocol/output/anthropic_messages_output.js +124 -0
- package/dist/protocol/output/anthropic_messages_stream.d.ts +16 -0
- package/dist/protocol/output/anthropic_messages_stream.js +267 -0
- package/dist/protocol/output/chat_completions.d.ts +29 -0
- package/dist/protocol/output/chat_completions.js +406 -0
- package/dist/protocol/output/chat_reasoning_detail.d.ts +2 -0
- package/dist/protocol/output/chat_reasoning_detail.js +13 -0
- package/dist/protocol/output/delivered_stream_snapshot.d.ts +10 -0
- package/dist/protocol/output/delivered_stream_snapshot.js +31 -0
- package/dist/protocol/output/openai_responses.d.ts +10 -0
- package/dist/protocol/output/openai_responses.js +14 -0
- package/dist/protocol/output/openai_responses_output.d.ts +14 -0
- package/dist/protocol/output/openai_responses_output.js +125 -0
- package/dist/protocol/output/openai_responses_stream.d.ts +18 -0
- package/dist/protocol/output/openai_responses_stream.js +546 -0
- package/dist/protocol/output/sse_stream.d.ts +31 -0
- package/dist/protocol/output/sse_stream.js +67 -0
- package/dist/providers/anthropic_safeguards.d.ts +11 -0
- package/dist/providers/anthropic_safeguards.js +81 -0
- package/dist/providers/aws_assume_role.d.ts +17 -0
- package/dist/providers/aws_assume_role.js +107 -0
- package/dist/providers/cancel_estimate.d.ts +43 -0
- package/dist/providers/cancel_estimate.js +89 -0
- package/dist/providers/execution.d.ts +72 -0
- package/dist/providers/execution.js +491 -0
- package/dist/providers/model_capabilities.d.ts +11 -0
- package/dist/providers/model_capabilities.js +29 -0
- package/dist/providers/pi.d.ts +65 -0
- package/dist/providers/pi.js +325 -0
- package/dist/providers/pi_context.d.ts +7 -0
- package/dist/providers/pi_context.js +405 -0
- package/dist/providers/pi_options.d.ts +11 -0
- package/dist/providers/pi_options.js +410 -0
- package/dist/providers/pi_output.d.ts +2 -0
- package/dist/providers/pi_output.js +453 -0
- package/dist/providers/provider_attempt_runner.d.ts +55 -0
- package/dist/providers/provider_attempt_runner.js +90 -0
- package/dist/providers/provider_call.d.ts +77 -0
- package/dist/providers/provider_call.js +296 -0
- package/dist/providers/provider_reported_cost.d.ts +10 -0
- package/dist/providers/provider_reported_cost.js +123 -0
- package/dist/providers/reasoning.d.ts +12 -0
- package/dist/providers/reasoning.js +30 -0
- package/dist/providers/response_capture.d.ts +23 -0
- package/dist/providers/response_capture.js +47 -0
- package/dist/providers/stream_finalization.d.ts +46 -0
- package/dist/providers/stream_finalization.js +165 -0
- package/dist/providers/subscription_limits.d.ts +33 -0
- package/dist/providers/subscription_limits.js +179 -0
- package/dist/providers/subscription_usage.d.ts +10 -0
- package/dist/providers/subscription_usage.js +79 -0
- package/dist/runtime/claude_code/auxiliary_routing.d.ts +3 -0
- package/dist/runtime/claude_code/auxiliary_routing.js +60 -0
- package/dist/runtime/customer_disconnect.d.ts +20 -0
- package/dist/runtime/customer_disconnect.js +49 -0
- package/dist/runtime/explicit_model.d.ts +7 -0
- package/dist/runtime/explicit_model.js +57 -0
- package/dist/runtime/harness_identity/conversation.d.ts +33 -0
- package/dist/runtime/harness_identity/conversation.js +39 -0
- package/dist/runtime/harness_identity/extract.d.ts +8 -0
- package/dist/runtime/harness_identity/extract.js +214 -0
- package/dist/runtime/harness_identity/index.d.ts +2 -0
- package/dist/runtime/harness_identity/index.js +2 -0
- package/dist/runtime/prepare_routed_completion.d.ts +33 -0
- package/dist/runtime/prepare_routed_completion.js +186 -0
- package/dist/runtime/provider_stream_lifecycle.d.ts +31 -0
- package/dist/runtime/provider_stream_lifecycle.js +88 -0
- package/dist/runtime/provider_stream_outcome.d.ts +23 -0
- package/dist/runtime/provider_stream_outcome.js +55 -0
- package/dist/runtime/request_tags.d.ts +7 -0
- package/dist/runtime/request_tags.js +33 -0
- package/dist/runtime/routed_completion.d.ts +17 -0
- package/dist/runtime/routed_completion.js +80 -0
- package/dist/runtime/routed_protocol.d.ts +30 -0
- package/dist/runtime/routed_protocol.js +1 -0
- package/dist/runtime/routed_runtime.d.ts +40 -0
- package/dist/runtime/routed_runtime.js +535 -0
- package/dist/runtime/routing_lease.d.ts +26 -0
- package/dist/runtime/routing_lease.js +210 -0
- package/dist/runtime/runtime_reporter.d.ts +71 -0
- package/dist/runtime/runtime_reporter.js +35 -0
- package/dist/runtime/strict_provider_access.d.ts +6 -0
- package/dist/runtime/strict_provider_access.js +40 -0
- package/dist/self_host/config.d.ts +46 -0
- package/dist/self_host/config.js +105 -0
- package/dist/self_host/main.d.ts +16 -0
- package/dist/self_host/main.js +95 -0
- package/dist/self_host/platform.d.ts +13 -0
- package/dist/self_host/platform.js +50 -0
- package/dist/self_host/prefix_store.d.ts +46 -0
- package/dist/self_host/prefix_store.js +261 -0
- package/dist/self_host/resolve.d.ts +28 -0
- package/dist/self_host/resolve.js +167 -0
- package/dist/self_host/subscriptions/access.d.ts +10 -0
- package/dist/self_host/subscriptions/access.js +37 -0
- package/dist/self_host/subscriptions/http.d.ts +15 -0
- package/dist/self_host/subscriptions/http.js +187 -0
- package/dist/self_host/subscriptions/index.d.ts +24 -0
- package/dist/self_host/subscriptions/index.js +24 -0
- package/dist/self_host/subscriptions/oauth.d.ts +59 -0
- package/dist/self_host/subscriptions/oauth.js +376 -0
- package/dist/self_host/subscriptions/store.d.ts +78 -0
- package/dist/self_host/subscriptions/store.js +236 -0
- package/dist/strategies/auto_routing_selector.d.ts +12 -0
- package/dist/strategies/auto_routing_selector.js +61 -0
- package/dist/strategies/eval_relevance.d.ts +17 -0
- package/dist/strategies/eval_relevance.js +32 -0
- package/dist/strategies/fallback_decision.d.ts +8 -0
- package/dist/strategies/fallback_decision.js +17 -0
- package/dist/strategies/priority_selector.d.ts +7 -0
- package/dist/strategies/priority_selector.js +37 -0
- package/dist/strategies/route_decision.d.ts +22 -0
- package/dist/strategies/route_decision.js +65 -0
- package/dist/strategies/routing.d.ts +74 -0
- package/dist/strategies/routing.js +280 -0
- package/dist/strategies/selector_projection.d.ts +15 -0
- package/dist/strategies/selector_projection.js +161 -0
- package/dist/telemetry/background.d.ts +7 -0
- package/dist/telemetry/background.js +33 -0
- package/dist/telemetry/benchmark_replay.d.ts +37 -0
- package/dist/telemetry/benchmark_replay.js +108 -0
- package/dist/telemetry/billing_finalization.d.ts +64 -0
- package/dist/telemetry/billing_finalization.js +96 -0
- package/dist/telemetry/ingest_values.d.ts +4 -0
- package/dist/telemetry/ingest_values.js +12 -0
- package/dist/telemetry/model_cost.d.ts +3 -0
- package/dist/telemetry/model_cost.js +15 -0
- package/dist/telemetry/prefix_state.d.ts +47 -0
- package/dist/telemetry/prefix_state.js +116 -0
- package/dist/telemetry/report.d.ts +88 -0
- package/dist/telemetry/report.js +621 -0
- package/dist/telemetry/requests/interaction_observability.d.ts +45 -0
- package/dist/telemetry/requests/interaction_observability.js +180 -0
- package/dist/telemetry/requests/retained_interaction_request.d.ts +8 -0
- package/dist/telemetry/requests/retained_interaction_request.js +10 -0
- package/dist/telemetry/scrub.d.ts +2 -0
- package/dist/telemetry/scrub.js +31 -0
- package/dist/telemetry/skills/claude/catalog.d.ts +6 -0
- package/dist/telemetry/skills/claude/catalog.js +99 -0
- package/dist/telemetry/skills/claude/file_reads.d.ts +4 -0
- package/dist/telemetry/skills/claude/file_reads.js +110 -0
- package/dist/telemetry/skills/claude/observations.d.ts +3 -0
- package/dist/telemetry/skills/claude/observations.js +366 -0
- package/dist/telemetry/skills/codex/catalog.d.ts +11 -0
- package/dist/telemetry/skills/codex/catalog.js +138 -0
- package/dist/telemetry/skills/codex/exec_file_reads.d.ts +9 -0
- package/dist/telemetry/skills/codex/exec_file_reads.js +36 -0
- package/dist/telemetry/skills/codex/explicit.d.ts +3 -0
- package/dist/telemetry/skills/codex/explicit.js +90 -0
- package/dist/telemetry/skills/codex/file_reads.d.ts +4 -0
- package/dist/telemetry/skills/codex/file_reads.js +37 -0
- package/dist/telemetry/skills/codex/identity.d.ts +2 -0
- package/dist/telemetry/skills/codex/identity.js +20 -0
- package/dist/telemetry/skills/observations.d.ts +21 -0
- package/dist/telemetry/skills/observations.js +41 -0
- package/dist/telemetry/skills/paths.d.ts +11 -0
- package/dist/telemetry/skills/paths.js +61 -0
- package/dist/telemetry/skills/pi.d.ts +6 -0
- package/dist/telemetry/skills/pi.js +223 -0
- package/dist/telemetry/skills/shell_file_reads.d.ts +7 -0
- package/dist/telemetry/skills/shell_file_reads.js +226 -0
- package/dist/telemetry/skills/shell_words.d.ts +13 -0
- package/dist/telemetry/skills/shell_words.js +189 -0
- package/dist/telemetry/tools/input.d.ts +2 -0
- package/dist/telemetry/tools/input.js +14 -0
- package/dist/telemetry/tools/observations.d.ts +29 -0
- package/dist/telemetry/tools/observations.js +247 -0
- package/dist/telemetry/usage.d.ts +57 -0
- package/dist/telemetry/usage.js +136 -0
- package/dist/types.d.ts +97 -0
- package/dist/types.js +1 -0
- package/package.json +22 -7
- package/src/bun.ts +2 -2
- package/src/context/eval_catalog.ts +1 -1
- package/src/context/interaction_fingerprint.ts +9 -9
- package/src/context/interaction_fingerprint_format.ts +1 -1
- package/src/context/interaction_lease_depth.ts +1 -1
- package/src/context/pricing.ts +6 -3
- package/src/context/provider_prompt_accounting.ts +5 -5
- package/src/context/routing_context.ts +16 -16
- package/src/http/auth.ts +1 -1
- package/src/http/handler.ts +15 -8
- package/src/http/serve.ts +3 -3
- package/src/index.ts +14 -6
- package/src/ingress/anthropic_messages.ts +12 -12
- package/src/ingress/anthropic_models.ts +1 -1
- package/src/ingress/chat_completions.ts +17 -10
- package/src/ingress/claude_code/request_context.ts +2 -2
- package/src/ingress/codex.ts +14 -10
- package/src/ingress/codex_models.ts +4 -4
- package/src/ingress/json.ts +1 -1
- package/src/ingress/models.ts +22 -10
- package/src/ingress/muse_code.ts +9 -0
- package/src/ingress/muse_models.ts +36 -0
- package/src/interaction/capabilities.ts +1 -1
- package/src/interaction/portable_reasoning_state.ts +1 -1
- package/src/interaction/provider_continuation_state.ts +1 -1
- package/src/interaction/tool_identity.ts +2 -2
- package/src/interaction/types.ts +2 -0
- package/src/models/catalog.ts +310 -0
- package/src/models/context_limits.ts +1 -1
- package/src/models/execution_provider.ts +5 -2
- package/src/models/ids.ts +1 -1
- package/src/models/provider_defaults.ts +4 -1
- package/src/models/runtime_overrides.ts +23 -1
- package/src/models/subscriptions.ts +54 -0
- package/src/observability/errors.ts +2 -2
- package/src/platform/platform.ts +9 -5
- package/src/protocol/input/anthropic_messages.ts +7 -7
- package/src/protocol/input/chat_completions.ts +8 -6
- package/src/protocol/input/chat_completions_validation.ts +6 -5
- package/src/protocol/input/openai_responses.ts +6 -6
- package/src/protocol/output/anthropic_messages.ts +3 -3
- package/src/protocol/output/anthropic_messages_output.ts +6 -4
- package/src/protocol/output/anthropic_messages_stream.ts +7 -7
- package/src/protocol/output/chat_completions.ts +13 -13
- package/src/protocol/output/chat_reasoning_detail.ts +1 -1
- package/src/protocol/output/openai_responses.ts +3 -3
- package/src/protocol/output/openai_responses_output.ts +4 -2
- package/src/protocol/output/openai_responses_stream.ts +6 -6
- package/src/protocol/output/sse_stream.ts +3 -3
- package/src/providers/anthropic_safeguards.ts +2 -2
- package/src/providers/aws_assume_role.ts +2 -2
- package/src/providers/cancel_estimate.ts +1 -1
- package/src/providers/execution.ts +17 -17
- package/src/providers/pi.ts +34 -19
- package/src/providers/pi_context.ts +6 -6
- package/src/providers/pi_options.ts +27 -11
- package/src/providers/pi_output.ts +5 -5
- package/src/providers/provider_attempt_runner.ts +1 -1
- package/src/providers/provider_call.ts +21 -17
- package/src/providers/provider_reported_cost.ts +3 -3
- package/src/providers/reasoning.ts +2 -2
- package/src/providers/stream_finalization.ts +9 -9
- package/src/providers/subscription_limits.ts +24 -7
- package/src/runtime/claude_code/auxiliary_routing.ts +5 -5
- package/src/runtime/customer_disconnect.ts +1 -1
- package/src/runtime/explicit_model.ts +19 -20
- package/src/runtime/harness_identity/conversation.ts +1 -1
- package/src/runtime/harness_identity/extract.ts +3 -3
- package/src/runtime/harness_identity/index.ts +2 -2
- package/src/runtime/prepare_routed_completion.ts +35 -16
- package/src/runtime/provider_stream_lifecycle.ts +1 -1
- package/src/runtime/provider_stream_outcome.ts +2 -2
- package/src/runtime/request_tags.ts +2 -2
- package/src/runtime/routed_completion.ts +11 -11
- package/src/runtime/routed_protocol.ts +2 -2
- package/src/runtime/routed_runtime.ts +20 -19
- package/src/runtime/routing_lease.ts +7 -7
- package/src/runtime/runtime_reporter.ts +3 -3
- package/src/runtime/strict_provider_access.ts +42 -0
- package/src/self_host/main.ts +12 -12
- package/src/self_host/platform.ts +5 -5
- package/src/self_host/prefix_store.ts +2 -2
- package/src/self_host/resolve.ts +17 -31
- package/src/self_host/subscriptions/access.ts +2 -2
- package/src/self_host/subscriptions/http.ts +2 -2
- package/src/self_host/subscriptions/index.ts +4 -4
- package/src/self_host/subscriptions/oauth.ts +139 -8
- package/src/self_host/subscriptions/store.ts +2 -1
- package/src/strategies/auto_routing_selector.ts +2 -2
- package/src/strategies/eval_relevance.ts +3 -3
- package/src/strategies/priority_selector.ts +1 -1
- package/src/strategies/route_decision.ts +7 -7
- package/src/strategies/routing.ts +10 -10
- package/src/strategies/selector_projection.ts +2 -2
- package/src/telemetry/billing_finalization.ts +3 -3
- package/src/telemetry/model_cost.ts +1 -1
- package/src/telemetry/prefix_state.ts +4 -4
- package/src/telemetry/report.ts +21 -21
- package/src/telemetry/requests/interaction_observability.ts +1 -1
- package/src/telemetry/requests/retained_interaction_request.ts +1 -1
- package/src/telemetry/skills/claude/catalog.ts +1 -1
- package/src/telemetry/skills/claude/file_reads.ts +6 -6
- package/src/telemetry/skills/claude/observations.ts +3 -3
- package/src/telemetry/skills/codex/catalog.ts +3 -3
- package/src/telemetry/skills/codex/exec_file_reads.ts +4 -4
- package/src/telemetry/skills/codex/explicit.ts +3 -3
- package/src/telemetry/skills/codex/file_reads.ts +5 -5
- package/src/telemetry/skills/observations.ts +7 -7
- package/src/telemetry/skills/pi.ts +3 -3
- package/src/telemetry/skills/shell_file_reads.ts +2 -2
- package/src/telemetry/skills/shell_words.ts +1 -1
- package/src/telemetry/tools/input.ts +1 -1
- package/src/telemetry/tools/observations.ts +9 -9
- package/src/telemetry/usage.ts +5 -5
- package/src/types.ts +20 -3
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { providerForModel } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
/** Actual serving provider for a canonical model on a resolved managed router. */
|
|
3
|
+
export function executionProviderForModel(credentials, model) {
|
|
4
|
+
const configured = credentials.model_configs?.[model]?.provider?.trim();
|
|
5
|
+
return configured || providerForModel(model);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The key that serves a model on a resolved router: a platform-supplied
|
|
9
|
+
* credential first, then the resolved provider key. Missing declarations are
|
|
10
|
+
* user-owned so unknown platform data cannot trigger managed-key billing.
|
|
11
|
+
*/
|
|
12
|
+
export function keySourceForModel(credentials, model) {
|
|
13
|
+
const supplied = credentials.provider_credentials?.[model];
|
|
14
|
+
if (supplied)
|
|
15
|
+
return supplied.subscription ? "subscription" : "user";
|
|
16
|
+
return credentials.provider_key_sources?.[executionProviderForModel(credentials, model)] ?? "user";
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type Gateway = {
|
|
2
|
+
label: string;
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
compat: Record<string, unknown>;
|
|
5
|
+
requestFields(options: {
|
|
6
|
+
zdr: boolean;
|
|
7
|
+
}): Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
export declare function gatewayFor(provider: unknown): Gateway | undefined;
|
|
10
|
+
/** Deep-merges gateway routing fields into a provider request body. */
|
|
11
|
+
export declare function payloadWithGatewayFields(payload: Record<string, unknown>, fields: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { isRecord } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
function gateway(spec) {
|
|
3
|
+
return { ...spec, compat: { thinkingFormat: "openrouter", ...spec.compat } };
|
|
4
|
+
}
|
|
5
|
+
const GATEWAYS = {
|
|
6
|
+
openrouter: gateway({
|
|
7
|
+
label: "OpenRouter",
|
|
8
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
9
|
+
requestFields: ({ zdr }) => zdr ? { provider: { data_collection: "deny", zdr: true } } : {},
|
|
10
|
+
}),
|
|
11
|
+
// https://vercel.com/docs/ai-gateway/models-and-providers/provider-options
|
|
12
|
+
"vercel-ai-gateway": gateway({
|
|
13
|
+
label: "Vercel AI Gateway",
|
|
14
|
+
baseUrl: "https://ai-gateway.vercel.sh/v1",
|
|
15
|
+
// Pi detects OpenRouter's role, caching, and session conventions from its
|
|
16
|
+
// URL but not Vercel's: the system role reaches every upstream, and
|
|
17
|
+
// x-session-affinity keeps prompt-cache locality.
|
|
18
|
+
compat: {
|
|
19
|
+
supportsDeveloperRole: false,
|
|
20
|
+
sendSessionAffinityHeaders: true,
|
|
21
|
+
sessionAffinityFormat: "openai",
|
|
22
|
+
},
|
|
23
|
+
// Vercel passes requests through untouched unless asked to place the
|
|
24
|
+
// cache breakpoints Anthropic models need.
|
|
25
|
+
requestFields: ({ zdr }) => ({
|
|
26
|
+
providerOptions: {
|
|
27
|
+
gateway: { caching: "auto", ...(zdr ? { zeroDataRetention: true } : {}) },
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
export function gatewayFor(provider) {
|
|
33
|
+
return typeof provider === "string" ? GATEWAYS[provider.toLowerCase()] : undefined;
|
|
34
|
+
}
|
|
35
|
+
/** Deep-merges gateway routing fields into a provider request body. */
|
|
36
|
+
export function payloadWithGatewayFields(payload, fields) {
|
|
37
|
+
const merged = { ...payload };
|
|
38
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
39
|
+
const current = merged[key];
|
|
40
|
+
merged[key] = isRecord(current) && isRecord(value)
|
|
41
|
+
? payloadWithGatewayFields(current, value)
|
|
42
|
+
: value;
|
|
43
|
+
}
|
|
44
|
+
return merged;
|
|
45
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function requireCandidateModels(value: unknown): string[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { providerForModel } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
import { HttpError } from "../http/errors.js";
|
|
3
|
+
export function requireCandidateModels(value) {
|
|
4
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
5
|
+
throw new HttpError(400, "routing.candidate_models must include at least one model.", "invalid_routing_request", "routing.candidate_models");
|
|
6
|
+
}
|
|
7
|
+
const candidates = value.map((item, index) => {
|
|
8
|
+
if (typeof item !== "string" || item.trim() === "") {
|
|
9
|
+
throw new HttpError(400, "routing.candidate_models must contain non-empty strings.", "invalid_routing_request", `routing.candidate_models[${index}]`);
|
|
10
|
+
}
|
|
11
|
+
providerForModel(item);
|
|
12
|
+
return item;
|
|
13
|
+
});
|
|
14
|
+
return [...new Set(candidates)];
|
|
15
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Display label for a provider slug; custom slugs title-case per segment. */
|
|
2
|
+
export declare function providerLabel(provider: string): string;
|
|
3
|
+
/** Endpoint fallback when neither the resolved config nor the registry has one. */
|
|
4
|
+
export declare function defaultBaseUrl(provider: string): string | null;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { gatewayFor } from "./gateways.js";
|
|
2
|
+
// Built-in model provider presentation and endpoint defaults; gateways carry
|
|
3
|
+
// their own. Mirrors the hosted Dari model catalog's provider defaults; keep
|
|
4
|
+
// the two in sync when adding a provider.
|
|
5
|
+
const PROVIDER_LABELS = {
|
|
6
|
+
openai: "OpenAI",
|
|
7
|
+
anthropic: "Anthropic",
|
|
8
|
+
fireworks: "Fireworks",
|
|
9
|
+
meta: "Meta",
|
|
10
|
+
xai: "xAI",
|
|
11
|
+
dari: "Dari",
|
|
12
|
+
"amazon-bedrock": "Amazon Bedrock",
|
|
13
|
+
azure: "Microsoft Azure",
|
|
14
|
+
};
|
|
15
|
+
/** Display label for a provider slug; custom slugs title-case per segment. */
|
|
16
|
+
export function providerLabel(provider) {
|
|
17
|
+
const known = PROVIDER_LABELS[provider.toLowerCase()] ?? gatewayFor(provider)?.label;
|
|
18
|
+
if (known)
|
|
19
|
+
return known;
|
|
20
|
+
return (provider
|
|
21
|
+
.split(/[._-]+/)
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
24
|
+
.join(" ") || provider);
|
|
25
|
+
}
|
|
26
|
+
const PROVIDER_BASE_URLS = {
|
|
27
|
+
openai: "https://api.openai.com/v1",
|
|
28
|
+
anthropic: "https://api.anthropic.com",
|
|
29
|
+
fireworks: "https://api.fireworks.ai/inference/v1",
|
|
30
|
+
xai: "https://api.x.ai/v1",
|
|
31
|
+
// Meta's Model API serves OpenAI Responses and Chat Completions here, and
|
|
32
|
+
// Anthropic Messages at https://api.meta.ai.
|
|
33
|
+
meta: "https://api.meta.ai/v1",
|
|
34
|
+
// Pi-ai derives the effective AWS region from the endpoint unless the
|
|
35
|
+
// model config overrides base_url or the native id is an inference profile
|
|
36
|
+
// ARN, so this default only pins us-east-1 when nothing else is configured.
|
|
37
|
+
"amazon-bedrock": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
38
|
+
// Microsoft Azure has no default: the platform derives each model's base
|
|
39
|
+
// URL from the credential's resource endpoint at resolve time.
|
|
40
|
+
};
|
|
41
|
+
/** Endpoint fallback when neither the resolved config nor the registry has one. */
|
|
42
|
+
export function defaultBaseUrl(provider) {
|
|
43
|
+
return PROVIDER_BASE_URLS[provider.toLowerCase()] ?? gatewayFor(provider)?.baseUrl ?? null;
|
|
44
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function providerThinkingLevelOverrides(provider: string): Record<string, string> | undefined;
|
|
2
|
+
/** Registered Pi metadata with the serving provider's thinking level overrides. */
|
|
3
|
+
export declare function withThinkingLevelOverrides(provider: string, registered: Record<string, unknown> | undefined): Record<string, unknown> | undefined;
|
|
4
|
+
export declare function offRequiresWireNone(modelId: string): boolean;
|
|
5
|
+
export declare function contextWindowOverride(modelId: string): number | undefined;
|
|
6
|
+
export declare function inputModalitiesOverride(modelId: string): string[] | undefined;
|
|
7
|
+
export declare function runtimeCompat(provider: string, registered: Record<string, unknown> | undefined, modelId?: string): unknown;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { canonicalModelId, isRecord } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
import { gatewayFor } from "./gateways.js";
|
|
3
|
+
const MODEL_CONTEXT_OVERRIDES = {
|
|
4
|
+
// Selector and title models are not router candidate configs, so their
|
|
5
|
+
// context windows cannot depend on the Pi registry carrying them.
|
|
6
|
+
"openai/gpt-5.6-luna": 1_050_000,
|
|
7
|
+
"openai/gpt-6-luna": 1_050_000,
|
|
8
|
+
};
|
|
9
|
+
// Models whose true non-reasoning mode is the provider-literal effort "none"
|
|
10
|
+
// rather than omitting the field. Live-validated: Fireworks DeepSeek thinks
|
|
11
|
+
// by default when the request carries no reasoning_effort (and pi-ai's
|
|
12
|
+
// completions path drops Dari's "off" before serializing), so a client's
|
|
13
|
+
// explicit off must be injected into the provider payload as
|
|
14
|
+
// reasoning_effort "none" (verified quiet: ~2 output tokens vs ~40 thinking).
|
|
15
|
+
// OpenAI gpt-5.x models need no entry: the pi-ai registry already maps their
|
|
16
|
+
// "off" to wire "none".
|
|
17
|
+
// Models whose catalog metadata is not yet bundled in the installed Pi registry
|
|
18
|
+
// but need explicit compat overrides to produce correct provider payloads.
|
|
19
|
+
const MODEL_COMPAT_OVERRIDES = {
|
|
20
|
+
// The Pi registry does not carry Fable 5.1, Opus 5.5, Sonnet 5.5, and Opus 5's
|
|
21
|
+
// adaptive-thinking compatibility for every serving provider (OpenRouter,
|
|
22
|
+
// Bedrock), so it is declared here. Sonnet 5 is in the Pi
|
|
23
|
+
// registry (with forceAdaptiveThinking), but it's missing supportsTemperature
|
|
24
|
+
// (the Anthropic docs confirm non-default temperature returns 400).
|
|
25
|
+
"anthropic/claude-fable-5-1": {
|
|
26
|
+
forceAdaptiveThinking: true,
|
|
27
|
+
supportsTemperature: false,
|
|
28
|
+
},
|
|
29
|
+
"anthropic/claude-opus-5-5": {
|
|
30
|
+
forceAdaptiveThinking: true,
|
|
31
|
+
supportsTemperature: false,
|
|
32
|
+
supportsMidConvoEffort: true,
|
|
33
|
+
},
|
|
34
|
+
"anthropic/claude-opus-5": {
|
|
35
|
+
forceAdaptiveThinking: true,
|
|
36
|
+
supportsTemperature: false,
|
|
37
|
+
},
|
|
38
|
+
"anthropic/claude-sonnet-5-5": {
|
|
39
|
+
forceAdaptiveThinking: true,
|
|
40
|
+
supportsTemperature: false,
|
|
41
|
+
supportsMidConvoEffort: true,
|
|
42
|
+
},
|
|
43
|
+
"anthropic/claude-sonnet-5": {
|
|
44
|
+
supportsTemperature: false,
|
|
45
|
+
},
|
|
46
|
+
"anthropic/claude-haiku-5-5": {
|
|
47
|
+
forceAdaptiveThinking: true,
|
|
48
|
+
supportsTemperature: false,
|
|
49
|
+
},
|
|
50
|
+
// GPT-6 Astra always reasons and OpenAI rejects temperature on it (400
|
|
51
|
+
// "Unsupported parameter: 'temperature'"), on api.openai.com and on Azure
|
|
52
|
+
// alike. The OpenAI transports do not read this flag themselves, so
|
|
53
|
+
// buildOptions drops the parameter. Live-validated 2026-09-15.
|
|
54
|
+
"openai/gpt-6-astra": {
|
|
55
|
+
supportsTemperature: false,
|
|
56
|
+
},
|
|
57
|
+
// GPT-6 Sol and Luna are newer than the installed Pi registry. They retain
|
|
58
|
+
// the GPT-5.6 Responses feature set, including explicit prompt caching and
|
|
59
|
+
// deferred tool loading. Keep this local until Pi ships their metadata.
|
|
60
|
+
"openai/gpt-6.1-sol": {
|
|
61
|
+
supportsStrictMode: true,
|
|
62
|
+
supportsOpenAIGrammarTools: true,
|
|
63
|
+
supportsAdditionalTools: true,
|
|
64
|
+
supportsToolSearch: true,
|
|
65
|
+
supportsExplicitPromptCacheMode: true,
|
|
66
|
+
supportsReasoningConfigurationUpdate: true,
|
|
67
|
+
},
|
|
68
|
+
"openai/gpt-6-sol": {
|
|
69
|
+
supportsStrictMode: true,
|
|
70
|
+
supportsOpenAIGrammarTools: true,
|
|
71
|
+
supportsAdditionalTools: true,
|
|
72
|
+
supportsToolSearch: true,
|
|
73
|
+
supportsExplicitPromptCacheMode: true,
|
|
74
|
+
supportsReasoningConfigurationUpdate: true,
|
|
75
|
+
},
|
|
76
|
+
"openai/gpt-6-luna": {
|
|
77
|
+
supportsStrictMode: true,
|
|
78
|
+
supportsOpenAIGrammarTools: true,
|
|
79
|
+
supportsAdditionalTools: true,
|
|
80
|
+
supportsToolSearch: true,
|
|
81
|
+
supportsExplicitPromptCacheMode: true,
|
|
82
|
+
supportsReasoningConfigurationUpdate: true,
|
|
83
|
+
},
|
|
84
|
+
// Kimi K3 is not in the installed Pi registry under the Fireworks provider.
|
|
85
|
+
// Fireworks returns preserved thinking in reasoning_content and accepts the
|
|
86
|
+
// model's documented low/high/max reasoning_effort values.
|
|
87
|
+
"moonshotai/Kimi-K3": {
|
|
88
|
+
thinkingFormat: "deepseek",
|
|
89
|
+
supportsReasoningEffort: true,
|
|
90
|
+
requiresReasoningContentOnAssistantMessages: true,
|
|
91
|
+
},
|
|
92
|
+
// DeepSeek V4 Flash 0731 is not in the installed Pi registry (new model),
|
|
93
|
+
// so it needs the same compat overrides as Kimi K3 for correct deepseek-
|
|
94
|
+
// format response parsing and multi-turn reasoning continuity.
|
|
95
|
+
"deepseek-ai/DeepSeek-V4-Flash-0731": {
|
|
96
|
+
thinkingFormat: "deepseek",
|
|
97
|
+
supportsReasoningEffort: true,
|
|
98
|
+
requiresReasoningContentOnAssistantMessages: true,
|
|
99
|
+
},
|
|
100
|
+
"deepseek-ai/DeepSeek-V4.1-Flash-1017": {
|
|
101
|
+
thinkingFormat: "deepseek",
|
|
102
|
+
supportsReasoningEffort: true,
|
|
103
|
+
requiresReasoningContentOnAssistantMessages: true,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
// Serving-provider specific compat that replaces the model-level override
|
|
107
|
+
// above. Microsoft Foundry serves DeepSeek through its own OpenAI-compatible
|
|
108
|
+
// endpoint: the `thinking` parameter the deepseek thinking format sends is
|
|
109
|
+
// rejected (400 unrecognized_request_argument), plain reasoning_effort
|
|
110
|
+
// (none/low/high/max) is accepted, and reasoning comes back in
|
|
111
|
+
// reasoning_content. Grok on Foundry takes reasoning_effort the same way.
|
|
112
|
+
// Live-validated against a Foundry resource on 2026-09-15.
|
|
113
|
+
const PROVIDER_MODEL_COMPAT_OVERRIDES = {
|
|
114
|
+
azure: {
|
|
115
|
+
"deepseek-ai/DeepSeek-V4-Flash-0731": {
|
|
116
|
+
supportsReasoningEffort: true,
|
|
117
|
+
requiresReasoningContentOnAssistantMessages: true,
|
|
118
|
+
},
|
|
119
|
+
"xai/grok-4.6": {
|
|
120
|
+
supportsReasoningEffort: true,
|
|
121
|
+
},
|
|
122
|
+
"xai/grok-4.7": {
|
|
123
|
+
supportsReasoningEffort: true,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
// Compat keys that describe a model's native reasoning wire format, which a
|
|
128
|
+
// gateway replaces with its own.
|
|
129
|
+
const NATIVE_REASONING_COMPAT_KEYS = new Set([
|
|
130
|
+
"thinkingFormat",
|
|
131
|
+
"supportsReasoningEffort",
|
|
132
|
+
"requiresReasoningContentOnAssistantMessages",
|
|
133
|
+
]);
|
|
134
|
+
// Models whose input modalities are not detectable from the Pi registry.
|
|
135
|
+
// GPT-5.6 is registered for Bedrock only under the unprefixed
|
|
136
|
+
// "openai.gpt-5.6-*" ids; Dari executes the "us." inference profiles, which
|
|
137
|
+
// miss the registry and would otherwise be pruned as text-only.
|
|
138
|
+
const MODEL_INPUT_OVERRIDES = {
|
|
139
|
+
"anthropic/claude-haiku-5-5": ["text", "image"],
|
|
140
|
+
"anthropic/claude-sonnet-5-5": ["text", "image"],
|
|
141
|
+
"openai/gpt-6.1-sol": ["text", "image"],
|
|
142
|
+
"openai/gpt-6-sol": ["text", "image"],
|
|
143
|
+
"openai/gpt-6-luna": ["text", "image"],
|
|
144
|
+
"openai/gpt-5.6-luna": ["text", "image"],
|
|
145
|
+
"openai/gpt-5.6-sol": ["text", "image"],
|
|
146
|
+
"openai/gpt-5.6-terra": ["text", "image"],
|
|
147
|
+
"openai/gpt-6-astra": ["text", "image"],
|
|
148
|
+
"moonshotai/Kimi-K3": ["text", "image"],
|
|
149
|
+
"deepseek-ai/DeepSeek-V4.1-Flash-1017": ["text", "image"],
|
|
150
|
+
"zai-org/GLM-5.3-Flash": ["text", "image"],
|
|
151
|
+
// Grok 4.6 and 4.7 are registered for xAI's Responses API only; Foundry
|
|
152
|
+
// serves them through chat completions with the same text and image input.
|
|
153
|
+
"xai/grok-4.6": ["text", "image"],
|
|
154
|
+
"xai/grok-4.7": ["text", "image"],
|
|
155
|
+
};
|
|
156
|
+
const MODEL_OFF_WIRE_NONE = new Set([
|
|
157
|
+
// No longer bundled under Fireworks in Pi 1.1; preserve explicit off.
|
|
158
|
+
"zai-org/GLM-5.2",
|
|
159
|
+
"deepseek-ai/DeepSeek-V4-Pro-0813",
|
|
160
|
+
"fireworks/deepseek-ai/DeepSeek-V4-Flash",
|
|
161
|
+
"deepseek-ai/DeepSeek-V4-Flash-0731",
|
|
162
|
+
"deepseek-ai/DeepSeek-V4.1-Flash-1017",
|
|
163
|
+
]);
|
|
164
|
+
// Wire values a provider's API accepts for thinking levels the Pi registry
|
|
165
|
+
// leaves unmapped. Meta's Model API takes reasoning effort "none" on every
|
|
166
|
+
// Muse model (dev.meta.ai/docs/coding-agents).
|
|
167
|
+
const PROVIDER_THINKING_LEVEL_OVERRIDES = {
|
|
168
|
+
meta: { off: "none" },
|
|
169
|
+
};
|
|
170
|
+
export function providerThinkingLevelOverrides(provider) {
|
|
171
|
+
return PROVIDER_THINKING_LEVEL_OVERRIDES[provider];
|
|
172
|
+
}
|
|
173
|
+
/** Registered Pi metadata with the serving provider's thinking level overrides. */
|
|
174
|
+
export function withThinkingLevelOverrides(provider, registered) {
|
|
175
|
+
const override = providerThinkingLevelOverrides(provider);
|
|
176
|
+
if (registered === undefined || override === undefined)
|
|
177
|
+
return registered;
|
|
178
|
+
const map = isRecord(registered.thinkingLevelMap) ? registered.thinkingLevelMap : {};
|
|
179
|
+
return { ...registered, thinkingLevelMap: { ...map, ...override } };
|
|
180
|
+
}
|
|
181
|
+
export function offRequiresWireNone(modelId) {
|
|
182
|
+
return MODEL_OFF_WIRE_NONE.has(canonicalModelId(modelId));
|
|
183
|
+
}
|
|
184
|
+
export function contextWindowOverride(modelId) {
|
|
185
|
+
return MODEL_CONTEXT_OVERRIDES[canonicalModelId(modelId)];
|
|
186
|
+
}
|
|
187
|
+
export function inputModalitiesOverride(modelId) {
|
|
188
|
+
return MODEL_INPUT_OVERRIDES[canonicalModelId(modelId)];
|
|
189
|
+
}
|
|
190
|
+
export function runtimeCompat(provider, registered, modelId) {
|
|
191
|
+
const canonical = modelId ? canonicalModelId(modelId) : undefined;
|
|
192
|
+
const compatOverride = canonical
|
|
193
|
+
? PROVIDER_MODEL_COMPAT_OVERRIDES[provider]?.[canonical] ?? MODEL_COMPAT_OVERRIDES[canonical]
|
|
194
|
+
: undefined;
|
|
195
|
+
const gateway = gatewayFor(provider);
|
|
196
|
+
if (gateway) {
|
|
197
|
+
// A gateway's own dialect decides how reasoning goes over the wire, so
|
|
198
|
+
// the model overrides' native reasoning settings do not apply.
|
|
199
|
+
const modelOverride = Object.fromEntries(Object.entries(compatOverride ?? {}).filter(([key]) => !NATIVE_REASONING_COMPAT_KEYS.has(key)));
|
|
200
|
+
return {
|
|
201
|
+
...(isRecord(registered?.compat) ? registered.compat : {}),
|
|
202
|
+
...modelOverride,
|
|
203
|
+
...gateway.compat,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
if (provider !== "fireworks") {
|
|
207
|
+
if (compatOverride === undefined)
|
|
208
|
+
return registered?.compat;
|
|
209
|
+
return {
|
|
210
|
+
...(isRecord(registered?.compat) ? registered.compat : {}),
|
|
211
|
+
...compatOverride,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
// Fireworks needs two compat defaults pi-ai does not detect for it:
|
|
215
|
+
// serverless cache hits ride on session-affinity headers pi-ai only sends
|
|
216
|
+
// when compat asks for them, and several Fireworks chat templates (e.g.
|
|
217
|
+
// DeepSeek) silently drop developer-role messages, so system prompts must
|
|
218
|
+
// go out under the system role. Registry-declared compat keys still win,
|
|
219
|
+
// and per-model overrides win over both for models the registry omits.
|
|
220
|
+
return {
|
|
221
|
+
sendSessionAffinityHeaders: true,
|
|
222
|
+
supportsDeveloperRole: false,
|
|
223
|
+
...(isRecord(registered?.compat) ? registered.compat : {}),
|
|
224
|
+
...compatOverride,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RouterModelPrice } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
import type { ClientHarness, ResolvedRouterModelConfig, SubscriptionKind } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Whether a plan may serve a model for this client: each plan serves only its
|
|
5
|
+
* own provider's models, and only to the client its provider allows.
|
|
6
|
+
*/
|
|
7
|
+
export declare function subscriptionServes(kind: SubscriptionKind, model: string, clientHarness: ClientHarness | undefined): boolean;
|
|
8
|
+
export declare function codexModelConfig(modelId: string, price: RouterModelPrice | null): ResolvedRouterModelConfig;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { nativeModelId, providerForModel, } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
const CODEX_BACKEND_URL = "https://chatgpt.com/backend-api";
|
|
3
|
+
// The model provider whose models each kind of plan serves.
|
|
4
|
+
const SUBSCRIPTION_MODEL_PROVIDERS = {
|
|
5
|
+
openai_codex: "openai",
|
|
6
|
+
anthropic_claude_code: "anthropic",
|
|
7
|
+
meta_muse: "meta",
|
|
8
|
+
};
|
|
9
|
+
// The client each plan is limited to, as its provider limits it: a Claude Code
|
|
10
|
+
// plan serves only Claude Code, and a Muse Code plan only Muse Code.
|
|
11
|
+
const SUBSCRIPTION_CLIENTS = {
|
|
12
|
+
anthropic_claude_code: "claude_code",
|
|
13
|
+
meta_muse: "muse_code",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Whether a plan may serve a model for this client: each plan serves only its
|
|
17
|
+
* own provider's models, and only to the client its provider allows.
|
|
18
|
+
*/
|
|
19
|
+
export function subscriptionServes(kind, model, clientHarness) {
|
|
20
|
+
if (SUBSCRIPTION_MODEL_PROVIDERS[kind] !== providerForModel(model))
|
|
21
|
+
return false;
|
|
22
|
+
const client = SUBSCRIPTION_CLIENTS[kind];
|
|
23
|
+
return client === undefined || clientHarness === client;
|
|
24
|
+
}
|
|
25
|
+
// A ChatGPT plan serves OpenAI models as the `openai-codex` provider through
|
|
26
|
+
// the Codex backend.
|
|
27
|
+
export function codexModelConfig(modelId, price) {
|
|
28
|
+
return {
|
|
29
|
+
provider: "openai-codex",
|
|
30
|
+
native_model_id: nativeModelId(modelId),
|
|
31
|
+
api: "openai-codex-responses",
|
|
32
|
+
base_url: CODEX_BACKEND_URL,
|
|
33
|
+
// A plan bills no tokens; the catalog price only feeds cost estimates.
|
|
34
|
+
cost: price ?? { input: 0, output: 0 },
|
|
35
|
+
fast_mode: false,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type OperationalErrorContext, type RequestErrorContext } from "../platform/platform.js";
|
|
2
|
+
export type { OperationalErrorCode } from "../platform/platform.js";
|
|
3
|
+
export declare function captureRequestError(error: unknown, context: RequestErrorContext): void;
|
|
4
|
+
/**
|
|
5
|
+
* Report failures deliberately caught outside the ingress exception path,
|
|
6
|
+
* including work after a response has started and process shutdown.
|
|
7
|
+
*/
|
|
8
|
+
export declare function captureOperationalError(error: unknown, context: OperationalErrorContext): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { gatewayPlatform, } from "../platform/platform.js";
|
|
2
|
+
export function captureRequestError(error, context) {
|
|
3
|
+
gatewayPlatform().captureRequestError(error, context);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Report failures deliberately caught outside the ingress exception path,
|
|
7
|
+
* including work after a response has started and process shutdown.
|
|
8
|
+
*/
|
|
9
|
+
export function captureOperationalError(error, context) {
|
|
10
|
+
gatewayPlatform().captureOperationalError(error, context);
|
|
11
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { Provider, ReasoningEffort, RoutingStrategy } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
import type { HarnessConversationIdentity } from "../runtime/harness_identity/index.js";
|
|
3
|
+
import type { InteractionRequest, SourceProtocol } from "../interaction/types.js";
|
|
4
|
+
import type { SubscriptionUsageLimit } from "../providers/subscription_limits.js";
|
|
5
|
+
import type { ClientHarness, ProviderCredential, ProviderKeySource, ResolvedRouter } from "../types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Everything the gateway runtime needs from the deployment around it: router
|
|
8
|
+
* configuration and credentials, durable routing state, accounting sinks, and
|
|
9
|
+
* error reporting. The self-hosted gateway implements it with a local config
|
|
10
|
+
* file and SQLite (`self_host/`); other deployments supply their own.
|
|
11
|
+
*
|
|
12
|
+
* Methods may throw. Call sites that must not fail a served request catch,
|
|
13
|
+
* log, and continue.
|
|
14
|
+
*/
|
|
15
|
+
export type GatewayPlatform = {
|
|
16
|
+
/**
|
|
17
|
+
* Authenticate the request's key and return the router it may use, with
|
|
18
|
+
* decrypted provider credentials and the prefix-cache evidence matching
|
|
19
|
+
* `prefixHashes`. Throws HttpError(401) for an unknown key.
|
|
20
|
+
*/
|
|
21
|
+
resolveRouter(request: ResolveRouterRequest): Promise<ResolvedRouter>;
|
|
22
|
+
/**
|
|
23
|
+
* Optional. Supply the credential for one enabled model of this request,
|
|
24
|
+
* consulted after `resolveRouter` and before its provider keys (for the
|
|
25
|
+
* self-hosted gateway, its environment keys), so an embedder can serve
|
|
26
|
+
* per-tenant keys from its own store. Undefined keeps the resolved key. A
|
|
27
|
+
* credential with `subscription` serves the model on that plan, even on a
|
|
28
|
+
* strict router; a plan that cannot serve the model for this client (see
|
|
29
|
+
* SubscriptionKind) is ignored.
|
|
30
|
+
*/
|
|
31
|
+
resolveProviderCredential?(request: ProviderCredentialRequest): Promise<ProviderCredential | undefined>;
|
|
32
|
+
/** Persist one completed turn's prefix entry and/or refresh a read entry. */
|
|
33
|
+
writePrefixState(write: PrefixStateWrite): Promise<void>;
|
|
34
|
+
/** Set or clear a conversation's prefetched routing lease. */
|
|
35
|
+
writePendingLease(write: PendingLeaseWrite): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Hold an exhausted personal subscription until it resets. Resolves whether
|
|
38
|
+
* another connected subscription for the same provider can serve a retry.
|
|
39
|
+
*/
|
|
40
|
+
markSubscriptionUnavailable(hold: SubscriptionHold): Promise<boolean>;
|
|
41
|
+
/**
|
|
42
|
+
* Account one call served on a platform-managed provider key. Only reached
|
|
43
|
+
* when `resolveRouter` reports a "managed" key source.
|
|
44
|
+
*/
|
|
45
|
+
recordUsage(usage: Record<string, unknown>): Promise<void>;
|
|
46
|
+
/** Receive the finished request's log row. Must not throw. */
|
|
47
|
+
recordRequest(record: RequestRecord): void;
|
|
48
|
+
captureRequestError(error: unknown, context: RequestErrorContext): void;
|
|
49
|
+
captureOperationalError(error: unknown, context: OperationalErrorContext): void;
|
|
50
|
+
};
|
|
51
|
+
export type ResolveRouterRequest = {
|
|
52
|
+
routerId: string;
|
|
53
|
+
apiKey: string;
|
|
54
|
+
prefixHashes?: string[];
|
|
55
|
+
conversationId?: string;
|
|
56
|
+
includePublicEvalCatalog?: boolean;
|
|
57
|
+
clientHarness?: ClientHarness;
|
|
58
|
+
};
|
|
59
|
+
export type ProviderCredentialRequest = {
|
|
60
|
+
provider: Provider;
|
|
61
|
+
model: string;
|
|
62
|
+
routerId: string;
|
|
63
|
+
organizationId: string;
|
|
64
|
+
apiKey: string;
|
|
65
|
+
clientHarness?: ClientHarness;
|
|
66
|
+
};
|
|
67
|
+
export type PrefixStateWrite = {
|
|
68
|
+
organization_id: string;
|
|
69
|
+
router_id: string;
|
|
70
|
+
received_at: string;
|
|
71
|
+
zdr: boolean;
|
|
72
|
+
prefix_entry: Record<string, unknown> | null;
|
|
73
|
+
touched_prefix_hash: string | null;
|
|
74
|
+
};
|
|
75
|
+
export type PendingLeaseWrite = {
|
|
76
|
+
router_id: string;
|
|
77
|
+
conversation_id: string;
|
|
78
|
+
decided_at_depth: number;
|
|
79
|
+
pending_lease: {
|
|
80
|
+
model: string;
|
|
81
|
+
reasoning_effort: string;
|
|
82
|
+
turns: number;
|
|
83
|
+
reason: string;
|
|
84
|
+
output_text: string | null;
|
|
85
|
+
} | null;
|
|
86
|
+
};
|
|
87
|
+
export type SubscriptionHold = {
|
|
88
|
+
userId: string;
|
|
89
|
+
credentialId: string | undefined;
|
|
90
|
+
limit: SubscriptionUsageLimit;
|
|
91
|
+
};
|
|
92
|
+
export type RequestRecord = {
|
|
93
|
+
row: Record<string, unknown>;
|
|
94
|
+
summary: RequestSummary;
|
|
95
|
+
distinctId: string;
|
|
96
|
+
interaction: InteractionRequest;
|
|
97
|
+
isNewConversation: boolean;
|
|
98
|
+
zdr: boolean;
|
|
99
|
+
harnessConversationIdentity?: HarnessConversationIdentity;
|
|
100
|
+
tags: RequestTags;
|
|
101
|
+
};
|
|
102
|
+
export type RequestTags = Record<string, string>;
|
|
103
|
+
export type RequestSummary = {
|
|
104
|
+
request_id: string;
|
|
105
|
+
organization_id: string;
|
|
106
|
+
router_id: string;
|
|
107
|
+
api_key_id: string | null;
|
|
108
|
+
source_protocol: SourceProtocol;
|
|
109
|
+
request_kind: "user_message" | "tool_continuation" | "other";
|
|
110
|
+
status: "completed" | "provider_error" | "selector_error" | "aborted";
|
|
111
|
+
error_code: string | null;
|
|
112
|
+
stream: boolean;
|
|
113
|
+
zdr: boolean;
|
|
114
|
+
strategy: RoutingStrategy;
|
|
115
|
+
selected_model: string | null;
|
|
116
|
+
selected_provider: Provider | null;
|
|
117
|
+
selected_reasoning_effort: ReasoningEffort | null;
|
|
118
|
+
next_model: string | null;
|
|
119
|
+
next_reasoning_effort: ReasoningEffort | null;
|
|
120
|
+
fallback_model: string | null;
|
|
121
|
+
fallback_reasoning_effort: ReasoningEffort | null;
|
|
122
|
+
provider_key_source: ProviderKeySource | null;
|
|
123
|
+
message_count: number;
|
|
124
|
+
tool_count: number;
|
|
125
|
+
candidate_count: number;
|
|
126
|
+
provider_attempt_count: number;
|
|
127
|
+
prefix_match_depth: number | null;
|
|
128
|
+
prefix_warm_tokens: number | null;
|
|
129
|
+
selector_latency_ms: number | null;
|
|
130
|
+
provider_latency_ms: number | null;
|
|
131
|
+
total_latency_ms: number;
|
|
132
|
+
input_tokens: number | null;
|
|
133
|
+
cache_read_tokens: number | null;
|
|
134
|
+
cache_write_tokens: number | null;
|
|
135
|
+
output_tokens: number | null;
|
|
136
|
+
total_tokens: number | null;
|
|
137
|
+
total_cost_usd: number | null;
|
|
138
|
+
cost_source: "provider" | "pricing" | null;
|
|
139
|
+
pricing_known: boolean | null;
|
|
140
|
+
};
|
|
141
|
+
export type RequestErrorContext = {
|
|
142
|
+
request: Request;
|
|
143
|
+
routerId: string;
|
|
144
|
+
requestId?: string;
|
|
145
|
+
sourceProtocol: SourceProtocol | "openai_models" | "anthropic_models";
|
|
146
|
+
status: number;
|
|
147
|
+
};
|
|
148
|
+
export type OperationalErrorCode = "background_drain_timeout" | "billing_usage_report_failed" | "routing_report_assembly_failed" | "routing_report_barrier_failed" | "server_force_stop_failed" | "stream_report_finalization_failed" | "subscription_unavailable_ingest_failed";
|
|
149
|
+
export type OperationalErrorContext = {
|
|
150
|
+
code: OperationalErrorCode;
|
|
151
|
+
requestId?: string;
|
|
152
|
+
routerId?: string;
|
|
153
|
+
};
|
|
154
|
+
/** Bind the platform every request uses. The latest binding wins. */
|
|
155
|
+
export declare function bindGatewayPlatform(platform: GatewayPlatform): void;
|
|
156
|
+
export declare function gatewayPlatform(): GatewayPlatform;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
let bound = null;
|
|
2
|
+
/** Bind the platform every request uses. The latest binding wins. */
|
|
3
|
+
export function bindGatewayPlatform(platform) {
|
|
4
|
+
bound = platform;
|
|
5
|
+
}
|
|
6
|
+
export function gatewayPlatform() {
|
|
7
|
+
if (bound === null) {
|
|
8
|
+
throw new Error("No gateway platform is bound; create the request handler first.");
|
|
9
|
+
}
|
|
10
|
+
return bound;
|
|
11
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Stable public identity for the standard /v1 router. Platforms resolve it
|
|
2
|
+
// to the caller's default router.
|
|
3
|
+
export const DEFAULT_ROUTER_ALIAS = "default";
|
|
4
|
+
// The most prefix hashes one router resolution looks up.
|
|
5
|
+
export const ROUTING_PREFIX_HASHES_MAX_COUNT = 200;
|