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.
- package/CHANGELOG.md +22 -0
- package/dist/index.d.ts +224 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +440 -120
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +52 -4
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +26 -20
- package/dist/internal/index.js.map +1 -1
- package/docs/02-getting-started/02-nextjs-app-router.mdx +2 -2
- package/docs/02-getting-started/08-angular.mdx +327 -0
- package/docs/02-getting-started/{03-nextjs-pages-router.mdx → 10-nextjs-pages-router.mdx} +12 -20
- package/docs/02-getting-started/index.mdx +2 -0
- package/docs/03-agents/01-overview.mdx +1 -0
- package/docs/03-agents/04-loop-control.mdx +117 -0
- package/docs/03-agents/06-tool-approvals.mdx +1 -0
- package/docs/03-agents/09-chat-platforms.mdx +164 -0
- package/docs/03-agents/index.mdx +6 -0
- package/docs/03-ai-sdk-core/60-telemetry.mdx +16 -3
- package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +10 -0
- package/docs/04-ai-sdk-ui/21-transport.mdx +86 -0
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +46 -0
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +46 -0
- package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +35 -0
- package/package.json +12 -12
- package/src/agent/create-agent-ui-stream-response.ts +3 -0
- package/src/agent/create-agent-ui-stream.ts +16 -0
- package/src/agent/pipe-agent-ui-stream-to-response.ts +3 -0
- package/src/agent/tool-loop-agent-settings.ts +37 -1
- package/src/agent/tool-loop-agent.ts +43 -7
- package/src/generate-object/generate-object.ts +1 -1
- package/src/generate-text/generate-text-events.ts +37 -0
- package/src/generate-text/generate-text.ts +528 -374
- package/src/generate-text/index.ts +8 -0
- package/src/generate-text/prepare-step.ts +12 -0
- package/src/generate-text/restricted-telemetry-dispatcher.ts +31 -18
- package/src/generate-text/steering.ts +293 -0
- package/src/generate-text/step-result.ts +18 -0
- package/src/generate-text/stream-text.ts +664 -473
- package/src/middleware/extract-json-middleware.ts +8 -2
- package/src/middleware/extract-reasoning-middleware.ts +42 -30
- package/src/telemetry/create-telemetry-dispatcher.ts +3 -0
- package/src/telemetry/telemetry.ts +15 -1
- 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 {
|
|
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
|
|
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:
|
|
95
|
+
text: reasoning,
|
|
90
96
|
});
|
|
91
97
|
|
|
92
98
|
transformedContent.push({
|
|
93
99
|
type: 'text',
|
|
94
|
-
text
|
|
100
|
+
text,
|
|
95
101
|
});
|
|
96
102
|
}
|
|
97
103
|
|
|
98
|
-
return {
|
|
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
|
+
}
|