ai 7.0.152 → 7.0.154

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/index.d.ts +224 -9
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +440 -120
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +52 -4
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +26 -20
  9. package/dist/internal/index.js.map +1 -1
  10. package/docs/02-getting-started/02-nextjs-app-router.mdx +2 -2
  11. package/docs/02-getting-started/08-angular.mdx +327 -0
  12. package/docs/02-getting-started/{03-nextjs-pages-router.mdx → 10-nextjs-pages-router.mdx} +12 -20
  13. package/docs/02-getting-started/index.mdx +2 -0
  14. package/docs/03-agents/01-overview.mdx +1 -0
  15. package/docs/03-agents/04-loop-control.mdx +117 -0
  16. package/docs/03-agents/06-tool-approvals.mdx +1 -0
  17. package/docs/03-agents/09-chat-platforms.mdx +164 -0
  18. package/docs/03-agents/index.mdx +6 -0
  19. package/docs/03-ai-sdk-core/60-telemetry.mdx +16 -3
  20. package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +10 -0
  21. package/docs/04-ai-sdk-ui/21-transport.mdx +86 -0
  22. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +46 -0
  23. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +46 -0
  24. package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +35 -0
  25. package/package.json +12 -12
  26. package/src/agent/create-agent-ui-stream-response.ts +3 -0
  27. package/src/agent/create-agent-ui-stream.ts +16 -0
  28. package/src/agent/pipe-agent-ui-stream-to-response.ts +3 -0
  29. package/src/agent/tool-loop-agent-settings.ts +37 -1
  30. package/src/agent/tool-loop-agent.ts +43 -7
  31. package/src/generate-object/generate-object.ts +1 -1
  32. package/src/generate-text/generate-text-events.ts +37 -0
  33. package/src/generate-text/generate-text.ts +528 -374
  34. package/src/generate-text/index.ts +8 -0
  35. package/src/generate-text/prepare-step.ts +12 -0
  36. package/src/generate-text/restricted-telemetry-dispatcher.ts +31 -18
  37. package/src/generate-text/steering.ts +293 -0
  38. package/src/generate-text/step-result.ts +18 -0
  39. package/src/generate-text/stream-text.ts +664 -473
  40. package/src/middleware/extract-json-middleware.ts +8 -2
  41. package/src/middleware/extract-reasoning-middleware.ts +42 -30
  42. package/src/telemetry/create-telemetry-dispatcher.ts +3 -0
  43. package/src/telemetry/telemetry.ts +15 -1
  44. package/src/util/is-caused-by-abort.ts +20 -0
@@ -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 }) => {
@@ -1,5 +1,6 @@
1
1
  import { asArray, type Context } from '@ai-sdk/provider-utils';
2
2
  import type { Callback } from '../util/callback';
3
+ import { VERSION } from '../version';
3
4
  import {
4
5
  filterIncludedContext,
5
6
  filterToolContext,
@@ -61,6 +62,7 @@ function augmentEvent<EVENT>(
61
62
  recordInputs: telemetry.recordInputs,
62
63
  recordOutputs: telemetry.recordOutputs,
63
64
  functionId: telemetry.functionId,
65
+ aiVersion: VERSION,
64
66
  },
65
67
  );
66
68
 
@@ -224,6 +226,7 @@ export function createTelemetryDispatcher({
224
226
  onStepEnd == null && onStepFinish == null
225
227
  ? undefined
226
228
  : mergeCallbacks(onStepEnd, onStepFinish),
229
+ onStepError: mergeTelemetryCallback('onStepError'),
227
230
  onObjectStepStart: mergeTelemetryCallback('onObjectStepStart'),
228
231
  onObjectStepEnd: mergeTelemetryCallback('onObjectStepEnd'),
229
232
  onEmbedStart: mergeTelemetryCallback('onEmbedStart'),
@@ -22,6 +22,7 @@ import type {
22
22
  GenerateTextEndEvent,
23
23
  GenerateTextStartEvent,
24
24
  GenerateTextStepEndEvent,
25
+ GenerateTextStepErrorEvent,
25
26
  GenerateTextStepStartEvent,
26
27
  } from '../generate-text/generate-text-events';
27
28
  import type {
@@ -59,7 +60,13 @@ export type InferTelemetryEvent<EVENT> = EVENT &
59
60
  Omit<
60
61
  TelemetryOptions,
61
62
  'integrations' | 'isEnabled' | 'includeRuntimeContext'
62
- >;
63
+ > & {
64
+ /**
65
+ * The version of the `ai` package that emitted this event.
66
+ * Absent in older releases.
67
+ */
68
+ readonly aiVersion?: string;
69
+ };
63
70
 
64
71
  type BivariantCallback<EVENT> = {
65
72
  bivarianceHack(event: EVENT): PromiseLike<void> | void;
@@ -110,6 +117,7 @@ export interface TelemetryDispatcher {
110
117
  onStepEnd?: Callback<GenerateTextStepEndEvent>;
111
118
  /** @deprecated Use `onStepEnd` instead. */
112
119
  onStepFinish?: Callback<GenerateTextStepEndEvent>;
120
+ onStepError?: Callback<GenerateTextStepErrorEvent>;
113
121
  onObjectStepStart?: Callback<GenerateObjectStepStartEvent>;
114
122
  onObjectStepEnd?: Callback<GenerateObjectStepEndEvent>;
115
123
  onEmbedStart?: Callback<EmbeddingModelCallStartEvent>;
@@ -202,6 +210,12 @@ export interface Telemetry {
202
210
  */
203
211
  onStepFinish?: Callback<InferTelemetryEvent<GenerateTextStepEndEvent>>;
204
212
 
213
+ /**
214
+ * Called when a step that started fails before it produces a step result.
215
+ * Use it to close step-level spans. The call then ends with `onError`.
216
+ */
217
+ onStepError?: Callback<InferTelemetryEvent<GenerateTextStepErrorEvent>>;
218
+
205
219
  /**
206
220
  * Called when an object generation step (single LLM invocation) begins.
207
221
  * For generateObject/streamObject there is always exactly one step.
@@ -0,0 +1,20 @@
1
+ import { isAbortError } from '@ai-sdk/provider-utils';
2
+
3
+ /**
4
+ * Checks if the error is an abort or timeout error, or is caused by one.
5
+ * Providers can wrap the abort or timeout error, e.g. as the cause of an
6
+ * API call error.
7
+ */
8
+ export function isCausedByAbort(error: unknown): boolean {
9
+ let current = error;
10
+
11
+ for (let depth = 0; current != null && depth < 5; depth++) {
12
+ if (isAbortError(current)) {
13
+ return true;
14
+ }
15
+
16
+ current = (current as { cause?: unknown }).cause;
17
+ }
18
+
19
+ return false;
20
+ }