@ai-sdk/provider-utils 3.0.35 → 3.0.37

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.mjs CHANGED
@@ -583,6 +583,32 @@ function isAbortError(error) {
583
583
 
584
584
  // src/handle-fetch-error.ts
585
585
  var FETCH_FAILED_ERROR_MESSAGES = ["fetch failed", "failed to fetch"];
586
+ var RETRYABLE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
587
+ "ConnectionRefused",
588
+ "ConnectionClosed",
589
+ "FailedToOpenSocket",
590
+ "ECONNRESET",
591
+ "ECONNREFUSED",
592
+ "ETIMEDOUT",
593
+ "EPIPE",
594
+ "UND_ERR_SOCKET",
595
+ "UND_ERR_HEADERS_TIMEOUT",
596
+ "UND_ERR_BODY_TIMEOUT",
597
+ "UND_ERR_CONNECT_TIMEOUT"
598
+ ]);
599
+ function findNetworkError(error) {
600
+ const visited = /* @__PURE__ */ new Set();
601
+ let current = error;
602
+ while (current instanceof Error && !visited.has(current)) {
603
+ visited.add(current);
604
+ const errorWithCode = current;
605
+ if (typeof errorWithCode.code === "string" && RETRYABLE_NETWORK_ERROR_CODES.has(errorWithCode.code)) {
606
+ return errorWithCode;
607
+ }
608
+ current = current.cause;
609
+ }
610
+ return void 0;
611
+ }
586
612
  function handleFetchError({
587
613
  error,
588
614
  url,
@@ -604,6 +630,29 @@ function handleFetchError({
604
630
  });
605
631
  }
606
632
  }
633
+ const networkError = findNetworkError(error);
634
+ if (networkError != null) {
635
+ if (APICallError.isInstance(error)) {
636
+ return new APICallError({
637
+ message: error.message,
638
+ cause: error.cause,
639
+ url: error.url,
640
+ requestBodyValues: error.requestBodyValues,
641
+ statusCode: error.statusCode,
642
+ responseHeaders: error.responseHeaders,
643
+ responseBody: error.responseBody,
644
+ data: error.data,
645
+ isRetryable: true
646
+ });
647
+ }
648
+ return new APICallError({
649
+ message: `Cannot connect to API: ${error instanceof Error ? error.message : networkError.message}`,
650
+ cause: error,
651
+ url,
652
+ requestBodyValues,
653
+ isRetryable: true
654
+ });
655
+ }
607
656
  return error;
608
657
  }
609
658
 
@@ -660,7 +709,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
660
709
  }
661
710
 
662
711
  // src/version.ts
663
- var VERSION = true ? "3.0.35" : "0.0.0-test";
712
+ var VERSION = true ? "3.0.37" : "0.0.0-test";
664
713
 
665
714
  // src/get-from-api.ts
666
715
  var getOriginalFetch = () => globalThis.fetch;
@@ -1312,6 +1361,62 @@ async function resolve(value) {
1312
1361
  // src/response-handler.ts
1313
1362
  import { APICallError as APICallError4, EmptyResponseBodyError } from "@ai-sdk/provider";
1314
1363
  var textDecoder = new TextDecoder();
1364
+ function wrapResponseBodyStream({
1365
+ stream,
1366
+ url,
1367
+ requestBodyValues,
1368
+ statusCode,
1369
+ responseHeaders
1370
+ }) {
1371
+ const reader = stream.getReader();
1372
+ let readerReleased = false;
1373
+ const releaseReader = () => {
1374
+ if (!readerReleased) {
1375
+ reader.releaseLock();
1376
+ readerReleased = true;
1377
+ }
1378
+ };
1379
+ return new ReadableStream({
1380
+ async pull(controller) {
1381
+ try {
1382
+ const { done, value } = await reader.read();
1383
+ if (done) {
1384
+ releaseReader();
1385
+ controller.close();
1386
+ } else {
1387
+ controller.enqueue(value);
1388
+ }
1389
+ } catch (error) {
1390
+ releaseReader();
1391
+ if (isAbortError(error)) {
1392
+ controller.error(error);
1393
+ return;
1394
+ }
1395
+ controller.error(
1396
+ handleFetchError({
1397
+ error: new APICallError4({
1398
+ message: "Failed to process successful response",
1399
+ cause: error,
1400
+ statusCode,
1401
+ url,
1402
+ responseHeaders,
1403
+ requestBodyValues
1404
+ }),
1405
+ url,
1406
+ requestBodyValues
1407
+ })
1408
+ );
1409
+ }
1410
+ },
1411
+ async cancel(reason) {
1412
+ try {
1413
+ await reader.cancel(reason);
1414
+ } finally {
1415
+ releaseReader();
1416
+ }
1417
+ }
1418
+ });
1419
+ }
1315
1420
  async function readResponseBodyAsText({
1316
1421
  response,
1317
1422
  url
@@ -1377,7 +1482,7 @@ var createJsonErrorResponseHandler = ({
1377
1482
  };
1378
1483
  }
1379
1484
  };
1380
- var createEventSourceResponseHandler = (chunkSchema) => async ({ response }) => {
1485
+ var createEventSourceResponseHandler = (chunkSchema) => async ({ response, url, requestBodyValues }) => {
1381
1486
  const responseHeaders = extractResponseHeaders(response);
1382
1487
  if (response.body == null) {
1383
1488
  throw new EmptyResponseBodyError({});
@@ -1385,7 +1490,13 @@ var createEventSourceResponseHandler = (chunkSchema) => async ({ response }) =>
1385
1490
  return {
1386
1491
  responseHeaders,
1387
1492
  value: parseJsonEventStream({
1388
- stream: response.body,
1493
+ stream: wrapResponseBodyStream({
1494
+ stream: response.body,
1495
+ url,
1496
+ requestBodyValues,
1497
+ statusCode: response.status,
1498
+ responseHeaders
1499
+ }),
1389
1500
  schema: chunkSchema
1390
1501
  })
1391
1502
  };
@@ -2797,11 +2908,12 @@ function convertBase64ToUint8Array(base64String) {
2797
2908
  return Uint8Array.from(latin1string, (byte) => byte.codePointAt(0));
2798
2909
  }
2799
2910
  function convertUint8ArrayToBase64(array) {
2800
- let latin1string = "";
2801
- for (let i = 0; i < array.length; i++) {
2802
- latin1string += String.fromCodePoint(array[i]);
2911
+ const chunks = [];
2912
+ const chunkSize = 4096;
2913
+ for (let i = 0; i < array.length; i += chunkSize) {
2914
+ chunks.push(String.fromCodePoint(...array.subarray(i, i + chunkSize)));
2803
2915
  }
2804
- return btoa(latin1string);
2916
+ return btoa(chunks.join(""));
2805
2917
  }
2806
2918
  function convertToBase64(value) {
2807
2919
  return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value;