@ai-sdk/provider-utils 5.0.32 → 5.0.34
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 +13 -0
- package/dist/index.js +99 -16
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/handle-fetch-error.ts +44 -12
- package/src/response-handler.ts +78 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @ai-sdk/provider-utils
|
|
2
2
|
|
|
3
|
+
## 5.0.34
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [aa45741]
|
|
8
|
+
- @ai-sdk/provider@4.0.9
|
|
9
|
+
|
|
10
|
+
## 5.0.33
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 90192f1: Mark transient network errors that occur while reading successful response bodies as retryable.
|
|
15
|
+
|
|
3
16
|
## 5.0.32
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1254,24 +1254,31 @@ function isAbortError(error) {
|
|
|
1254
1254
|
|
|
1255
1255
|
// src/handle-fetch-error.ts
|
|
1256
1256
|
var FETCH_FAILED_ERROR_MESSAGES = ["fetch failed", "failed to fetch"];
|
|
1257
|
-
var
|
|
1257
|
+
var RETRYABLE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
1258
1258
|
"ConnectionRefused",
|
|
1259
1259
|
"ConnectionClosed",
|
|
1260
1260
|
"FailedToOpenSocket",
|
|
1261
1261
|
"ECONNRESET",
|
|
1262
1262
|
"ECONNREFUSED",
|
|
1263
1263
|
"ETIMEDOUT",
|
|
1264
|
-
"EPIPE"
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1264
|
+
"EPIPE",
|
|
1265
|
+
"UND_ERR_SOCKET",
|
|
1266
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
1267
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
1268
|
+
"UND_ERR_CONNECT_TIMEOUT"
|
|
1269
|
+
]);
|
|
1270
|
+
function findNetworkError(error) {
|
|
1271
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1272
|
+
let current = error;
|
|
1273
|
+
while (current instanceof Error && !visited.has(current)) {
|
|
1274
|
+
visited.add(current);
|
|
1275
|
+
const errorWithCode = current;
|
|
1276
|
+
if (typeof errorWithCode.code === "string" && RETRYABLE_NETWORK_ERROR_CODES.has(errorWithCode.code)) {
|
|
1277
|
+
return errorWithCode;
|
|
1278
|
+
}
|
|
1279
|
+
current = current.cause;
|
|
1273
1280
|
}
|
|
1274
|
-
return
|
|
1281
|
+
return void 0;
|
|
1275
1282
|
}
|
|
1276
1283
|
function handleFetchError({
|
|
1277
1284
|
error,
|
|
@@ -1294,9 +1301,23 @@ function handleFetchError({
|
|
|
1294
1301
|
});
|
|
1295
1302
|
}
|
|
1296
1303
|
}
|
|
1297
|
-
|
|
1304
|
+
const networkError = findNetworkError(error);
|
|
1305
|
+
if (networkError != null) {
|
|
1306
|
+
if (APICallError.isInstance(error)) {
|
|
1307
|
+
return new APICallError({
|
|
1308
|
+
message: error.message,
|
|
1309
|
+
cause: error.cause,
|
|
1310
|
+
url: error.url,
|
|
1311
|
+
requestBodyValues: error.requestBodyValues,
|
|
1312
|
+
statusCode: error.statusCode,
|
|
1313
|
+
responseHeaders: error.responseHeaders,
|
|
1314
|
+
responseBody: error.responseBody,
|
|
1315
|
+
data: error.data,
|
|
1316
|
+
isRetryable: true
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1298
1319
|
return new APICallError({
|
|
1299
|
-
message: `Cannot connect to API: ${error.message}`,
|
|
1320
|
+
message: `Cannot connect to API: ${error instanceof Error ? error.message : networkError.message}`,
|
|
1300
1321
|
cause: error,
|
|
1301
1322
|
url,
|
|
1302
1323
|
requestBodyValues,
|
|
@@ -1359,7 +1380,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
|
|
|
1359
1380
|
}
|
|
1360
1381
|
|
|
1361
1382
|
// src/version.ts
|
|
1362
|
-
var VERSION = true ? "5.0.
|
|
1383
|
+
var VERSION = true ? "5.0.34" : "0.0.0-test";
|
|
1363
1384
|
|
|
1364
1385
|
// src/get-from-api.ts
|
|
1365
1386
|
var getOriginalFetch = () => globalThis.fetch;
|
|
@@ -3579,6 +3600,62 @@ async function retryWithExponentialBackoffInternal(f, {
|
|
|
3579
3600
|
// src/response-handler.ts
|
|
3580
3601
|
import { APICallError as APICallError4, EmptyResponseBodyError } from "@ai-sdk/provider";
|
|
3581
3602
|
var textDecoder2 = new TextDecoder();
|
|
3603
|
+
function wrapResponseBodyStream({
|
|
3604
|
+
stream,
|
|
3605
|
+
url,
|
|
3606
|
+
requestBodyValues,
|
|
3607
|
+
statusCode,
|
|
3608
|
+
responseHeaders
|
|
3609
|
+
}) {
|
|
3610
|
+
const reader = stream.getReader();
|
|
3611
|
+
let readerReleased = false;
|
|
3612
|
+
const releaseReader = () => {
|
|
3613
|
+
if (!readerReleased) {
|
|
3614
|
+
reader.releaseLock();
|
|
3615
|
+
readerReleased = true;
|
|
3616
|
+
}
|
|
3617
|
+
};
|
|
3618
|
+
return new ReadableStream({
|
|
3619
|
+
async pull(controller) {
|
|
3620
|
+
try {
|
|
3621
|
+
const { done, value } = await reader.read();
|
|
3622
|
+
if (done) {
|
|
3623
|
+
releaseReader();
|
|
3624
|
+
controller.close();
|
|
3625
|
+
} else {
|
|
3626
|
+
controller.enqueue(value);
|
|
3627
|
+
}
|
|
3628
|
+
} catch (error) {
|
|
3629
|
+
releaseReader();
|
|
3630
|
+
if (isAbortError(error)) {
|
|
3631
|
+
controller.error(error);
|
|
3632
|
+
return;
|
|
3633
|
+
}
|
|
3634
|
+
controller.error(
|
|
3635
|
+
handleFetchError({
|
|
3636
|
+
error: new APICallError4({
|
|
3637
|
+
message: "Failed to process successful response",
|
|
3638
|
+
cause: error,
|
|
3639
|
+
statusCode,
|
|
3640
|
+
url,
|
|
3641
|
+
responseHeaders,
|
|
3642
|
+
requestBodyValues
|
|
3643
|
+
}),
|
|
3644
|
+
url,
|
|
3645
|
+
requestBodyValues
|
|
3646
|
+
})
|
|
3647
|
+
);
|
|
3648
|
+
}
|
|
3649
|
+
},
|
|
3650
|
+
async cancel(reason) {
|
|
3651
|
+
try {
|
|
3652
|
+
await reader.cancel(reason);
|
|
3653
|
+
} finally {
|
|
3654
|
+
releaseReader();
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
});
|
|
3658
|
+
}
|
|
3582
3659
|
async function readResponseBodyAsText({
|
|
3583
3660
|
response,
|
|
3584
3661
|
url
|
|
@@ -3644,7 +3721,7 @@ var createJsonErrorResponseHandler = ({
|
|
|
3644
3721
|
};
|
|
3645
3722
|
}
|
|
3646
3723
|
};
|
|
3647
|
-
var createEventSourceResponseHandler = (chunkSchema) => async ({ response }) => {
|
|
3724
|
+
var createEventSourceResponseHandler = (chunkSchema) => async ({ response, url, requestBodyValues }) => {
|
|
3648
3725
|
const responseHeaders = extractResponseHeaders(response);
|
|
3649
3726
|
if (response.body == null) {
|
|
3650
3727
|
throw new EmptyResponseBodyError({});
|
|
@@ -3652,7 +3729,13 @@ var createEventSourceResponseHandler = (chunkSchema) => async ({ response }) =>
|
|
|
3652
3729
|
return {
|
|
3653
3730
|
responseHeaders,
|
|
3654
3731
|
value: parseJsonEventStream({
|
|
3655
|
-
stream:
|
|
3732
|
+
stream: wrapResponseBodyStream({
|
|
3733
|
+
stream: response.body,
|
|
3734
|
+
url,
|
|
3735
|
+
requestBodyValues,
|
|
3736
|
+
statusCode: response.status,
|
|
3737
|
+
responseHeaders
|
|
3738
|
+
}),
|
|
3656
3739
|
schema: chunkSchema
|
|
3657
3740
|
})
|
|
3658
3741
|
};
|