@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,410 @@
|
|
|
1
|
+
import { isReasoningEffort, isRecord } from "@mupt-ai/dari-router/policy-engine";
|
|
2
|
+
import { requiredCapabilitiesFor } from "../interaction/capabilities.js";
|
|
3
|
+
import { toolWireName, toolsByWireName } from "../interaction/tool_identity.js";
|
|
4
|
+
import { gatewayFor, payloadWithGatewayFields } from "../models/gateways.js";
|
|
5
|
+
import { offRequiresWireNone } from "../models/runtime_overrides.js";
|
|
6
|
+
import { effectiveReasoningForModel, validateReasoningEffortForModel } from "./reasoning.js";
|
|
7
|
+
import { isBedrockApi, isOpenAIResponsesApi } from "./model_capabilities.js";
|
|
8
|
+
import { forwardsAnthropicSafeguards, payloadWithSafeguards } from "./anthropic_safeguards.js";
|
|
9
|
+
const ANTHROPIC_FAST_MODE_BETA = "fast-mode-2026-02-01";
|
|
10
|
+
const ANTHROPIC_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
|
|
11
|
+
// Anthropic rejects newer models from older Claude Code versions, so forward
|
|
12
|
+
// the client's own user agent and keep this fallback current for other clients.
|
|
13
|
+
const CLAUDE_CODE_USER_AGENT = "claude-cli/2.1.280";
|
|
14
|
+
const IMAGE_DETAILS = ["auto", "low", "high", "original"];
|
|
15
|
+
const isAnthropic = (api) => api === "anthropic-messages";
|
|
16
|
+
const isCompletions = (api) => api === "openai-completions";
|
|
17
|
+
// Responses payloads Pi builds from the public OpenAI/Azure APIs (not Codex).
|
|
18
|
+
const isResponses = (api) => api === "openai-responses" || api === "azure-openai-responses";
|
|
19
|
+
const isOpenAI = (api) => isResponses(api) || isCompletions(api);
|
|
20
|
+
const isGoogle = (api) => api === "google-generative-ai" || api === "google-vertex";
|
|
21
|
+
export function buildOptions(request, auth, selectedModel, model, pi, sessionId, selectedReasoningEffort, timeoutMs = 1800_000, signal, fetch) {
|
|
22
|
+
const api = model.api;
|
|
23
|
+
const providerAuth = typeof auth === "string" ? { type: "bearer", apiKey: auth } : auth;
|
|
24
|
+
const { generation, toolChoice, parallelToolCalls, responseFormat } = request;
|
|
25
|
+
const headers = {};
|
|
26
|
+
const bearerHeader = sendsBearerToMessages(providerAuth, model);
|
|
27
|
+
if (bearerHeader)
|
|
28
|
+
headers.authorization = `Bearer ${providerAuth.apiKey}`;
|
|
29
|
+
const options = {
|
|
30
|
+
...(bearerHeader ? {} : authenticationOptions(providerAuth, api)),
|
|
31
|
+
maxRetries: 0,
|
|
32
|
+
timeoutMs,
|
|
33
|
+
signal,
|
|
34
|
+
fetch,
|
|
35
|
+
metadata: { ...request.metadata, ...(request.user ? { user: request.user } : {}) },
|
|
36
|
+
// Feeds OpenAI prompt_cache_key + session-affinity headers inside pi-ai;
|
|
37
|
+
// ignored by providers without session-based caching.
|
|
38
|
+
sessionId: sessionId || undefined,
|
|
39
|
+
};
|
|
40
|
+
const patches = [];
|
|
41
|
+
if (isClaudeCodeOAuth(providerAuth, api)) {
|
|
42
|
+
headers["user-agent"] = request.claudeCodeUserAgent ?? CLAUDE_CODE_USER_AGENT;
|
|
43
|
+
}
|
|
44
|
+
if (model.provider === "meta" && request.museCodeClientId !== undefined) {
|
|
45
|
+
headers["x-client-id"] = request.museCodeClientId;
|
|
46
|
+
}
|
|
47
|
+
// Pi's Anthropic transport honors compat.supportsTemperature; the OpenAI
|
|
48
|
+
// transports forward temperature regardless, so drop it here for models
|
|
49
|
+
// that reject it instead of failing the whole request.
|
|
50
|
+
if (!(isRecord(model.compat) && model.compat.supportsTemperature === false)) {
|
|
51
|
+
options.temperature = generation.temperature;
|
|
52
|
+
}
|
|
53
|
+
options.maxTokens = generation.maxOutputTokens;
|
|
54
|
+
if (generation.topP !== undefined || generation.stop !== undefined) {
|
|
55
|
+
patches.push((payload) => payloadWithSamplingControls(payload, request, api));
|
|
56
|
+
}
|
|
57
|
+
if (isAnthropic(api)) {
|
|
58
|
+
const budgetTokens = request.reasoning?.budgetTokens;
|
|
59
|
+
if (request.reasoning?.enabled === false) {
|
|
60
|
+
patches.push((payload) => ({ ...payload, thinking: { type: "disabled" } }));
|
|
61
|
+
}
|
|
62
|
+
else if (budgetTokens !== undefined) {
|
|
63
|
+
patches.push((payload) => ({
|
|
64
|
+
...payload,
|
|
65
|
+
thinking: { ...asRecord(payload.thinking), type: "enabled", budget_tokens: budgetTokens },
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
patches.push(payloadWithoutThinkingBlockBinding);
|
|
69
|
+
}
|
|
70
|
+
const gatewayFields = gatewayFor(model.provider)?.requestFields({ zdr: model.zeroDataRetention === true });
|
|
71
|
+
if (gatewayFields !== undefined && Object.keys(gatewayFields).length > 0) {
|
|
72
|
+
patches.push((payload) => payloadWithGatewayFields(payload, gatewayFields));
|
|
73
|
+
}
|
|
74
|
+
const safeguards = request.anthropicSafeguards;
|
|
75
|
+
if (safeguards !== undefined && forwardsAnthropicSafeguards(request, model)) {
|
|
76
|
+
patches.push((payload) => payloadWithSafeguards(payload, safeguards));
|
|
77
|
+
}
|
|
78
|
+
if (isOpenAIResponsesApi(api) && requiredCapabilitiesFor(request).includes("openai_hosted_web_search")) {
|
|
79
|
+
options.emitProviderEvents = true;
|
|
80
|
+
const hosted = request.tools.flatMap((tool) => tool.kind === "hosted" ? [{ ...tool.config }] : []);
|
|
81
|
+
if (hosted.length > 0) {
|
|
82
|
+
patches.push((payload) => ({ ...payload, tools: [...asArray(payload.tools), ...hosted] }));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (isOpenAI(api)) {
|
|
86
|
+
const details = imageDetailQueues(request);
|
|
87
|
+
if (details.size > 0)
|
|
88
|
+
patches.push((payload) => payloadWithImageDetails(payload, details));
|
|
89
|
+
}
|
|
90
|
+
if (toolChoice !== undefined) {
|
|
91
|
+
// Bedrock builds its Converse toolConfig from options.toolChoice before
|
|
92
|
+
// onPayload runs, so the choice must ride on options, not a payload patch.
|
|
93
|
+
if (isBedrockApi(api))
|
|
94
|
+
options.toolChoice = bedrockToolChoice(toolChoice);
|
|
95
|
+
else
|
|
96
|
+
patches.push((payload) => ({ ...payload, tool_choice: providerToolChoice(toolChoice, api) }));
|
|
97
|
+
}
|
|
98
|
+
if (request.tools.some((tool) => tool.kind === "function" && (tool.strict !== undefined || isAnthropic(api)))) {
|
|
99
|
+
patches.push((payload) => payloadWithStrictTools(payload, request, api));
|
|
100
|
+
}
|
|
101
|
+
if (responseFormat !== undefined) {
|
|
102
|
+
options.responseFormat = piResponseFormat(responseFormat);
|
|
103
|
+
// Pi keeps responseFormat in options but does not serialize it in simple
|
|
104
|
+
// OpenAI adapters, so patch the provider payload at the boundary.
|
|
105
|
+
patches.push((payload) => payloadWithResponseFormat(payload, responseFormat, api));
|
|
106
|
+
}
|
|
107
|
+
if (parallelToolCalls !== undefined) {
|
|
108
|
+
patches.push((payload) => payloadWithParallelToolCalls(payload, parallelToolCalls, api));
|
|
109
|
+
}
|
|
110
|
+
if (model.fastMode === true) {
|
|
111
|
+
if (model.provider === "openai" && isOpenAI(api) && api !== "azure-openai-responses") {
|
|
112
|
+
// Pi's simple Responses adapter drops serviceTier while lowering its
|
|
113
|
+
// options, so patch the payload too; the option still feeds usage pricing.
|
|
114
|
+
if (api === "openai-responses")
|
|
115
|
+
options.serviceTier = "priority";
|
|
116
|
+
patches.push((payload) => ({ ...payload, service_tier: "priority" }));
|
|
117
|
+
}
|
|
118
|
+
else if (model.provider === "anthropic" && isAnthropic(api)) {
|
|
119
|
+
headers["anthropic-beta"] = ANTHROPIC_FAST_MODE_BETA;
|
|
120
|
+
patches.push((payload) => ({ ...payload, speed: "fast" }));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const reasoning = providerReasoning(request, selectedModel, model, pi, selectedReasoningEffort);
|
|
124
|
+
if (reasoning !== undefined && reasoning !== "off") {
|
|
125
|
+
options.reasoning = reasoning;
|
|
126
|
+
}
|
|
127
|
+
else if (reasoning === "off" && isCompletions(api) && offRequiresWireNone(selectedModel)) {
|
|
128
|
+
patches.push((payload) => payloadWithReasoningNone(payload, model));
|
|
129
|
+
}
|
|
130
|
+
if (isOpenAIResponsesApi(api))
|
|
131
|
+
patches.push(payloadWithDetailedReasoningSummary);
|
|
132
|
+
// Some clients send the default tool_choice even after omitting tools for
|
|
133
|
+
// a turn. OpenAI rejects every tool_choice value when the lowered payload
|
|
134
|
+
// has no tools, so enforce that provider invariant after all tool patches.
|
|
135
|
+
if ((toolChoice !== undefined || parallelToolCalls !== undefined) && !isBedrockApi(api)) {
|
|
136
|
+
patches.push(payloadWithoutOrphanedToolChoice);
|
|
137
|
+
}
|
|
138
|
+
if (Object.keys(headers).length > 0)
|
|
139
|
+
options.headers = headers;
|
|
140
|
+
if (patches.length > 0)
|
|
141
|
+
options.onPayload = (payload) => applyPayloadPatches(payload, patches);
|
|
142
|
+
return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined));
|
|
143
|
+
}
|
|
144
|
+
export function supportedThinkingLevels(model, pi) {
|
|
145
|
+
const levels = Array.isArray(model.supportedThinkingLevels)
|
|
146
|
+
? model.supportedThinkingLevels
|
|
147
|
+
: pi.getSupportedThinkingLevels?.(model);
|
|
148
|
+
return Array.isArray(levels) ? levels.filter((level) => typeof level === "string") : ["off"];
|
|
149
|
+
}
|
|
150
|
+
function providerReasoning(request, selectedModel, model, pi, selectedReasoningEffort) {
|
|
151
|
+
const supportedLevels = supportedThinkingLevels(model, pi);
|
|
152
|
+
const defaultReasoningEffort = isReasoningEffort(model.defaultThinkingLevel) ? model.defaultThinkingLevel : undefined;
|
|
153
|
+
const effective = effectiveReasoningForModel({
|
|
154
|
+
request,
|
|
155
|
+
selectedModel,
|
|
156
|
+
supportedLevels,
|
|
157
|
+
selectedReasoningEffort,
|
|
158
|
+
defaultReasoningEffort,
|
|
159
|
+
});
|
|
160
|
+
const baseEffort = request.reasoning?.baseEffort;
|
|
161
|
+
if (baseEffort !== undefined)
|
|
162
|
+
validateReasoningEffortForModel(baseEffort, selectedModel, supportedLevels);
|
|
163
|
+
return request.reasoning?.hasConfigurationUpdate ? baseEffort ?? defaultReasoningEffort : effective;
|
|
164
|
+
}
|
|
165
|
+
function authenticationOptions(auth, api) {
|
|
166
|
+
if (auth.type === "bearer")
|
|
167
|
+
return { apiKey: auth.apiKey };
|
|
168
|
+
if (!isBedrockApi(api))
|
|
169
|
+
throw new Error("AWS SigV4 authentication requires the Bedrock API.");
|
|
170
|
+
return {
|
|
171
|
+
env: {
|
|
172
|
+
AWS_ACCESS_KEY_ID: auth.access_key_id,
|
|
173
|
+
AWS_SECRET_ACCESS_KEY: auth.secret_access_key,
|
|
174
|
+
AWS_SESSION_TOKEN: auth.session_token ?? "",
|
|
175
|
+
AWS_REGION: auth.region,
|
|
176
|
+
AWS_DEFAULT_REGION: auth.region,
|
|
177
|
+
AWS_BEARER_TOKEN_BEDROCK: "",
|
|
178
|
+
AWS_PROFILE: "",
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// Anthropic Messages endpoints outside Anthropic that take the key as a bearer
|
|
183
|
+
// token (Claude Code's ANTHROPIC_AUTH_TOKEN) and reject x-api-key.
|
|
184
|
+
const BEARER_MESSAGES_PROVIDERS = new Set(["meta"]);
|
|
185
|
+
function sendsBearerToMessages(auth, model) {
|
|
186
|
+
return auth.type === "bearer" && isAnthropic(model.api) && BEARER_MESSAGES_PROVIDERS.has(model.provider);
|
|
187
|
+
}
|
|
188
|
+
function isClaudeCodeOAuth(auth, api) {
|
|
189
|
+
return auth.type === "bearer" && isAnthropic(api) && auth.apiKey.includes("sk-ant-oat");
|
|
190
|
+
}
|
|
191
|
+
// Chains patches, preserving the "undefined means unchanged" contract for the
|
|
192
|
+
// combined result.
|
|
193
|
+
function applyPayloadPatches(payload, patches) {
|
|
194
|
+
if (!isRecord(payload))
|
|
195
|
+
return undefined;
|
|
196
|
+
let current = payload;
|
|
197
|
+
let changed = false;
|
|
198
|
+
for (const patch of patches) {
|
|
199
|
+
const next = patch(current);
|
|
200
|
+
if (isRecord(next)) {
|
|
201
|
+
current = next;
|
|
202
|
+
changed = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return changed ? current : undefined;
|
|
206
|
+
}
|
|
207
|
+
function asRecord(value) {
|
|
208
|
+
return isRecord(value) ? value : {};
|
|
209
|
+
}
|
|
210
|
+
function asArray(value) {
|
|
211
|
+
return Array.isArray(value) ? value : [];
|
|
212
|
+
}
|
|
213
|
+
function payloadWithSamplingControls(payload, request, api) {
|
|
214
|
+
const { topP, stop } = request.generation;
|
|
215
|
+
const camelCase = isGoogle(api) || isBedrockApi(api);
|
|
216
|
+
const controls = {};
|
|
217
|
+
// Anthropic rejects top_p with thinking; keep the hosted path aligned with
|
|
218
|
+
// the router's unsupported Anthropic top_p control.
|
|
219
|
+
if (topP !== undefined && !isAnthropic(api))
|
|
220
|
+
controls[camelCase ? "topP" : "top_p"] = topP;
|
|
221
|
+
if (stop !== undefined && !isOpenAIResponsesApi(api)) {
|
|
222
|
+
const key = camelCase ? "stopSequences" : isAnthropic(api) ? "stop_sequences" : "stop";
|
|
223
|
+
controls[key] = isCompletions(api) || typeof stop !== "string" ? stop : [stop];
|
|
224
|
+
}
|
|
225
|
+
if (isGoogle(api))
|
|
226
|
+
return { ...payload, config: { ...asRecord(payload.config), ...controls } };
|
|
227
|
+
if (isBedrockApi(api))
|
|
228
|
+
return { ...payload, inferenceConfig: { ...asRecord(payload.inferenceConfig), ...controls } };
|
|
229
|
+
return { ...payload, ...controls };
|
|
230
|
+
}
|
|
231
|
+
// Pi sends `thinking.block_binding: {prefix_mismatch_behavior: "drop_block"}`
|
|
232
|
+
// plus the binding-controls beta on mid-conversation-effort models (Fable 5.1,
|
|
233
|
+
// Opus 5). That opts every request into the preserved-thinking prefix check:
|
|
234
|
+
// when a replayed thinking block's recorded prefix no longer matches (client
|
|
235
|
+
// re-render, retry, or provider refusal in the loop), the API silently drops
|
|
236
|
+
// the block, which mutates the prompt bytes from that block onward and
|
|
237
|
+
// re-writes the rest of the conversation at cache-write prices. On
|
|
238
|
+
// organizations not yet enforced (created before 2026-08-31), opting out keeps
|
|
239
|
+
// the prefix stable and the cache warm; the API records the mismatch without
|
|
240
|
+
// acting on it.
|
|
241
|
+
function payloadWithoutThinkingBlockBinding(payload) {
|
|
242
|
+
const thinking = payload.thinking;
|
|
243
|
+
if (!isRecord(thinking) || !isRecord(thinking.block_binding))
|
|
244
|
+
return undefined;
|
|
245
|
+
const { block_binding: _, ...rest } = thinking;
|
|
246
|
+
const betas = Array.isArray(payload.betas)
|
|
247
|
+
? payload.betas.filter((beta) => beta !== ANTHROPIC_BINDING_CONTROLS_BETA)
|
|
248
|
+
: payload.betas;
|
|
249
|
+
return { ...payload, thinking: rest, betas };
|
|
250
|
+
}
|
|
251
|
+
// These models need explicit "none" rather than the provider default.
|
|
252
|
+
// Gateways use nested reasoning; direct providers use reasoning_effort.
|
|
253
|
+
function payloadWithReasoningNone(payload, model) {
|
|
254
|
+
if (!gatewayFor(model.provider))
|
|
255
|
+
return { ...payload, reasoning_effort: "none" };
|
|
256
|
+
const { reasoning_effort: _, ...rest } = payload;
|
|
257
|
+
return { ...rest, reasoning: { ...asRecord(payload.reasoning), effort: "none" } };
|
|
258
|
+
}
|
|
259
|
+
// Pi's default "auto" summary leaves many reasoning items empty (93% on the
|
|
260
|
+
// ChatGPT Codex backend). Readable summaries are the only reasoning a later
|
|
261
|
+
// turn on another provider can replay, so ask for detailed ones.
|
|
262
|
+
function payloadWithDetailedReasoningSummary(payload) {
|
|
263
|
+
if (!isRecord(payload.reasoning) || payload.reasoning.summary === undefined)
|
|
264
|
+
return undefined;
|
|
265
|
+
return { ...payload, reasoning: { ...payload.reasoning, summary: "detailed" } };
|
|
266
|
+
}
|
|
267
|
+
function piResponseFormat(format) {
|
|
268
|
+
if (format.type !== "json_schema")
|
|
269
|
+
return format;
|
|
270
|
+
const { type: _, ...jsonSchema } = format;
|
|
271
|
+
return { type: "json_schema", jsonSchema };
|
|
272
|
+
}
|
|
273
|
+
function payloadWithResponseFormat(payload, format, api) {
|
|
274
|
+
if (format.type === "text")
|
|
275
|
+
return undefined;
|
|
276
|
+
if (isAnthropic(api)) {
|
|
277
|
+
const schema = format.type === "json_schema" ? format.schema : { type: "object" };
|
|
278
|
+
return { ...payload, output_config: { ...asRecord(payload.output_config), format: { type: "json_schema", schema } } };
|
|
279
|
+
}
|
|
280
|
+
if (format.type === "json_object") {
|
|
281
|
+
if (isResponses(api))
|
|
282
|
+
return { ...payload, text: { ...asRecord(payload.text), format } };
|
|
283
|
+
if (isCompletions(api))
|
|
284
|
+
return { ...payload, response_format: format };
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
const { type: _, ...jsonSchema } = format;
|
|
288
|
+
if (isResponses(api))
|
|
289
|
+
return { ...payload, text: { ...asRecord(payload.text), format: { ...jsonSchema, type: "json_schema" } } };
|
|
290
|
+
if (isCompletions(api))
|
|
291
|
+
return { ...payload, response_format: { type: "json_schema", json_schema: jsonSchema } };
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
function bedrockToolChoice(choice) {
|
|
295
|
+
if (typeof choice === "string")
|
|
296
|
+
return choice;
|
|
297
|
+
if (choice.kind === "hosted")
|
|
298
|
+
return undefined;
|
|
299
|
+
return { type: "function", function: { name: toolWireName(choice.namespace, choice.name) } };
|
|
300
|
+
}
|
|
301
|
+
function providerToolChoice(choice, api) {
|
|
302
|
+
if (typeof choice === "string") {
|
|
303
|
+
if (isAnthropic(api))
|
|
304
|
+
return { type: choice === "required" ? "any" : choice };
|
|
305
|
+
return choice === "any" ? "required" : choice;
|
|
306
|
+
}
|
|
307
|
+
if (choice.kind === "hosted")
|
|
308
|
+
return { type: choice.type };
|
|
309
|
+
const name = toolWireName(choice.namespace, choice.name);
|
|
310
|
+
if (isAnthropic(api))
|
|
311
|
+
return { type: "tool", name };
|
|
312
|
+
// Pi currently declares both interaction tool kinds as JSON function tools.
|
|
313
|
+
if (isResponses(api))
|
|
314
|
+
return { type: "function", name };
|
|
315
|
+
return { type: "function", function: { name } };
|
|
316
|
+
}
|
|
317
|
+
function payloadWithoutOrphanedToolChoice(payload) {
|
|
318
|
+
if (!("tool_choice" in payload) || asArray(payload.tools).length > 0)
|
|
319
|
+
return undefined;
|
|
320
|
+
const { tool_choice: _, ...rest } = payload;
|
|
321
|
+
return rest;
|
|
322
|
+
}
|
|
323
|
+
function payloadWithStrictTools(payload, request, api) {
|
|
324
|
+
if (!Array.isArray(payload.tools) || !(isOpenAI(api) || isAnthropic(api)))
|
|
325
|
+
return undefined;
|
|
326
|
+
const definitions = toolsByWireName(request.tools);
|
|
327
|
+
const functionTool = (name) => {
|
|
328
|
+
const tool = typeof name === "string" ? definitions.get(name) : undefined;
|
|
329
|
+
return tool?.kind === "function" ? tool : undefined;
|
|
330
|
+
};
|
|
331
|
+
const tools = payload.tools.map((entry) => {
|
|
332
|
+
if (!isRecord(entry))
|
|
333
|
+
return entry;
|
|
334
|
+
if (isAnthropic(api)) {
|
|
335
|
+
const tool = functionTool(entry.name);
|
|
336
|
+
if (!tool)
|
|
337
|
+
return entry;
|
|
338
|
+
// defer_loading is intentionally not restored from the definition: Pi
|
|
339
|
+
// decides placement (deferred batch vs force-loaded immediate), and
|
|
340
|
+
// re-adding it here would recreate the cache_control/defer_loading
|
|
341
|
+
// combination Anthropic rejects. The entry spread preserves Pi's choice.
|
|
342
|
+
return {
|
|
343
|
+
...entry,
|
|
344
|
+
...(tool.parameters !== undefined ? { input_schema: tool.parameters } : {}),
|
|
345
|
+
...(tool.strict !== undefined ? { strict: tool.strict } : {}),
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
if (isCompletions(api) && isRecord(entry.function)) {
|
|
349
|
+
const strict = functionTool(entry.function.name)?.strict;
|
|
350
|
+
return strict === undefined ? entry : { ...entry, function: { ...entry.function, strict } };
|
|
351
|
+
}
|
|
352
|
+
const strict = functionTool(entry.name)?.strict;
|
|
353
|
+
return strict === undefined ? entry : { ...entry, strict };
|
|
354
|
+
});
|
|
355
|
+
return { ...payload, tools };
|
|
356
|
+
}
|
|
357
|
+
function payloadWithParallelToolCalls(payload, enabled, api) {
|
|
358
|
+
if (isOpenAI(api))
|
|
359
|
+
return { ...payload, parallel_tool_calls: enabled };
|
|
360
|
+
if (!isAnthropic(api) || enabled)
|
|
361
|
+
return undefined;
|
|
362
|
+
const current = asRecord(payload.tool_choice);
|
|
363
|
+
if (current.type === "none")
|
|
364
|
+
return undefined;
|
|
365
|
+
return { ...payload, tool_choice: { type: "auto", ...current, disable_parallel_tool_use: true } };
|
|
366
|
+
}
|
|
367
|
+
// Fills `detail` on Responses (`input_image`) and Chat (`image_url`) parts,
|
|
368
|
+
// matching request images to payload images by URL in order.
|
|
369
|
+
function payloadWithImageDetails(payload, details) {
|
|
370
|
+
const queues = new Map([...details].map(([url, queue]) => [url, [...queue]]));
|
|
371
|
+
let changed = false;
|
|
372
|
+
const patch = (value) => {
|
|
373
|
+
if (Array.isArray(value))
|
|
374
|
+
return value.map(patch);
|
|
375
|
+
if (!isRecord(value))
|
|
376
|
+
return value;
|
|
377
|
+
const node = Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, patch(entry)]));
|
|
378
|
+
if (node.type === "input_image" && typeof node.image_url === "string") {
|
|
379
|
+
const detail = queues.get(node.image_url)?.shift();
|
|
380
|
+
if (detail === undefined)
|
|
381
|
+
return node;
|
|
382
|
+
changed = true;
|
|
383
|
+
return { ...node, detail };
|
|
384
|
+
}
|
|
385
|
+
if (node.type === "image_url" && isRecord(node.image_url) && typeof node.image_url.url === "string") {
|
|
386
|
+
const detail = queues.get(node.image_url.url)?.shift();
|
|
387
|
+
if (detail === undefined)
|
|
388
|
+
return node;
|
|
389
|
+
changed = true;
|
|
390
|
+
return { ...node, image_url: { ...node.image_url, detail } };
|
|
391
|
+
}
|
|
392
|
+
return node;
|
|
393
|
+
};
|
|
394
|
+
const patched = patch(payload);
|
|
395
|
+
return changed ? patched : undefined;
|
|
396
|
+
}
|
|
397
|
+
function imageDetailQueues(request) {
|
|
398
|
+
const details = new Map();
|
|
399
|
+
for (const item of request.items) {
|
|
400
|
+
const content = item.type === "message" ? item.content : item.type === "tool_result" ? item.output : undefined;
|
|
401
|
+
for (const part of asArray(content)) {
|
|
402
|
+
if (!isRecord(part) || part.type !== "image" || typeof part.url !== "string")
|
|
403
|
+
continue;
|
|
404
|
+
if (!IMAGE_DETAILS.includes(part.detail))
|
|
405
|
+
continue;
|
|
406
|
+
details.set(part.url, [...(details.get(part.url) ?? []), part.detail]);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return details;
|
|
410
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { InteractionOutput, InteractionRequest, ProviderIdentity } from "../interaction/types.js";
|
|
2
|
+
export declare function piMessageToInteractionOutput(message: Record<string, unknown>, source: ProviderIdentity, request: Pick<InteractionRequest, "tools">): InteractionOutput;
|