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.
@@ -111,7 +111,7 @@ function asAsyncIterableStream(stream) {
111
111
  }
112
112
  //#endregion
113
113
  //#region src/version.ts
114
- const VERSION = "7.0.151";
114
+ const VERSION = "7.0.153";
115
115
  //#endregion
116
116
  //#region src/util/download/download.ts
117
117
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "7.0.151",
3
+ "version": "7.0.153",
4
4
  "type": "module",
5
5
  "description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
6
6
  "license": "Apache-2.0",
@@ -42,20 +42,20 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "@ai-sdk/gateway": "4.0.124",
46
- "@ai-sdk/provider": "4.0.33",
47
- "@ai-sdk/provider-utils": "5.0.67"
45
+ "@ai-sdk/gateway": "4.0.126",
46
+ "@ai-sdk/provider": "4.0.34",
47
+ "@ai-sdk/provider-utils": "5.0.68"
48
48
  },
49
49
  "devDependencies": {
50
- "@ai-sdk/amazon-bedrock": "5.0.123",
51
- "@ai-sdk/deepseek": "3.0.72",
52
- "@ai-sdk/google": "4.0.104",
53
- "@ai-sdk/groq": "4.0.69",
54
- "@ai-sdk/huggingface": "2.0.77",
55
- "@ai-sdk/moonshotai": "3.0.76",
56
- "@ai-sdk/openai": "4.0.101",
50
+ "@ai-sdk/amazon-bedrock": "5.0.124",
51
+ "@ai-sdk/deepseek": "3.0.73",
52
+ "@ai-sdk/google": "4.0.105",
53
+ "@ai-sdk/groq": "4.0.70",
54
+ "@ai-sdk/huggingface": "2.0.78",
55
+ "@ai-sdk/moonshotai": "3.0.78",
56
+ "@ai-sdk/openai": "4.0.102",
57
57
  "@ai-sdk/test-server": "2.0.4",
58
- "@ai-sdk/xai": "5.0.29",
58
+ "@ai-sdk/xai": "5.0.30",
59
59
  "@edge-runtime/vm": "^5.0.0",
60
60
  "@smithy/eventstream-codec": "^4.3.3",
61
61
  "@smithy/util-utf8": "^4.3.3",
@@ -479,7 +479,7 @@ export async function generateObject<
479
479
  });
480
480
 
