@ai-sdk/gateway 4.0.16 → 4.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @ai-sdk/gateway
2
2
 
3
+ ## 4.0.19
4
+
5
+ ### Patch Changes
6
+
7
+ - 4be62c1: fix(provider-utils): validate provider-response URLs in `getFromApi`
8
+
9
+ `getFromApi` now has a `validateUrl` flag. It is optional so existing callers keep compiling (omitting it behaves like `false`, i.e. no validation), but all AI SDK provider packages set it explicitly at every call site so each one makes a visible trust decision. When `true`, the URL is routed through `fetchWithValidatedRedirects` — the same guard used by `downloadBlob` — which rejects private/loopback/link-local targets, re-validates every redirect hop, strips proxy/metadata/cookie request headers, and drops all caller headers except the user-agent on cross-origin redirects (custom API-key headers must not follow a redirect off-origin any more than `Authorization` may); blocked URLs throw `DownloadError`. It is enabled at the image/video/audio download and polling call sites where the URL comes from a provider response body; URLs built from developer-configured endpoints pass `validateUrl: false` and are unaffected.
10
+
11
+ A new optional `credentialedOrigin` withholds caller headers unless the URL is same-origin with it, so the API key is not sent to a response-supplied host on a different origin.
12
+
13
+ A new optional `trustedOrigin` exempts URLs (and redirect hops) that are same-origin with the developer-configured provider endpoint from target validation, so self-hosted and localhost deployments whose response URLs point back at the configured host keep working; all other hops are still validated.
14
+
15
+ Also closes range gaps in `validateDownloadUrl` (IPv4 `224.0.0.0/4` multicast and the TEST-NET documentation ranges `192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`; IPv6 documentation ranges `2001:db8::/32` and `3fff::/20`), and follows only the fetch-spec redirect status codes (301/302/303/307/308) — a `Location` header on any other status is not followed. This guard performs string/literal checks only and does not resolve DNS; hostnames that resolve to private addresses and DNS rebinding remain out of scope and must be constrained at the network layer (or by injecting a Node `fetch` that pins the resolved IP at connect time) for server deployments handling untrusted URLs. See `contributing/secure-url-handling.md`.
16
+
17
+ - f8e82fd: Add experimental streaming transcription support to the gateway provider (`GatewayTranscriptionModel.doStream`), speaking the shared transcription-stream WebSocket envelope from `@ai-sdk/provider-utils`. `experimental_streamTranscribe` now works with gateway string model IDs, e.g. `experimental_streamTranscribe({ model: 'openai/gpt-realtime-whisper', ... })`.
18
+ - Updated dependencies [4be62c1]
19
+ - Updated dependencies [7805e4a]
20
+ - Updated dependencies [cd12954]
21
+ - @ai-sdk/provider-utils@5.0.9
22
+
23
+ ## 4.0.18
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies [e193290]
28
+ - @ai-sdk/provider-utils@5.0.8
29
+
30
+ ## 4.0.17
31
+
32
+ ### Patch Changes
33
+
34
+ - 867f80a: chore(provider/gateway): update gateway model settings files
35
+
3
36
  ## 4.0.16
4
37
 
5
38
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { LanguageModelV4, ProviderV4, EmbeddingModelV4, ImageModelV4, Experimental_VideoModelV4, RerankingModelV4, SpeechModelV4, TranscriptionModelV4, Experimental_RealtimeFactoryV4, TypeValidationError } from '@ai-sdk/provider';
2
2
  import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
3
- import { FetchFunction, InferSchema } from '@ai-sdk/provider-utils';
3
+ import { FetchFunction, WebSocketConstructor, InferSchema } from '@ai-sdk/provider-utils';
4
4
 
