@ai-sdk/provider-utils 5.0.7 → 5.0.10

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/dist/index.js CHANGED
@@ -14,6 +14,155 @@ function combineHeaders(...headers) {
14
14
  );
15
15
  }
16
16
 
17
+ // src/remove-undefined-entries.ts
18
+ function removeUndefinedEntries(record) {
19
+ return Object.fromEntries(
20
+ Object.entries(record).filter(([_key, value]) => value != null)
21
+ );
22
+ }
23
+
24
+ // src/delay.ts
25
+ async function delay(delayInMs, options) {
26
+ if (delayInMs == null) {
27
+ return Promise.resolve();
28
+ }
29
+ const signal = options == null ? void 0 : options.abortSignal;
30
+ return new Promise((resolve2, reject) => {
31
+ if (signal == null ? void 0 : signal.aborted) {
32
+ reject(createAbortError());
33
+ return;
34
+ }
35
+ const timeoutId = setTimeout(() => {
36
+ cleanup();
37
+ resolve2();
38
+ }, delayInMs);
39
+ const cleanup = () => {
40
+ clearTimeout(timeoutId);
41
+ signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
42
+ };
43
+ const onAbort = () => {
44
+ cleanup();
45
+ reject(createAbortError());
46
+ };
47
+ signal == null ? void 0 : signal.addEventListener("abort", onAbort);
48
+ });
49
+ }
50
+ function createAbortError() {
51
+ return new DOMException("Delay was aborted", "AbortError");
52
+ }
53
+
54
+ // src/websocket.ts
55
+ function getWebSocketConstructor(webSocket) {
56
+ const WebSocketConstructor = webSocket != null ? webSocket : globalThis.WebSocket;
57
+ if (WebSocketConstructor == null) {
58
+ throw new Error("No WebSocket implementation available.");
59
+ }
60
+ return WebSocketConstructor;
61
+ }
62
+ function toWebSocketUrl(url) {
63
+ const wsUrl = new URL(url);
64
+ if (wsUrl.protocol === "http:") {
65
+ wsUrl.protocol = "ws:";
66
+ } else if (wsUrl.protocol === "https:") {
67
+ wsUrl.protocol = "wss:";
68
+ }
69
+ return wsUrl;
70
+ }
71
+ var textDecoder = new TextDecoder();
72
+ async function readWebSocketMessageText(data) {
73
+ if (typeof data === "string") return data;
74
+ if (data instanceof ArrayBuffer) return textDecoder.decode(data);
75
+ if (ArrayBuffer.isView(data)) {
76
+ return textDecoder.decode(data);
77
+ }
78
+ if (typeof Blob !== "undefined" && data instanceof Blob) {
79
+ return data.text();
80
+ }
81
+ return String(data);
82
+ }
83
+ var WEBSOCKET_OPEN_STATE = 1;
84
+ async function waitForWebSocketBufferDrain(socket, {
85
+ highWaterMark = 1024 * 1024,
86
+ pollIntervalMs = 20,
87
+ abortSignal
88
+ } = {}) {
89
+ var _a2;
90
+ while (socket.readyState === WEBSOCKET_OPEN_STATE && ((_a2 = socket.bufferedAmount) != null ? _a2 : 0) > highWaterMark) {
91
+ if ((abortSignal == null ? void 0 : abortSignal.aborted) === true) {
92
+ return;
93
+ }
94
+ await delay(pollIntervalMs);
95
+ }
96
+ }
97
+
98
+ // src/connect-to-websocket.ts
99
+ function connectToWebSocket({
100
+ url,
101
+ protocols,
102
+ headers,
103
+ webSocket,
104
+ abortSignal,
105
+ onOpen,
106
+ onMessageText,
107
+ onProcessingError,
108
+ onSocketError,
109
+ onClose,
110
+ onAbort
111
+ }) {
112
+ var _a2;
113
+ let socket;
114
+ let abortListener;
115
+ const close = (code) => {
116
+ if (abortListener != null) {
117
+ abortSignal == null ? void 0 : abortSignal.removeEventListener("abort", abortListener);
118
+ abortListener = void 0;
119
+ }
120
+ try {
121
+ socket == null ? void 0 : socket.close(code);
122
+ } catch (e) {
123
+ }
124
+ };
125
+ if (abortSignal == null ? void 0 : abortSignal.aborted) {
126
+ onAbort == null ? void 0 : onAbort((_a2 = abortSignal.reason) != null ? _a2 : new Error("Aborted"));
127
+ return { socket: void 0, close };
128
+ }
129
+ try {
130
+ const WebSocketConstructor = getWebSocketConstructor(webSocket);
131
+ socket = new WebSocketConstructor(url, protocols, {
132
+ headers: removeUndefinedEntries(headers != null ? headers : {})
133
+ });
134
+ } catch (error) {
135
+ onProcessingError(error);
136
+ return { socket: void 0, close };
137
+ }
138
+ if (abortSignal != null && onAbort != null) {
139
+ abortListener = () => {
140
+ var _a3;
141
+ return onAbort((_a3 = abortSignal.reason) != null ? _a3 : new Error("Aborted"));
142
+ };
143
+ abortSignal.addEventListener("abort", abortListener, { once: true });
144
+ }
145
+ const openedSocket = socket;
146
+ socket.onopen = () => {
147
+ try {
148
+ onOpen == null ? void 0 : onOpen(openedSocket);
149
+ } catch (error) {
150
+ onProcessingError(error);
151
+ }
152
+ };
153
+ let tail = Promise.resolve();
154
+ socket.onmessage = (event) => {
155
+ tail = tail.then(() => readWebSocketMessageText(event.data)).then((text) => onMessageText(text)).catch(onProcessingError);
156
+ };
157
+ socket.onerror = () => {
158
+ tail = tail.then(() => onSocketError == null ? void 0 : onSocketError()).catch(onProcessingError);
159
+ };
160
+ socket.onclose = () => {
161
+ tail = tail.then(() => onClose == null ? void 0 : onClose()).catch(onProcessingError);
162
+ };
163
+ return { socket, close };
164
+ }
165
+
17
166
  // src/convert-async-iterator-to-readable-stream.ts
