@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
package/src/ingress/models.ts
CHANGED
|
@@ -2,17 +2,20 @@
|
|
|
2
2
|
Codex reads the Codex catalog; Anthropic-SDK clients (Claude Desktop /
|
|
3
3
|
Cowork gateway probes, Claude Code) read the Anthropic list shape. The
|
|
4
4
|
handler detects the caller, authenticates in that protocol's auth shape,
|
|
5
|
-
and selects the matching catalog adapter.
|
|
5
|
+
and selects the matching catalog adapter. `?detail=1` instead returns the
|
|
6
|
+
model catalog (models/catalog.ts), optionally narrowed with
|
|
7
|
+
`provider=<id>[,<id>...]`. */
|
|
6
8
|
|
|
7
|
-
import { anthropicToken, bearerToken } from "../http/auth";
|
|
8
|
-
import { errorResponse } from "../http/errors";
|
|
9
|
-
import { captureRequestError } from "../observability/errors";
|
|
10
|
-
import { anthropicErrorResponse } from "./anthropic_messages";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
9
|
+
import { anthropicToken, bearerToken } from "../http/auth.js";
|
|
10
|
+
import { errorResponse } from "../http/errors.js";
|
|
11
|
+
import { captureRequestError } from "../observability/errors.js";
|
|
12
|
+
import { anthropicErrorResponse } from "./anthropic_messages.js";
|
|
13
|
+
import { listModelCatalog } from "../models/catalog.js";
|
|
14
|
+
import { modelSupportsImageInput } from "../providers/model_capabilities.js";
|
|
15
|
+
import { modelMetadataLookup } from "../providers/pi.js";
|
|
16
|
+
import { resolveRouter } from "../strategies/routing.js";
|
|
17
|
+
import { anthropicModelsResponse } from "./anthropic_models.js";
|
|
18
|
+
import { codexModelsResponse } from "./codex_models.js";
|
|
16
19
|
|
|
17
20
|
export async function handleModels(request: Request, routerId: string): Promise<Response> {
|
|
18
21
|
// Anthropic SDK clients always send anthropic-version, and API-key probes
|
|
@@ -26,6 +29,15 @@ export async function handleModels(request: Request, routerId: string): Promise<
|
|
|
26
29
|
// Resolution authenticates the key and confirms the router exists even
|
|
27
30
|
// when the response body (Anthropic shape) does not depend on it.
|
|
28
31
|
const router = await resolveRouter({ routerId, apiKey });
|
|
32
|
+
const query = new URL(request.url).searchParams;
|
|
33
|
+
if (query.get("detail") === "1") {
|
|
34
|
+
const providers = query.get("provider")?.split(",").map((id) => id.trim()).filter(Boolean);
|
|
35
|
+
const data = await listModelCatalog({
|
|
36
|
+
...(providers?.length ? { providers } : {}),
|
|
37
|
+
signal: request.signal,
|
|
38
|
+
});
|
|
39
|
+
return Response.json({ object: "list", data }, { headers: { "Cache-Control": "no-store" } });
|
|
40
|
+
}
|
|
29
41
|
if (anthropicClient) {
|
|
30
42
|
return Response.json(anthropicModelsResponse(), {
|
|
31
43
|
headers: {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Muse Code names its surface (TUI, `muse exec`, desktop, `muse serve`) in
|
|
2
|
+
// x-client-id on every model request.
|
|
3
|
+
const MUSE_CODE_CLIENT_IDS = new Set(["tbh:tui", "tbh:exec", "tbh:desktop", "tbh:serve"]);
|
|
4
|
+
|
|
5
|
+
/** Muse Code's x-client-id when the request comes from Muse Code. */
|
|
6
|
+
export function museCodeClientId(headers: Headers): string | undefined {
|
|
7
|
+
const clientId = headers.get("x-client-id")?.trim().toLowerCase();
|
|
8
|
+
return clientId !== undefined && MUSE_CODE_CLIENT_IDS.has(clientId) ? clientId : undefined;
|
|
9
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { bearerToken } from "../http/auth.js";
|
|
2
|
+
import { errorResponse } from "../http/errors.js";
|
|
3
|
+
import { resolveRouter } from "../strategies/routing.js";
|
|
4
|
+
import type { ResolvedRouter } from "../types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Muse Code fetches its model list from its base URL's origin
|
|
8
|
+
* (`/muse-code/models`) before its first request. A list of only the router's
|
|
9
|
+
* models lets Muse Code pick from them and start on the first; `dari/routing`
|
|
10
|
+
* leads it only on the Autorouting plan.
|
|
11
|
+
*/
|
|
12
|
+
export function museCodeModelsResponse(
|
|
13
|
+
router: Pick<ResolvedRouter, "enabled_models" | "autorouting_enabled">,
|
|
14
|
+
): Record<string, unknown> {
|
|
15
|
+
const ids = [
|
|
16
|
+
...(router.autorouting_enabled === false ? [] : ["dari/routing"]),
|
|
17
|
+
...router.enabled_models.map((model) => `dari/model/${model}`),
|
|
18
|
+
];
|
|
19
|
+
return {
|
|
20
|
+
data: ids.map((id, index) => ({
|
|
21
|
+
id,
|
|
22
|
+
display_label: id === "dari/routing" ? "Dari Routing" : id.slice("dari/model/".length),
|
|
23
|
+
is_default: index === 0,
|
|
24
|
+
})),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function handleMuseCodeModels(request: Request, routerId: string): Promise<Response> {
|
|
29
|
+
try {
|
|
30
|
+
// Only Muse Code fetches this list, so its plans apply even without a Meta key.
|
|
31
|
+
const router = await resolveRouter({ routerId, apiKey: bearerToken(request.headers), clientHarness: "muse_code" });
|
|
32
|
+
return Response.json(museCodeModelsResponse(router), { headers: { "Cache-Control": "no-store" } });
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return errorResponse(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HardCapability } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
-
import type { InteractionItem, InteractionRequest } from "./types";
|
|
2
|
+
import type { InteractionItem, InteractionRequest } from "./types.js";
|
|
3
3
|
|
|
4
4
|
export function requiredCapabilitiesFor(
|
|
5
5
|
request: Pick<InteractionRequest, "items" | "responseFormat" | "toolChoice" | "tools">
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
type PortableReasoningState,
|
|
5
5
|
} from "@mupt-ai/dari-router/protocols";
|
|
6
6
|
|
|
7
|
-
import { rethrowFrameworkErrorAsHttp } from "../http/errors";
|
|
7
|
+
import { rethrowFrameworkErrorAsHttp } from "../http/errors.js";
|
|
8
8
|
|
|
9
9
|
export type { PortableReasoningState } from "@mupt-ai/dari-router/protocols";
|
|
10
10
|
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type ProviderIdentity,
|
|
7
7
|
} from "@mupt-ai/dari-router/protocols";
|
|
8
8
|
|
|
9
|
-
import { rethrowFrameworkErrorAsHttp } from "../http/errors";
|
|
9
|
+
import { rethrowFrameworkErrorAsHttp } from "../http/errors.js";
|
|
10
10
|
|
|
11
11
|
export type { ProviderContinuationState, ProviderIdentity } from "@mupt-ai/dari-router/protocols";
|
|
12
12
|
export { compatibleProviderContinuation, isAnthropicEffort, sameProviderIdentity } from "@mupt-ai/dari-router/protocols";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HttpError } from "../http/errors";
|
|
2
|
-
import type { InteractionTool, ProviderIdentity } from "./types";
|
|
1
|
+
import { HttpError } from "../http/errors.js";
|
|
2
|
+
import type { InteractionTool, ProviderIdentity } from "./types.js";
|
|
3
3
|
|
|
4
4
|
export const TOOL_CALL_ID_MAX_LENGTH = 512;
|
|
5
5
|
|
package/src/interaction/types.ts
CHANGED
|
@@ -235,6 +235,8 @@ export type InteractionRequest = {
|
|
|
235
235
|
agentContext?: AgentRequestContext;
|
|
236
236
|
// Claude Code's own user agent; Anthropic gates subscription models on it.
|
|
237
237
|
claudeCodeUserAgent?: string;
|
|
238
|
+
// Muse Code's own x-client-id, which Meta attributes its requests by.
|
|
239
|
+
museCodeClientId?: string;
|
|
238
240
|
anthropicSafeguards?: AnthropicSafeguards;
|
|
239
241
|
model?: string;
|
|
240
242
|
instructions?: string;
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { getSupportedThinkingLevels, type Api, type Model } from "@mupt-ai/pi-ai";
|
|
2
|
+
import {
|
|
3
|
+
getBuiltinModelDataGeneratedAt,
|
|
4
|
+
getBuiltinModels,
|
|
5
|
+
getBuiltinProviders,
|
|
6
|
+
} from "@mupt-ai/pi-ai/providers/all";
|
|
7
|
+
import {
|
|
8
|
+
REASONING_EFFORTS,
|
|
9
|
+
isReasoningEffort,
|
|
10
|
+
isRecord,
|
|
11
|
+
type ReasoningEffort,
|
|
12
|
+
} from "@mupt-ai/dari-router/policy-engine";
|
|
13
|
+
import { HttpError } from "../http/errors.js";
|
|
14
|
+
|
|
15
|
+
// The models each provider can serve to a coding agent, with the limits,
|
|
16
|
+
// thinking levels, and list prices a caller needs to pick and price one.
|
|
17
|
+
// Gateways (OpenRouter, Vercel AI Gateway) are listed live from their public
|
|
18
|
+
// models endpoints; model providers come from the bundled Pi catalog.
|
|
19
|
+
|
|
20
|
+
export type CatalogModel = {
|
|
21
|
+
// Canonical `provider/native-id`; request it as `dari/model/<id>`.
|
|
22
|
+
id: string;
|
|
23
|
+
provider: string;
|
|
24
|
+
native_model_id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
context_window: number | null;
|
|
27
|
+
max_output_tokens: number | null;
|
|
28
|
+
input_modalities: string[];
|
|
29
|
+
// Accepted thinking levels; ["off"] for models that do not reason.
|
|
30
|
+
thinking_levels: ReasoningEffort[];
|
|
31
|
+
// List price in USD per million tokens; null when the source publishes
|
|
32
|
+
// none, e.g. meta-routers whose price depends on the model they pick.
|
|
33
|
+
price: CatalogModelPrice | null;
|
|
34
|
+
// When the price was read: the fetch time for gateways, the catalog's
|
|
35
|
+
// generation time for model providers.
|
|
36
|
+
price_as_of: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type CatalogModelPrice = {
|
|
40
|
+
input: number;
|
|
41
|
+
output: number;
|
|
42
|
+
cached_input: number | null;
|
|
43
|
+
cache_write: number | null;
|
|
44
|
+
// Long-context rates, each applying to prompts above its token threshold.
|
|
45
|
+
tiers: CatalogPriceTier[];
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type CatalogPriceTier = {
|
|
49
|
+
input_tokens_above: number;
|
|
50
|
+
input: number;
|
|
51
|
+
output: number;
|
|
52
|
+
cached_input: number | null;
|
|
53
|
+
cache_write: number | null;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export type ModelCatalogOptions = {
|
|
57
|
+
// Providers to list; defaults to DEFAULT_CATALOG_PROVIDERS. Any Pi built-in
|
|
58
|
+
// provider id is accepted.
|
|
59
|
+
providers?: readonly string[] | undefined;
|
|
60
|
+
fetch?: ((url: string, init?: RequestInit) => Promise<Response>) | undefined;
|
|
61
|
+
signal?: AbortSignal | undefined;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const DEFAULT_CATALOG_PROVIDERS: readonly string[] = [
|
|
65
|
+
"openai",
|
|
66
|
+
"anthropic",
|
|
67
|
+
"meta",
|
|
68
|
+
"xai",
|
|
69
|
+
"fireworks",
|
|
70
|
+
"openrouter",
|
|
71
|
+
"vercel-ai-gateway",
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
type LiveListing = {
|
|
75
|
+
url: string;
|
|
76
|
+
models: (data: unknown[], asOf: string) => CatalogModel[];
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const LIVE_LISTINGS: Record<string, LiveListing> = {
|
|
80
|
+
openrouter: { url: "https://openrouter.ai/api/v1/models", models: openRouterModels },
|
|
81
|
+
"vercel-ai-gateway": { url: "https://ai-gateway.vercel.sh/v1/models", models: vercelModels },
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** List the agent-capable models of each requested provider. */
|
|
85
|
+
export async function listModelCatalog(options: ModelCatalogOptions = {}): Promise<CatalogModel[]> {
|
|
86
|
+
const providers = [...new Set(options.providers ?? DEFAULT_CATALOG_PROVIDERS)];
|
|
87
|
+
const builtin = new Set<string>(getBuiltinProviders());
|
|
88
|
+
for (const provider of providers) {
|
|
89
|
+
if (LIVE_LISTINGS[provider] === undefined && !builtin.has(provider)) {
|
|
90
|
+
throw new HttpError(400, `Unknown catalog provider '${provider}'.`, "unknown_provider", "provider");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const lists = await Promise.all(providers.map(async (provider) => {
|
|
94
|
+
const listing = LIVE_LISTINGS[provider];
|
|
95
|
+
return listing === undefined
|
|
96
|
+
? piModels(provider)
|
|
97
|
+
: listing.models(await fetchListing(listing.url, options), new Date().toISOString());
|
|
98
|
+
}));
|
|
99
|
+
return lists.flat();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function fetchListing(url: string, options: ModelCatalogOptions): Promise<unknown[]> {
|
|
103
|
+
let status: number | undefined;
|
|
104
|
+
let body: unknown = null;
|
|
105
|
+
// Network errors, aborts, and unparseable bodies are upstream failures
|
|
106
|
+
// too: all of them surface as catalog_unavailable rather than a raw 500.
|
|
107
|
+
try {
|
|
108
|
+
const response = await (options.fetch ?? fetch)(url, {
|
|
109
|
+
headers: { accept: "application/json" },
|
|
110
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
111
|
+
});
|
|
112
|
+
status = response.status;
|
|
113
|
+
body = response.ok ? await response.json() : null;
|
|
114
|
+
} catch {
|
|
115
|
+
// Leaves body null.
|
|
116
|
+
}
|
|
117
|
+
if (!isRecord(body) || !Array.isArray(body.data)) {
|
|
118
|
+
const detail = status === undefined ? "could not be reached" : `returned no model list (HTTP ${status})`;
|
|
119
|
+
throw new HttpError(502, `${url} ${detail}.`, "catalog_unavailable");
|
|
120
|
+
}
|
|
121
|
+
return body.data;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function piModels(provider: string): CatalogModel[] {
|
|
125
|
+
const generatedAt = getBuiltinModelDataGeneratedAt();
|
|
126
|
+
const asOf = generatedAt === undefined ? "" : new Date(generatedAt).toISOString();
|
|
127
|
+
const models = getBuiltinModels(provider as never) as unknown as Model<Api>[];
|
|
128
|
+
return models.map((model) => ({
|
|
129
|
+
id: `${provider}/${model.id}`,
|
|
130
|
+
provider,
|
|
131
|
+
native_model_id: model.id,
|
|
132
|
+
name: model.name,
|
|
133
|
+
context_window: model.contextWindow,
|
|
134
|
+
max_output_tokens: model.maxTokens,
|
|
135
|
+
input_modalities: [...model.input],
|
|
136
|
+
thinking_levels: orderedEfforts(getSupportedThinkingLevels(model)),
|
|
137
|
+
price: piPrice(model.cost),
|
|
138
|
+
price_as_of: asOf,
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function piPrice(cost: Model<Api>["cost"]): CatalogModelPrice {
|
|
143
|
+
return {
|
|
144
|
+
input: cost.input,
|
|
145
|
+
output: cost.output,
|
|
146
|
+
cached_input: cost.cacheRead,
|
|
147
|
+
cache_write: cost.cacheWrite,
|
|
148
|
+
tiers: (cost.tiers ?? []).map((tier) => ({
|
|
149
|
+
input_tokens_above: tier.inputTokensAbove,
|
|
150
|
+
input: tier.input,
|
|
151
|
+
output: tier.output,
|
|
152
|
+
cached_input: tier.cacheRead,
|
|
153
|
+
cache_write: tier.cacheWrite,
|
|
154
|
+
})),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// https://openrouter.ai/docs/api/api-reference/models/get-models
|
|
159
|
+
function openRouterModels(data: unknown[], asOf: string): CatalogModel[] {
|
|
160
|
+
return data.filter(isRecord).flatMap((model) => {
|
|
161
|
+
const architecture = isRecord(model.architecture) ? model.architecture : {};
|
|
162
|
+
const parameters = stringList(model.supported_parameters);
|
|
163
|
+
if (typeof model.id !== "string" || !parameters.includes("tools")) return [];
|
|
164
|
+
if (!stringList(architecture.output_modalities).includes("text")) return [];
|
|
165
|
+
const reasoning = isRecord(model.reasoning) ? model.reasoning : {};
|
|
166
|
+
const topProvider = isRecord(model.top_provider) ? model.top_provider : {};
|
|
167
|
+
return [{
|
|
168
|
+
id: `openrouter/${model.id}`,
|
|
169
|
+
provider: "openrouter",
|
|
170
|
+
native_model_id: model.id,
|
|
171
|
+
name: typeof model.name === "string" ? model.name : model.id,
|
|
172
|
+
context_window: positiveInteger(model.context_length),
|
|
173
|
+
max_output_tokens: positiveInteger(topProvider.max_completion_tokens),
|
|
174
|
+
input_modalities: stringList(architecture.input_modalities),
|
|
175
|
+
thinking_levels: gatewayThinkingLevels({
|
|
176
|
+
reasons: parameters.includes("reasoning"),
|
|
177
|
+
efforts: Array.isArray(reasoning.supported_efforts) ? stringList(reasoning.supported_efforts) : null,
|
|
178
|
+
canDisable: reasoning.mandatory !== true,
|
|
179
|
+
}),
|
|
180
|
+
price: isRecord(model.pricing) ? openRouterPrice(model.pricing) : null,
|
|
181
|
+
price_as_of: asOf,
|
|
182
|
+
}];
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function openRouterPrice(pricing: Record<string, unknown>): CatalogModelPrice | null {
|
|
187
|
+
const base = rates(pricing, "prompt", "completion");
|
|
188
|
+
if (base === null) return null;
|
|
189
|
+
// Overrides restate only the rates they change; time-of-day overrides are
|
|
190
|
+
// not context tiers.
|
|
191
|
+
const tiers = (Array.isArray(pricing.overrides) ? pricing.overrides : [])
|
|
192
|
+
.filter(isRecord)
|
|
193
|
+
.flatMap((override) => {
|
|
194
|
+
const threshold = positiveInteger(override.min_prompt_tokens);
|
|
195
|
+
if (threshold === null || "utc_days" in override || "utc_start" in override || "utc_end" in override) {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
const tier = rates({ ...pricing, ...override }, "prompt", "completion", override);
|
|
199
|
+
return tier === null ? [] : [{ input_tokens_above: threshold, ...tier }];
|
|
200
|
+
});
|
|
201
|
+
return { ...base, tiers };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// https://vercel.com/docs/ai-gateway/models-and-providers
|
|
205
|
+
function vercelModels(data: unknown[], asOf: string): CatalogModel[] {
|
|
206
|
+
return data.filter(isRecord).flatMap((model) => {
|
|
207
|
+
const modalities = isRecord(model.modalities) ? model.modalities : {};
|
|
208
|
+
const parameters = stringList(model.supported_parameters);
|
|
209
|
+
if (typeof model.id !== "string" || model.type !== "language" || !parameters.includes("tools")) return [];
|
|
210
|
+
if (!stringList(modalities.output).includes("text")) return [];
|
|
211
|
+
const options = Array.isArray(model.reasoning_options) ? model.reasoning_options.filter(isRecord) : [];
|
|
212
|
+
const effort = options.find((option) => option.type === "effort");
|
|
213
|
+
return [{
|
|
214
|
+
id: `vercel-ai-gateway/${model.id}`,
|
|
215
|
+
provider: "vercel-ai-gateway",
|
|
216
|
+
native_model_id: model.id,
|
|
217
|
+
name: typeof model.name === "string" ? model.name : model.id,
|
|
218
|
+
context_window: positiveInteger(model.context_window),
|
|
219
|
+
max_output_tokens: positiveInteger(model.max_tokens),
|
|
220
|
+
input_modalities: stringList(modalities.input),
|
|
221
|
+
thinking_levels: gatewayThinkingLevels({
|
|
222
|
+
reasons: parameters.includes("reasoning") || options.length > 0,
|
|
223
|
+
efforts: effort === undefined ? null : stringList(effort.values),
|
|
224
|
+
canDisable: options.length === 0 || options.some((option) => option.type === "toggle"),
|
|
225
|
+
}),
|
|
226
|
+
price: isRecord(model.pricing) ? vercelPrice(model.pricing) : null,
|
|
227
|
+
price_as_of: asOf,
|
|
228
|
+
}];
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function vercelPrice(pricing: Record<string, unknown>): CatalogModelPrice | null {
|
|
233
|
+
const base = rates(pricing, "input", "output");
|
|
234
|
+
if (base === null) return null;
|
|
235
|
+
// Each rate lists its own {cost, min, max} ranges; a range covers prompts of
|
|
236
|
+
// at least `min` tokens, so it is the tier above `min - 1`.
|
|
237
|
+
const ranged = new Map<number, Record<string, unknown>>();
|
|
238
|
+
for (const key of ["input", "output", "input_cache_read", "input_cache_write"]) {
|
|
239
|
+
const ranges = Array.isArray(pricing[`${key}_tiers`]) ? pricing[`${key}_tiers`] as unknown[] : [];
|
|
240
|
+
for (const range of ranges.filter(isRecord)) {
|
|
241
|
+
const start = positiveInteger(range.min);
|
|
242
|
+
if (start === null || range.cost == null) continue;
|
|
243
|
+
ranged.set(start - 1, { ...ranged.get(start - 1), [key]: range.cost });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const tiers = [...ranged.entries()]
|
|
247
|
+
.sort(([left], [right]) => left - right)
|
|
248
|
+
.flatMap(([threshold, stated]) => {
|
|
249
|
+
const tier = rates({ ...pricing, ...stated }, "input", "output", stated);
|
|
250
|
+
return tier === null ? [] : [{ input_tokens_above: threshold, ...tier }];
|
|
251
|
+
});
|
|
252
|
+
return { ...base, tiers };
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Base rates from per-token strings. A tier inherits input and output from
|
|
256
|
+
// the base price but states its own cache rates, or has none.
|
|
257
|
+
function rates(
|
|
258
|
+
pricing: Record<string, unknown>,
|
|
259
|
+
inputKey: string,
|
|
260
|
+
outputKey: string,
|
|
261
|
+
cacheRates: Record<string, unknown> = pricing,
|
|
262
|
+
): Omit<CatalogPriceTier, "input_tokens_above"> | null {
|
|
263
|
+
const input = perMillion(pricing[inputKey]);
|
|
264
|
+
const output = perMillion(pricing[outputKey]);
|
|
265
|
+
// Meta-routers with variable prices list negative rates.
|
|
266
|
+
if (input === null || output === null) return null;
|
|
267
|
+
return {
|
|
268
|
+
input,
|
|
269
|
+
output,
|
|
270
|
+
cached_input: perMillion(cacheRates.input_cache_read),
|
|
271
|
+
cache_write: perMillion(cacheRates.input_cache_write),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// USD per token as a decimal string -> USD per million tokens. Shifting the
|
|
276
|
+
// exponent in the string keeps "0.000001" exactly 1.
|
|
277
|
+
function perMillion(value: unknown): number | null {
|
|
278
|
+
const rate = typeof value === "string" ? Number(`${value.trim()}e6`)
|
|
279
|
+
: typeof value === "number" ? value * 1_000_000
|
|
280
|
+
: Number.NaN;
|
|
281
|
+
return Number.isFinite(rate) && rate >= 0 ? rate : null;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Gateways forward `reasoning.effort`; models that reason without a stated
|
|
285
|
+
// effort list take the standard low/medium/high levels.
|
|
286
|
+
function gatewayThinkingLevels(args: {
|
|
287
|
+
reasons: boolean;
|
|
288
|
+
efforts: string[] | null;
|
|
289
|
+
canDisable: boolean;
|
|
290
|
+
}): ReasoningEffort[] {
|
|
291
|
+
if (!args.reasons) return ["off"];
|
|
292
|
+
const efforts = args.efforts ?? ["low", "medium", "high"];
|
|
293
|
+
return orderedEfforts([
|
|
294
|
+
...efforts.map((effort) => effort === "none" ? "off" : effort),
|
|
295
|
+
...(args.canDisable ? ["off"] : []),
|
|
296
|
+
]);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function orderedEfforts(levels: readonly string[]): ReasoningEffort[] {
|
|
300
|
+
const accepted = new Set(levels.filter(isReasoningEffort));
|
|
301
|
+
return REASONING_EFFORTS.filter((effort) => accepted.has(effort));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function stringList(value: unknown): string[] {
|
|
305
|
+
return Array.isArray(value) ? value.filter((item): item is string => typeof item === "string") : [];
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function positiveInteger(value: unknown): number | null {
|
|
309
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : null;
|
|
310
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ResolvedRouterModelConfig } from "../types";
|
|
1
|
+
import type { ResolvedRouterModelConfig } from "../types.js";
|
|
2
2
|
|
|
3
3
|
export function effectiveContextWindow(config: ResolvedRouterModelConfig | undefined, allowLongContext = false): number | null {
|
|
4
4
|
const window = config?.context_window;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { providerForModel } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
-
import type { ProviderKeySource, ResolvedRouter } from "../types";
|
|
2
|
+
import type { ProviderKeySource, ResolvedRouter } from "../types.js";
|
|
3
3
|
|
|
4
4
|
/** Actual serving provider for a canonical model on a resolved managed router. */
|
|
5
5
|
export function executionProviderForModel(
|
|
@@ -11,12 +11,15 @@ export function executionProviderForModel(
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* The key that serves a model on a resolved router
|
|
14
|
+
* The key that serves a model on a resolved router: a platform-supplied
|
|
15
|
+
* credential first, then the resolved provider key. Missing declarations are
|
|
15
16
|
* user-owned so unknown platform data cannot trigger managed-key billing.
|
|
16
17
|
*/
|
|
17
18
|
export function keySourceForModel(
|
|
18
19
|
credentials: ResolvedRouter,
|
|
19
20
|
model: string,
|
|
20
21
|
): ProviderKeySource {
|
|
22
|
+
const supplied = credentials.provider_credentials?.[model];
|
|
23
|
+
if (supplied) return supplied.subscription ? "subscription" : "user";
|
|
21
24
|
return credentials.provider_key_sources?.[executionProviderForModel(credentials, model)] ?? "user";
|
|
22
25
|
}
|
package/src/models/ids.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { providerForModel } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
-
import { HttpError } from "../http/errors";
|
|
2
|
+
import { HttpError } from "../http/errors.js";
|
|
3
3
|
|
|
4
4
|
export function requireCandidateModels(value: unknown): string[] {
|
|
5
5
|
if (!Array.isArray(value) || value.length === 0) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { gatewayFor } from "./gateways";
|
|
1
|
+
import { gatewayFor } from "./gateways.js";
|
|
2
2
|
|
|
3
3
|
// Built-in model provider presentation and endpoint defaults; gateways carry
|
|
4
4
|
// their own. Mirrors the hosted Dari model catalog's provider defaults; keep
|
|
@@ -33,6 +33,9 @@ const PROVIDER_BASE_URLS: Record<string, string> = {
|
|
|
33
33
|
anthropic: "https://api.anthropic.com",
|
|
34
34
|
fireworks: "https://api.fireworks.ai/inference/v1",
|
|
35
35
|
xai: "https://api.x.ai/v1",
|
|
36
|
+
// Meta's Model API serves OpenAI Responses and Chat Completions here, and
|
|
37
|
+
// Anthropic Messages at https://api.meta.ai.
|
|
38
|
+
meta: "https://api.meta.ai/v1",
|
|
36
39
|
// Pi-ai derives the effective AWS region from the endpoint unless the
|
|
37
40
|
// model config overrides base_url or the native id is an inference profile
|
|
38
41
|
// ARN, so this default only pins us-east-1 when nothing else is configured.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { canonicalModelId, isRecord } from "@mupt-ai/dari-router/policy-engine";
|
|
2
2
|
|
|
3
|
-
import { gatewayFor } from "./gateways";
|
|
3
|
+
import { gatewayFor } from "./gateways.js";
|
|
4
4
|
|
|
5
5
|
const MODEL_CONTEXT_OVERRIDES: Record<string, number> = {
|
|
6
6
|
// Selector and title models are not router candidate configs, so their
|
|
@@ -169,6 +169,28 @@ const MODEL_OFF_WIRE_NONE: ReadonlySet<string> = new Set([
|
|
|
169
169
|
"deepseek-ai/DeepSeek-V4.1-Flash-1017",
|
|
170
170
|
]);
|
|
171
171
|
|
|
172
|
+
// Wire values a provider's API accepts for thinking levels the Pi registry
|
|
173
|
+
// leaves unmapped. Meta's Model API takes reasoning effort "none" on every
|
|
174
|
+
// Muse model (dev.meta.ai/docs/coding-agents).
|
|
175
|
+
const PROVIDER_THINKING_LEVEL_OVERRIDES: Record<string, Record<string, string>> = {
|
|
176
|
+
meta: { off: "none" },
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export function providerThinkingLevelOverrides(provider: string): Record<string, string> | undefined {
|
|
180
|
+
return PROVIDER_THINKING_LEVEL_OVERRIDES[provider];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Registered Pi metadata with the serving provider's thinking level overrides. */
|
|
184
|
+
export function withThinkingLevelOverrides(
|
|
185
|
+
provider: string,
|
|
186
|
+
registered: Record<string, unknown> | undefined,
|
|
187
|
+
): Record<string, unknown> | undefined {
|
|
188
|
+
const override = providerThinkingLevelOverrides(provider);
|
|
189
|
+
if (registered === undefined || override === undefined) return registered;
|
|
190
|
+
const map = isRecord(registered.thinkingLevelMap) ? registered.thinkingLevelMap : {};
|
|
191
|
+
return { ...registered, thinkingLevelMap: { ...map, ...override } };
|
|
192
|
+
}
|
|
193
|
+
|
|
172
194
|
export function offRequiresWireNone(modelId: string): boolean {
|
|
173
195
|
return MODEL_OFF_WIRE_NONE.has(canonicalModelId(modelId));
|
|
174
196
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
nativeModelId,
|
|
3
|
+
providerForModel,
|
|
4
|
+
type RouterModelPrice,
|
|
5
|
+
} from "@mupt-ai/dari-router/policy-engine";
|
|
6
|
+
|
|
7
|
+
import type { ClientHarness, ResolvedRouterModelConfig, SubscriptionKind } from "../types.js";
|
|
8
|
+
|
|
9
|
+
const CODEX_BACKEND_URL = "https://chatgpt.com/backend-api";
|
|
10
|
+
|
|
11
|
+
// The model provider whose models each kind of plan serves.
|
|
12
|
+
const SUBSCRIPTION_MODEL_PROVIDERS: Record<SubscriptionKind, string> = {
|
|
13
|
+
openai_codex: "openai",
|
|
14
|
+
anthropic_claude_code: "anthropic",
|
|
15
|
+
meta_muse: "meta",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// The client each plan is limited to, as its provider limits it: a Claude Code
|
|
19
|
+
// plan serves only Claude Code, and a Muse Code plan only Muse Code.
|
|
20
|
+
const SUBSCRIPTION_CLIENTS: Partial<Record<SubscriptionKind, ClientHarness>> = {
|
|
21
|
+
anthropic_claude_code: "claude_code",
|
|
22
|
+
meta_muse: "muse_code",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Whether a plan may serve a model for this client: each plan serves only its
|
|
27
|
+
* own provider's models, and only to the client its provider allows.
|
|
28
|
+
*/
|
|
29
|
+
export function subscriptionServes(
|
|
30
|
+
kind: SubscriptionKind,
|
|
31
|
+
model: string,
|
|
32
|
+
clientHarness: ClientHarness | undefined,
|
|
33
|
+
): boolean {
|
|
34
|
+
if (SUBSCRIPTION_MODEL_PROVIDERS[kind] !== providerForModel(model)) return false;
|
|
35
|
+
const client = SUBSCRIPTION_CLIENTS[kind];
|
|
36
|
+
return client === undefined || clientHarness === client;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// A ChatGPT plan serves OpenAI models as the `openai-codex` provider through
|
|
40
|
+
// the Codex backend.
|
|
41
|
+
export function codexModelConfig(
|
|
42
|
+
modelId: string,
|
|
43
|
+
price: RouterModelPrice | null,
|
|
44
|
+
): ResolvedRouterModelConfig {
|
|
45
|
+
return {
|
|
46
|
+
provider: "openai-codex",
|
|
47
|
+
native_model_id: nativeModelId(modelId),
|
|
48
|
+
api: "openai-codex-responses",
|
|
49
|
+
base_url: CODEX_BACKEND_URL,
|
|
50
|
+
// A plan bills no tokens; the catalog price only feeds cost estimates.
|
|
51
|
+
cost: price ?? { input: 0, output: 0 },
|
|
52
|
+
fast_mode: false,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
gatewayPlatform,
|
|
3
3
|
type OperationalErrorContext,
|
|
4
4
|
type RequestErrorContext,
|
|
5
|
-
} from "../platform/platform";
|
|
5
|
+
} from "../platform/platform.js";
|
|
6
6
|
|
|
7
|
-
export type { OperationalErrorCode } from "../platform/platform";
|
|
7
|
+
export type { OperationalErrorCode } from "../platform/platform.js";
|
|
8
8
|
|
|
9
9
|
export function captureRequestError(
|
|
10
10
|
error: unknown,
|
package/src/platform/platform.ts
CHANGED
|
@@ -3,15 +3,15 @@ import type {
|
|
|
3
3
|
ReasoningEffort,
|
|
4
4
|
RoutingStrategy,
|
|
5
5
|
} from "@mupt-ai/dari-router/policy-engine";
|
|
6
|
-
import type { HarnessConversationIdentity } from "../runtime/harness_identity";
|
|
7
|
-
import type { InteractionRequest, SourceProtocol } from "../interaction/types";
|
|
8
|
-
import type { SubscriptionUsageLimit } from "../providers/subscription_limits";
|
|
6
|
+
import type { HarnessConversationIdentity } from "../runtime/harness_identity/index.js";
|
|
7
|
+
import type { InteractionRequest, SourceProtocol } from "../interaction/types.js";
|
|
8
|
+
import type { SubscriptionUsageLimit } from "../providers/subscription_limits.js";
|
|
9
9
|
import type {
|
|
10
10
|
ClientHarness,
|
|
11
11
|
ProviderCredential,
|
|
12
12
|
ProviderKeySource,
|
|
13
13
|
ResolvedRouter,
|
|
14
|
-
} from "../types";
|
|
14
|
+
} from "../types.js";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Everything the gateway runtime needs from the deployment around it: router
|
|
@@ -33,7 +33,10 @@ export type GatewayPlatform = {
|
|
|
33
33
|
* Optional. Supply the credential for one enabled model of this request,
|
|
34
34
|
* consulted after `resolveRouter` and before its provider keys (for the
|
|
35
35
|
* self-hosted gateway, its environment keys), so an embedder can serve
|
|
36
|
-
* per-tenant keys from its own store. Undefined keeps the resolved key.
|
|
36
|
+
* per-tenant keys from its own store. Undefined keeps the resolved key. A
|
|
37
|
+
* credential with `subscription` serves the model on that plan, even on a
|
|
38
|
+
* strict router; a plan that cannot serve the model for this client (see
|
|
39
|
+
* SubscriptionKind) is ignored.
|
|
37
40
|
*/
|
|
38
41
|
resolveProviderCredential?(
|
|
39
42
|
request: ProviderCredentialRequest,
|
|
@@ -74,6 +77,7 @@ export type ProviderCredentialRequest = {
|
|
|
74
77
|
organizationId: string;
|
|
75
78
|
// The gateway key the request authenticated with.
|
|
76
79
|
apiKey: string;
|
|
80
|
+
clientHarness?: ClientHarness;
|
|
77
81
|
};
|
|
78
82
|
|
|
79
83
|
export type PrefixStateWrite = {
|