5
- type GatewayModelId = 'alibaba/qwen-3-14b' | 'alibaba/qwen-3-235b' | 'alibaba/qwen-3-30b' | 'alibaba/qwen-3-32b' | 'alibaba/qwen-3.6-max-preview' | 'alibaba/qwen3-235b-a22b-thinking' | 'alibaba/qwen3-coder' | 'alibaba/qwen3-coder-30b-a3b' | 'alibaba/qwen3-coder-next' | 'alibaba/qwen3-coder-plus' | 'alibaba/qwen3-max' | 'alibaba/qwen3-max-preview' | 'alibaba/qwen3-max-thinking' | 'alibaba/qwen3-next-80b-a3b-instruct' | 'alibaba/qwen3-next-80b-a3b-thinking' | 'alibaba/qwen3-vl-235b-a22b-instruct' | 'alibaba/qwen3-vl-instruct' | 'alibaba/qwen3-vl-thinking' | 'alibaba/qwen3.5-flash' | 'alibaba/qwen3.5-plus' | 'alibaba/qwen3.6-27b' | 'alibaba/qwen3.6-plus' | 'alibaba/qwen3.7-max' | 'alibaba/qwen3.7-plus' | 'amazon/nova-2-lite' | 'amazon/nova-lite' | 'amazon/nova-micro' | 'amazon/nova-pro' | 'anthropic/claude-3-haiku' | 'anthropic/claude-3.5-haiku' | 'anthropic/claude-fable-5' | 'anthropic/claude-haiku-4.5' | 'anthropic/claude-opus-4' | 'anthropic/claude-opus-4.1' | 'anthropic/claude-opus-4.5' | 'anthropic/claude-opus-4.6' | 'anthropic/claude-opus-4.7' | 'anthropic/claude-opus-4.8' | 'anthropic/claude-sonnet-4' | 'anthropic/claude-sonnet-4.5' | 'anthropic/claude-sonnet-4.6' | 'anthropic/claude-sonnet-5' | 'arcee-ai/trinity-large-preview' | 'arcee-ai/trinity-large-thinking' | 'arcee-ai/trinity-mini' | 'bytedance/seed-1.6' | 'bytedance/seed-1.8' | 'cohere/command-a' | 'deepseek/deepseek-r1' | 'deepseek/deepseek-v3' | 'deepseek/deepseek-v3.1' | 'deepseek/deepseek-v3.1-terminus' | 'deepseek/deepseek-v3.2' | 'deepseek/deepseek-v3.2-thinking' | 'deepseek/deepseek-v4-flash' | 'deepseek/deepseek-v4-pro' | 'google/gemini-2.5-flash' | 'google/gemini-2.5-flash-image' | 'google/gemini-2.5-flash-lite' | 'google/gemini-2.5-pro' | 'google/gemini-3-flash' | 'google/gemini-3-pro-image' | 'google/gemini-3-pro-preview' | 'google/gemini-3.1-flash-image' | 'google/gemini-3.1-flash-image-preview' | 'google/gemini-3.1-flash-lite' | 'google/gemini-3.1-flash-lite-image' | 'google/gemini-3.1-flash-lite-preview' | 'google/gemini-3.1-pro-preview' | 'google/gemini-3.5-flash' | 'google/gemini-omni-flash-preview' | 'google/gemma-4-26b-a4b-it' | 'google/gemma-4-31b-it' | 'inception/mercury-2' | 'inception/mercury-coder-small' | 'interfaze/interfaze-beta' | 'kwaipilot/kat-coder-pro-v1' | 'kwaipilot/kat-coder-pro-v2' | 'meituan/longcat-flash-chat' | 'meituan/longcat-flash-thinking-2601' | 'meta/llama-3.1-70b' | 'meta/llama-3.1-8b' | 'meta/llama-3.2-11b' | 'meta/llama-3.2-1b' | 'meta/llama-3.2-3b' | 'meta/llama-3.2-90b' | 'meta/llama-3.3-70b' | 'meta/llama-4-maverick' | 'meta/llama-4-scout' | 'meta/muse-spark-1.1' | 'minimax/minimax-m2' | 'minimax/minimax-m2.1' | 'minimax/minimax-m2.1-lightning' | 'minimax/minimax-m2.5' | 'minimax/minimax-m2.5-highspeed' | 'minimax/minimax-m2.7' | 'minimax/minimax-m2.7-highspeed' | 'minimax/minimax-m3' | 'mistral/codestral' | 'mistral/devstral-2' | 'mistral/devstral-small' | 'mistral/devstral-small-2' | 'mistral/magistral-medium' | 'mistral/magistral-small' | 'mistral/ministral-14b' | 'mistral/ministral-3b' | 'mistral/ministral-8b' | 'mistral/mistral-large-3' | 'mistral/mistral-medium' | 'mistral/mistral-medium-3.5' | 'mistral/mistral-nemo' | 'mistral/mistral-small' | 'mistral/pixtral-12b' | 'mistral/pixtral-large' | 'moonshotai/kimi-k2' | 'moonshotai/kimi-k2-thinking' | 'moonshotai/kimi-k2.5' | 'moonshotai/kimi-k2.6' | 'moonshotai/kimi-k2.7-code' | 'moonshotai/kimi-k2.7-code-highspeed' | 'morph/morph-v3-fast' | 'morph/morph-v3-large' | 'nvidia/nemotron-3-nano-30b-a3b' | 'nvidia/nemotron-3-super-120b-a12b' | 'nvidia/nemotron-3-ultra-550b-a55b' | 'nvidia/nemotron-nano-12b-v2-vl' | 'nvidia/nemotron-nano-9b-v2' | 'openai/gpt-3.5-turbo' | 'openai/gpt-3.5-turbo-instruct' | 'openai/gpt-4-turbo' | 'openai/gpt-4.1' | 'openai/gpt-4.1-mini' | 'openai/gpt-4.1-nano' | 'openai/gpt-4o' | 'openai/gpt-4o-mini' | 'openai/gpt-4o-mini-search-preview' | 'openai/gpt-5' | 'openai/gpt-5-chat' | 'openai/gpt-5-codex' | 'openai/gpt-5-mini' | 'openai/gpt-5-nano' | 'openai/gpt-5-pro' | 'openai/gpt-5.1-codex' | 'openai/gpt-5.1-codex-max' | 'openai/gpt-5.1-codex-mini' | 'openai/gpt-5.1-instant' | 'openai/gpt-5.1-thinking' | 'openai/gpt-5.2' | 'openai/gpt-5.2-chat' | 'openai/gpt-5.2-codex' | 'openai/gpt-5.2-pro' | 'openai/gpt-5.3-chat' | 'openai/gpt-5.3-codex' | 'openai/gpt-5.4' | 'openai/gpt-5.4-mini' | 'openai/gpt-5.4-nano' | 'openai/gpt-5.4-pro' | 'openai/gpt-5.5' | 'openai/gpt-5.5-pro' | 'openai/gpt-5.6-luna' | 'openai/gpt-5.6-sol' | 'openai/gpt-5.6-terra' | 'openai/gpt-oss-120b' | 'openai/gpt-oss-20b' | 'openai/gpt-oss-safeguard-20b' | 'openai/o1' | 'openai/o3' | 'openai/o3-deep-research' | 'openai/o3-mini' | 'openai/o3-pro' | 'openai/o4-mini' | 'perplexity/sonar' | 'perplexity/sonar-pro' | 'perplexity/sonar-reasoning-pro' | 'sakana/fugu-ultra' | 'stepfun/step-3.5-flash' | 'stepfun/step-3.7-flash' | 'xai/grok-4.1-fast-non-reasoning' | 'xai/grok-4.1-fast-reasoning' | 'xai/grok-4.20-multi-agent' | 'xai/grok-4.20-multi-agent-beta' | 'xai/grok-4.20-non-reasoning' | 'xai/grok-4.20-non-reasoning-beta' | 'xai/grok-4.20-reasoning' | 'xai/grok-4.20-reasoning-beta' | 'xai/grok-4.3' | 'xai/grok-4.5' | 'xai/grok-build-0.1' | 'xiaomi/mimo-v2-flash' | 'xiaomi/mimo-v2-pro' | 'xiaomi/mimo-v2.5' | 'xiaomi/mimo-v2.5-pro' | 'zai/glm-4.5' | 'zai/glm-4.5-air' | 'zai/glm-4.5v' | 'zai/glm-4.6' | 'zai/glm-4.6v' | 'zai/glm-4.6v-flash' | 'zai/glm-4.7' | 'zai/glm-4.7-flash' | 'zai/glm-4.7-flashx' | 'zai/glm-5' | 'zai/glm-5-turbo' | 'zai/glm-5.1' | 'zai/glm-5.2' | 'zai/glm-5.2-fast' | 'zai/glm-5v-turbo' | (string & {});
5
+ type GatewayModelId = 'alibaba/qwen-3-14b' | 'alibaba/qwen-3-235b' | 'alibaba/qwen-3-30b' | 'alibaba/qwen-3-32b' | 'alibaba/qwen-3.6-max-preview' | 'alibaba/qwen3-235b-a22b-thinking' | 'alibaba/qwen3-coder' | 'alibaba/qwen3-coder-30b-a3b' | 'alibaba/qwen3-coder-next' | 'alibaba/qwen3-coder-plus' | 'alibaba/qwen3-max' | 'alibaba/qwen3-max-preview' | 'alibaba/qwen3-max-thinking' | 'alibaba/qwen3-next-80b-a3b-instruct' | 'alibaba/qwen3-next-80b-a3b-thinking' | 'alibaba/qwen3-vl-235b-a22b-instruct' | 'alibaba/qwen3-vl-instruct' | 'alibaba/qwen3-vl-thinking' | 'alibaba/qwen3.5-flash' | 'alibaba/qwen3.5-plus' | 'alibaba/qwen3.6-27b' | 'alibaba/qwen3.6-plus' | 'alibaba/qwen3.7-max' | 'alibaba/qwen3.7-plus' | 'amazon/nova-2-lite' | 'amazon/nova-lite' | 'amazon/nova-micro' | 'amazon/nova-pro' | 'anthropic/claude-3-haiku' | 'anthropic/claude-3.5-haiku' | 'anthropic/claude-fable-5' | 'anthropic/claude-haiku-4.5' | 'anthropic/claude-opus-4' | 'anthropic/claude-opus-4.1' | 'anthropic/claude-opus-4.5' | 'anthropic/claude-opus-4.6' | 'anthropic/claude-opus-4.7' | 'anthropic/claude-opus-4.8' | 'anthropic/claude-sonnet-4' | 'anthropic/claude-sonnet-4.5' | 'anthropic/claude-sonnet-4.6' | 'anthropic/claude-sonnet-5' | 'arcee-ai/trinity-large-preview' | 'arcee-ai/trinity-large-thinking' | 'arcee-ai/trinity-mini' | 'bytedance/seed-1.6' | 'bytedance/seed-1.8' | 'cohere/command-a' | 'deepseek/deepseek-r1' | 'deepseek/deepseek-v3' | 'deepseek/deepseek-v3.1' | 'deepseek/deepseek-v3.1-terminus' | 'deepseek/deepseek-v3.2' | 'deepseek/deepseek-v3.2-thinking' | 'deepseek/deepseek-v4-flash' | 'deepseek/deepseek-v4-pro' | 'google/gemini-2.5-flash' | 'google/gemini-2.5-flash-image' | 'google/gemini-2.5-flash-lite' | 'google/gemini-2.5-pro' | 'google/gemini-3-flash' | 'google/gemini-3-pro-image' | 'google/gemini-3-pro-preview' | 'google/gemini-3.1-flash-image' | 'google/gemini-3.1-flash-image-preview' | 'google/gemini-3.1-flash-lite' | 'google/gemini-3.1-flash-lite-image' | 'google/gemini-3.1-flash-lite-preview' | 'google/gemini-3.1-pro-preview' | 'google/gemini-3.5-flash' | 'google/gemini-omni-flash-preview' | 'google/gemma-4-26b-a4b-it' | 'google/gemma-4-31b-it' | 'inception/mercury-2' | 'inception/mercury-coder-small' | 'interfaze/interfaze-beta' | 'kwaipilot/kat-coder-air-v2.5' | 'kwaipilot/kat-coder-pro-v1' | 'kwaipilot/kat-coder-pro-v2' | 'kwaipilot/kat-coder-pro-v2.5' | 'meituan/longcat-flash-chat' | 'meituan/longcat-flash-thinking-2601' | 'meta/llama-3.1-70b' | 'meta/llama-3.1-8b' | 'meta/llama-3.2-11b' | 'meta/llama-3.2-1b' | 'meta/llama-3.2-3b' | 'meta/llama-3.2-90b' | 'meta/llama-3.3-70b' | 'meta/llama-4-maverick' | 'meta/llama-4-scout' | 'meta/muse-spark-1.1' | 'minimax/minimax-m2' | 'minimax/minimax-m2.1' | 'minimax/minimax-m2.1-lightning' | 'minimax/minimax-m2.5' | 'minimax/minimax-m2.5-highspeed' | 'minimax/minimax-m2.7' | 'minimax/minimax-m2.7-highspeed' | 'minimax/minimax-m3' | 'mistral/codestral' | 'mistral/devstral-2' | 'mistral/devstral-small' | 'mistral/devstral-small-2' | 'mistral/magistral-medium' | 'mistral/magistral-small' | 'mistral/ministral-14b' | 'mistral/ministral-3b' | 'mistral/ministral-8b' | 'mistral/mistral-large-3' | 'mistral/mistral-medium' | 'mistral/mistral-medium-3.5' | 'mistral/mistral-nemo' | 'mistral/mistral-small' | 'mistral/pixtral-12b' | 'mistral/pixtral-large' | 'moonshotai/kimi-k2' | 'moonshotai/kimi-k2-thinking' | 'moonshotai/kimi-k2.5' | 'moonshotai/kimi-k2.6' | 'moonshotai/kimi-k2.7-code' | 'moonshotai/kimi-k2.7-code-highspeed' | 'morph/morph-v3-fast' | 'morph/morph-v3-large' | 'nvidia/nemotron-3-nano-30b-a3b' | 'nvidia/nemotron-3-super-120b-a12b' | 'nvidia/nemotron-3-ultra-550b-a55b' | 'nvidia/nemotron-nano-12b-v2-vl' | 'nvidia/nemotron-nano-9b-v2' | 'openai/gpt-3.5-turbo' | 'openai/gpt-3.5-turbo-instruct' | 'openai/gpt-4-turbo' | 'openai/gpt-4.1' | 'openai/gpt-4.1-mini' | 'openai/gpt-4.1-nano' | 'openai/gpt-4o' | 'openai/gpt-4o-mini' | 'openai/gpt-4o-mini-search-preview' | 'openai/gpt-5' | 'openai/gpt-5-chat' | 'openai/gpt-5-codex' | 'openai/gpt-5-mini' | 'openai/gpt-5-nano' | 'openai/gpt-5-pro' | 'openai/gpt-5.1-codex' | 'openai/gpt-5.1-codex-max' | 'openai/gpt-5.1-codex-mini' | 'openai/gpt-5.1-instant' | 'openai/gpt-5.1-thinking' | 'openai/gpt-5.2' | 'openai/gpt-5.2-chat' | 'openai/gpt-5.2-codex' | 'openai/gpt-5.2-pro' | 'openai/gpt-5.3-chat' | 'openai/gpt-5.3-codex' | 'openai/gpt-5.4' | 'openai/gpt-5.4-mini' | 'openai/gpt-5.4-nano' | 'openai/gpt-5.4-pro' | 'openai/gpt-5.5' | 'openai/gpt-5.5-pro' | 'openai/gpt-5.6-luna' | 'openai/gpt-5.6-sol' | 'openai/gpt-5.6-terra' | 'openai/gpt-oss-120b' | 'openai/gpt-oss-20b' | 'openai/gpt-oss-safeguard-20b' | 'openai/o1' | 'openai/o3' | 'openai/o3-deep-research' | 'openai/o3-mini' | 'openai/o3-pro' | 'openai/o4-mini' | 'perplexity/sonar' | 'perplexity/sonar-pro' | 'perplexity/sonar-reasoning-pro' | 'sakana/fugu-ultra' | 'stepfun/step-3.5-flash' | 'stepfun/step-3.7-flash' | 'xai/grok-4.1-fast-non-reasoning' | 'xai/grok-4.1-fast-reasoning' | 'xai/grok-4.20-multi-agent' | 'xai/grok-4.20-multi-agent-beta' | 'xai/grok-4.20-non-reasoning' | 'xai/grok-4.20-non-reasoning-beta' | 'xai/grok-4.20-reasoning' | 'xai/grok-4.20-reasoning-beta' | 'xai/grok-4.3' | 'xai/grok-4.5' | 'xai/grok-build-0.1' | 'xiaomi/mimo-v2-flash' | 'xiaomi/mimo-v2-pro' | 'xiaomi/mimo-v2.5' | 'xiaomi/mimo-v2.5-pro' | 'zai/glm-4.5' | 'zai/glm-4.5-air' | 'zai/glm-4.5v' | 'zai/glm-4.6' | 'zai/glm-4.6v' | 'zai/glm-4.6v-flash' | 'zai/glm-4.7' | 'zai/glm-4.7-flash' | 'zai/glm-4.7-flashx' | 'zai/glm-5' | 'zai/glm-5-turbo' | 'zai/glm-5.1' | 'zai/glm-5.2' | 'zai/glm-5.2-fast' | 'zai/glm-5v-turbo' | (string & {});
6
6
 