18
167
  function convertAsyncIteratorToReadableStream(iterator) {
19
168
  let cancelled = false;
@@ -140,36 +289,6 @@ function createToolNameMapping({
140
289
  };
141
290
  }
142
291
 
143
- // src/delay.ts
144
- async function delay(delayInMs, options) {
145
- if (delayInMs == null) {
146
- return Promise.resolve();
147
- }
148
- const signal = options == null ? void 0 : options.abortSignal;
149
- return new Promise((resolve2, reject) => {
150
- if (signal == null ? void 0 : signal.aborted) {
151
- reject(createAbortError());
152
- return;
153
- }
154
- const timeoutId = setTimeout(() => {
155
- cleanup();
156
- resolve2();
157
- }, delayInMs);
158
- const cleanup = () => {
159
- clearTimeout(timeoutId);
160
- signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
161
- };
162
- const onAbort = () => {
163
- cleanup();
164
- reject(createAbortError());
165
- };
166
- signal == null ? void 0 : signal.addEventListener("abort", onAbort);
167
- });
168
- }
169
- function createAbortError() {
170
- return new DOMException("Delay was aborted", "AbortError");
171
- }
172
-
173
292
  // src/delayed-promise.ts
174
293
  var DelayedPromise = class {
175
294
  constructor() {
@@ -528,6 +647,51 @@ function isBrowserRuntime(globalThisAny = globalThis) {
528
647
  return globalThisAny.window != null;
529
648
  }
530
649
 
650
+ // src/is-same-origin.ts
651
+ function isSameOrigin(url, baseUrl) {
652
+ try {
653
+ return new URL(url).origin === new URL(baseUrl).origin;
654
+ } catch (e) {
655
+ return false;
656
+ }
657
+ }
658
+
659
+ // src/sanitize-request-headers.ts
660
+ var BLOCKED_REQUEST_HEADERS = [
661
+ // Hop-by-hop / transport (RFC 7230 §6.1)
662
+ "connection",
663
+ "keep-alive",
664
+ "te",
665
+ "trailer",
666
+ "transfer-encoding",
667
+ "upgrade",
668
+ // Host / virtual-host routing
669
+ "host",
670
+ // Proxy / origin spoofing
671
+ "forwarded",
672
+ "proxy-authorization",
673
+ "via",
674
+ "x-forwarded-for",
675
+ "x-forwarded-host",
676
+ "x-forwarded-proto",
677
+ "x-real-ip",
678
+ // Cloud metadata (GCP, AWS IMDSv1/v2, Azure, Alibaba, DigitalOcean)
679
+ "metadata",
680
+ "metadata-flavor",
681
+ "x-aws-ec2-metadata-token",
682
+ "x-metadata-token",
683
+ // Session / cookie
684
+ "cookie",
685
+ "set-cookie"
686
+ ];
687
+ function sanitizeRequestHeaders(input) {
688
+ const headers = new Headers(input);
689
+ for (const name2 of BLOCKED_REQUEST_HEADERS) {
690
+ headers.delete(name2);
691
+ }
692
+ return headers;
693
+ }
694
+
531
695
  // src/validate-download-url.ts
532
696
  function validateDownloadUrl(url) {
533
697
  let parsed;
@@ -599,9 +763,12 @@ function isPrivateIPv4(ip) {
599
763
  if (a === 169 && b === 254) return true;
600
764
  if (a === 172 && b >= 16 && b <= 31) return true;
601
765
  if (a === 192 && b === 0 && c === 0) return true;
766
+ if (a === 192 && b === 0 && c === 2) return true;
602
767
  if (a === 192 && b === 168) return true;
603
768
  if (a === 198 && (b === 18 || b === 19)) return true;
604
- if (a >= 240) return true;
769
+ if (a === 198 && b === 51 && c === 100) return true;
770
+ if (a === 203 && b === 0 && c === 113) return true;
771
+ if (a >= 224) return true;
605
772
  return false;
606
773
  }
607
774
  function parseIPv6(ip) {
@@ -649,6 +816,8 @@ function isPrivateIPv6(ip) {
649
816
  if ((groups[0] & 65472) === 65152) return true;
650
817
  if ((groups[0] & 65472) === 65216) return true;
651
818
  if ((groups[0] & 65280) === 65280) return true;
819
+ if (groups[0] === 8193 && groups[1] === 3512) return true;
820
+ if (groups[0] === 16383 && (groups[1] & 61440) === 0) return true;
652
821
  const embedsIPv4 = (
653
822
  // ::/96 — IPv4-compatible (deprecated)
654
823
  topZero(6) || // ::ffff:0:0/96 — IPv4-mapped (ffff in group 5)
@@ -669,23 +838,29 @@ function isPrivateIPv6(ip) {
669
838
 
670
839
  // src/fetch-with-validated-redirects.ts
671
840
  var MAX_DOWNLOAD_REDIRECTS = 10;
841
+ var REDIRECT_STATUS_CODES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
672
842
  async function fetchWithValidatedRedirects({
673
843
  url,
674
844
  headers,
675
845
  abortSignal,
676
- maxRedirects = MAX_DOWNLOAD_REDIRECTS
846
+ maxRedirects = MAX_DOWNLOAD_REDIRECTS,
847
+ fetch = globalThis.fetch,
848
+ trustedOrigin
677
849
  }) {
678
- const baseInit = { signal: abortSignal };
679
- if (headers !== void 0) {
680
- baseInit.headers = headers;
681
- }
850
+ let currentHeaders = headers === void 0 ? void 0 : sanitizeRequestHeaders(headers);
851
+ const perHopInit = (redirect) => {
852
+ const init = { signal: abortSignal, redirect };
853
+ if (currentHeaders !== void 0) {
854
+ init.headers = new Headers(currentHeaders);
855
+ }
856
+ return init;
857
+ };
682
858
  let currentUrl = url;
683
859
  for (let redirectCount = 0; redirectCount <= maxRedirects; redirectCount++) {
684
- validateDownloadUrl(currentUrl);
685
- const response = await fetch(currentUrl, {
686
- ...baseInit,
687
- redirect: "manual"
688
- });
860
+ if (trustedOrigin === void 0 || !isSameOrigin(currentUrl, trustedOrigin)) {
861
+ validateDownloadUrl(currentUrl);
862
+ }
863
+ const response = await fetch(currentUrl, perHopInit("manual"));
689
864
  if (response.type === "opaqueredirect") {
690
865
  if (!isBrowserRuntime()) {
691
866
  throw new DownloadError({
@@ -693,12 +868,19 @@ async function fetchWithValidatedRedirects({
693
868
  message: `Redirect from ${currentUrl} could not be validated and was blocked`
694
869
  });
695
870
  }
696
- return await fetch(currentUrl, { ...baseInit, redirect: "follow" });
871
+ return await fetch(currentUrl, perHopInit("follow"));
697
872
  }
698
873
  const location = response.headers.get("location");
699
- if (response.status >= 300 && response.status < 400 && location) {
874
+ if (REDIRECT_STATUS_CODES.has(response.status) && location) {
700
875
  await cancelResponseBody(response);
701
- currentUrl = new URL(location, currentUrl).toString();
876
+ const nextUrl = new URL(location, currentUrl).toString();
877
+ if (currentHeaders !== void 0 && !isSameOrigin(nextUrl, currentUrl)) {
878
+ const userAgent = currentHeaders.get("user-agent");
879
+ currentHeaders = new Headers(
880
+ userAgent == null ? void 0 : { "user-agent": userAgent }
881
+ );
882
+ }
883
+ currentUrl = nextUrl;
702
884
  continue;
703
885
  }
704
886
  return response;
@@ -971,7 +1153,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
971
1153
  }
972
1154
 
973
1155
  // src/version.ts
974
- var VERSION = true ? "5.0.7" : "0.0.0-test";
1156
+ var VERSION = true ? "5.0.10" : "0.0.0-test";
975
1157
 
976
1158
  // src/get-from-api.ts
977
1159
  var getOriginalFetch = () => globalThis.fetch;
@@ -981,16 +1163,27 @@ var getFromApi = async ({
981
1163
  successfulResponseHandler,
982
1164
  failedResponseHandler,
983
1165
  abortSignal,
984
- fetch: fetch2 = getOriginalFetch()
1166
+ fetch = getOriginalFetch(),
1167
+ validateUrl,
1168
+ credentialedOrigin,
1169
+ trustedOrigin
985
1170
  }) => {
986
1171
  try {
987
- const response = await fetch2(url, {
1172
+ const outgoingHeaders = credentialedOrigin !== void 0 && !isSameOrigin(url, credentialedOrigin) ? {} : headers;
1173
+ const requestHeaders = withUserAgentSuffix(
1174
+ outgoingHeaders,
1175
+ `ai-sdk/provider-utils/${VERSION}`,
1176
+ getRuntimeEnvironmentUserAgent()
1177
+ );
1178
+ const response = validateUrl ? await fetchWithValidatedRedirects({
1179
+ url,
1180
+ headers: requestHeaders,
1181
+ abortSignal,
1182
+ fetch,
1183
+ trustedOrigin
1184
+ }) : await fetch(url, {
988
1185
  method: "GET",
989
- headers: withUserAgentSuffix(
990
- headers,
991
- `ai-sdk/provider-utils/${VERSION}`,
992
- getRuntimeEnvironmentUserAgent()
993
- ),
1186
+ headers: requestHeaders,
994
1187
  signal: abortSignal
995
1188
  });
996
1189
  const responseHeaders = extractResponseHeaders(response);
@@ -1088,15 +1281,6 @@ function isBuffer(value) {
1088
1281
  return (_b2 = (_a2 = globalThis.Buffer) == null ? void 0 : _a2.isBuffer(value)) != null ? _b2 : false;
1089
1282
  }
1090
1283
 
1091
- // src/is-same-origin.ts
1092
- function isSameOrigin(url, baseUrl) {
1093
- try {
1094
- return new URL(url).origin === new URL(baseUrl).origin;
1095
- } catch (e) {
1096
- return false;
1097
- }
1098
- }
1099
-
1100
1284
  // src/is-non-nullable.ts
1101
1285
  function isNonNullable(value) {
1102
1286
  return value != null;
@@ -2609,11 +2793,18 @@ function asSchema(schema) {
2609
2793
  }
2610
2794
  function standardSchema(standardSchema2) {
2611
2795
  return jsonSchema(
2612
- () => addAdditionalPropertiesToJsonSchema(
2613
- standardSchema2["~standard"].jsonSchema.input({
2614
- target: "draft-07"
2615
- })
2616
- ),
2796
+ () => {
2797
+ if (!hasStandardJsonSchema(standardSchema2)) {
2798
+ throw new Error(
2799
+ `Standard schema vendor '${standardSchema2["~standard"].vendor}' does not support JSON Schema conversion.`
2800
+ );
2801
+ }
2802
+ return addAdditionalPropertiesToJsonSchema(
2803
+ standardSchema2["~standard"].jsonSchema.input({
2804
+ target: "draft-07"
2805
+ })
2806
+ );
2807
+ },
2617
2808
  {
2618
2809
  validate: async (value) => {
2619
2810
  const result = await standardSchema2["~standard"].validate(value);
@@ -2628,6 +2819,9 @@ function standardSchema(standardSchema2) {
2628
2819
  }
2629
2820
  );
2630
2821
  }
2822
+ function hasStandardJsonSchema(schema) {
2823
+ return schema["~standard"].jsonSchema != null;
2824
+ }
2631
2825
  function zod3Schema(zodSchema2, options) {
2632
2826
  var _a2;
2633
2827
  const useReferences = (_a2 = options == null ? void 0 : options.useReferences) != null ? _a2 : false;
@@ -2814,7 +3008,7 @@ var postJsonToApi = async ({
2814
3008
  failedResponseHandler,
2815
3009
  successfulResponseHandler,
2816
3010
  abortSignal,
2817
- fetch: fetch2
3011
+ fetch
2818
3012
  }) => await postToApi({
2819
3013
  url,
2820
3014
  headers: {
@@ -2828,7 +3022,7 @@ var postJsonToApi = async ({
2828
3022
  failedResponseHandler,
2829
3023
  successfulResponseHandler,
2830
3024
  abortSignal,
2831
- fetch: fetch2
3025
+ fetch
2832
3026
  });
2833
3027
  var postFormDataToApi = async ({
2834
3028
  url,
@@ -2837,7 +3031,7 @@ var postFormDataToApi = async ({
2837
3031
  failedResponseHandler,
2838
3032
  successfulResponseHandler,
2839
3033
  abortSignal,
2840
- fetch: fetch2
3034
+ fetch
2841
3035
  }) => await postToApi({
2842
3036
  url,
2843
3037
  headers,
@@ -2848,7 +3042,7 @@ var postFormDataToApi = async ({
2848
3042
  failedResponseHandler,
2849
3043
  successfulResponseHandler,
2850
3044
  abortSignal,
2851
- fetch: fetch2
3045
+ fetch
2852
3046
  });
2853
3047
  var postToApi = async ({
2854
3048
  url,
@@ -2857,10 +3051,10 @@ var postToApi = async ({
2857
3051
  successfulResponseHandler,
2858
3052
  failedResponseHandler,
2859
3053
  abortSignal,
2860
- fetch: fetch2 = getOriginalFetch2()
3054
+ fetch = getOriginalFetch2()
2861
3055
  }) => {
2862
3056
  try {
2863
- const response = await fetch2(url, {
3057
+ const response = await fetch(url, {
2864
3058
  method: "POST",
2865
3059
  headers: withUserAgentSuffix(
2866
3060
  headers,
@@ -3012,13 +3206,6 @@ function createProviderExecutedToolFactory({
3012
3206
  });
3013
3207
  }
3014
3208
 
3015
- // src/remove-undefined-entries.ts
3016
- function removeUndefinedEntries(record) {
3017
- return Object.fromEntries(
3018
- Object.entries(record).filter(([_key, value]) => value != null)
3019
- );
3020
- }
3021
-
3022
3209
  // src/resolve.ts
3023
3210
  async function resolve(value) {
3024
3211
  if (typeof value === "function") {
@@ -3153,12 +3340,12 @@ async function retryWithExponentialBackoffInternal(f, {
3153
3340
 
3154
3341
  // src/response-handler.ts
3155
3342
  import { APICallError as APICallError4, EmptyResponseBodyError } from "@ai-sdk/provider";
3156
- var textDecoder = new TextDecoder();
3343
+ var textDecoder2 = new TextDecoder();
3157
3344
  async function readResponseBodyAsText({
3158
3345
  response,
3159
3346
  url
3160
3347
  }) {
3161
- return textDecoder.decode(
3348
+ return textDecoder2.decode(
3162
3349
  await readResponseWithSizeLimit({
3163
3350
  response,
3164
3351
  url
@@ -3481,34 +3668,150 @@ function stripFileExtension(filename) {
3481
3668
  return firstDotIndex === -1 ? filename : filename.slice(0, firstDotIndex);
3482
3669
  }
3483
3670
 
3484
- // src/websocket.ts
3485
- function getWebSocketConstructor(webSocket) {
3486
- const WebSocketConstructor = webSocket != null ? webSocket : globalThis.WebSocket;
3487
- if (WebSocketConstructor == null) {
3488
- throw new Error("No WebSocket implementation available.");
3671
+ // src/transcription-stream-envelope.ts
3672
+ var TRANSCRIPTION_STREAM_START_FRAME_TYPE = "transcription-stream.start";
3673
+ var TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE = "transcription-stream.audio-done";
3674
+ function parseTranscriptionStreamClientFrame(text) {
3675
+ let value;
3676
+ try {
3677
+ value = secureJsonParse(text);
3678
+ } catch (e) {
3679
+ return { type: "invalid", message: "malformed JSON" };
3680
+ }
3681
+ if (value == null || typeof value !== "object" || Array.isArray(value)) {
3682
+ return { type: "invalid", message: "frame must be a JSON object" };
3683
+ }
3684
+ const frame = value;
3685
+ if (typeof frame.type !== "string") {
3686
+ return { type: "invalid", message: "frame type must be a string" };
3687
+ }
3688
+ switch (frame.type) {
3689
+ case TRANSCRIPTION_STREAM_START_FRAME_TYPE: {
3690
+ const inputAudioFormat = frame.inputAudioFormat;
3691
+ if (inputAudioFormat == null || typeof inputAudioFormat !== "object" || Array.isArray(inputAudioFormat) || typeof inputAudioFormat.type !== "string") {
3692
+ return {
3693
+ type: "invalid",
3694
+ message: "start frame must have an inputAudioFormat object with a string type"
3695
+ };
3696
+ }
3697
+ if (inputAudioFormat.rate !== void 0 && typeof inputAudioFormat.rate !== "number") {
3698
+ return {
3699
+ type: "invalid",
3700
+ message: "inputAudioFormat.rate must be a number when present"
3701
+ };
3702
+ }
3703
+ if (frame.providerOptions !== void 0 && (frame.providerOptions == null || typeof frame.providerOptions !== "object" || Array.isArray(frame.providerOptions))) {
3704
+ return {
3705
+ type: "invalid",
3706
+ message: "providerOptions must be an object when present"
3707
+ };
3708
+ }
3709
+ if (frame.includeRawChunks !== void 0 && typeof frame.includeRawChunks !== "boolean") {
3710
+ return {
3711
+ type: "invalid",
3712
+ message: "includeRawChunks must be a boolean when present"
3713
+ };
3714
+ }
3715
+ return {
3716
+ type: "start",
3717
+ frame
3718
+ };
3719
+ }
3720
+ case TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE:
3721
+ return { type: "audio-done" };
3722
+ default:
3723
+ return { type: "unknown" };
3489
3724
  }
3490
- return WebSocketConstructor;
3491
3725
  }
3492
- function toWebSocketUrl(url) {
3493
- const wsUrl = new URL(url);
3494
- if (wsUrl.protocol === "http:") {
3495
- wsUrl.protocol = "ws:";
3496
- } else if (wsUrl.protocol === "https:") {
3497
- wsUrl.protocol = "wss:";
3726
+ function serializeTranscriptionStreamPart(part) {
3727
+ try {
3728
+ if (part.type === "error" && isError(part.error)) {
3729
+ return JSON.stringify({
3730
+ ...part,
3731
+ error: { name: part.error.name, message: part.error.message }
3732
+ });
3733
+ }
3734
+ return JSON.stringify(part);
3735
+ } catch (e) {
3736
+ return void 0;
3498
3737
  }
3499
- return wsUrl;
3500
3738
  }
3501
- var textDecoder2 = new TextDecoder();
3502
- async function readWebSocketMessageText(data) {
3503
- if (typeof data === "string") return data;
3504
- if (data instanceof ArrayBuffer) return textDecoder2.decode(data);
3505
- if (ArrayBuffer.isView(data)) {
3506
- return textDecoder2.decode(data);
3739
+ function isError(value) {
3740
+ return value instanceof Error || Object.prototype.toString.call(value) === "[object Error]";
3741
+ }
3742
+ function parseTranscriptionStreamPart(text) {
3743
+ let value;
3744
+ try {
3745
+ value = secureJsonParse(text);
3746
+ } catch (e) {
3747
+ return void 0;
3507
3748
  }
3508
- if (typeof Blob !== "undefined" && data instanceof Blob) {
3509
- return data.text();
3749
+ if (value == null || typeof value !== "object" || Array.isArray(value)) {
3750
+ return void 0;
3510
3751
  }
3511
- return String(data);
3752
+ const part = value;
3753
+ switch (part.type) {
3754
+ case "stream-start":
3755
+ return Array.isArray(part.warnings) && part.warnings.every(isWarning) ? part : void 0;
3756
+ case "transcript-delta":
3757
+ return isString(part.delta) && isOptional(part.id, isString) && isOptional(part.providerMetadata, isPlainObject) ? part : void 0;
3758
+ case "transcript-partial":
3759
+ return isString(part.text) && isOptional(part.id, isString) && isOptional(part.startSecond, isNumber) && isOptional(part.durationInSeconds, isNumber) && isOptional(part.channelIndex, isNumber) && isOptional(part.providerMetadata, isPlainObject) ? part : void 0;
3760
+ case "transcript-final":
3761
+ return isString(part.text) && isOptional(part.id, isString) && isOptional(part.startSecond, isNumber) && isOptional(part.endSecond, isNumber) && isOptional(part.channelIndex, isNumber) && isOptional(part.providerMetadata, isPlainObject) ? part : void 0;
3762
+ case "finish":
3763
+ return isString(part.text) && Array.isArray(part.segments) && part.segments.every(isSegment) && isOptional(part.language, isString) && isOptional(part.durationInSeconds, isNumber) && isOptional(part.providerMetadata, isPlainObject) ? part : void 0;
3764
+ case "response-metadata": {
3765
+ if (!(isOptional(part.modelId, isString) && isOptional(part.headers, isPlainObject))) {
3766
+ return void 0;
3767
+ }
3768
+ const timestamp = part.timestamp;
3769
+ if (timestamp == null) {
3770
+ return { ...part, timestamp: void 0 };
3771
+ }
3772
+ if (typeof timestamp !== "string") {
3773
+ return void 0;
3774
+ }
3775
+ const revived = new Date(timestamp);
3776
+ return Number.isNaN(revived.getTime()) ? void 0 : { ...part, timestamp: revived };
3777
+ }
3778
+ case "raw":
3779
+ return "rawValue" in part ? part : void 0;
3780
+ case "error":
3781
+ return "error" in part ? part : void 0;
3782
+ default:
3783
+ return void 0;
3784
+ }
3785
+ }
3786
+ function isString(value) {
3787
+ return typeof value === "string";
3788
+ }
3789
+ function isNumber(value) {
3790
+ return typeof value === "number";
3791
+ }
3792
+ function isOptional(value, check) {
3793
+ return value === void 0 || check(value);
3794
+ }
3795
+ function isPlainObject(value) {
3796
+ return typeof value === "object" && value != null && !Array.isArray(value);
3797
+ }
3798
+ function isWarning(value) {
3799
+ return isPlainObject(value) && isString(value.type);
3800
+ }
3801
+ function isSegment(value) {
3802
+ return isPlainObject(value) && isString(value.text) && isNumber(value.startSecond) && isNumber(value.endSecond);
3803
+ }
3804
+
3805
+ // src/validate-base-url.ts
3806
+ import { InvalidArgumentError as InvalidArgumentError3 } from "@ai-sdk/provider";
3807
+ function validateBaseURL(baseURL) {
3808
+ if ((baseURL == null ? void 0 : baseURL.trim()) === "") {
3809
+ throw new InvalidArgumentError3({
3810
+ argument: "baseURL",
3811
+ message: "baseURL must be a non-empty string."
3812
+ });
3813
+ }
3814
+ return baseURL;
3512
3815
  }
3513
3816
 
3514
3817
  // src/without-trailing-slash.ts
@@ -3554,6 +3857,8 @@ export {
3554
3857
  DEFAULT_MAX_DOWNLOAD_SIZE,
3555
3858
  DelayedPromise,
3556
3859
  DownloadError,
3860
+ TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE as EXPERIMENTAL_TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE,
3861
+ TRANSCRIPTION_STREAM_START_FRAME_TYPE as EXPERIMENTAL_TRANSCRIPTION_STREAM_START_FRAME_TYPE,
3557
3862
  EventSourceParserStream2 as EventSourceParserStream,
3558
3863
  StreamingToolCallTracker,
3559
3864
  VERSION,
@@ -3563,6 +3868,7 @@ export {
3563
3868
  asSchema,
3564
3869
  cancelResponseBody,
3565
3870
  combineHeaders,
3871
+ connectToWebSocket,
3566
3872
  convertAsyncIteratorToReadableStream,
3567
3873
  convertBase64ToUint8Array,
3568
3874
  convertImageModelFileToDataUri,
@@ -3585,6 +3891,9 @@ export {
3585
3891
  downloadBlob,
3586
3892
  dynamicTool,
3587
3893
  executeTool,
3894
+ parseTranscriptionStreamClientFrame as experimental_parseTranscriptionStreamClientFrame,
3895
+ parseTranscriptionStreamPart as experimental_parseTranscriptionStreamPart,
3896
+ serializeTranscriptionStreamPart as experimental_serializeTranscriptionStreamPart,
3588
3897
  extractLines,
3589
3898
  extractResponseHeaders,
3590
3899
  fetchWithValidatedRedirects,
@@ -3636,8 +3945,10 @@ export {
3636
3945
  stripFileExtension,
3637
3946
  toWebSocketUrl,
3638
3947
  tool,
3948
+ validateBaseURL,
3639
3949
  validateDownloadUrl,
3640
3950
  validateTypes,
3951
+ waitForWebSocketBufferDrain,
3641
3952
  withUserAgentSuffix,
3642
3953
  withoutTrailingSlash,
3643
3954
  zodSchema