ai 7.0.112 → 7.0.114
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 +35 -0
- package/README.md +6 -6
- package/dist/index.d.ts +16 -0
- package/dist/index.js +378 -256
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal/index.js +182 -78
- package/dist/internal/index.js.map +1 -1
- package/docs/02-foundations/02-providers-and-models.mdx +3 -0
- package/docs/02-foundations/03-prompts.mdx +1 -1
- package/docs/02-foundations/04-tools.mdx +2 -2
- package/docs/02-foundations/06-provider-options.mdx +11 -11
- package/docs/02-getting-started/00-choosing-a-provider.mdx +4 -4
- package/docs/02-getting-started/02-nextjs-app-router.mdx +3 -3
- package/docs/02-getting-started/03-nextjs-pages-router.mdx +3 -3
- package/docs/02-getting-started/04-svelte.mdx +7 -7
- package/docs/02-getting-started/05-nuxt.mdx +7 -7
- package/docs/02-getting-started/06-nodejs.mdx +3 -3
- package/docs/02-getting-started/07-expo.mdx +3 -3
- package/docs/02-getting-started/08-tanstack-start.mdx +3 -3
- package/docs/02-getting-started/09-coding-agents.mdx +1 -1
- package/docs/03-agents/03-workflows.mdx +2 -2
- package/docs/03-agents/04-loop-control.mdx +1 -1
- package/docs/03-agents/05-configuring-call-options.mdx +4 -2
- package/docs/03-agents/06-memory.mdx +2 -2
- package/docs/03-agents/06-policy-tool-approvals.mdx +2 -2
- package/docs/03-agents/06-tool-approvals.mdx +16 -0
- package/docs/03-agents/07-workflow-agent.mdx +11 -11
- package/docs/03-agents/08-terminal-ui.mdx +2 -2
- package/docs/03-ai-sdk-core/05-generating-text.mdx +2 -2
- package/docs/03-ai-sdk-core/17-mcp-apps.mdx +1 -1
- package/docs/03-ai-sdk-core/20-prompt-engineering.mdx +1 -1
- package/docs/03-ai-sdk-core/26-reasoning.mdx +13 -12
- package/docs/03-ai-sdk-core/31-reranking.mdx +12 -10
- package/docs/03-ai-sdk-core/32-evaluation.mdx +1 -1
- package/docs/03-ai-sdk-core/35-image-generation.mdx +2 -2
- package/docs/03-ai-sdk-core/37-speech.mdx +8 -6
- package/docs/03-ai-sdk-core/39-file-uploads.mdx +1 -1
- package/docs/03-ai-sdk-core/41-skill-uploads.mdx +1 -1
- package/docs/03-ai-sdk-core/42-batch.mdx +1 -1
- package/docs/03-ai-sdk-core/45-provider-management.mdx +21 -21
- package/docs/03-ai-sdk-core/60-telemetry.mdx +1 -1
- package/docs/03-ai-sdk-core/65-devtools.mdx +3 -3
- package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +1 -1
- package/docs/04-ai-sdk-ui/02-chatbot.mdx +3 -3
- package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +3 -3
- package/docs/04-ai-sdk-ui/03-chatbot-resume-streams.mdx +1 -1
- package/docs/05-ai-sdk-rsc/02-streaming-react-components.mdx +5 -5
- package/docs/05-ai-sdk-rsc/04-multistep-interfaces.mdx +1 -1
- package/docs/05-ai-sdk-rsc/06-loading-state.mdx +1 -1
- package/docs/05-ai-sdk-rsc/10-migrating-to-ui.mdx +3 -3
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +5 -3
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +5 -3
- package/docs/07-reference/01-ai-sdk-core/06-rerank.mdx +5 -5
- package/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +3 -3
- package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +4 -2
- package/docs/07-reference/01-ai-sdk-core/20-start-batch.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/32-validate-ui-messages.mdx +18 -0
- package/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +4 -4
- package/docs/07-reference/01-ai-sdk-core/60-wrap-language-model.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/61-wrap-image-model.mdx +1 -1
- package/docs/07-reference/02-ai-sdk-ui/50-direct-chat-transport.mdx +3 -3
- package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +1 -1
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +8 -8
- package/docs/07-reference/06-ai-sdk-tui/01-run-agent-tui.mdx +1 -1
- package/docs/09-troubleshooting/11-use-chat-custom-request-options.mdx +3 -3
- package/docs/09-troubleshooting/13-repeated-assistant-messages.mdx +2 -2
- package/docs/09-troubleshooting/17-use-chat-stale-body-data.mdx +1 -1
- package/docs/09-troubleshooting/70-high-memory-usage-with-images.mdx +2 -2
- package/package.json +11 -11
- package/src/embed/embed-many.ts +18 -2
- package/src/evaluate/evaluate.ts +1 -10
- package/src/generate-speech/generate-speech.ts +15 -4
- package/src/generate-speech/generated-audio-file.ts +0 -8
- package/src/generate-text/execute-tools-from-stream.ts +0 -2
- package/src/generate-text/generate-text.ts +1 -0
- package/src/generate-text/generated-file.ts +0 -8
- package/src/generate-text/invoke-tool-callbacks-from-stream.ts +9 -8
- package/src/generate-text/output.ts +0 -2
- package/src/generate-text/parse-tool-call.ts +38 -25
- package/src/generate-text/restricted-telemetry-dispatcher.ts +6 -58
- package/src/generate-text/stream-text.ts +1 -0
- package/src/generate-text/to-response-messages.ts +7 -0
- package/src/generate-text/tool-call.ts +26 -0
- package/src/generate-text/validate-tool-approvals.ts +39 -3
- package/src/generate-video/generate-video.ts +0 -2
- package/src/middleware/extract-reasoning-middleware.ts +1 -1
- package/src/middleware/wrap-embedding-model.ts +9 -1
- package/src/model/get-embedding-model-provider-options-transformer.ts +17 -0
- package/src/prompt/content-part.ts +3 -0
- package/src/prompt/standardize-prompt.ts +2 -0
- package/src/registry/custom-provider.ts +12 -5
- package/src/telemetry/create-telemetry-dispatcher.ts +58 -6
- package/src/telemetry/filter-included-context.ts +57 -2
- package/src/ui/chat.ts +108 -17
- package/src/ui/convert-to-model-messages.ts +8 -0
- package/src/ui/direct-chat-transport.ts +2 -0
- package/src/ui/process-ui-message-stream.ts +6 -0
- package/src/ui/ui-messages.ts +10 -0
- package/src/ui/validate-ui-messages.ts +98 -132
- package/src/ui-message-stream/to-ui-message-chunk.ts +7 -0
- package/src/ui-message-stream/ui-message-chunks.ts +2 -0
- package/src/util/write-to-server-response.ts +0 -2
|
@@ -78,12 +78,4 @@ export class DefaultGeneratedFile implements GeneratedFile {
|
|
|
78
78
|
|
|
79
79
|
export class DefaultGeneratedFileWithType extends DefaultGeneratedFile {
|
|
80
80
|
readonly type = 'file';
|
|
81
|
-
|
|
82
|
-
constructor(options: {
|
|
83
|
-
data: string | Uint8Array;
|
|
84
|
-
mediaType: string;
|
|
85
|
-
providerMetadata?: Record<string, JSONObject>;
|
|
86
|
-
}) {
|
|
87
|
-
super(options);
|
|
88
|
-
}
|
|
89
81
|
}
|
|
@@ -35,7 +35,7 @@ export function invokeToolCallbacksFromStream<TOOLS extends ToolSet>({
|
|
|
35
35
|
string,
|
|
36
36
|
{
|
|
37
37
|
toolName: string;
|
|
38
|
-
|
|
38
|
+
validatedContexts: Record<string, Promise<unknown> | undefined>;
|
|
39
39
|
}
|
|
40
40
|
> = createIdMap();
|
|
41
41
|
|
|
@@ -48,22 +48,23 @@ export function invokeToolCallbacksFromStream<TOOLS extends ToolSet>({
|
|
|
48
48
|
}): Promise<unknown> => {
|
|
49
49
|
const ongoingToolCall = ongoingToolCalls[toolCallId];
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const validatedContext = ongoingToolCall?.validatedContexts[toolName];
|
|
52
|
+
if (validatedContext != null) {
|
|
53
|
+
return validatedContext;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
const tool = getOwn(tools, toolName);
|
|
56
|
-
const
|
|
57
|
+
const newValidatedContext = validateToolContext({
|
|
57
58
|
toolName,
|
|
58
59
|
context: getOwn(toolsContext, toolName),
|
|
59
60
|
contextSchema: tool?.contextSchema,
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
if (ongoingToolCall != null) {
|
|
63
|
-
ongoingToolCall.
|
|
64
|
+
ongoingToolCall.validatedContexts[toolName] = newValidatedContext;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
return
|
|
67
|
+
return newValidatedContext;
|
|
67
68
|
};
|
|
68
69
|
|
|
69
70
|
return stream.pipeThrough(
|
|
@@ -80,7 +81,7 @@ export function invokeToolCallbacksFromStream<TOOLS extends ToolSet>({
|
|
|
80
81
|
case 'tool-input-start': {
|
|
81
82
|
ongoingToolCalls[chunk.id] = {
|
|
82
83
|
toolName: chunk.toolName,
|
|
83
|
-
|
|
84
|
+
validatedContexts: createIdMap(),
|
|
84
85
|
};
|
|
85
86
|
|
|
86
87
|
const tool = getOwn(tools, chunk.toolName);
|
|
@@ -120,7 +121,7 @@ export function invokeToolCallbacksFromStream<TOOLS extends ToolSet>({
|
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
case 'tool-call': {
|
|
123
|
-
const toolName =
|
|
124
|
+
const toolName = chunk.toolName;
|
|
124
125
|
const tool = getOwn(tools, toolName);
|
|
125
126
|
|
|
126
127
|
if (!chunk.invalid && tool?.onInputAvailable != null) {
|
|
@@ -12,7 +12,12 @@ import { NoSuchToolError } from '../error/no-such-tool-error';
|
|
|
12
12
|
import { ToolCallRepairError } from '../error/tool-call-repair-error';
|
|
13
13
|
import type { Instructions } from '../prompt';
|
|
14
14
|
import { getOwn } from '../util/get-own';
|
|
15
|
-
import
|
|
15
|
+
import {
|
|
16
|
+
getToolCallInputSchemaInput,
|
|
17
|
+
setToolCallInputSchemaInput,
|
|
18
|
+
type DynamicToolCall,
|
|
19
|
+
type TypedToolCall,
|
|
20
|
+
} from './tool-call';
|
|
16
21
|
import type { ToolCallRepairFunction } from './tool-call-repair-function';
|
|
17
22
|
import type { ToolInputRefinement } from './tool-input-refinement';
|
|
18
23
|
|
|
@@ -167,7 +172,7 @@ async function waitForPromiseWithAbortSignal<T>({
|
|
|
167
172
|
});
|
|
168
173
|
}
|
|
169
174
|
|
|
170
|
-
async function refineParsedToolCallInput<TOOLS extends ToolSet>({
|
|
175
|
+
export async function refineParsedToolCallInput<TOOLS extends ToolSet>({
|
|
171
176
|
toolCall,
|
|
172
177
|
refineToolInput,
|
|
173
178
|
}: {
|
|
@@ -180,10 +185,15 @@ async function refineParsedToolCallInput<TOOLS extends ToolSet>({
|
|
|
180
185
|
return toolCall;
|
|
181
186
|
}
|
|
182
187
|
|
|
183
|
-
|
|
188
|
+
const refinedToolCall = {
|
|
184
189
|
...toolCall,
|
|
185
190
|
input: await refine(toolCall.input as InferToolInput<TOOLS[keyof TOOLS]>),
|
|
186
191
|
} as TypedToolCall<TOOLS>;
|
|
192
|
+
|
|
193
|
+
const inputSchemaInput = getToolCallInputSchemaInput(toolCall);
|
|
194
|
+
return inputSchemaInput == null
|
|
195
|
+
? refinedToolCall
|
|
196
|
+
: setToolCallInputSchemaInput(refinedToolCall, inputSchemaInput.value);
|
|
187
197
|
}
|
|
188
198
|
|
|
189
199
|
async function parseProviderExecutedDynamicToolCall(
|
|
@@ -253,26 +263,29 @@ async function doParseToolCall<TOOLS extends ToolSet>({
|
|
|
253
263
|
});
|
|
254
264
|
}
|
|
255
265
|
|
|
256
|
-
return
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
266
|
+
return setToolCallInputSchemaInput(
|
|
267
|
+
tool.type === 'dynamic'
|
|
268
|
+
? {
|
|
269
|
+
type: 'tool-call',
|
|
270
|
+
toolCallId: toolCall.toolCallId,
|
|
271
|
+
toolName: toolCall.toolName,
|
|
272
|
+
input: parseResult.value,
|
|
273
|
+
providerExecuted: toolCall.providerExecuted,
|
|
274
|
+
providerMetadata: toolCall.providerMetadata,
|
|
275
|
+
...(tool.metadata != null ? { toolMetadata: tool.metadata } : {}),
|
|
276
|
+
dynamic: true,
|
|
277
|
+
title: tool.title,
|
|
278
|
+
}
|
|
279
|
+
: {
|
|
280
|
+
type: 'tool-call',
|
|
281
|
+
toolCallId: toolCall.toolCallId,
|
|
282
|
+
toolName,
|
|
283
|
+
input: parseResult.value,
|
|
284
|
+
providerExecuted: toolCall.providerExecuted,
|
|
285
|
+
providerMetadata: toolCall.providerMetadata,
|
|
286
|
+
...(tool.metadata != null ? { toolMetadata: tool.metadata } : {}),
|
|
287
|
+
title: tool.title,
|
|
288
|
+
},
|
|
289
|
+
parseResult.rawValue,
|
|
290
|
+
);
|
|
278
291
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from '
|
|
7
|
-
import { filterIncludedContext } from '../telemetry/filter-included-context';
|
|
1
|
+
import type { Context, ToolSet } from '@ai-sdk/provider-utils';
|
|
2
|
+
import {
|
|
3
|
+
filterIncludedContext,
|
|
4
|
+
filterToolContext,
|
|
5
|
+
filterToolsContext,
|
|
6
|
+
} from '../telemetry/filter-included-context';
|
|
8
7
|
import { createTelemetryDispatcher } from '../telemetry/create-telemetry-dispatcher';
|
|
9
8
|
import type { TelemetryDispatcher } from '../telemetry/telemetry';
|
|
10
9
|
import type {
|
|
@@ -98,57 +97,6 @@ function restrictStepResult<
|
|
|
98
97
|
});
|
|
99
98
|
}
|
|
100
99
|
|
|
101
|
-
/**
|
|
102
|
-
* Returns a shallow copy of the tools context with only top-level properties
|
|
103
|
-
* marked for telemetry inclusion for each tool.
|
|
104
|
-
*/
|
|
105
|
-
function filterToolsContext<TOOLS extends ToolSet>({
|
|
106
|
-
toolsContext,
|
|
107
|
-
includeToolsContext,
|
|
108
|
-
}: {
|
|
109
|
-
toolsContext: InferToolSetContext<TOOLS>;
|
|
110
|
-
includeToolsContext: IncludedToolsContext<TOOLS>;
|
|
111
|
-
}): InferToolSetContext<TOOLS> {
|
|
112
|
-
if (includeToolsContext == null) {
|
|
113
|
-
return {} as InferToolSetContext<TOOLS>;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return Object.fromEntries(
|
|
117
|
-
Object.entries(toolsContext).map(([toolName, toolContext]) => [
|
|
118
|
-
toolName,
|
|
119
|
-
filterToolContext({
|
|
120
|
-
toolName,
|
|
121
|
-
toolContext,
|
|
122
|
-
includeToolsContext,
|
|
123
|
-
}),
|
|
124
|
-
]),
|
|
125
|
-
) as InferToolSetContext<TOOLS>;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function filterToolContext<TOOLS extends ToolSet>({
|
|
129
|
-
toolName,
|
|
130
|
-
toolContext,
|
|
131
|
-
includeToolsContext,
|
|
132
|
-
}: {
|
|
133
|
-
toolName: string;
|
|
134
|
-
toolContext: unknown;
|
|
135
|
-
includeToolsContext: IncludedToolsContext<TOOLS>;
|
|
136
|
-
}) {
|
|
137
|
-
const includeToolContext = (
|
|
138
|
-
includeToolsContext as
|
|
139
|
-
| Record<
|
|
140
|
-
string,
|
|
141
|
-
IncludedContext<InferToolContext<TOOLS[typeof toolName]>>
|
|
142
|
-
>
|
|
143
|
-
| undefined
|
|
144
|
-
)?.[toolName];
|
|
145
|
-
|
|
146
|
-
return filterIncludedContext({
|
|
147
|
-
context: toolContext as InferToolContext<TOOLS[typeof toolName]>,
|
|
148
|
-
includeContext: includeToolContext,
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
100
|
/**
|
|
153
101
|
* Creates a telemetry dispatcher that only includes configured runtime context
|
|
154
102
|
* properties in text-generation lifecycle events before dispatching them.
|
|
@@ -6,8 +6,10 @@ import type {
|
|
|
6
6
|
} from '../prompt';
|
|
7
7
|
import { createToolModelOutput } from '../prompt/create-tool-model-output';
|
|
8
8
|
import { getOwn } from '../util/get-own';
|
|
9
|
+
import { isDeepEqualData } from '../util/is-deep-equal-data';
|
|
9
10
|
import type { ContentPart } from './content-part';
|
|
10
11
|
import type { ToolSet } from '@ai-sdk/provider-utils';
|
|
12
|
+
import { getToolCallInputSchemaInput } from './tool-call';
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Converts the result of a `generateText` or `streamText` call to a list of response messages.
|
|
@@ -129,6 +131,7 @@ export async function toResponseMessages<TOOLS extends ToolSet>({
|
|
|
129
131
|
break;
|
|
130
132
|
}
|
|
131
133
|
case 'tool-approval-request':
|
|
134
|
+
const inputSchemaInput = getToolCallInputSchemaInput(part.toolCall);
|
|
132
135
|
content.push({
|
|
133
136
|
type: 'tool-approval-request',
|
|
134
137
|
approvalId: part.approvalId,
|
|
@@ -136,6 +139,10 @@ export async function toResponseMessages<TOOLS extends ToolSet>({
|
|
|
136
139
|
...(part.reason != null ? { reason: part.reason } : {}),
|
|
137
140
|
isAutomatic: part.isAutomatic,
|
|
138
141
|
...(part.signature != null ? { signature: part.signature } : {}),
|
|
142
|
+
...(inputSchemaInput != null &&
|
|
143
|
+
!isDeepEqualData(inputSchemaInput.value, part.toolCall.input)
|
|
144
|
+
? { inputSchemaInput: inputSchemaInput.value }
|
|
145
|
+
: {}),
|
|
139
146
|
});
|
|
140
147
|
break;
|
|
141
148
|
}
|
|
@@ -3,6 +3,8 @@ import type { InferToolInput, ToolSet } from '@ai-sdk/provider-utils';
|
|
|
3
3
|
import type { ProviderMetadata } from '../types';
|
|
4
4
|
import type { ValueOf } from '../util/value-of';
|
|
5
5
|
|
|
6
|
+
const inputSchemaInputSymbol = Symbol('ai-sdk-tool-call-input-schema-input');
|
|
7
|
+
|
|
6
8
|
type BaseToolCall = {
|
|
7
9
|
type: 'tool-call';
|
|
8
10
|
toolCallId: string;
|
|
@@ -58,3 +60,27 @@ export type DynamicToolCall = BaseToolCall & {
|
|
|
58
60
|
export type TypedToolCall<TOOLS extends ToolSet> =
|
|
59
61
|
| StaticToolCall<TOOLS>
|
|
60
62
|
| DynamicToolCall;
|
|
63
|
+
|
|
64
|
+
export function setToolCallInputSchemaInput<TOOLS extends ToolSet>(
|
|
65
|
+
toolCall: TypedToolCall<TOOLS>,
|
|
66
|
+
inputSchemaInput: unknown,
|
|
67
|
+
): TypedToolCall<TOOLS> {
|
|
68
|
+
Object.defineProperty(toolCall, inputSchemaInputSymbol, {
|
|
69
|
+
value: inputSchemaInput,
|
|
70
|
+
});
|
|
71
|
+
return toolCall;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function getToolCallInputSchemaInput<TOOLS extends ToolSet>(
|
|
75
|
+
toolCall: TypedToolCall<TOOLS>,
|
|
76
|
+
): { value: unknown } | undefined {
|
|
77
|
+
return inputSchemaInputSymbol in toolCall
|
|
78
|
+
? {
|
|
79
|
+
value: (
|
|
80
|
+
toolCall as TypedToolCall<TOOLS> & {
|
|
81
|
+
[inputSchemaInputSymbol]: unknown;
|
|
82
|
+
}
|
|
83
|
+
)[inputSchemaInputSymbol],
|
|
84
|
+
}
|
|
85
|
+
: undefined;
|
|
86
|
+
}
|
|
@@ -10,10 +10,13 @@ import {
|
|
|
10
10
|
import { InvalidToolApprovalSignatureError } from '../error/invalid-tool-approval-signature-error';
|
|
11
11
|
import { InvalidToolInputError } from '../error/invalid-tool-input-error';
|
|
12
12
|
import { getOwn } from '../util/get-own';
|
|
13
|
+
import { isDeepEqualData } from '../util/is-deep-equal-data';
|
|
13
14
|
import type { CollectedToolApprovals } from './collect-tool-approvals';
|
|
15
|
+
import { refineParsedToolCallInput } from './parse-tool-call';
|
|
14
16
|
import { resolveToolApproval } from './resolve-tool-approval';
|
|
15
17
|
import { verifyToolApprovalSignature } from './tool-approval-signature';
|
|
16
18
|
import type { ToolApprovalConfiguration } from './tool-approval-configuration';
|
|
19
|
+
import type { ToolInputRefinement } from './tool-input-refinement';
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* Re-validates approved tool approvals reconstructed from client-supplied
|
|
@@ -31,6 +34,7 @@ export async function validateApprovedToolApprovals<
|
|
|
31
34
|
toolsContext,
|
|
32
35
|
runtimeContext,
|
|
33
36
|
toolApprovalSecret,
|
|
37
|
+
refineToolInput,
|
|
34
38
|
}: {
|
|
35
39
|
approvedToolApprovals: Array<CollectedToolApprovals<TOOLS>>;
|
|
36
40
|
tools: TOOLS | undefined;
|
|
@@ -39,6 +43,7 @@ export async function validateApprovedToolApprovals<
|
|
|
39
43
|
toolsContext: InferToolSetContext<TOOLS>;
|
|
40
44
|
runtimeContext: RUNTIME_CONTEXT;
|
|
41
45
|
toolApprovalSecret?: string | Uint8Array;
|
|
46
|
+
refineToolInput?: ToolInputRefinement<TOOLS>;
|
|
42
47
|
}): Promise<{
|
|
43
48
|
approvedToolApprovals: Array<CollectedToolApprovals<TOOLS>>;
|
|
44
49
|
deniedToolApprovals: Array<CollectedToolApprovals<TOOLS>>;
|
|
@@ -53,7 +58,7 @@ export async function validateApprovedToolApprovals<
|
|
|
53
58
|
> = [];
|
|
54
59
|
|
|
55
60
|
for (const approval of approvedToolApprovals) {
|
|
56
|
-
const {
|
|
61
|
+
const { approvalRequest, toolCall } = approval;
|
|
57
62
|
// Look up the tool by own property only: `toolName` comes from
|
|
58
63
|
// client-supplied history, so a name matching an inherited object property
|
|
59
64
|
// (e.g. `constructor`, `toString`) must resolve to "no such tool" rather
|
|
@@ -88,18 +93,49 @@ export async function validateApprovedToolApprovals<
|
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
if (isExecutableTool(tool) && tool.inputSchema != null) {
|
|
96
|
+
const hasInputSchemaInput = Object.prototype.hasOwnProperty.call(
|
|
97
|
+
approvalRequest,
|
|
98
|
+
'inputSchemaInput',
|
|
99
|
+
);
|
|
91
100
|
const validation = await safeValidateTypes({
|
|
92
|
-
value:
|
|
101
|
+
value: hasInputSchemaInput
|
|
102
|
+
? approvalRequest.inputSchemaInput
|
|
103
|
+
: toolCall.input,
|
|
93
104
|
schema: asSchema(tool.inputSchema),
|
|
94
105
|
});
|
|
95
106
|
|
|
107
|
+
let validationError: unknown;
|
|
96
108
|
if (!validation.success) {
|
|
109
|
+
validationError = validation.error;
|
|
110
|
+
} else {
|
|
111
|
+
try {
|
|
112
|
+
const revalidatedToolCall = await refineParsedToolCallInput({
|
|
113
|
+
toolCall: {
|
|
114
|
+
...toolCall,
|
|
115
|
+
input: validation.value,
|
|
116
|
+
},
|
|
117
|
+
refineToolInput,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Revalidation must never change the operation that was approved,
|
|
121
|
+
// including when older or projected history omits the schema input.
|
|
122
|
+
if (!isDeepEqualData(revalidatedToolCall.input, toolCall.input)) {
|
|
123
|
+
validationError = new Error(
|
|
124
|
+
'Approved tool input does not match the validated schema output.',
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
validationError = error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (validationError != null) {
|
|
97
133
|
invalid.push({
|
|
98
134
|
...approval,
|
|
99
135
|
error: new InvalidToolInputError({
|
|
100
136
|
toolName: toolCall.toolName,
|
|
101
137
|
toolInput: JSON.stringify(toolCall.input),
|
|
102
|
-
cause:
|
|
138
|
+
cause: validationError,
|
|
103
139
|
}),
|
|
104
140
|
});
|
|
105
141
|
continue;
|
|
@@ -24,7 +24,7 @@ export function extractReasoningMiddleware({
|
|
|
24
24
|
startWithReasoning?: boolean;
|
|
25
25
|
}): LanguageModelMiddleware {
|
|
26
26
|
const openingTag = `<${tagName}>`;
|
|
27
|
-
const closingTag =
|
|
27
|
+
const closingTag = `</${tagName}>`;
|
|
28
28
|
|
|
29
29
|
return {
|
|
30
30
|
specificationVersion: 'v4',
|
|
@@ -7,12 +7,17 @@ import type {
|
|
|
7
7
|
import {
|
|
8
8
|
asArray,
|
|
9
9
|
EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL,
|
|
10
|
+
EXPERIMENTAL_EMBEDDING_MODEL_PROVIDER_OPTIONS_TRANSFORMER,
|
|
10
11
|
} from '@ai-sdk/provider-utils';
|
|
11
12
|
import { asEmbeddingModelV4 } from '../model/as-embedding-model-v4';
|
|
12
13
|
import {
|
|
13
14
|
getEmbeddingModelMaxInputBytesPerCall,
|
|
14
15
|
type EmbeddingModelWithMaxInputBytesPerCall,
|
|
15
16
|
} from '../model/get-embedding-model-max-input-bytes-per-call';
|
|
17
|
+
import {
|
|
18
|
+
getEmbeddingModelProviderOptionsTransformer,
|
|
19
|
+
type EmbeddingModelWithProviderOptionsTransformer,
|
|
20
|
+
} from '../model/get-embedding-model-provider-options-transformer';
|
|
16
21
|
import type { EmbeddingModelMiddleware } from '../types';
|
|
17
22
|
|
|
18
23
|
/**
|
|
@@ -63,7 +68,8 @@ const doWrap = ({
|
|
|
63
68
|
middleware: EmbeddingModelMiddleware;
|
|
64
69
|
modelId?: string;
|
|
65
70
|
providerId?: string;
|
|
66
|
-
}): EmbeddingModelWithMaxInputBytesPerCall
|
|
71
|
+
}): EmbeddingModelWithMaxInputBytesPerCall &
|
|
72
|
+
EmbeddingModelWithProviderOptionsTransformer => {
|
|
67
73
|
async function doTransform({
|
|
68
74
|
params,
|
|
69
75
|
}: {
|
|
@@ -80,6 +86,8 @@ const doWrap = ({
|
|
|
80
86
|
overrideMaxEmbeddingsPerCall?.({ model }) ?? model.maxEmbeddingsPerCall,
|
|
81
87
|
[EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL]:
|
|
82
88
|
getEmbeddingModelMaxInputBytesPerCall(model),
|
|
89
|
+
[EXPERIMENTAL_EMBEDDING_MODEL_PROVIDER_OPTIONS_TRANSFORMER]:
|
|
90
|
+
getEmbeddingModelProviderOptionsTransformer(model),
|
|
83
91
|
supportsParallelCalls:
|
|
84
92
|
overrideSupportsParallelCalls?.({ model }) ?? model.supportsParallelCalls,
|
|
85
93
|
async doEmbed(
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EmbeddingModelV4 } from '@ai-sdk/provider';
|
|
2
|
+
import {
|
|
3
|
+
EXPERIMENTAL_EMBEDDING_MODEL_PROVIDER_OPTIONS_TRANSFORMER,
|
|
4
|
+
type EmbeddingModelProviderOptionsTransformer,
|
|
5
|
+
} from '@ai-sdk/provider-utils';
|
|
6
|
+
|
|
7
|
+
export type EmbeddingModelWithProviderOptionsTransformer = EmbeddingModelV4 & {
|
|
8
|
+
readonly [EXPERIMENTAL_EMBEDDING_MODEL_PROVIDER_OPTIONS_TRANSFORMER]?: EmbeddingModelProviderOptionsTransformer;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function getEmbeddingModelProviderOptionsTransformer(
|
|
12
|
+
model: EmbeddingModelV4,
|
|
13
|
+
) {
|
|
14
|
+
return (model as EmbeddingModelWithProviderOptionsTransformer)[
|
|
15
|
+
EXPERIMENTAL_EMBEDDING_MODEL_PROVIDER_OPTIONS_TRANSFORMER
|
|
16
|
+
];
|
|
17
|
+
}
|
|
@@ -284,6 +284,9 @@ export const toolApprovalRequestSchema: ZodType<ToolApprovalRequest> = z.object(
|
|
|
284
284
|
approvalId: z.string(),
|
|
285
285
|
toolCallId: z.string(),
|
|
286
286
|
reason: z.string().optional(),
|
|
287
|
+
isAutomatic: z.boolean().optional(),
|
|
288
|
+
signature: z.string().optional(),
|
|
289
|
+
inputSchemaInput: z.unknown().optional(),
|
|
287
290
|
},
|
|
288
291
|
);
|
|
289
292
|
|
|
@@ -82,6 +82,8 @@ export async function standardizePrompt({
|
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
// Require explicit trust in supplied system messages to reduce prompt-injection
|
|
86
|
+
// risk. The opt-in permits all system messages, including instruction text.
|
|
85
87
|
if (
|
|
86
88
|
!allowSystemInMessages &&
|
|
87
89
|
messages.some(message => message.role === 'system')
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Experimental_EvaluationModelV4 as EvaluationModelV4,
|
|
3
3
|
type EmbeddingModelV4,
|
|
4
|
+
type Experimental_VideoModelV3,
|
|
4
5
|
type Experimental_VideoModelV4,
|
|
5
6
|
type FilesV4,
|
|
6
7
|
type ImageModelV4,
|
|
@@ -35,6 +36,12 @@ import type { SpeechModel } from '../types/speech-model';
|
|
|
35
36
|
import type { TranscriptionModel } from '../types/transcription-model';
|
|
36
37
|
import type { VideoModel } from '../types/video-model';
|
|
37
38
|
|
|
39
|
+
type ProviderWithOptionalVideoModel = {
|
|
40
|
+
videoModel?: (
|
|
41
|
+
modelId: string,
|
|
42
|
+
) => Experimental_VideoModelV3 | Experimental_VideoModelV4;
|
|
43
|
+
};
|
|
44
|
+
|
|
38
45
|
/**
|
|
39
46
|
* Creates a custom provider with specified language models, text embedding models, image models, transcription models, speech models, file APIs, skill APIs, and an optional fallback provider.
|
|
40
47
|
*
|
|
@@ -247,11 +254,11 @@ export function customProvider<
|
|
|
247
254
|
return resolveVideoModel(videoModels[modelId]);
|
|
248
255
|
}
|
|
249
256
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (videoModel) {
|
|
254
|
-
return videoModel(modelId);
|
|
257
|
+
const provider = fallbackProviderArg as
|
|
258
|
+
| ProviderWithOptionalVideoModel
|
|
259
|
+
| undefined;
|
|
260
|
+
if (provider?.videoModel) {
|
|
261
|
+
return resolveVideoModel(provider.videoModel(modelId));
|
|
255
262
|
}
|
|
256
263
|
|
|
257
264
|
throw new NoSuchModelError({ modelId, modelType: 'videoModel' });
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { asArray } from '@ai-sdk/provider-utils';
|
|
1
|
+
import { asArray, type Context } from '@ai-sdk/provider-utils';
|
|
2
2
|
import type { Callback } from '../util/callback';
|
|
3
|
+
import {
|
|
4
|
+
filterIncludedContext,
|
|
5
|
+
filterToolContext,
|
|
6
|
+
filterToolsContext,
|
|
7
|
+
} from './filter-included-context';
|
|
3
8
|
import { mergeCallbacks } from '../util/merge-callbacks';
|
|
4
9
|
import type {
|
|
5
10
|
InferTelemetryEvent,
|
|
@@ -41,14 +46,59 @@ function augmentEvent<EVENT>(
|
|
|
41
46
|
event: EVENT,
|
|
42
47
|
telemetry: Pick<
|
|
43
48
|
TelemetryOptions,
|
|
44
|
-
|
|
49
|
+
| 'recordInputs'
|
|
50
|
+
| 'recordOutputs'
|
|
51
|
+
| 'functionId'
|
|
52
|
+
| 'includeRuntimeContext'
|
|
53
|
+
| 'includeToolsContext'
|
|
45
54
|
>,
|
|
55
|
+
filterContext = false,
|
|
46
56
|
): InferTelemetryEvent<EVENT> {
|
|
47
|
-
|
|
57
|
+
const augmentedEvent = Object.assign(
|
|
48
58
|
Object.create(Object.getPrototypeOf(event)),
|
|
49
59
|
event,
|
|
50
|
-
|
|
60
|
+
{
|
|
61
|
+
recordInputs: telemetry.recordInputs,
|
|
62
|
+
recordOutputs: telemetry.recordOutputs,
|
|
63
|
+
functionId: telemetry.functionId,
|
|
64
|
+
},
|
|
51
65
|
);
|
|
66
|
+
|
|
67
|
+
if (
|
|
68
|
+
filterContext &&
|
|
69
|
+
event != null &&
|
|
70
|
+
typeof event === 'object' &&
|
|
71
|
+
'runtimeContext' in event
|
|
72
|
+
) {
|
|
73
|
+
augmentedEvent.runtimeContext = filterIncludedContext({
|
|
74
|
+
context: event.runtimeContext as Context,
|
|
75
|
+
includeContext: telemetry.includeRuntimeContext,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (filterContext && event != null && typeof event === 'object') {
|
|
80
|
+
if ('toolsContext' in event) {
|
|
81
|
+
augmentedEvent.toolsContext = filterToolsContext({
|
|
82
|
+
toolsContext: event.toolsContext as Record<string, Context>,
|
|
83
|
+
includeToolsContext: telemetry.includeToolsContext,
|
|
84
|
+
});
|
|
85
|
+
} else if (
|
|
86
|
+
'toolContext' in event &&
|
|
87
|
+
event.toolContext != null &&
|
|
88
|
+
'toolCall' in event &&
|
|
89
|
+
event.toolCall != null &&
|
|
90
|
+
typeof event.toolCall === 'object' &&
|
|
91
|
+
'toolName' in event.toolCall
|
|
92
|
+
) {
|
|
93
|
+
augmentedEvent.toolContext = filterToolContext({
|
|
94
|
+
toolName: event.toolCall.toolName as string,
|
|
95
|
+
toolContext: event.toolContext,
|
|
96
|
+
includeToolsContext: telemetry.includeToolsContext,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return augmentedEvent;
|
|
52
102
|
}
|
|
53
103
|
|
|
54
104
|
/**
|
|
@@ -86,6 +136,8 @@ export function createTelemetryDispatcher({
|
|
|
86
136
|
recordInputs: telemetry?.recordInputs,
|
|
87
137
|
recordOutputs: telemetry?.recordOutputs,
|
|
88
138
|
functionId: telemetry?.functionId,
|
|
139
|
+
includeRuntimeContext: telemetry?.includeRuntimeContext,
|
|
140
|
+
includeToolsContext: telemetry?.includeToolsContext,
|
|
89
141
|
};
|
|
90
142
|
|
|
91
143
|
const mergeTelemetryCallback = <KEY extends TelemetryCallbackKey>(
|
|
@@ -127,7 +179,7 @@ export function createTelemetryDispatcher({
|
|
|
127
179
|
await runWithTracingChannelSpan(
|
|
128
180
|
{
|
|
129
181
|
type,
|
|
130
|
-
event: augmentEvent(event, telemetryMetadata),
|
|
182
|
+
event: augmentEvent(event, telemetryMetadata, true),
|
|
131
183
|
},
|
|
132
184
|
execute,
|
|
133
185
|
),
|
|
@@ -136,7 +188,7 @@ export function createTelemetryDispatcher({
|
|
|
136
188
|
openTelemetryChannelSpanContext({
|
|
137
189
|
message: {
|
|
138
190
|
type,
|
|
139
|
-
event: augmentEvent(event, telemetryMetadata),
|
|
191
|
+
event: augmentEvent(event, telemetryMetadata, true),
|
|
140
192
|
},
|
|
141
193
|
completion,
|
|
142
194
|
}),
|