7
7
  /**
8
- * Shared WebSocket subprotocol contract for AI Gateway realtime auth.
8
+ * Shared WebSocket subprotocol contract for AI Gateway realtime and streaming
9
+ * transcription auth.
9
10
  *
10
11
  * The browser `WebSocket` API cannot set request headers, so the Gateway auth
11
12
  * (bearer) token is carried through the `Sec-WebSocket-Protocol` handshake
@@ -14,8 +15,9 @@ type GatewayModelId = 'alibaba/qwen-3-14b' | 'alibaba/qwen-3-235b' | 'alibaba/qw
14
15
  *
15
16
  * This module is the single source of truth for that contract so the client and
16
17
  * the Gateway server can't drift: the client encodes values with
17
- * `getGatewayRealtimeProtocols`, and the Gateway server decodes them with
18
- * `getGatewayRealtimeAuthToken` / `getGatewayRealtimeTeamIdOrSlug`.
18
+ * `getGatewayRealtimeProtocols` / `getGatewayTranscriptionProtocols`, and the
19
+ * Gateway server decodes them with `getGatewayRealtimeAuthToken` /
20
+ * `getGatewayRealtimeTeamIdOrSlug`.
19
21
  *
20
22
  * WebSocket subprotocol values must fit the RFC token grammar. The auth token is
21
23
  * sent as-is, so callers must use tokens that are valid subprotocol tokens; the
@@ -24,11 +26,16 @@ type GatewayModelId = 'alibaba/qwen-3-14b' | 'alibaba/qwen-3-235b' | 'alibaba/qw
24
26
  * budget) because intermediaries may reject large upgrade headers.
25
27
  */
