@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,494 @@
|
|
|
1
|
+
import { isReasoningEffort, isRecord } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
import { HttpError } from "../../http/errors.js";
|
|
3
|
+
import { parseDataImageUrl } from "../../interaction/image.js";
|
|
4
|
+
import { decodeUntrustedProviderContinuationState } from "../../interaction/provider_continuation_state.js";
|
|
5
|
+
import { decodeUntrustedPortableReasoningState } from "../../interaction/portable_reasoning_state.js";
|
|
6
|
+
import { toolsByWireName } from "../../interaction/tool_identity.js";
|
|
7
|
+
import { explicitModelId, isAnthropicRouterModel, unsupportedModelMessage } from "./router_model.js";
|
|
8
|
+
const SUPPORTED_SERVER_TOOL_TYPES = [
|
|
9
|
+
"bash_20250124",
|
|
10
|
+
"text_editor_20250124",
|
|
11
|
+
"tool_search_tool_20250919",
|
|
12
|
+
"tool_search_tool_regex_20250919",
|
|
13
|
+
"tool_search_tool_regex",
|
|
14
|
+
"tool_search_tool_regex_20251119",
|
|
15
|
+
"tool_search_tool_bm25",
|
|
16
|
+
"tool_search_tool_bm25_20251119",
|
|
17
|
+
];
|
|
18
|
+
const isServerToolType = (type) => SUPPORTED_SERVER_TOOL_TYPES.includes(type);
|
|
19
|
+
export function anthropicMessagesToInteraction(payload) {
|
|
20
|
+
const model = requiredString(payload.model, "model");
|
|
21
|
+
if (!isAnthropicRouterModel(model) && explicitModelId(model) === null) {
|
|
22
|
+
throw invalidRequest(unsupportedModelMessage(), "model");
|
|
23
|
+
}
|
|
24
|
+
const tools = anthropicTools(payload.tools);
|
|
25
|
+
toolsByWireName(tools);
|
|
26
|
+
const toolChoice = anthropicToolChoice(payload.tool_choice);
|
|
27
|
+
const maxOutputTokens = requiredPositiveInteger(payload.max_tokens, "max_tokens");
|
|
28
|
+
const stream = optionalBoolean(payload.stream, "stream") ?? false;
|
|
29
|
+
const sessionId = metadataSessionId(payload.metadata);
|
|
30
|
+
return {
|
|
31
|
+
sourceProtocol: "anthropic_messages",
|
|
32
|
+
model,
|
|
33
|
+
instructions: anthropicSystem(payload.system),
|
|
34
|
+
items: anthropicItems(payload.messages),
|
|
35
|
+
tools,
|
|
36
|
+
toolChoice,
|
|
37
|
+
parallelToolCalls: parallelToolCalls(payload.tool_choice),
|
|
38
|
+
generation: {
|
|
39
|
+
temperature: optionalNumber(payload.temperature, "temperature"),
|
|
40
|
+
topP: optionalNumber(payload.top_p, "top_p"),
|
|
41
|
+
maxOutputTokens,
|
|
42
|
+
stop: stopSequences(payload.stop_sequences),
|
|
43
|
+
},
|
|
44
|
+
reasoning: anthropicReasoning(payload.thinking, payload.output_config),
|
|
45
|
+
responseFormat: anthropicResponseFormat(payload.output_config),
|
|
46
|
+
stream,
|
|
47
|
+
metadata: optionalRecord(payload.metadata, "metadata"),
|
|
48
|
+
user: metadataUser(payload.metadata),
|
|
49
|
+
...(sessionId !== undefined ? { promptCacheKey: sessionId } : {}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function anthropicItems(value) {
|
|
53
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
54
|
+
throw invalidRequest("messages must be a non-empty array.", "messages");
|
|
55
|
+
}
|
|
56
|
+
const items = [];
|
|
57
|
+
for (const [messageIndex, rawMessage] of value.entries()) {
|
|
58
|
+
if (!isRecord(rawMessage)) {
|
|
59
|
+
throw invalidRequest(`messages[${messageIndex}] must be an object.`, `messages.${messageIndex}`);
|
|
60
|
+
}
|
|
61
|
+
const role = requiredString(rawMessage.role, `messages.${messageIndex}.role`);
|
|
62
|
+
if (role !== "system" && role !== "user" && role !== "assistant") {
|
|
63
|
+
throw invalidRequest(`Unsupported Anthropic message role '${role}'.`, `messages.${messageIndex}.role`);
|
|
64
|
+
}
|
|
65
|
+
appendAnthropicMessage(items, role, rawMessage.content, messageIndex);
|
|
66
|
+
}
|
|
67
|
+
return items;
|
|
68
|
+
}
|
|
69
|
+
function appendAnthropicMessage(items, role, value, messageIndex) {
|
|
70
|
+
if (typeof value === "string") {
|
|
71
|
+
items.push({
|
|
72
|
+
type: "message",
|
|
73
|
+
role,
|
|
74
|
+
content: [{ type: "text", text: value }],
|
|
75
|
+
contentShape: "string",
|
|
76
|
+
});
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
80
|
+
throw invalidRequest(`messages[${messageIndex}].content must be a string or a non-empty array.`, `messages.${messageIndex}.content`);
|
|
81
|
+
}
|
|
82
|
+
let buffered = [];
|
|
83
|
+
const flushMessage = () => {
|
|
84
|
+
if (buffered.length === 0)
|
|
85
|
+
return;
|
|
86
|
+
items.push({ type: "message", role, content: buffered, contentShape: "parts" });
|
|
87
|
+
buffered = [];
|
|
88
|
+
};
|
|
89
|
+
let pendingServerToolUse = null;
|
|
90
|
+
for (const [contentIndex, rawBlock] of value.entries()) {
|
|
91
|
+
const param = `messages.${messageIndex}.content.${contentIndex}`;
|
|
92
|
+
if (!isRecord(rawBlock))
|
|
93
|
+
throw invalidRequest(`${param} must be an object.`, param);
|
|
94
|
+
const type = requiredString(rawBlock.type, `${param}.type`);
|
|
95
|
+
if (type === "text") {
|
|
96
|
+
buffered.push({ type: "text", text: requiredStringAllowEmpty(rawBlock.text, `${param}.text`) });
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (type === "image") {
|
|
100
|
+
if (role !== "user")
|
|
101
|
+
throw invalidRequest("Anthropic image blocks are only supported on user messages.", param);
|
|
102
|
+
buffered.push(anthropicImage(rawBlock.source, `${param}.source`));
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (type === "thinking" || type === "redacted_thinking") {
|
|
106
|
+
if (role !== "assistant")
|
|
107
|
+
throw invalidRequest(`${type} blocks require the assistant role.`, param);
|
|
108
|
+
flushMessage();
|
|
109
|
+
items.push(anthropicReasoningItem(rawBlock, type, param));
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (type === "tool_use") {
|
|
113
|
+
if (role !== "assistant")
|
|
114
|
+
throw invalidRequest("tool_use blocks require the assistant role.", param);
|
|
115
|
+
flushMessage();
|
|
116
|
+
const input = rawBlock.input;
|
|
117
|
+
if (!isRecord(input))
|
|
118
|
+
throw invalidRequest(`${param}.input must be an object.`, `${param}.input`);
|
|
119
|
+
items.push({
|
|
120
|
+
type: "tool_call",
|
|
121
|
+
callId: requiredString(rawBlock.id, `${param}.id`),
|
|
122
|
+
kind: "function",
|
|
123
|
+
name: requiredString(rawBlock.name, `${param}.name`),
|
|
124
|
+
input,
|
|
125
|
+
status: "completed",
|
|
126
|
+
});
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (type === "server_tool_use") {
|
|
130
|
+
if (role !== "assistant")
|
|
131
|
+
throw invalidRequest("server_tool_use blocks require the assistant role.", param);
|
|
132
|
+
flushMessage();
|
|
133
|
+
const serverId = requiredString(rawBlock.id, `${param}.id`);
|
|
134
|
+
const serverName = requiredString(rawBlock.name, `${param}.name`);
|
|
135
|
+
const serverInput = isRecord(rawBlock.input) ? rawBlock.input : {};
|
|
136
|
+
pendingServerToolUse = { callId: serverId, name: serverName, input: serverInput };
|
|
137
|
+
items.push({
|
|
138
|
+
type: "hosted_tool_call",
|
|
139
|
+
id: serverId,
|
|
140
|
+
tool: "server_tool_use",
|
|
141
|
+
providerType: "server_tool_use",
|
|
142
|
+
payload: { id: serverId, name: serverName, input: serverInput },
|
|
143
|
+
serverToolUseId: serverId,
|
|
144
|
+
serverToolName: serverName,
|
|
145
|
+
serverToolInput: serverInput,
|
|
146
|
+
});
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (type === "tool_search_tool_result") {
|
|
150
|
+
if (role !== "assistant")
|
|
151
|
+
throw invalidRequest("tool_search_tool_result blocks require the assistant role.", param);
|
|
152
|
+
flushMessage();
|
|
153
|
+
const toolUseId = requiredString(rawBlock.tool_use_id, `${param}.tool_use_id`);
|
|
154
|
+
const resultContent = rawBlock.content;
|
|
155
|
+
if (!Array.isArray(resultContent)) {
|
|
156
|
+
throw invalidRequest("tool_search_tool_result blocks require a content array.", `${param}.content`);
|
|
157
|
+
}
|
|
158
|
+
const references = [];
|
|
159
|
+
for (const [refIndex, refBlock] of resultContent.entries()) {
|
|
160
|
+
if (!isRecord(refBlock) || refBlock.type !== "tool_reference") {
|
|
161
|
+
throw invalidRequest(`tool_search_tool_result content.${refIndex} must be a tool_reference block.`, `${param}.content.${refIndex}`);
|
|
162
|
+
}
|
|
163
|
+
references.push({
|
|
164
|
+
type: "tool_reference",
|
|
165
|
+
toolName: requiredString(refBlock.tool_name, `${param}.content.${refIndex}.tool_name`),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const serverToolUse = pendingServerToolUse?.callId === toolUseId ? pendingServerToolUse : null;
|
|
169
|
+
if (serverToolUse)
|
|
170
|
+
pendingServerToolUse = null;
|
|
171
|
+
items.push({
|
|
172
|
+
type: "hosted_tool_call",
|
|
173
|
+
id: `${toolUseId}_result`,
|
|
174
|
+
tool: "tool_search",
|
|
175
|
+
providerType: "tool_search_result",
|
|
176
|
+
payload: {
|
|
177
|
+
tool_use_id: toolUseId,
|
|
178
|
+
content: references,
|
|
179
|
+
...(serverToolUse ? { name: serverToolUse.name, input: serverToolUse.input } : {}),
|
|
180
|
+
},
|
|
181
|
+
serverToolUseId: toolUseId,
|
|
182
|
+
serverToolName: serverToolUse?.name,
|
|
183
|
+
serverToolInput: serverToolUse?.input,
|
|
184
|
+
serverToolResult: references,
|
|
185
|
+
});
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (type === "tool_result") {
|
|
189
|
+
if (role !== "user")
|
|
190
|
+
throw invalidRequest("tool_result blocks require the user role.", param);
|
|
191
|
+
flushMessage();
|
|
192
|
+
const result = anthropicToolResultContent(rawBlock.content, `${param}.content`);
|
|
193
|
+
const loadedTools = result.output
|
|
194
|
+
? (Array.isArray(result.output)
|
|
195
|
+
? result.output.flatMap((part) => part.type === "tool_reference" ? [part.toolName] : [])
|
|
196
|
+
: [])
|
|
197
|
+
: [];
|
|
198
|
+
// Deduplicate and filter out any empty names
|
|
199
|
+
const uniqueLoadedTools = [...new Set(loadedTools)].filter(Boolean);
|
|
200
|
+
items.push({
|
|
201
|
+
type: "tool_result",
|
|
202
|
+
callId: requiredString(rawBlock.tool_use_id, `${param}.tool_use_id`),
|
|
203
|
+
kind: "function",
|
|
204
|
+
output: result.output,
|
|
205
|
+
outputShape: result.shape,
|
|
206
|
+
isError: optionalBoolean(rawBlock.is_error, `${param}.is_error`),
|
|
207
|
+
...(uniqueLoadedTools.length > 0 ? { loadedTools: uniqueLoadedTools } : {}),
|
|
208
|
+
});
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
throw new HttpError(400, `Anthropic content block type '${type}' is not supported.`, "unsupported_content_block", param);
|
|
212
|
+
}
|
|
213
|
+
flushMessage();
|
|
214
|
+
}
|
|
215
|
+
function anthropicImage(value, param) {
|
|
216
|
+
if (!isRecord(value))
|
|
217
|
+
throw invalidRequest(`${param} must be an object.`, param);
|
|
218
|
+
const type = requiredString(value.type, `${param}.type`);
|
|
219
|
+
if (type === "base64") {
|
|
220
|
+
const mediaType = requiredString(value.media_type, `${param}.media_type`);
|
|
221
|
+
if (!mediaType.startsWith("image/"))
|
|
222
|
+
throw invalidRequest(`${param}.media_type must be an image MIME type.`, `${param}.media_type`);
|
|
223
|
+
const data = requiredString(value.data, `${param}.data`);
|
|
224
|
+
const url = `data:${mediaType};base64,${data}`;
|
|
225
|
+
if (!parseDataImageUrl(url))
|
|
226
|
+
throw invalidRequest(`${param} must contain a base64 image.`, param);
|
|
227
|
+
return { type: "image", url };
|
|
228
|
+
}
|
|
229
|
+
if (type === "url") {
|
|
230
|
+
throw new HttpError(400, "Anthropic URL image sources are not supported; use a base64 image source.", "unsupported_image_source", `${param}.type`);
|
|
231
|
+
}
|
|
232
|
+
throw new HttpError(400, `Anthropic image source type '${type}' is not supported.`, "unsupported_image_source", `${param}.type`);
|
|
233
|
+
}
|
|
234
|
+
function anthropicReasoningItem(block, type, param) {
|
|
235
|
+
const encoded = requiredString(type === "thinking" ? block.signature : block.data, `${param}.${type === "thinking" ? "signature" : "data"}`);
|
|
236
|
+
const continuation = decodeUntrustedProviderContinuationState(encoded);
|
|
237
|
+
const portable = continuation ? null : decodeUntrustedPortableReasoningState(encoded);
|
|
238
|
+
if (!continuation && !portable) {
|
|
239
|
+
const field = type === "thinking" ? "signature" : "data";
|
|
240
|
+
throw new HttpError(400, `${param}.${field} must be a Dari reasoning-state envelope; raw provider state has no recoverable provider/model provenance.`, "invalid_provider_continuation_state", `${param}.${field}`);
|
|
241
|
+
}
|
|
242
|
+
const thinking = type === "thinking" ? requiredStringAllowEmpty(block.thinking, `${param}.thinking`) : "";
|
|
243
|
+
const reasoning = {
|
|
244
|
+
type: "reasoning",
|
|
245
|
+
summary: thinking ? [thinking] : [],
|
|
246
|
+
content: [],
|
|
247
|
+
};
|
|
248
|
+
if (continuation) {
|
|
249
|
+
reasoning.source = continuation.source;
|
|
250
|
+
reasoning.continuation = continuation;
|
|
251
|
+
}
|
|
252
|
+
else if (portable?.source) {
|
|
253
|
+
reasoning.source = portable.source;
|
|
254
|
+
}
|
|
255
|
+
return reasoning;
|
|
256
|
+
}
|
|
257
|
+
function anthropicToolResultContent(value, param) {
|
|
258
|
+
if (value === undefined)
|
|
259
|
+
return { output: null, shape: "absent" };
|
|
260
|
+
if (value === null)
|
|
261
|
+
return { output: null, shape: "null" };
|
|
262
|
+
if (typeof value === "string")
|
|
263
|
+
return { output: value, shape: "string" };
|
|
264
|
+
if (!Array.isArray(value))
|
|
265
|
+
throw invalidRequest(`${param} must be a string or an array.`, param);
|
|
266
|
+
return {
|
|
267
|
+
output: value.map((rawBlock, index) => {
|
|
268
|
+
const blockParam = `${param}.${index}`;
|
|
269
|
+
if (!isRecord(rawBlock))
|
|
270
|
+
throw invalidRequest(`${blockParam} must be an object.`, blockParam);
|
|
271
|
+
if (rawBlock.type === "text") {
|
|
272
|
+
return { type: "text", text: requiredStringAllowEmpty(rawBlock.text, `${blockParam}.text`) };
|
|
273
|
+
}
|
|
274
|
+
if (rawBlock.type === "image")
|
|
275
|
+
return anthropicImage(rawBlock.source, `${blockParam}.source`);
|
|
276
|
+
if (rawBlock.type === "tool_reference") {
|
|
277
|
+
return {
|
|
278
|
+
type: "tool_reference",
|
|
279
|
+
toolName: requiredString(rawBlock.tool_name, `${blockParam}.tool_name`),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
throw new HttpError(400, `Anthropic tool result block type '${String(rawBlock.type ?? "unknown")}' is not supported.`, "unsupported_content_block", blockParam);
|
|
283
|
+
}),
|
|
284
|
+
shape: "parts",
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function anthropicSystem(value) {
|
|
288
|
+
if (value === undefined || value === null)
|
|
289
|
+
return undefined;
|
|
290
|
+
if (typeof value === "string")
|
|
291
|
+
return value;
|
|
292
|
+
if (!Array.isArray(value))
|
|
293
|
+
throw invalidRequest("system must be a string or an array.", "system");
|
|
294
|
+
return value.map((rawBlock, index) => {
|
|
295
|
+
if (!isRecord(rawBlock) || rawBlock.type !== "text") {
|
|
296
|
+
throw new HttpError(400, "Only text system blocks are supported.", "unsupported_content_block", `system.${index}`);
|
|
297
|
+
}
|
|
298
|
+
return requiredStringAllowEmpty(rawBlock.text, `system.${index}.text`);
|
|
299
|
+
}).join("\n\n");
|
|
300
|
+
}
|
|
301
|
+
function anthropicTools(value) {
|
|
302
|
+
if (value === undefined || value === null)
|
|
303
|
+
return [];
|
|
304
|
+
if (!Array.isArray(value))
|
|
305
|
+
throw invalidRequest("tools must be an array.", "tools");
|
|
306
|
+
return value.map((rawTool, index) => {
|
|
307
|
+
if (!isRecord(rawTool))
|
|
308
|
+
throw invalidRequest(`tools[${index}] must be an object.`, `tools.${index}`);
|
|
309
|
+
const type = rawTool.type;
|
|
310
|
+
if (type !== undefined && type !== "custom") {
|
|
311
|
+
if (typeof type === "string" && isServerToolType(type)) {
|
|
312
|
+
if (type === "bash_20250124" || type === "text_editor_20250124") {
|
|
313
|
+
return {
|
|
314
|
+
kind: "client_tool",
|
|
315
|
+
name: requiredString(rawTool.name, `tools.${index}.name`),
|
|
316
|
+
type,
|
|
317
|
+
description: optionalString(rawTool.description, `tools.${index}.description`),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
kind: "server_tool",
|
|
322
|
+
name: requiredString(rawTool.name, `tools.${index}.name`),
|
|
323
|
+
type,
|
|
324
|
+
description: optionalString(rawTool.description, `tools.${index}.description`),
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
throw new HttpError(400, `Anthropic tool type '${String(type)}' is not supported by this router.`, "unsupported_tool", `tools.${index}.type`);
|
|
328
|
+
}
|
|
329
|
+
const schema = rawTool.input_schema;
|
|
330
|
+
if (!isRecord(schema))
|
|
331
|
+
throw invalidRequest(`tools[${index}].input_schema must be an object.`, `tools.${index}.input_schema`);
|
|
332
|
+
return {
|
|
333
|
+
kind: "function",
|
|
334
|
+
name: requiredString(rawTool.name, `tools.${index}.name`),
|
|
335
|
+
description: optionalString(rawTool.description, `tools.${index}.description`),
|
|
336
|
+
parameters: schema,
|
|
337
|
+
strict: optionalBoolean(rawTool.strict, `tools.${index}.strict`),
|
|
338
|
+
deferLoading: optionalBoolean(rawTool.defer_loading, `tools.${index}.defer_loading`),
|
|
339
|
+
};
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function anthropicToolChoice(value) {
|
|
343
|
+
if (value === undefined || value === null)
|
|
344
|
+
return undefined;
|
|
345
|
+
if (!isRecord(value))
|
|
346
|
+
throw invalidRequest("tool_choice must be an object.", "tool_choice");
|
|
347
|
+
const type = requiredString(value.type, "tool_choice.type");
|
|
348
|
+
if (type === "auto" || type === "any" || type === "none")
|
|
349
|
+
return type;
|
|
350
|
+
if (type === "tool")
|
|
351
|
+
return { kind: "function", name: requiredString(value.name, "tool_choice.name") };
|
|
352
|
+
throw invalidRequest(`Unsupported Anthropic tool choice '${type}'.`, "tool_choice.type");
|
|
353
|
+
}
|
|
354
|
+
function parallelToolCalls(value) {
|
|
355
|
+
if (!isRecord(value) || value.disable_parallel_tool_use === undefined)
|
|
356
|
+
return undefined;
|
|
357
|
+
return !requiredBoolean(value.disable_parallel_tool_use, "tool_choice.disable_parallel_tool_use");
|
|
358
|
+
}
|
|
359
|
+
function anthropicReasoning(thinkingValue, outputConfigValue) {
|
|
360
|
+
const effort = anthropicEffort(outputConfigValue);
|
|
361
|
+
if (thinkingValue === undefined || thinkingValue === null) {
|
|
362
|
+
return effort ? { effort, enabled: effort !== "off" } : undefined;
|
|
363
|
+
}
|
|
364
|
+
if (!isRecord(thinkingValue))
|
|
365
|
+
throw invalidRequest("thinking must be an object.", "thinking");
|
|
366
|
+
const type = requiredString(thinkingValue.type, "thinking.type");
|
|
367
|
+
if (type === "disabled")
|
|
368
|
+
return { effort: effort ?? "off", enabled: false };
|
|
369
|
+
if (type !== "enabled" && type !== "adaptive") {
|
|
370
|
+
throw invalidRequest(`Unsupported Anthropic thinking type '${type}'.`, "thinking.type");
|
|
371
|
+
}
|
|
372
|
+
const budgetTokens = type === "enabled"
|
|
373
|
+
? requiredPositiveInteger(thinkingValue.budget_tokens, "thinking.budget_tokens")
|
|
374
|
+
: undefined;
|
|
375
|
+
return {
|
|
376
|
+
...(effort ? { effort } : {}),
|
|
377
|
+
enabled: true,
|
|
378
|
+
...(budgetTokens !== undefined ? { budgetTokens } : {}),
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
function anthropicEffort(value) {
|
|
382
|
+
if (value === undefined || value === null)
|
|
383
|
+
return undefined;
|
|
384
|
+
if (!isRecord(value))
|
|
385
|
+
throw invalidRequest("output_config must be an object.", "output_config");
|
|
386
|
+
if (value.effort === undefined || value.effort === null)
|
|
387
|
+
return undefined;
|
|
388
|
+
const effort = requiredString(value.effort, "output_config.effort");
|
|
389
|
+
if (!isReasoningEffort(effort)
|
|
390
|
+
|| (effort !== "low" && effort !== "medium" && effort !== "high" && effort !== "xhigh" && effort !== "max")) {
|
|
391
|
+
throw invalidRequest(`Unsupported Anthropic effort '${effort}'.`, "output_config.effort");
|
|
392
|
+
}
|
|
393
|
+
return effort;
|
|
394
|
+
}
|
|
395
|
+
function anthropicResponseFormat(value) {
|
|
396
|
+
if (!isRecord(value) || value.format === undefined || value.format === null)
|
|
397
|
+
return undefined;
|
|
398
|
+
if (!isRecord(value.format))
|
|
399
|
+
throw invalidRequest("output_config.format must be an object.", "output_config.format");
|
|
400
|
+
if (value.format.type !== "json_schema") {
|
|
401
|
+
throw new HttpError(400, "Only Anthropic json_schema output formats are supported.", "unsupported_response_format", "output_config.format.type");
|
|
402
|
+
}
|
|
403
|
+
const schema = value.format.schema;
|
|
404
|
+
if (!isRecord(schema))
|
|
405
|
+
throw invalidRequest("output_config.format.schema must be an object.", "output_config.format.schema");
|
|
406
|
+
return {
|
|
407
|
+
type: "json_schema",
|
|
408
|
+
name: optionalString(value.format.name, "output_config.format.name") ?? "response",
|
|
409
|
+
schema,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function stopSequences(value) {
|
|
413
|
+
if (value === undefined || value === null)
|
|
414
|
+
return undefined;
|
|
415
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
|
|
416
|
+
throw invalidRequest("stop_sequences must be an array of strings.", "stop_sequences");
|
|
417
|
+
}
|
|
418
|
+
return value;
|
|
419
|
+
}
|
|
420
|
+
function metadataUser(value) {
|
|
421
|
+
return isRecord(value) && typeof value.user_id === "string" ? value.user_id : undefined;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Anthropic Messages has no prompt-cache field, but Claude Code packs a JSON
|
|
425
|
+
* object into metadata.user_id whose session_id changes per conversation. Only
|
|
426
|
+
* that member identifies a conversation — the surrounding device and account
|
|
427
|
+
* ids are shared by every conversation on the machine, so keying provider
|
|
428
|
+
* cache affinity on the raw string would collide across concurrent sessions.
|
|
429
|
+
*/
|
|
430
|
+
function metadataSessionId(value) {
|
|
431
|
+
const userId = metadataUser(value);
|
|
432
|
+
if (!userId)
|
|
433
|
+
return undefined;
|
|
434
|
+
let parsed;
|
|
435
|
+
try {
|
|
436
|
+
parsed = JSON.parse(userId);
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
return undefined;
|
|
440
|
+
}
|
|
441
|
+
if (!isRecord(parsed) || typeof parsed.session_id !== "string")
|
|
442
|
+
return undefined;
|
|
443
|
+
return parsed.session_id.trim() || undefined;
|
|
444
|
+
}
|
|
445
|
+
function optionalRecord(value, param) {
|
|
446
|
+
if (value === undefined || value === null)
|
|
447
|
+
return undefined;
|
|
448
|
+
if (!isRecord(value))
|
|
449
|
+
throw invalidRequest(`${param} must be an object.`, param);
|
|
450
|
+
return value;
|
|
451
|
+
}
|
|
452
|
+
function optionalString(value, param) {
|
|
453
|
+
if (value === undefined || value === null)
|
|
454
|
+
return undefined;
|
|
455
|
+
if (typeof value !== "string")
|
|
456
|
+
throw invalidRequest(`${param} must be a string.`, param);
|
|
457
|
+
return value;
|
|
458
|
+
}
|
|
459
|
+
function requiredString(value, param) {
|
|
460
|
+
if (typeof value !== "string" || !value)
|
|
461
|
+
throw invalidRequest(`${param} must be a non-empty string.`, param);
|
|
462
|
+
return value;
|
|
463
|
+
}
|
|
464
|
+
function requiredStringAllowEmpty(value, param) {
|
|
465
|
+
if (typeof value !== "string")
|
|
466
|
+
throw invalidRequest(`${param} must be a string.`, param);
|
|
467
|
+
return value;
|
|
468
|
+
}
|
|
469
|
+
function optionalNumber(value, param) {
|
|
470
|
+
if (value === undefined || value === null)
|
|
471
|
+
return undefined;
|
|
472
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
473
|
+
throw invalidRequest(`${param} must be a finite number.`, param);
|
|
474
|
+
return value;
|
|
475
|
+
}
|
|
476
|
+
function optionalBoolean(value, param) {
|
|
477
|
+
if (value === undefined || value === null)
|
|
478
|
+
return undefined;
|
|
479
|
+
return requiredBoolean(value, param);
|
|
480
|
+
}
|
|
481
|
+
function requiredBoolean(value, param) {
|
|
482
|
+
if (typeof value !== "boolean")
|
|
483
|
+
throw invalidRequest(`${param} must be a boolean.`, param);
|
|
484
|
+
return value;
|
|
485
|
+
}
|
|
486
|
+
function requiredPositiveInteger(value, param) {
|
|
487
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
488
|
+
throw invalidRequest(`${param} must be a positive integer.`, param);
|
|
489
|
+
}
|
|
490
|
+
return value;
|
|
491
|
+
}
|
|
492
|
+
function invalidRequest(message, param) {
|
|
493
|
+
return new HttpError(400, message, "invalid_request_error", param);
|
|
494
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type ChatCompletionRequest } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
import type { InteractionRequest } from "../../interaction/types.js";
|
|
3
|
+
export declare function chatCompletionsToInteraction(request: ChatCompletionRequest): InteractionRequest;
|
|
4
|
+
export declare function internalChatCompletionsToInteraction(request: ChatCompletionRequest): InteractionRequest;
|