ai 7.0.98 → 7.0.100
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 +16 -0
- package/dist/index.d.ts +12 -4
- package/dist/index.js +91 -24
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.js.map +1 -1
- package/docs/02-foundations/02-providers-and-models.mdx +1 -0
- package/docs/02-getting-started/07-expo.mdx +7 -0
- package/docs/03-ai-sdk-core/55-testing.mdx +75 -0
- package/docs/04-ai-sdk-ui/21-error-handling.mdx +28 -2
- package/docs/07-reference/01-ai-sdk-core/06-embed-many.mdx +1 -1
- package/docs/07-reference/05-ai-sdk-errors/ai-api-call-error.mdx +4 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-argument-error.mdx +6 -1
- package/docs/07-reference/05-ai-sdk-errors/ai-ui-message-stream-error.mdx +6 -2
- package/package.json +4 -4
- package/src/embed/embed-many.ts +5 -2
- package/src/error/ui-message-stream-error.ts +5 -2
- package/src/ui/call-completion-api.ts +22 -6
- package/src/ui/chat.ts +16 -5
- package/src/ui/convert-file-list-to-file-ui-parts.ts +5 -1
- package/src/ui/create-ui-api-call-error.ts +23 -0
- package/src/ui/http-chat-transport.ts +18 -8
- package/src/util/data-url.ts +14 -2
- package/src/util/split-array.ts +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# ai
|
|
2
2
|
|
|
3
|
+
## 7.0.100
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6431635: feat(ai): expose typed AI SDK errors for UI transport and completion failures
|
|
8
|
+
- Updated dependencies [23a0fff]
|
|
9
|
+
- @ai-sdk/gateway@4.0.81
|
|
10
|
+
|
|
11
|
+
## 7.0.99
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 615ac89: feat(ai): use InvalidArgumentError for utility input validation
|
|
16
|
+
- Updated dependencies [7f76d83]
|
|
17
|
+
- @ai-sdk/gateway@4.0.80
|
|
18
|
+
|
|
3
19
|
## 7.0.98
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -7052,7 +7052,9 @@ interface EmbedManyResult {
|
|
|
7052
7052
|
* @param abortSignal - An optional abort signal that can be used to cancel the call.
|
|
7053
7053
|
* @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
|
|
7054
7054
|
*
|
|
7055
|
-
* @param maxParallelCalls - Maximum number of concurrent requests
|
|
7055
|
+
* @param maxParallelCalls - Maximum number of concurrent requests when a request is split into
|
|
7056
|
+
* multiple model calls. Must be greater than 0 when the model supports parallel calls.
|
|
7057
|
+
* Default: Infinity.
|
|
7056
7058
|
*
|
|
7057
7059
|
* @param telemetry - Optional telemetry configuration.
|
|
7058
7060
|
* @param runtimeContext - User-defined runtime context passed to callbacks and, when explicitly included, telemetry.
|
|
@@ -7108,7 +7110,8 @@ declare function embedMany<RUNTIME_CONTEXT extends Context = Context>({ model: m
|
|
|
7108
7110
|
*/
|
|
7109
7111
|
providerOptions?: ProviderOptions;
|
|
7110
7112
|
/**
|
|
7111
|
-
* Maximum number of concurrent requests.
|
|
7113
|
+
* Maximum number of concurrent requests when a request is split into multiple model calls.
|
|
7114
|
+
* Must be greater than 0 when the model supports parallel calls.
|
|
7112
7115
|
*
|
|
7113
7116
|
* @default Infinity
|
|
7114
7117
|
*/
|
|
@@ -7516,9 +7519,11 @@ declare class UnsupportedModelVersionError extends AISDKError {
|
|
|
7516
7519
|
|
|
7517
7520
|
declare const symbol$5: unique symbol;
|
|
7518
7521
|
/**
|
|
7519
|
-
* Error thrown when a UI message stream
|
|
7522
|
+
* Error thrown when a UI message stream reports an error or contains invalid
|
|
7523
|
+
* or out-of-sequence chunks.
|
|
7520
7524
|
*
|
|
7521
7525
|
* This typically occurs when:
|
|
7526
|
+
* - An error chunk is received
|
|
7522
7527
|
* - A delta chunk is received without a corresponding start chunk
|
|
7523
7528
|
* - An end chunk is received without a corresponding start chunk
|
|
7524
7529
|
* - A tool invocation is not found for the given toolCallId
|
|
@@ -7532,7 +7537,8 @@ declare class UIMessageStreamError extends AISDKError {
|
|
|
7532
7537
|
*/
|
|
7533
7538
|
readonly chunkType: string;
|
|
7534
7539
|
/**
|
|
7535
|
-
* The ID associated with the failing chunk (part ID or toolCallId)
|
|
7540
|
+
* The ID associated with the failing chunk (part ID or toolCallId), or an
|
|
7541
|
+
* empty string when the chunk does not have an ID.
|
|
7536
7542
|
*/
|
|
7537
7543
|
readonly chunkId: string;
|
|
7538
7544
|
constructor({ chunkType, chunkId, message, }: {
|
|
@@ -7887,6 +7893,8 @@ declare function createDownload(options?: {
|
|
|
7887
7893
|
|
|
7888
7894
|
/**
|
|
7889
7895
|
* Converts a data URL of type text/* to a text string.
|
|
7896
|
+
*
|
|
7897
|
+
* @throws {InvalidArgumentError} If the data URL is malformed or cannot be decoded.
|
|
7890
7898
|
*/
|
|
7891
7899
|
declare function getTextFromDataUrl(dataUrl: string): string;
|
|
7892
7900
|
|
package/dist/index.js
CHANGED
|
@@ -1178,7 +1178,7 @@ import {
|
|
|
1178
1178
|
} from "@ai-sdk/provider-utils";
|
|
1179
1179
|
|
|
1180
1180
|
// src/version.ts
|
|
1181
|
-
var VERSION = true ? "7.0.
|
|
1181
|
+
var VERSION = true ? "7.0.100" : "0.0.0-test";
|
|
1182
1182
|
|
|
1183
1183
|
// src/util/download/download.ts
|
|
1184
1184
|
var download = async ({
|
|
@@ -13639,7 +13639,11 @@ function getEmbeddingModelMaxInputBytesPerCall(model) {
|
|
|
13639
13639
|
// src/util/split-array.ts
|
|
13640
13640
|
function splitArray(array3, chunkSize) {
|
|
13641
13641
|
if (chunkSize <= 0) {
|
|
13642
|
-
throw new
|
|
13642
|
+
throw new InvalidArgumentError({
|
|
13643
|
+
parameter: "chunkSize",
|
|
13644
|
+
value: chunkSize,
|
|
13645
|
+
message: "chunkSize must be greater than 0"
|
|
13646
|
+
});
|
|
13643
13647
|
}
|
|
13644
13648
|
const result = [];
|
|
13645
13649
|
for (let i = 0; i < array3.length; i += chunkSize) {
|
|
@@ -14737,12 +14741,20 @@ function getTextFromDataUrl(dataUrl) {
|
|
|
14737
14741
|
const [header, base64Content] = dataUrl.split(",");
|
|
14738
14742
|
const mediaType = header.split(";")[0].split(":")[1];
|
|
14739
14743
|
if (mediaType == null || base64Content == null) {
|
|
14740
|
-
throw new
|
|
14744
|
+
throw new InvalidArgumentError({
|
|
14745
|
+
parameter: "dataUrl",
|
|
14746
|
+
value: dataUrl,
|
|
14747
|
+
message: "Invalid data URL format"
|
|
14748
|
+
});
|
|
14741
14749
|
}
|
|
14742
14750
|
try {
|
|
14743
14751
|
return atob2(base64Content);
|
|
14744
14752
|
} catch (e) {
|
|
14745
|
-
throw new
|
|
14753
|
+
throw new InvalidArgumentError({
|
|
14754
|
+
parameter: "dataUrl",
|
|
14755
|
+
value: dataUrl,
|
|
14756
|
+
message: "Error decoding data URL"
|
|
14757
|
+
});
|
|
14746
14758
|
}
|
|
14747
14759
|
}
|
|
14748
14760
|
|
|
@@ -18962,6 +18974,26 @@ import {
|
|
|
18962
18974
|
withUserAgentSuffix as withUserAgentSuffix16,
|
|
18963
18975
|
getRuntimeEnvironmentUserAgent as getRuntimeEnvironmentUserAgent2
|
|
18964
18976
|
} from "@ai-sdk/provider-utils";
|
|
18977
|
+
import { EmptyResponseBodyError as EmptyResponseBodyError2 } from "@ai-sdk/provider";
|
|
18978
|
+
|
|
18979
|
+
// src/ui/create-ui-api-call-error.ts
|
|
18980
|
+
import { APICallError as APICallError3 } from "@ai-sdk/provider";
|
|
18981
|
+
async function createUIApiCallError({
|
|
18982
|
+
response,
|
|
18983
|
+
url,
|
|
18984
|
+
fallbackMessage
|
|
18985
|
+
}) {
|
|
18986
|
+
const responseBody = await response.text();
|
|
18987
|
+
return new APICallError3({
|
|
18988
|
+
message: responseBody || fallbackMessage,
|
|
18989
|
+
url,
|
|
18990
|
+
// UI requests can contain prompts, messages, and other sensitive values.
|
|
18991
|
+
// Keep them out of client-facing error objects.
|
|
18992
|
+
requestBodyValues: void 0,
|
|
18993
|
+
statusCode: response.status,
|
|
18994
|
+
responseBody
|
|
18995
|
+
});
|
|
18996
|
+
}
|
|
18965
18997
|
|
|
18966
18998
|
// src/ui/process-text-stream.ts
|
|
18967
18999
|
async function processTextStream({
|
|
@@ -19021,12 +19053,16 @@ async function callCompletionApi({
|
|
|
19021
19053
|
throw err;
|
|
19022
19054
|
});
|
|
19023
19055
|
if (!response.ok) {
|
|
19024
|
-
throw
|
|
19025
|
-
|
|
19026
|
-
|
|
19056
|
+
throw await createUIApiCallError({
|
|
19057
|
+
response,
|
|
19058
|
+
url: api,
|
|
19059
|
+
fallbackMessage: "Failed to fetch the chat response."
|
|
19060
|
+
});
|
|
19027
19061
|
}
|
|
19028
19062
|
if (!response.body) {
|
|
19029
|
-
throw new
|
|
19063
|
+
throw new EmptyResponseBodyError2({
|
|
19064
|
+
message: "The response body is empty."
|
|
19065
|
+
});
|
|
19030
19066
|
}
|
|
19031
19067
|
let result = "";
|
|
19032
19068
|
switch (streamProtocol) {
|
|
@@ -19056,7 +19092,11 @@ async function callCompletionApi({
|
|
|
19056
19092
|
result += streamPart.delta;
|
|
19057
19093
|
setCompletion(result);
|
|
19058
19094
|
} else if (streamPart.type === "error") {
|
|
19059
|
-
throw new
|
|
19095
|
+
throw new UIMessageStreamError({
|
|
19096
|
+
chunkType: "error",
|
|
19097
|
+
chunkId: "",
|
|
19098
|
+
message: streamPart.errorText
|
|
19099
|
+
});
|
|
19060
19100
|
}
|
|
19061
19101
|
}
|
|
19062
19102
|
})
|
|
@@ -19069,7 +19109,11 @@ async function callCompletionApi({
|
|
|
19069
19109
|
}
|
|
19070
19110
|
default: {
|
|
19071
19111
|
const exhaustiveCheck = streamProtocol;
|
|
19072
|
-
throw new
|
|
19112
|
+
throw new InvalidArgumentError({
|
|
19113
|
+
parameter: "streamProtocol",
|
|
19114
|
+
value: exhaustiveCheck,
|
|
19115
|
+
message: `Unknown stream protocol: ${exhaustiveCheck}`
|
|
19116
|
+
});
|
|
19073
19117
|
}
|
|
19074
19118
|
}
|
|
19075
19119
|
if (onFinish) {
|
|
@@ -19099,12 +19143,16 @@ import {
|
|
|
19099
19143
|
} from "@ai-sdk/provider-utils";
|
|
19100
19144
|
|
|
19101
19145
|
// src/ui/convert-file-list-to-file-ui-parts.ts
|
|
19146
|
+
import { UnsupportedFunctionalityError as UnsupportedFunctionalityError6 } from "@ai-sdk/provider";
|
|
19102
19147
|
async function convertFileListToFileUIParts(files) {
|
|
19103
19148
|
if (files == null) {
|
|
19104
19149
|
return [];
|
|
19105
19150
|
}
|
|
19106
19151
|
if (!globalThis.FileList || !(files instanceof globalThis.FileList)) {
|
|
19107
|
-
throw new
|
|
19152
|
+
throw new UnsupportedFunctionalityError6({
|
|
19153
|
+
functionality: "FileList",
|
|
19154
|
+
message: "FileList is not supported in the current environment"
|
|
19155
|
+
});
|
|
19108
19156
|
}
|
|
19109
19157
|
return Promise.all(
|
|
19110
19158
|
Array.from(files).map(async (file) => {
|
|
@@ -19136,6 +19184,7 @@ import {
|
|
|
19136
19184
|
normalizeHeaders,
|
|
19137
19185
|
resolve as resolve2
|
|
19138
19186
|
} from "@ai-sdk/provider-utils";
|
|
19187
|
+
import { EmptyResponseBodyError as EmptyResponseBodyError3 } from "@ai-sdk/provider";
|
|
19139
19188
|
var HttpChatTransport = class {
|
|
19140
19189
|
constructor({
|
|
19141
19190
|
api = "/api/chat",
|
|
@@ -19200,12 +19249,16 @@ var HttpChatTransport = class {
|
|
|
19200
19249
|
signal: abortSignal
|
|
19201
19250
|
});
|
|
19202
19251
|
if (!response.ok) {
|
|
19203
|
-
throw
|
|
19204
|
-
|
|
19205
|
-
|
|
19252
|
+
throw await createUIApiCallError({
|
|
19253
|
+
response,
|
|
19254
|
+
url: api,
|
|
19255
|
+
fallbackMessage: "Failed to fetch the chat response."
|
|
19256
|
+
});
|
|
19206
19257
|
}
|
|
19207
19258
|
if (!response.body) {
|
|
19208
|
-
throw new
|
|
19259
|
+
throw new EmptyResponseBodyError3({
|
|
19260
|
+
message: "The response body is empty."
|
|
19261
|
+
});
|
|
19209
19262
|
}
|
|
19210
19263
|
return this.processResponseStream(response.body);
|
|
19211
19264
|
}
|
|
@@ -19240,12 +19293,16 @@ var HttpChatTransport = class {
|
|
|
19240
19293
|
return null;
|
|
19241
19294
|
}
|
|
19242
19295
|
if (!response.ok) {
|
|
19243
|
-
throw
|
|
19244
|
-
|
|
19245
|
-
|
|
19296
|
+
throw await createUIApiCallError({
|
|
19297
|
+
response,
|
|
19298
|
+
url: api,
|
|
19299
|
+
fallbackMessage: "Failed to fetch the chat response."
|
|
19300
|
+
});
|
|
19246
19301
|
}
|
|
19247
19302
|
if (!response.body) {
|
|
19248
|
-
throw new
|
|
19303
|
+
throw new EmptyResponseBodyError3({
|
|
19304
|
+
message: "The response body is empty."
|
|
19305
|
+
});
|
|
19249
19306
|
}
|
|
19250
19307
|
return this.processResponseStream(response.body);
|
|
19251
19308
|
}
|
|
@@ -19335,12 +19392,18 @@ var AbstractChat = class {
|
|
|
19335
19392
|
(m) => m.id === message.messageId
|
|
19336
19393
|
);
|
|
19337
19394
|
if (messageIndex === -1) {
|
|
19338
|
-
throw new
|
|
19395
|
+
throw new InvalidArgumentError({
|
|
19396
|
+
parameter: "message.messageId",
|
|
19397
|
+
value: message.messageId,
|
|
19398
|
+
message: `message with id ${message.messageId} not found`
|
|
19399
|
+
});
|
|
19339
19400
|
}
|
|
19340
19401
|
if (this.state.messages[messageIndex].role !== "user") {
|
|
19341
|
-
throw new
|
|
19342
|
-
|
|
19343
|
-
|
|
19402
|
+
throw new InvalidArgumentError({
|
|
19403
|
+
parameter: "message.messageId",
|
|
19404
|
+
value: message.messageId,
|
|
19405
|
+
message: `message with id ${message.messageId} is not a user message`
|
|
19406
|
+
});
|
|
19344
19407
|
}
|
|
19345
19408
|
this.state.messages = this.state.messages.slice(0, messageIndex + 1);
|
|
19346
19409
|
this.state.replaceMessage(messageIndex, {
|
|
@@ -19373,7 +19436,11 @@ var AbstractChat = class {
|
|
|
19373
19436
|
} = {}) => {
|
|
19374
19437
|
const messageIndex = messageId == null ? this.state.messages.length - 1 : this.state.messages.findIndex((message) => message.id === messageId);
|
|
19375
19438
|
if (messageIndex === -1) {
|
|
19376
|
-
throw new
|
|
19439
|
+
throw new InvalidArgumentError({
|
|
19440
|
+
parameter: "messageId",
|
|
19441
|
+
value: messageId,
|
|
19442
|
+
message: `message ${messageId} not found`
|
|
19443
|
+
});
|
|
19377
19444
|
}
|
|
19378
19445
|
this.state.messages = this.state.messages.slice(
|
|
19379
19446
|
0,
|