26
28
  /**
27
- * Marker subprotocol offered on every handshake so the Gateway can echo a
28
- * negotiated subprotocol on the 101 response (some clients require the server to
29
- * select one of the offered subprotocols).
29
+ * Marker subprotocol offered on every realtime handshake so the Gateway can
30
+ * echo a negotiated subprotocol on the 101 response (some clients require the
31
+ * server to select one of the offered subprotocols).
30
32
  */
31
33
  declare const GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realtime.v1";
34
+ /**
35
+ * Marker subprotocol for streaming transcription handshakes (same negotiation
36
+ * purpose as `GATEWAY_REALTIME_SUBPROTOCOL`).
37
+ */
38
+ declare const GATEWAY_TRANSCRIPTION_SUBPROTOCOL = "ai-gateway-transcription.v1";
32
39
  /** Subprotocol prefix that carries the Gateway auth (bearer) token. */
33
40
  declare const GATEWAY_AUTH_SUBPROTOCOL_PREFIX = "ai-gateway-auth.";
34
41
  /** Subprotocol prefix that carries optional Vercel team scoping. */
@@ -40,6 +47,13 @@ declare const GATEWAY_TEAM_SUBPROTOCOL_PREFIX = "ai-gateway-team.";
40
47
  declare function getGatewayRealtimeProtocols(token: string, options?: {
41
48
  teamIdOrSlug?: string;
42
49
  }): string[];
50
+ /**
51
+ * Client-side: `getGatewayRealtimeProtocols`, but with the streaming
52
+ * transcription marker subprotocol.
53
+ */
54
+ declare function getGatewayTranscriptionProtocols(token: string, options?: {
55
+ teamIdOrSlug?: string;
56
+ }): string[];
43
57
  /**
44
58
  * Server-side: extract the Gateway auth (bearer) token from a
45
59
  * `Sec-WebSocket-Protocol` header value, or `undefined` when it is absent or
@@ -57,13 +71,13 @@ declare function getGatewayRealtimeAuthToken(secWebSocketProtocol: string | null
57
71
  */
58
72
  declare function getGatewayRealtimeTeamIdOrSlug(secWebSocketProtocol: string | null | undefined): string | undefined;
59
73
 
60
- type GatewayRealtimeModelId = 'openai/gpt-realtime-1.5' | 'openai/gpt-realtime-2' | 'openai/gpt-realtime-mini' | 'xai/grok-voice-think-fast-1.0' | (string & {});
74
+ type GatewayRealtimeModelId = 'openai/gpt-realtime-1.5' | 'openai/gpt-realtime-2' | 'openai/gpt-realtime-2.1' | 'openai/gpt-realtime-mini' | 'xai/grok-voice-think-fast-1.0' | (string & {});
61
75
 
62
76
  type GatewayRerankingModelId = 'cohere/rerank-v3.5' | 'cohere/rerank-v4-fast' | 'cohere/rerank-v4-pro' | 'voyage/rerank-2.5' | 'voyage/rerank-2.5-lite' | (string & {});
63
77
 
64
78
  type GatewaySpeechModelId = 'openai/tts-1' | 'openai/tts-1-hd' | 'xai/grok-tts' | (string & {});
65
79
 
66
- type GatewayTranscriptionModelId = 'openai/gpt-4o-mini-transcribe' | 'openai/gpt-4o-transcribe' | 'openai/whisper-1' | 'xai/grok-stt' | (string & {});
80
+ type GatewayTranscriptionModelId = 'openai/gpt-4o-mini-transcribe' | 'openai/gpt-4o-transcribe' | 'openai/gpt-realtime-whisper' | 'openai/whisper-1' | 'xai/grok-stt' | (string & {});
67
81
 
