@ai-sdk/provider-utils 5.0.7 → 5.0.9

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.9" : "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;
@@ -2814,7 +2998,7 @@ var postJsonToApi = async ({
2814
2998
  failedResponseHandler,
2815
2999
  successfulResponseHandler,
2816
3000
  abortSignal,
2817
- fetch: fetch2
3001
+ fetch
2818
3002
  }) => await postToApi({
2819
3003
  url,
2820
3004
  headers: {
@@ -2828,7 +3012,7 @@ var postJsonToApi = async ({
2828
3012
  failedResponseHandler,
2829
3013
  successfulResponseHandler,
2830
3014
  abortSignal,
2831
- fetch: fetch2
3015
+ fetch
2832
3016
  });
2833
3017
  var postFormDataToApi = async ({
2834
3018
  url,
@@ -2837,7 +3021,7 @@ var postFormDataToApi = async ({
2837
3021
  failedResponseHandler,
2838
3022
  successfulResponseHandler,
2839
3023
  abortSignal,
2840
- fetch: fetch2
3024
+ fetch
2841
3025
  }) => await postToApi({
2842
3026
  url,
2843
3027
  headers,
@@ -2848,7 +3032,7 @@ var postFormDataToApi = async ({
2848
3032
  failedResponseHandler,
2849
3033
  successfulResponseHandler,
2850
3034
  abortSignal,
2851
- fetch: fetch2
3035
+ fetch
2852
3036
  });
2853
3037
  var postToApi = async ({
2854
3038
  url,
@@ -2857,10 +3041,10 @@ var postToApi = async ({
2857
3041
  successfulResponseHandler,
2858
3042
  failedResponseHandler,
2859
3043
  abortSignal,
2860
- fetch: fetch2 = getOriginalFetch2()
3044
+ fetch = getOriginalFetch2()
2861
3045
  }) => {
2862
3046
  try {
2863
- const response = await fetch2(url, {
3047
+ const response = await fetch(url, {
2864
3048
  method: "POST",
2865
3049
  headers: withUserAgentSuffix(
2866
3050
  headers,
@@ -3012,13 +3196,6 @@ function createProviderExecutedToolFactory({
3012
3196
  });
3013
3197
  }
3014
3198
 
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
3199
  // src/resolve.ts
3023
3200
  async function resolve(value) {
3024
3201
  if (typeof value === "function") {
@@ -3153,12 +3330,12 @@ async function retryWithExponentialBackoffInternal(f, {
3153
3330
 
3154
3331
  // src/response-handler.ts
3155
3332
  import { APICallError as APICallError4, EmptyResponseBodyError } from "@ai-sdk/provider";
3156
- var textDecoder = new TextDecoder();
3333
+ var textDecoder2 = new TextDecoder();
3157
3334
  async function readResponseBodyAsText({
3158
3335
  response,
3159
3336
  url
3160
3337
  }) {
3161
- return textDecoder.decode(
3338
+ return textDecoder2.decode(
3162
3339
  await readResponseWithSizeLimit({
3163
3340
  response,
3164
3341
  url
@@ -3481,34 +3658,150 @@ function stripFileExtension(filename) {
3481
3658
  return firstDotIndex === -1 ? filename : filename.slice(0, firstDotIndex);
3482
3659
  }
3483
3660
 
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.");
3661
+ // src/transcription-stream-envelope.ts
3662
+ var TRANSCRIPTION_STREAM_START_FRAME_TYPE = "transcription-stream.start";
3663
+ var TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE = "transcription-stream.audio-done";
3664
+ function parseTranscriptionStreamClientFrame(text) {
3665
+ let value;
3666
+ try {
3667
+ value = secureJsonParse(text);
3668
+ } catch (e) {
3669
+ return { type: "invalid", message: "malformed JSON" };
3670
+ }
3671
+ if (value == null || typeof value !== "object" || Array.isArray(value)) {
3672
+ return { type: "invalid", message: "frame must be a JSON object" };
3673
+ }
3674
+ const frame = value;
3675
+ if (typeof frame.type !== "string") {
3676
+ return { type: "invalid", message: "frame type must be a string" };
3677
+ }
3678
+ switch (frame.type) {
3679
+ case TRANSCRIPTION_STREAM_START_FRAME_TYPE: {
3680
+ const inputAudioFormat = frame.inputAudioFormat;
3681
+ if (inputAudioFormat == null || typeof inputAudioFormat !== "object" || Array.isArray(inputAudioFormat) || typeof inputAudioFormat.type !== "string") {
3682
+ return {
3683
+ type: "invalid",
3684
+ message: "start frame must have an inputAudioFormat object with a string type"
3685
+ };
3686
+ }
3687
+ if (inputAudioFormat.rate !== void 0 && typeof inputAudioFormat.rate !== "number") {
3688
+ return {
3689
+ type: "invalid",
3690
+ message: "inputAudioFormat.rate must be a number when present"
3691
+ };
3692
+ }
3693
+ if (frame.providerOptions !== void 0 && (frame.providerOptions == null || typeof frame.providerOptions !== "object" || Array.isArray(frame.providerOptions))) {
3694
+ return {
3695
+ type: "invalid",
3696
+ message: "providerOptions must be an object when present"
3697
+ };
3698
+ }
3699
+ if (frame.includeRawChunks !== void 0 && typeof frame.includeRawChunks !== "boolean") {
3700
+ return {
3701
+ type: "invalid",
3702
+ message: "includeRawChunks must be a boolean when present"
3703
+ };
3704
+ }
3705
+ return {
3706
+ type: "start",
3707
+ frame
3708
+ };
3709
+ }
3710
+ case TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE:
3711
+ return { type: "audio-done" };
3712
+ default:
3713
+ return { type: "unknown" };
3489
3714
  }
3490
- return WebSocketConstructor;
3491
3715
  }
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:";
3716
+ function serializeTranscriptionStreamPart(part) {
3717
+ try {
3718
+ if (part.type === "error" && isError(part.error)) {
3719
+ return JSON.stringify({
3720
+ ...part,
3721
+ error: { name: part.error.name, message: part.error.message }
3722
+ });
3723
+ }
3724
+ return JSON.stringify(part);
3725
+ } catch (e) {
3726
+ return void 0;
3498
3727
  }
3499
- return wsUrl;
3500
3728
  }
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);
3729
+ function isError(value) {
3730
+ return value instanceof Error || Object.prototype.toString.call(value) === "[object Error]";
3731
+ }
3732
+ function parseTranscriptionStreamPart(text) {
3733
+ let value;
3734
+ try {
3735
+ value = secureJsonParse(text);
3736
+ } catch (e) {
3737
+ return void 0;
3507
3738
  }
3508
- if (typeof Blob !== "undefined" && data instanceof Blob) {
3509
- return data.text();
3739
+ if (value == null || typeof value !== "object" || Array.isArray(value)) {
3740
+ return void 0;
3510
3741
  }
3511
- return String(data);
3742
+ const part = value;
3743
+ switch (part.type) {
3744
+ case "stream-start":
3745
+ return Array.isArray(part.warnings) && part.warnings.every(isWarning) ? part : void 0;
3746
+ case "transcript-delta":
3747
+ return isString(part.delta) && isOptional(part.id, isString) && isOptional(part.providerMetadata, isPlainObject) ? part : void 0;
3748
+ case "transcript-partial":
3749
+ 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;
3750
+ case "transcript-final":
3751
+ 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;
3752
+ case "finish":
3753
+ 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;
3754
+ case "response-metadata": {
3755
+ if (!(isOptional(part.modelId, isString) && isOptional(part.headers, isPlainObject))) {
3756
+ return void 0;
3757
+ }
3758
+ const timestamp = part.timestamp;
3759
+ if (timestamp == null) {
3760
+ return { ...part, timestamp: void 0 };
3761
+ }
3762
+ if (typeof timestamp !== "string") {
3763
+ return void 0;
3764
+ }
3765
+ const revived = new Date(timestamp);
3766
+ return Number.isNaN(revived.getTime()) ? void 0 : { ...part, timestamp: revived };
3767
+ }
3768
+ case "raw":
3769
+ return "rawValue" in part ? part : void 0;
3770
+ case "error":
3771
+ return "error" in part ? part : void 0;
3772
+ default:
3773
+ return void 0;
3774
+ }
3775
+ }
3776
+ function isString(value) {
3777
+ return typeof value === "string";
3778
+ }
3779
+ function isNumber(value) {
3780
+ return typeof value === "number";
3781
+ }
3782
+ function isOptional(value, check) {
3783
+ return value === void 0 || check(value);
3784
+ }
3785
+ function isPlainObject(value) {
3786
+ return typeof value === "object" && value != null && !Array.isArray(value);
3787
+ }
3788
+ function isWarning(value) {
3789
+ return isPlainObject(value) && isString(value.type);
3790
+ }
3791
+ function isSegment(value) {
3792
+ return isPlainObject(value) && isString(value.text) && isNumber(value.startSecond) && isNumber(value.endSecond);
3793
+ }
3794
+
3795
+ // src/validate-base-url.ts
3796
+ import { InvalidArgumentError as InvalidArgumentError3 } from "@ai-sdk/provider";
3797
+ function validateBaseURL(baseURL) {
3798
+ if ((baseURL == null ? void 0 : baseURL.trim()) === "") {
3799
+ throw new InvalidArgumentError3({
3800
+ argument: "baseURL",
3801
+ message: "baseURL must be a non-empty string."
3802
+ });
3803
+ }
3804
+ return baseURL;
3512
3805
  }
3513
3806
 
3514
3807
  // src/without-trailing-slash.ts
@@ -3554,6 +3847,8 @@ export {
3554
3847
  DEFAULT_MAX_DOWNLOAD_SIZE,
3555
3848
  DelayedPromise,
3556
3849
  DownloadError,
3850
+ TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE as EXPERIMENTAL_TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE,
3851
+ TRANSCRIPTION_STREAM_START_FRAME_TYPE as EXPERIMENTAL_TRANSCRIPTION_STREAM_START_FRAME_TYPE,
3557
3852
  EventSourceParserStream2 as EventSourceParserStream,
3558
3853
  StreamingToolCallTracker,
3559
3854
  VERSION,
@@ -3563,6 +3858,7 @@ export {
3563
3858
  asSchema,
3564
3859
  cancelResponseBody,
3565
3860
  combineHeaders,
3861
+ connectToWebSocket,
3566
3862
  convertAsyncIteratorToReadableStream,
3567
3863
  convertBase64ToUint8Array,
3568
3864
  convertImageModelFileToDataUri,
@@ -3585,6 +3881,9 @@ export {
3585
3881
  downloadBlob,
3586
3882
  dynamicTool,
3587
3883
  executeTool,
3884
+ parseTranscriptionStreamClientFrame as experimental_parseTranscriptionStreamClientFrame,
3885
+ parseTranscriptionStreamPart as experimental_parseTranscriptionStreamPart,
3886
+ serializeTranscriptionStreamPart as experimental_serializeTranscriptionStreamPart,
3588
3887
  extractLines,
3589
3888
  extractResponseHeaders,
3590
3889
  fetchWithValidatedRedirects,
@@ -3636,8 +3935,10 @@ export {
3636
3935
  stripFileExtension,
3637
3936
  toWebSocketUrl,
3638
3937
  tool,
3938
+ validateBaseURL,
3639
3939
  validateDownloadUrl,
3640
3940
  validateTypes,
3941
+ waitForWebSocketBufferDrain,
3641
3942
  withUserAgentSuffix,
3642
3943
  withoutTrailingSlash,
3643
3944
  zodSchema