481
481
  const object = await parseAndValidateObjectResultWithRepair(
482
- text,
482
+ generateResult.structuredOutputText ?? text,
483
483
  outputStrategy,
484
484
  repairText,
485
485
  {
@@ -1631,8 +1631,14 @@ export async function generateText<
1631
1631
  (lastStep.finishReason !== 'tool-calls' && lastStep.text.length > 0)
1632
1632
  ) {
1633
1633
  const outputSpecification = output ?? text();
1634
+ // Select the structured output without changing the complete response
1635
+ // content, text, or messages exposed to callers.
1636
+ const textForOutput =
1637
+ (await outputSpecification.responseFormat)?.type === 'json'
1638
+ ? (currentModelResponse!.structuredOutputText ?? lastStep.text)
1639
+ : lastStep.text;
1634
1640
  resolvedOutput = await outputSpecification.parseCompleteOutput(
1635
- { text: lastStep.text },
1641
+ { text: textForOutput },
1636
1642
  {
1637
1643
  response: lastStep.response,
1638
1644
  usage: lastStep.usage,
@@ -67,7 +67,7 @@ export function extractJsonMiddleware(options?: {
67
67
  specificationVersion: 'v4',
68
68
 
69
69
  wrapGenerate: async ({ doGenerate }) => {
70
- const { content, ...rest } = await doGenerate();
70
+ const { content, structuredOutputText, ...rest } = await doGenerate();
71
71
 
72
72
  const transformedContent: LanguageModelV4Content[] = [];
73
73
  for (const part of content) {
@@ -82,7 +82,13 @@ export function extractJsonMiddleware(options?: {
82
82
  });
83
83
  }
84
84
 
85
- return { content: transformedContent, ...rest };
85
+ return {
86
+ content: transformedContent,
87
+ ...rest,
88
+ ...(structuredOutputText != null && {
89
+ structuredOutputText: transform(structuredOutputText),
90
+ }),
91
+ };
86
92
  },
87
93
  wrapStream: async ({ doStream }) => {
88
94
  const { stream, ...rest } = await doStream();
@@ -42,10 +42,40 @@ export function extractReasoningMiddleware({
42
42
  const escapedOpeningTag = openingTag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
43
43
  const escapedClosingTag = closingTag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
44
44
 
45
+ function extractReasoning(input: string) {
46
+ const text = startWithReasoning ? openingTag + input : input;
47
+ const regexp = new RegExp(
48
+ `${escapedOpeningTag}(.*?)${escapedClosingTag}`,
49
+ 'gs',
50
+ );
51
+ const matches = Array.from(text.matchAll(regexp));
52
+
53
+ if (!matches.length) {
54
+ return { text: input, reasoning: undefined };
55
+ }
56
+
57
+ const reasoning = matches.map(match => match[1]).join(separator);
58
+ let textWithoutReasoning = text;
59
+ for (let i = matches.length - 1; i >= 0; i--) {
60
+ const match = matches[i];
61
+ const beforeMatch = textWithoutReasoning.slice(0, match.index);
62
+ const afterMatch = textWithoutReasoning.slice(
63
+ match.index! + match[0].length,
64
+ );
65
+
66
+ textWithoutReasoning =
67
+ beforeMatch +
68
+ (beforeMatch.length > 0 && afterMatch.length > 0 ? separator : '') +
69
+ afterMatch;
70
+ }
71
+
72
+ return { text: textWithoutReasoning, reasoning };
73
+ }
74
+
45
75
  return {
46
76
  specificationVersion: 'v4',
47
77
  wrapGenerate: async ({ doGenerate }) => {
48
- const { content, ...rest } = await doGenerate();
78
+ const { content, structuredOutputText, ...rest } = await doGenerate();
49
79
 
50
80
  const transformedContent: LanguageModelV4Content[] = [];
51
81
  for (const part of content) {
@@ -54,48 +84,30 @@ export function extractReasoningMiddleware({
54
84
  continue;
55
85
  }
56
86
 
57
- const text = startWithReasoning ? openingTag + part.text : part.text;
58
-
59
- const regexp = new RegExp(
60
- `${escapedOpeningTag}(.*?)${escapedClosingTag}`,
61
- 'gs',
62
- );
63
- const matches = Array.from(text.matchAll(regexp));
64
-
65
- if (!matches.length) {
87
+ const { text, reasoning } = extractReasoning(part.text);
88
+ if (reasoning === undefined) {
66
89
  transformedContent.push(part);
67
90
  continue;
68
91
  }
69
92
 
70
- const reasoningText = matches.map(match => match[1]).join(separator);
71
-
72
- let textWithoutReasoning = text;
73
- for (let i = matches.length - 1; i >= 0; i--) {
74
- const match = matches[i];
75
-
76
- const beforeMatch = textWithoutReasoning.slice(0, match.index);
77
- const afterMatch = textWithoutReasoning.slice(
78
- match.index! + match[0].length,
79
- );
80
-
81
- textWithoutReasoning =
82
- beforeMatch +
83
- (beforeMatch.length > 0 && afterMatch.length > 0 ? separator : '') +
84
- afterMatch;
85
- }
86
-
87
93
  transformedContent.push({
88
94
  type: 'reasoning',
89
- text: reasoningText,
95
+ text: reasoning,
90
96
  });
91
97
 
92
98
  transformedContent.push({
93
99
  type: 'text',
94
- text: textWithoutReasoning,
100
+ text,
95
101
  });
96
102
  }
97
103
 
98
- return { content: transformedContent, ...rest };
104
+ return {
105
+ content: transformedContent,
106
+ ...rest,
107
+ ...(structuredOutputText != null && {
108
+ structuredOutputText: extractReasoning(structuredOutputText).text,
109
+ }),
110
+ };
99
111
  },
100
112
 
101
113
  wrapStream: async ({ doStream }) => {