68
82
  type GatewayVideoModelId = 'alibaba/wan-v2.5-t2v-preview' | 'alibaba/wan-v2.6-i2v' | 'alibaba/wan-v2.6-i2v-flash' | 'alibaba/wan-v2.6-r2v' | 'alibaba/wan-v2.6-r2v-flash' | 'alibaba/wan-v2.6-t2v' | 'alibaba/wan-v2.7-r2v' | 'alibaba/wan-v2.7-t2v' | 'bytedance/seedance-2.0' | 'bytedance/seedance-2.0-fast' | 'bytedance/seedance-v1.0-pro' | 'bytedance/seedance-v1.0-pro-fast' | 'bytedance/seedance-v1.5-pro' | 'google/veo-3.0-fast-generate-001' | 'google/veo-3.0-generate-001' | 'google/veo-3.1-fast-generate-001' | 'google/veo-3.1-generate-001' | 'klingai/kling-v2.5-turbo-i2v' | 'klingai/kling-v2.5-turbo-t2v' | 'klingai/kling-v2.6-i2v' | 'klingai/kling-v2.6-motion-control' | 'klingai/kling-v2.6-t2v' | 'klingai/kling-v3.0-i2v' | 'klingai/kling-v3.0-motion-control' | 'klingai/kling-v3.0-t2v' | 'xai/grok-imagine-video' | 'xai/grok-imagine-video-1.5' | 'xai/grok-imagine-video-1.5-preview' | (string & {});
69
83
 
