ai 6.0.199 → 6.0.201
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 +15 -0
- package/dist/index.js +80 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -11
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.mjs +1 -1
- package/docs/04-ai-sdk-ui/01-overview.mdx +1 -1
- package/package.json +1 -1
- package/src/generate-object/output-strategy.ts +3 -1
- package/src/generate-text/stream-text.ts +88 -5
- package/src/ui/process-ui-message-stream.ts +6 -5
- package/src/util/create-id-map.ts +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# ai
|
|
2
2
|
|
|
3
|
+
## 6.0.201
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0c8c0ed: fix(ai): return schema-transformed elements in array output mode
|
|
8
|
+
|
|
9
|
+
Previously final array output validation checked each element against the schema but returned the raw model output. Array output now returns the validated values so Zod transforms, coercions, defaults, and pipes are applied consistently with object output.
|
|
10
|
+
|
|
11
|
+
## 6.0.200
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 14098e7: fix(ai): reject `streamText` result promises with `NoOutputGeneratedError` when the model stream ends without producing any output. Previously such streams resolved with an empty step. Incomplete streams with partial output still resolve with the partial result.
|
|
16
|
+
- 2cabe9c: Harden UI message stream processing against prototype pollution from chunk IDs.
|
|
17
|
+
|
|
3
18
|
## 6.0.199
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1254,7 +1254,7 @@ function detectMediaType({
|
|
|
1254
1254
|
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
1255
1255
|
|
|
1256
1256
|
// src/version.ts
|
|
1257
|
-
var VERSION = true ? "6.0.
|
|
1257
|
+
var VERSION = true ? "6.0.201" : "0.0.0-test";
|
|
1258
1258
|
|
|
1259
1259
|
// src/util/download/download.ts
|
|
1260
1260
|
var download = async ({
|
|
@@ -5405,6 +5405,11 @@ function isDataUIMessageChunk(chunk) {
|
|
|
5405
5405
|
return chunk.type.startsWith("data-");
|
|
5406
5406
|
}
|
|
5407
5407
|
|
|
5408
|
+
// src/util/create-id-map.ts
|
|
5409
|
+
function createIdMap() {
|
|
5410
|
+
return /* @__PURE__ */ Object.create(null);
|
|
5411
|
+
}
|
|
5412
|
+
|
|
5408
5413
|
// src/ui/ui-messages.ts
|
|
5409
5414
|
function isDataUIPart(part) {
|
|
5410
5415
|
return part.type.startsWith("data-");
|
|
@@ -5448,9 +5453,9 @@ function createStreamingUIMessageState({
|
|
|
5448
5453
|
role: "assistant",
|
|
5449
5454
|
parts: []
|
|
5450
5455
|
},
|
|
5451
|
-
activeTextParts:
|
|
5452
|
-
activeReasoningParts:
|
|
5453
|
-
partialToolCalls:
|
|
5456
|
+
activeTextParts: createIdMap(),
|
|
5457
|
+
activeReasoningParts: createIdMap(),
|
|
5458
|
+
partialToolCalls: createIdMap()
|
|
5454
5459
|
};
|
|
5455
5460
|
}
|
|
5456
5461
|
function processUIMessageStream({
|
|
@@ -5924,8 +5929,8 @@ function processUIMessageStream({
|
|
|
5924
5929
|
break;
|
|
5925
5930
|
}
|
|
5926
5931
|
case "finish-step": {
|
|
5927
|
-
state.activeTextParts =
|
|
5928
|
-
state.activeReasoningParts =
|
|
5932
|
+
state.activeTextParts = createIdMap();
|
|
5933
|
+
state.activeReasoningParts = createIdMap();
|
|
5929
5934
|
break;
|
|
5930
5935
|
}
|
|
5931
5936
|
case "start": {
|
|
@@ -6564,6 +6569,28 @@ var originalGenerateId2 = (0, import_provider_utils18.createIdGenerator)({
|
|
|
6564
6569
|
prefix: "aitxt",
|
|
6565
6570
|
size: 24
|
|
6566
6571
|
});
|
|
6572
|
+
var isOutputChunkType = {
|
|
6573
|
+
file: true,
|
|
6574
|
+
source: true,
|
|
6575
|
+
"text-start": true,
|
|
6576
|
+
"text-end": true,
|
|
6577
|
+
"text-delta": true,
|
|
6578
|
+
"reasoning-start": true,
|
|
6579
|
+
"reasoning-end": true,
|
|
6580
|
+
"reasoning-delta": true,
|
|
6581
|
+
"tool-input-start": true,
|
|
6582
|
+
"tool-input-end": true,
|
|
6583
|
+
"tool-input-delta": true,
|
|
6584
|
+
"tool-approval-request": true,
|
|
6585
|
+
"tool-call": true,
|
|
6586
|
+
"tool-result": true,
|
|
6587
|
+
"tool-error": true,
|
|
6588
|
+
"stream-start": false,
|
|
6589
|
+
"response-metadata": false,
|
|
6590
|
+
finish: false,
|
|
6591
|
+
error: false,
|
|
6592
|
+
raw: false
|
|
6593
|
+
};
|
|
6567
6594
|
function streamText({
|
|
6568
6595
|
model,
|
|
6569
6596
|
tools,
|
|
@@ -6782,6 +6809,7 @@ var DefaultStreamTextResult = class {
|
|
|
6782
6809
|
let recordedRequest = {};
|
|
6783
6810
|
let recordedWarnings = [];
|
|
6784
6811
|
const recordedSteps = [];
|
|
6812
|
+
let recordedNoOutputError;
|
|
6785
6813
|
const pendingDeferredToolCalls = /* @__PURE__ */ new Map();
|
|
6786
6814
|
let rootSpan;
|
|
6787
6815
|
let activeTextContent = {};
|
|
@@ -6795,7 +6823,11 @@ var DefaultStreamTextResult = class {
|
|
|
6795
6823
|
await (onChunk == null ? void 0 : onChunk({ chunk: part }));
|
|
6796
6824
|
}
|
|
6797
6825
|
if (part.type === "error") {
|
|
6798
|
-
|
|
6826
|
+
const error = wrapGatewayError(part.error);
|
|
6827
|
+
if (NoOutputGeneratedError.isInstance(error)) {
|
|
6828
|
+
recordedNoOutputError = error;
|
|
6829
|
+
}
|
|
6830
|
+
await onError({ error });
|
|
6799
6831
|
}
|
|
6800
6832
|
if (part.type === "text-start") {
|
|
6801
6833
|
activeTextContent[part.id] = {
|
|
@@ -6946,8 +6978,8 @@ var DefaultStreamTextResult = class {
|
|
|
6946
6978
|
async flush(controller) {
|
|
6947
6979
|
var _a21, _b, _c, _d, _e, _f, _g;
|
|
6948
6980
|
try {
|
|
6949
|
-
if (recordedSteps.length === 0) {
|
|
6950
|
-
const error = (abortSignal == null ? void 0 : abortSignal.aborted) ? abortSignal.reason : new NoOutputGeneratedError({
|
|
6981
|
+
if (recordedSteps.length === 0 || recordedNoOutputError != null) {
|
|
6982
|
+
const error = (abortSignal == null ? void 0 : abortSignal.aborted) ? abortSignal.reason : recordedNoOutputError != null ? recordedNoOutputError : new NoOutputGeneratedError({
|
|
6951
6983
|
message: "No output generated. Check the stream for errors."
|
|
6952
6984
|
});
|
|
6953
6985
|
self._finishReason.reject(error);
|
|
@@ -7446,6 +7478,8 @@ var DefaultStreamTextResult = class {
|
|
|
7446
7478
|
const activeToolCallToolNames = {};
|
|
7447
7479
|
let stepFinishReason = "other";
|
|
7448
7480
|
let stepRawFinishReason = void 0;
|
|
7481
|
+
let hasReceivedTerminalChunk = false;
|
|
7482
|
+
let hasReceivedOutputChunk = false;
|
|
7449
7483
|
let stepUsage = createNullLanguageModelUsage();
|
|
7450
7484
|
let stepProviderMetadata;
|
|
7451
7485
|
let stepFirstChunk = true;
|
|
@@ -7481,6 +7515,9 @@ var DefaultStreamTextResult = class {
|
|
|
7481
7515
|
});
|
|
7482
7516
|
}
|
|
7483
7517
|
const chunkType = chunk.type;
|
|
7518
|
+
if (isOutputChunkType[chunkType]) {
|
|
7519
|
+
hasReceivedOutputChunk = true;
|
|
7520
|
+
}
|
|
7484
7521
|
switch (chunkType) {
|
|
7485
7522
|
case "tool-approval-request":
|
|
7486
7523
|
case "text-start":
|
|
@@ -7540,6 +7577,7 @@ var DefaultStreamTextResult = class {
|
|
|
7540
7577
|
break;
|
|
7541
7578
|
}
|
|
7542
7579
|
case "finish": {
|
|
7580
|
+
hasReceivedTerminalChunk = true;
|
|
7543
7581
|
stepUsage = chunk.usage;
|
|
7544
7582
|
stepFinishReason = chunk.finishReason;
|
|
7545
7583
|
stepRawFinishReason = chunk.rawFinishReason;
|
|
@@ -7599,6 +7637,7 @@ var DefaultStreamTextResult = class {
|
|
|
7599
7637
|
break;
|
|
7600
7638
|
}
|
|
7601
7639
|
case "error": {
|
|
7640
|
+
hasReceivedTerminalChunk = true;
|
|
7602
7641
|
controller.enqueue(chunk);
|
|
7603
7642
|
stepFinishReason = "error";
|
|
7604
7643
|
break;
|
|
@@ -7620,6 +7659,19 @@ var DefaultStreamTextResult = class {
|
|
|
7620
7659
|
// invoke onFinish callback and resolve toolResults promise when the stream is about to close:
|
|
7621
7660
|
async flush(controller) {
|
|
7622
7661
|
var _a22, _b2, _c2, _d2, _e2, _f2, _g2;
|
|
7662
|
+
if (!hasReceivedTerminalChunk && !hasReceivedOutputChunk) {
|
|
7663
|
+
controller.enqueue({
|
|
7664
|
+
type: "error",
|
|
7665
|
+
error: new NoOutputGeneratedError({
|
|
7666
|
+
message: "No output generated. The model stream ended without a finish chunk."
|
|
7667
|
+
})
|
|
7668
|
+
});
|
|
7669
|
+
doStreamSpan.end();
|
|
7670
|
+
clearStepTimeout();
|
|
7671
|
+
clearChunkTimeout();
|
|
7672
|
+
self.closeStream();
|
|
7673
|
+
return;
|
|
7674
|
+
}
|
|
7623
7675
|
const stepToolCallsJson = stepToolCalls.length > 0 ? JSON.stringify(stepToolCalls) : void 0;
|
|
7624
7676
|
try {
|
|
7625
7677
|
doStreamSpan.setAttributes(
|
|
@@ -7897,14 +7949,29 @@ var DefaultStreamTextResult = class {
|
|
|
7897
7949
|
)
|
|
7898
7950
|
);
|
|
7899
7951
|
}
|
|
7952
|
+
rejectResultPromises(error) {
|
|
7953
|
+
if (this._finishReason.isPending())
|
|
7954
|
+
this._finishReason.reject(error);
|
|
7955
|
+
if (this._rawFinishReason.isPending())
|
|
7956
|
+
this._rawFinishReason.reject(error);
|
|
7957
|
+
if (this._totalUsage.isPending())
|
|
7958
|
+
this._totalUsage.reject(error);
|
|
7959
|
+
if (this._steps.isPending())
|
|
7960
|
+
this._steps.reject(error);
|
|
7961
|
+
}
|
|
7900
7962
|
async consumeStream(options) {
|
|
7901
7963
|
var _a21;
|
|
7902
7964
|
try {
|
|
7903
7965
|
await consumeStream({
|
|
7904
7966
|
stream: this.fullStream,
|
|
7905
|
-
onError:
|
|
7967
|
+
onError: (error) => {
|
|
7968
|
+
var _a22;
|
|
7969
|
+
this.rejectResultPromises(error);
|
|
7970
|
+
(_a22 = options == null ? void 0 : options.onError) == null ? void 0 : _a22.call(options, error);
|
|
7971
|
+
}
|
|
7906
7972
|
});
|
|
7907
7973
|
} catch (error) {
|
|
7974
|
+
this.rejectResultPromises(error);
|
|
7908
7975
|
(_a21 = options == null ? void 0 : options.onError) == null ? void 0 : _a21.call(options, error);
|
|
7909
7976
|
}
|
|
7910
7977
|
}
|
|
@@ -9960,13 +10027,15 @@ var arrayOutputStrategy = (schema) => {
|
|
|
9960
10027
|
};
|
|
9961
10028
|
}
|
|
9962
10029
|
const inputArray = value.elements;
|
|
10030
|
+
const resultArray = [];
|
|
9963
10031
|
for (const element of inputArray) {
|
|
9964
10032
|
const result = await (0, import_provider_utils26.safeValidateTypes)({ value: element, schema });
|
|
9965
10033
|
if (!result.success) {
|
|
9966
10034
|
return result;
|
|
9967
10035
|
}
|
|
10036
|
+
resultArray.push(result.value);
|
|
9968
10037
|
}
|
|
9969
|
-
return { success: true, value:
|
|
10038
|
+
return { success: true, value: resultArray };
|
|
9970
10039
|
},
|
|
9971
10040
|
createElementStream(originalStream) {
|
|
9972
10041
|
let publishedElements = 0;
|