ai 7.0.151 → 7.0.153
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 +18 -0
- package/dist/index.js +42 -25
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +1 -1
- package/package.json +12 -12
- package/src/generate-object/generate-object.ts +1 -1
- package/src/generate-text/generate-text.ts +7 -1
- package/src/middleware/extract-json-middleware.ts +8 -2
- package/src/middleware/extract-reasoning-middleware.ts +42 -30
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# ai
|
|
2
2
|
|
|
3
|
+
## 7.0.153
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5475347: Fix non-streaming Responses API structured output failing when multiple assistant messages contain JSON. Providers can supply separate structured-output text for parsing, allowing OpenAI and Azure Responses models to select the last `final_answer` while preserving all generated content, annotations, conversation history, and token usage.
|
|
8
|
+
- Updated dependencies [5475347]
|
|
9
|
+
- Updated dependencies [e729d58]
|
|
10
|
+
- @ai-sdk/provider@4.0.34
|
|
11
|
+
- @ai-sdk/provider-utils@5.0.68
|
|
12
|
+
- @ai-sdk/gateway@4.0.126
|
|
13
|
+
|
|
14
|
+
## 7.0.152
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [a706678]
|
|
19
|
+
- @ai-sdk/gateway@4.0.125
|
|
20
|
+
|
|
3
21
|
## 7.0.151
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1175,7 +1175,7 @@ function cloneValue(value) {
|
|
|
1175
1175
|
}
|
|
1176
1176
|
//#endregion
|
|
1177
1177
|
//#region src/version.ts
|
|
1178
|
-
const VERSION = "7.0.
|
|
1178
|
+
const VERSION = "7.0.153";
|
|
1179
1179
|
//#endregion
|
|
1180
1180
|
//#region src/util/download/download.ts
|
|
1181
1181
|
/**
|
|
@@ -6012,11 +6012,15 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
|
|
|
6012
6012
|
callbacks: [onEnd, telemetryDispatcher.onEnd]
|
|
6013
6013
|
});
|
|
6014
6014
|
let resolvedOutput;
|
|
6015
|
-
if (lastStep.finishReason === "stop" || lastStep.finishReason !== "tool-calls" && lastStep.text.length > 0)
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6015
|
+
if (lastStep.finishReason === "stop" || lastStep.finishReason !== "tool-calls" && lastStep.text.length > 0) {
|
|
6016
|
+
const outputSpecification = output ?? text();
|
|
6017
|
+
const textForOutput = (await outputSpecification.responseFormat)?.type === "json" ? currentModelResponse.structuredOutputText ?? lastStep.text : lastStep.text;
|
|
6018
|
+
resolvedOutput = await outputSpecification.parseCompleteOutput({ text: textForOutput }, {
|
|
6019
|
+
response: lastStep.response,
|
|
6020
|
+
usage: lastStep.usage,
|
|
6021
|
+
finishReason: lastStep.finishReason
|
|
6022
|
+
});
|
|
6023
|
+
}
|
|
6020
6024
|
return new DefaultGenerateTextResult({
|
|
6021
6025
|
initialResponseMessages,
|
|
6022
6026
|
steps,
|
|
@@ -13911,7 +13915,7 @@ async function generateObject(options) {
|
|
|
13911
13915
|
},
|
|
13912
13916
|
callbacks: [resolvedOnStepEnd, telemetryDispatcher.onObjectStepEnd]
|
|
13913
13917
|
});
|
|
13914
|
-
const object = await parseAndValidateObjectResultWithRepair(text, outputStrategy, repairText, {
|
|
13918
|
+
const object = await parseAndValidateObjectResultWithRepair(generateResult.structuredOutputText ?? text, outputStrategy, repairText, {
|
|
13915
13919
|
response,
|
|
13916
13920
|
usage,
|
|
13917
13921
|
finishReason
|
|
@@ -15937,7 +15941,7 @@ function extractJsonMiddleware(options) {
|
|
|
15937
15941
|
return {
|
|
15938
15942
|
specificationVersion: "v4",
|
|
15939
15943
|
wrapGenerate: async ({ doGenerate }) => {
|
|
15940
|
-
const { content, ...rest } = await doGenerate();
|
|
15944
|
+
const { content, structuredOutputText, ...rest } = await doGenerate();
|
|
15941
15945
|
const transformedContent = [];
|
|
15942
15946
|
for (const part of content) {
|
|
15943
15947
|
if (part.type !== "text") {
|
|
@@ -15951,7 +15955,8 @@ function extractJsonMiddleware(options) {
|
|
|
15951
15955
|
}
|
|
15952
15956
|
return {
|
|
15953
15957
|
content: transformedContent,
|
|
15954
|
-
...rest
|
|
15958
|
+
...rest,
|
|
15959
|
+
...structuredOutputText != null && { structuredOutputText: transform(structuredOutputText) }
|
|
15955
15960
|
};
|
|
15956
15961
|
},
|
|
15957
15962
|
wrapStream: async ({ doStream }) => {
|
|
@@ -16083,43 +16088,55 @@ function extractReasoningMiddleware({ tagName, separator = "\n", startWithReason
|
|
|
16083
16088
|
});
|
|
16084
16089
|
const escapedOpeningTag = openingTag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16085
16090
|
const escapedClosingTag = closingTag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16091
|
+
function extractReasoning(input) {
|
|
16092
|
+
const text = startWithReasoning ? openingTag + input : input;
|
|
16093
|
+
const regexp = new RegExp(`${escapedOpeningTag}(.*?)${escapedClosingTag}`, "gs");
|
|
16094
|
+
const matches = Array.from(text.matchAll(regexp));
|
|
16095
|
+
if (!matches.length) return {
|
|
16096
|
+
text: input,
|
|
16097
|
+
reasoning: void 0
|
|
16098
|
+
};
|
|
16099
|
+
const reasoning = matches.map((match) => match[1]).join(separator);
|
|
16100
|
+
let textWithoutReasoning = text;
|
|
16101
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
16102
|
+
const match = matches[i];
|
|
16103
|
+
const beforeMatch = textWithoutReasoning.slice(0, match.index);
|
|
16104
|
+
const afterMatch = textWithoutReasoning.slice(match.index + match[0].length);
|
|
16105
|
+
textWithoutReasoning = beforeMatch + (beforeMatch.length > 0 && afterMatch.length > 0 ? separator : "") + afterMatch;
|
|
16106
|
+
}
|
|
16107
|
+
return {
|
|
16108
|
+
text: textWithoutReasoning,
|
|
16109
|
+
reasoning
|
|
16110
|
+
};
|
|
16111
|
+
}
|
|
16086
16112
|
return {
|
|
16087
16113
|
specificationVersion: "v4",
|
|
16088
16114
|
wrapGenerate: async ({ doGenerate }) => {
|
|
16089
|
-
const { content, ...rest } = await doGenerate();
|
|
16115
|
+
const { content, structuredOutputText, ...rest } = await doGenerate();
|
|
16090
16116
|
const transformedContent = [];
|
|
16091
16117
|
for (const part of content) {
|
|
16092
16118
|
if (part.type !== "text") {
|
|
16093
16119
|
transformedContent.push(part);
|
|
16094
16120
|
continue;
|
|
16095
16121
|
}
|
|
16096
|
-
const text
|
|
16097
|
-
|
|
16098
|
-
const matches = Array.from(text.matchAll(regexp));
|
|
16099
|
-
if (!matches.length) {
|
|
16122
|
+
const { text, reasoning } = extractReasoning(part.text);
|
|
16123
|
+
if (reasoning === void 0) {
|
|
16100
16124
|
transformedContent.push(part);
|
|
16101
16125
|
continue;
|
|
16102
16126
|
}
|
|
16103
|
-
const reasoningText = matches.map((match) => match[1]).join(separator);
|
|
16104
|
-
let textWithoutReasoning = text;
|
|
16105
|
-
for (let i = matches.length - 1; i >= 0; i--) {
|
|
16106
|
-
const match = matches[i];
|
|
16107
|
-
const beforeMatch = textWithoutReasoning.slice(0, match.index);
|
|
16108
|
-
const afterMatch = textWithoutReasoning.slice(match.index + match[0].length);
|
|
16109
|
-
textWithoutReasoning = beforeMatch + (beforeMatch.length > 0 && afterMatch.length > 0 ? separator : "") + afterMatch;
|
|
16110
|
-
}
|
|
16111
16127
|
transformedContent.push({
|
|
16112
16128
|
type: "reasoning",
|
|
16113
|
-
text:
|
|
16129
|
+
text: reasoning
|
|
16114
16130
|
});
|
|
16115
16131
|
transformedContent.push({
|
|
16116
16132
|
type: "text",
|
|
16117
|
-
text
|
|
16133
|
+
text
|
|
16118
16134
|
});
|
|
16119
16135
|
}
|
|
16120
16136
|
return {
|
|
16121
16137
|
content: transformedContent,
|
|
16122
|
-
...rest
|
|
16138
|
+
...rest,
|
|
16139
|
+
...structuredOutputText != null && { structuredOutputText: extractReasoning(structuredOutputText).text }
|
|
16123
16140
|
};
|
|
16124
16141
|
},
|
|
16125
16142
|
wrapStream: async ({ doStream }) => {
|