@@ -228,7 +242,7 @@ interface GatewayGenerationInfo {
228
242
 
229
243
  type GatewayEmbeddingModelId = 'alibaba/qwen3-embedding-0.6b' | 'alibaba/qwen3-embedding-4b' | 'alibaba/qwen3-embedding-8b' | 'amazon/titan-embed-text-v2' | 'cohere/embed-v4.0' | 'google/gemini-embedding-001' | 'google/gemini-embedding-2' | 'google/text-embedding-005' | 'google/text-multilingual-embedding-002' | 'mistral/codestral-embed' | 'mistral/mistral-embed' | 'openai/text-embedding-3-large' | 'openai/text-embedding-3-small' | 'openai/text-embedding-ada-002' | 'voyage/voyage-3-large' | 'voyage/voyage-3.5' | 'voyage/voyage-3.5-lite' | 'voyage/voyage-4' | 'voyage/voyage-4-large' | 'voyage/voyage-4-lite' | 'voyage/voyage-code-2' | 'voyage/voyage-code-3' | 'voyage/voyage-finance-2' | 'voyage/voyage-law-2' | (string & {});
230
244
 
231
- type GatewayImageModelId = 'bfl/flux-2-flex' | 'bfl/flux-2-klein-4b' | 'bfl/flux-2-klein-9b' | 'bfl/flux-2-max' | 'bfl/flux-2-pro' | 'bfl/flux-kontext-max' | 'bfl/flux-kontext-pro' | 'bfl/flux-pro-1.0-fill' | 'bfl/flux-pro-1.1' | 'bfl/flux-pro-1.1-ultra' | 'bytedance/seedream-4.0' | 'bytedance/seedream-4.5' | 'bytedance/seedream-5.0-lite' | 'google/imagen-4.0-fast-generate-001' | 'google/imagen-4.0-generate-001' | 'google/imagen-4.0-ultra-generate-001' | 'openai/gpt-image-1' | 'openai/gpt-image-1-mini' | 'openai/gpt-image-1.5' | 'openai/gpt-image-2' | 'prodia/flux-fast-schnell' | 'quiverai/arrow-1.1' | 'recraft/recraft-v2' | 'recraft/recraft-v3' | 'recraft/recraft-v4' | 'recraft/recraft-v4-pro' | 'recraft/recraft-v4.1' | 'recraft/recraft-v4.1-pro' | 'recraft/recraft-v4.1-utility' | 'recraft/recraft-v4.1-utility-pro' | 'xai/grok-imagine-image' | (string & {});
245
+ type GatewayImageModelId = 'bfl/flux-2-flex' | 'bfl/flux-2-klein-4b' | 'bfl/flux-2-klein-9b' | 'bfl/flux-2-max' | 'bfl/flux-2-pro' | 'bfl/flux-kontext-max' | 'bfl/flux-kontext-pro' | 'bfl/flux-pro-1.0-fill' | 'bfl/flux-pro-1.1' | 'bfl/flux-pro-1.1-ultra' | 'bytedance/seedream-4.0' | 'bytedance/seedream-4.5' | 'bytedance/seedream-5.0-lite' | 'bytedance/seedream-5.0-pro' | 'google/imagen-4.0-fast-generate-001' | 'google/imagen-4.0-generate-001' | 'google/imagen-4.0-ultra-generate-001' | 'openai/gpt-image-1' | 'openai/gpt-image-1-mini' | 'openai/gpt-image-1.5' | 'openai/gpt-image-2' | 'prodia/flux-fast-schnell' | 'quiverai/arrow-1.1' | 'recraft/recraft-v2' | 'recraft/recraft-v3' | 'recraft/recraft-v4' | 'recraft/recraft-v4-pro' | 'recraft/recraft-v4.1' | 'recraft/recraft-v4.1-pro' | 'recraft/recraft-v4.1-utility' | 'recraft/recraft-v4.1-utility-pro' | 'xai/grok-imagine-image' | (string & {});
232
246
 
233
247
  interface PerplexitySearchConfig {
234
248
  /**
@@ -763,6 +777,13 @@ interface GatewayProviderSettings {
763
777
  * or to provide a custom fetch implementation for e.g. testing.
764
778
  */
765
779
  fetch?: FetchFunction;
780
+ /**
781
+ * Custom WebSocket implementation used for streaming transcription. This is
782
+ * useful for testing or for runtimes without a global WebSocket. A
783
+ * header-capable implementation is not required — Gateway WebSocket auth is
784
+ * carried in the subprotocols.
785
+ */
786
+ webSocket?: WebSocketConstructor;
766
787
  /**
767
788
  * How frequently to refresh the metadata cache in milliseconds.
768
789
  */
@@ -1013,4 +1034,4 @@ declare class GatewayResponseError extends GatewayError {
1013
1034
 
1014
1035
  declare const VERSION: string;
1015
1036
 
1016
- export { GATEWAY_AUTH_SUBPROTOCOL_PREFIX, GATEWAY_REALTIME_SUBPROTOCOL, GATEWAY_TEAM_SUBPROTOCOL_PREFIX, GatewayAuthenticationError, type GatewayCreditsResponse, GatewayError, type GatewayErrorResponse, GatewayFailedDependencyError, GatewayForbiddenError, type GatewayGenerationInfo, type GatewayGenerationInfoParams, GatewayInternalServerError, GatewayInvalidRequestError, type GatewayLanguageModelEntry, type GatewayProviderOptions as GatewayLanguageModelOptions, type GatewayLanguageModelSpecification, type GatewayLanguageModelEntry as GatewayModelEntry, type GatewayModelId, GatewayModelNotFoundError, type GatewayProvider, type GatewayProviderOptions, type GatewayProviderSettings, GatewayRateLimitError, type GatewayRealtimeModelId, type GatewayRerankingModelId, GatewayResponseError, type GatewaySpeechModelId, type GatewaySpendReportParams, type GatewaySpendReportResponse, type GatewaySpendReportRow, type GatewayTranscriptionModelId, type GatewayVideoModelId, VERSION, createGateway, createGateway as createGatewayProvider, gateway, getGatewayRealtimeAuthToken, getGatewayRealtimeProtocols, getGatewayRealtimeTeamIdOrSlug };
1037
+ export { GATEWAY_AUTH_SUBPROTOCOL_PREFIX, GATEWAY_REALTIME_SUBPROTOCOL, GATEWAY_TEAM_SUBPROTOCOL_PREFIX, GATEWAY_TRANSCRIPTION_SUBPROTOCOL, GatewayAuthenticationError, type GatewayCreditsResponse, GatewayError, type GatewayErrorResponse, GatewayFailedDependencyError, GatewayForbiddenError, type GatewayGenerationInfo, type GatewayGenerationInfoParams, GatewayInternalServerError, GatewayInvalidRequestError, type GatewayLanguageModelEntry, type GatewayProviderOptions as GatewayLanguageModelOptions, type GatewayLanguageModelSpecification, type GatewayLanguageModelEntry as GatewayModelEntry, type GatewayModelId, GatewayModelNotFoundError, type GatewayProvider, type GatewayProviderOptions, type GatewayProviderSettings, GatewayRateLimitError, type GatewayRealtimeModelId, type GatewayRerankingModelId, GatewayResponseError, type GatewaySpeechModelId, type GatewaySpendReportParams, type GatewaySpendReportResponse, type GatewaySpendReportRow, type GatewayTranscriptionModelId, type GatewayVideoModelId, VERSION, createGateway, createGateway as createGatewayProvider, gateway, getGatewayRealtimeAuthToken, getGatewayRealtimeProtocols, getGatewayRealtimeTeamIdOrSlug, getGatewayTranscriptionProtocols };
package/dist/index.js CHANGED
@@ -1,12 +1,20 @@
1
1
  // src/gateway-realtime-auth.ts
2
2
  var GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realtime.v1";
3
+ var GATEWAY_TRANSCRIPTION_SUBPROTOCOL = "ai-gateway-transcription.v1";
3
4
  var GATEWAY_AUTH_SUBPROTOCOL_PREFIX = "ai-gateway-auth.";
4
5
  var GATEWAY_TEAM_SUBPROTOCOL_PREFIX = "ai-gateway-team.";
5
6
  function getGatewayRealtimeProtocols(token, options) {
6
- const protocols = [
7
- GATEWAY_REALTIME_SUBPROTOCOL,
8
- `${GATEWAY_AUTH_SUBPROTOCOL_PREFIX}${token}`
9
- ];
7
+ return buildGatewayProtocols(GATEWAY_REALTIME_SUBPROTOCOL, token, options);
8
+ }
9
+ function getGatewayTranscriptionProtocols(token, options) {
10
+ return buildGatewayProtocols(
11
+ GATEWAY_TRANSCRIPTION_SUBPROTOCOL,
12
+ token,
13
+ options
14
+ );
15
+ }
16
+ function buildGatewayProtocols(marker11, token, options) {
17
+ const protocols = [marker11, `${GATEWAY_AUTH_SUBPROTOCOL_PREFIX}${token}`];
10
18
  if (options == null ? void 0 : options.teamIdOrSlug) {
11
19
  protocols.push(
12
20
  `${GATEWAY_TEAM_SUBPROTOCOL_PREFIX}${encodeSubprotocolValue(options.teamIdOrSlug)}`
@@ -641,6 +649,7 @@ var GatewayFetchMetadata = class {
641
649
  try {
642
650
  const { value } = await getFromApi({
643
651
  url: `${this.config.baseURL}/config`,
652
+ validateUrl: false,
644
653
  headers: this.config.headers ? await resolve(this.config.headers) : void 0,
645
654
  successfulResponseHandler: createJsonResponseHandler(
646
655
  gatewayAvailableModelsResponseSchema
@@ -661,6 +670,7 @@ var GatewayFetchMetadata = class {
661
670
  const baseUrl = new URL(this.config.baseURL);
662
671
  const { value } = await getFromApi({
663
672
  url: `${baseUrl.origin}/v1/credits`,
673
+ validateUrl: false,
664
674
  headers: this.config.headers ? await resolve(this.config.headers) : void 0,
665
675
  successfulResponseHandler: createJsonResponseHandler(
666
676
  gatewayCreditsResponseSchema
@@ -768,6 +778,7 @@ var GatewaySpendReport = class {
768
778
  }
769
779
  const { value } = await getFromApi2({
770
780
  url: `${baseUrl.origin}/v1/report?${searchParams.toString()}`,
781
+ validateUrl: false,
771
782
  headers: this.config.headers ? await resolve2(this.config.headers) : void 0,
772
783
  successfulResponseHandler: createJsonResponseHandler2(
773
784
  gatewaySpendReportResponseSchema
@@ -853,6 +864,7 @@ var GatewayGenerationInfoFetcher = class {
853
864
  const baseUrl = new URL(this.config.baseURL);
854
865
  const { value } = await getFromApi3({
855
866
  url: `${baseUrl.origin}/v1/generation?id=${encodeURIComponent(params.id)}`,
867
+ validateUrl: false,
856
868
  headers: this.config.headers ? await resolve3(this.config.headers) : void 0,
857
869
  successfulResponseHandler: createJsonResponseHandler3(
858
870
  gatewayGenerationInfoResponseSchema
@@ -1865,13 +1877,23 @@ var gatewaySpeechResponseSchema = z13.object({
1865
1877
  });
1866
1878
 
1867
1879
  // src/gateway-transcription-model.ts
1880
+ import {
1881
+ getErrorMessage
1882
+ } from "@ai-sdk/provider";
1868
1883
  import {
1869
1884
  combineHeaders as combineHeaders7,
1885
+ convertBase64ToUint8Array,
1870
1886
  convertUint8ArrayToBase64 as convertUint8ArrayToBase643,
1871
1887
  createJsonErrorResponseHandler as createJsonErrorResponseHandler10,
1872
1888
  createJsonResponseHandler as createJsonResponseHandler9,
1889
+ connectToWebSocket,
1890
+ normalizeHeaders,
1891
+ experimental_parseTranscriptionStreamPart as parseTranscriptionStreamPart,
1873
1892
  postJsonToApi as postJsonToApi7,
1874
- resolve as resolve10
1893
+ resolve as resolve10,
1894
+ EXPERIMENTAL_TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE as TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE,
1895
+ waitForWebSocketBufferDrain,
1896
+ EXPERIMENTAL_TRANSCRIPTION_STREAM_START_FRAME_TYPE as TRANSCRIPTION_STREAM_START_FRAME_TYPE
1875
1897
  } from "@ai-sdk/provider-utils";
1876
1898
  import { z as z14 } from "zod/v4";
1877
1899
  var GatewayTranscriptionModel = class {
@@ -1941,6 +1963,41 @@ var GatewayTranscriptionModel = class {
1941
1963
  );
1942
1964
  }
1943
1965
  }
1966
+ async doStream(options) {
1967
+ var _a11, _b11, _c, _d, _e;
1968
+ const currentDate = (_c = (_b11 = (_a11 = this.config._internal) == null ? void 0 : _a11.currentDate) == null ? void 0 : _b11.call(_a11)) != null ? _c : /* @__PURE__ */ new Date();
1969
+ const headers = combineHeaders7(
1970
+ await resolve10((_d = this.config.headers) != null ? _d : {}),
1971
+ (_e = options.headers) != null ? _e : {},
1972
+ this.getModelConfigHeaders(),
1973
+ await resolve10(this.config.o11yHeaders)
1974
+ );
1975
+ const authMethod = await parseAuthMethod(headers);
1976
+ const startFrame = {
1977
+ type: TRANSCRIPTION_STREAM_START_FRAME_TYPE,
1978
+ inputAudioFormat: options.inputAudioFormat,
1979
+ ...options.providerOptions != null && {
1980
+ providerOptions: options.providerOptions
1981
+ },
1982
+ ...options.includeRawChunks != null && {
1983
+ includeRawChunks: options.includeRawChunks
1984
+ }
1985
+ };
1986
+ return {
1987
+ stream: createGatewayTranscriptionStream({
1988
+ webSocket: this.config.webSocket,
1989
+ url: toGatewayTranscriptionUrl(this.config.baseURL, this.modelId),
1990
+ protocols: getProtocolsFromHeaders(headers),
1991
+ headers,
1992
+ startFrame,
1993
+ audio: options.audio,
1994
+ abortSignal: options.abortSignal,
1995
+ authMethod
1996
+ }),
1997
+ request: { body: startFrame },
1998
+ response: { timestamp: currentDate, modelId: this.modelId }
1999
+ };
2000
+ }
1944
2001
  getUrl() {
1945
2002
  return `${this.config.baseURL}/transcription-model`;
1946
2003
  }
@@ -1951,6 +2008,163 @@ var GatewayTranscriptionModel = class {
1951
2008
  };
1952
2009
  }
1953
2010
  };
2011
+ function toGatewayTranscriptionUrl(baseURL, modelId) {
2012
+ const url = new URL(`${baseURL.replace(/^http/, "ws")}/transcription-model`);
2013
+ url.searchParams.set("ai-model-id", modelId);
2014
+ return url.toString();
2015
+ }
2016
+ function getProtocolsFromHeaders(headers) {
2017
+ const normalizedHeaders = normalizeHeaders(headers);
2018
+ const authorization = normalizedHeaders.authorization;
2019
+ const token = (authorization == null ? void 0 : authorization.startsWith("Bearer ")) ? authorization.slice("Bearer ".length) : void 0;
2020
+ return token == null ? [GATEWAY_TRANSCRIPTION_SUBPROTOCOL] : getGatewayTranscriptionProtocols(token, {
2021
+ teamIdOrSlug: normalizedHeaders[VERCEL_AI_GATEWAY_TEAM_HEADER]
2022
+ });
2023
+ }
2024
+ var MAX_AUDIO_FRAME_BYTES = 64 * 1024;
2025
+ function createGatewayTranscriptionStream({
2026
+ webSocket,
2027
+ url,
2028
+ protocols,
2029
+ headers,
2030
+ startFrame,
2031
+ audio,
2032
+ abortSignal,
2033
+ authMethod
2034
+ }) {
2035
+ let finished = false;
2036
+ let cleanup = () => {
2037
+ };
2038
+ return new ReadableStream({
2039
+ start: (controller) => {
2040
+ let audioReader;
2041
+ let hasServerErrorPart = false;
2042
+ let lastServerError;
2043
+ let audioStopped = false;
2044
+ let connection;
2045
+ cleanup = (closeCode) => {
2046
+ if (audioReader != null) {
2047
+ void audioReader.cancel().catch(() => {
2048
+ });
2049
+ } else {
2050
+ void audio.cancel().catch(() => {
2051
+ });
2052
+ }
2053
+ connection == null ? void 0 : connection.close(closeCode);
2054
+ };
2055
+ const stopAudio = () => {
2056
+ audioStopped = true;
2057
+ if (audioReader != null) {
2058
+ void audioReader.cancel().catch(() => {
2059
+ });
2060
+ audioReader = void 0;
2061
+ } else {
2062
+ void audio.cancel().catch(() => {
2063
+ });
2064
+ }
2065
+ };
2066
+ const finishWithError = (error) => {
2067
+ if (finished) return;
2068
+ finished = true;
2069
+ cleanup();
2070
+ void errorControllerWithGatewayError(controller, error, authMethod);
2071
+ };
2072
+ const sendAudio = async (socket) => {
2073
+ const reader = audio.getReader();
2074
+ audioReader = reader;
2075
+ try {
2076
+ while (true) {
2077
+ const { done, value } = await reader.read();
2078
+ if (done || finished) break;
2079
+ const bytes = typeof value === "string" ? convertBase64ToUint8Array(value) : value;
2080
+ for (let offset = 0; offset < bytes.length; offset += MAX_AUDIO_FRAME_BYTES) {
2081
+ if (finished) break;
2082
+ socket.send(
2083
+ bytes.subarray(offset, offset + MAX_AUDIO_FRAME_BYTES)
2084
+ );
2085
+ await waitForWebSocketBufferDrain(socket);
2086
+ }
2087
+ }
2088
+ } finally {
2089
+ reader.releaseLock();
2090
+ if (audioReader === reader) {
2091
+ audioReader = void 0;
2092
+ }
2093
+ }
2094
+ if (!finished && !audioStopped) {
2095
+ socket.send(
2096
+ JSON.stringify({
2097
+ type: TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE
2098
+ })
2099
+ );
2100
+ }
2101
+ };
2102
+ connection = connectToWebSocket({
2103
+ url,
2104
+ protocols,
2105
+ headers,
2106
+ webSocket,
2107
+ abortSignal,
2108
+ onAbort: (reason) => {
2109
+ if (finished) return;
2110
+ finished = true;
2111
+ cleanup();
2112
+ controller.error(reason);
2113
+ },
2114
+ onProcessingError: finishWithError,
2115
+ onOpen: (socket) => {
2116
+ socket.send(JSON.stringify(startFrame));
2117
+ void sendAudio(socket).catch(finishWithError);
2118
+ },
2119
+ // Server frames are envelope-serialized stream parts; the codec
2120
+ // handles parsing, unknown-part skipping, and timestamp revival.
2121
+ onMessageText: (text) => {
2122
+ if (finished) return;
2123
+ const part = parseTranscriptionStreamPart(text);
2124
+ if (part == null) return;
2125
+ if (part.type === "finish") {
2126
+ finished = true;
2127
+ controller.enqueue(part);
2128
+ controller.close();
2129
+ cleanup(1e3);
2130
+ return;
2131
+ }
2132
+ if (part.type === "error") {
2133
+ hasServerErrorPart = true;
2134
+ lastServerError = part.error;
2135
+ stopAudio();
2136
+ }
2137
+ controller.enqueue(part);
2138
+ },
2139
+ onSocketError: () => {
2140
+ finishWithError(
2141
+ new Error("Connection error on AI Gateway transcription stream")
2142
+ );
2143
+ },
2144
+ onClose: () => {
2145
+ if (hasServerErrorPart) {
2146
+ if (finished) return;
2147
+ void createErrorFromServerErrorPart(
2148
+ lastServerError,
2149
+ authMethod
2150
+ ).then(finishWithError);
2151
+ return;
2152
+ }
2153
+ finishWithError(
2154
+ new Error(
2155
+ "AI Gateway transcription stream closed before a finish part was received"
2156
+ )
2157
+ );
2158
+ }
2159
+ });
2160
+ },
2161
+ cancel: () => {
2162
+ if (finished) return;
2163
+ finished = true;
2164
+ cleanup();
2165
+ }
2166
+ });
2167
+ }
1954
2168
  var providerMetadataEntrySchema4 = z14.object({}).catchall(z14.unknown());
1955
2169
  var gatewayTranscriptionWarningSchema = z14.discriminatedUnion("type", [
1956
2170
  z14.object({
@@ -1987,6 +2201,36 @@ var gatewayTranscriptionResponseSchema = z14.object({
1987
2201
  warnings: z14.array(gatewayTranscriptionWarningSchema).optional(),
1988
2202
  providerMetadata: z14.record(z14.string(), providerMetadataEntrySchema4).optional()
1989
2203
  });
2204
+ async function errorControllerWithGatewayError(controller, error, authMethod) {
2205
+ controller.error(await asGatewayError(error, authMethod));
2206
+ }
2207
+ function getServerErrorMessage(error) {
2208
+ if (error != null && typeof error === "object" && "message" in error && typeof error.message === "string") {
2209
+ return error.message;
2210
+ }
2211
+ return getErrorMessage(error);
2212
+ }
2213
+ var SERVER_ERROR_STATUS_CODES = {
2214
+ authentication_error: 401,
2215
+ failed_dependency: 424,
2216
+ forbidden: 403,
2217
+ internal_server_error: 500,
2218
+ invalid_request_error: 400,
2219
+ model_not_found: 404,
2220
+ rate_limit_exceeded: 429
2221
+ };
2222
+ async function createErrorFromServerErrorPart(error, authMethod) {
2223
+ if (typeof error === "object" && error != null && "message" in error && typeof error.message === "string" && "type" in error && typeof error.type === "string" && error.type in SERVER_ERROR_STATUS_CODES) {
2224
+ return createGatewayErrorFromResponse({
2225
+ response: { error: { message: error.message, type: error.type } },
2226
+ statusCode: SERVER_ERROR_STATUS_CODES[error.type],
2227
+ authMethod
2228
+ });
2229
+ }
2230
+ return new Error(
2231
+ `AI Gateway transcription stream failed: ${getServerErrorMessage(error)}`
2232
+ );
2233
+ }
1990
2234
 
1991
2235
  // src/gateway-realtime-model.ts
1992
2236
  var GatewayRealtimeModel = class {
@@ -2387,7 +2631,7 @@ async function getVercelRequestId() {
2387
2631
  }
2388
2632
 
2389
2633
  // src/version.ts
2390
- var VERSION = true ? "4.0.16" : "0.0.0-test";
2634
+ var VERSION = true ? "4.0.19" : "0.0.0-test";
2391
2635
 
2392
2636
  // src/gateway-provider.ts
2393
2637
  var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
@@ -2633,7 +2877,8 @@ function createGateway(options = {}) {
2633
2877
  baseURL,
2634
2878
  headers: getHeaders,
2635
2879
  fetch: options.fetch,
2636
- o11yHeaders: createO11yHeaders()
2880
+ o11yHeaders: createO11yHeaders(),
2881
+ webSocket: options.webSocket
2637
2882
  });
2638
2883
  };
2639
2884
  provider.transcriptionModel = createTranscriptionModel;
@@ -2695,6 +2940,7 @@ export {
2695
2940
  GATEWAY_AUTH_SUBPROTOCOL_PREFIX,
2696
2941
  GATEWAY_REALTIME_SUBPROTOCOL,
2697
2942
  GATEWAY_TEAM_SUBPROTOCOL_PREFIX,
2943
+ GATEWAY_TRANSCRIPTION_SUBPROTOCOL,
2698
2944
  GatewayAuthenticationError,
2699
2945
  GatewayError,
2700
2946
  GatewayFailedDependencyError,
@@ -2710,6 +2956,7 @@ export {
2710
2956
  gateway,
2711
2957
  getGatewayRealtimeAuthToken,
2712
2958
  getGatewayRealtimeProtocols,
2713
- getGatewayRealtimeTeamIdOrSlug
2959
+ getGatewayRealtimeTeamIdOrSlug,
2960
+ getGatewayTranscriptionProtocols
2714
2961
  };
2715
2962
  //# sourceMappingURL=index.js.map