ai 7.0.127 → 7.0.129
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 +53 -0
- package/dist/index.d.ts +230 -155
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +386 -209
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +288 -70
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +407 -76
- package/dist/internal/index.js.map +1 -1
- package/dist/test/index.d.ts +25 -17
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +27 -21
- package/dist/test/index.js.map +1 -1
- package/docs/02-foundations/06-provider-options.mdx +11 -10
- package/docs/02-getting-started/03-nextjs-pages-router.mdx +1 -1
- package/docs/02-getting-started/07-expo.mdx +1 -1
- package/docs/03-agents/02-building-agents.mdx +16 -11
- package/docs/03-agents/07-workflow-agent.mdx +83 -15
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +44 -0
- package/docs/03-ai-sdk-core/17-runtime-and-tool-context.mdx +18 -14
- package/docs/03-ai-sdk-core/25-settings.mdx +3 -2
- package/docs/03-ai-sdk-core/26-reasoning.mdx +12 -5
- package/docs/03-ai-sdk-core/{32-evaluation.mdx → 32-decisions.mdx} +64 -67
- package/docs/03-ai-sdk-core/35-image-generation.mdx +3 -1
- package/docs/03-ai-sdk-core/45-provider-management.mdx +8 -8
- package/docs/03-ai-sdk-core/60-telemetry.mdx +40 -31
- package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +21 -22
- package/docs/03-ai-sdk-harnesses/08-terminal-ui.mdx +2 -2
- package/docs/04-ai-sdk-ui/21-error-handling.mdx +28 -3
- package/docs/06-advanced/09-multistep-interfaces.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +2 -2
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +2 -2
- package/docs/07-reference/01-ai-sdk-core/14-decide.mdx +74 -0
- package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +58 -4
- package/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +11 -11
- package/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +9 -9
- package/docs/07-reference/01-ai-sdk-core/66-extract-reasoning-middleware.mdx +24 -8
- package/docs/07-reference/02-ai-sdk-ui/32-prune-messages.mdx +1 -1
- package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +1 -0
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +39 -2
- package/docs/07-reference/05-ai-sdk-errors/ai-decision-unsupported-question-type-error.mdx +31 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-such-model-error.mdx +3 -3
- package/docs/07-reference/05-ai-sdk-errors/ai-no-such-provider-error.mdx +3 -3
- package/docs/08-migration-guides/23-migration-guide-7-0.mdx +1 -1
- package/docs/08-migration-guides/29-migration-guide-4-0.mdx +1 -1
- package/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx +2 -2
- package/package.json +15 -15
- package/src/decide/decide-events.ts +129 -0
- package/src/{evaluate/evaluate.ts → decide/decide.ts} +36 -38
- package/src/decide/decision-provider.ts +11 -0
- package/src/decide/decision-result.ts +39 -0
- package/src/decide/index.ts +64 -0
- package/src/{evaluate → decide}/restricted-telemetry-dispatcher.ts +7 -7
- package/src/{evaluate/validate-evaluation.ts → decide/validate-decision.ts} +9 -9
- package/src/error/index.ts +10 -1
- package/src/generate-object/generate-object.ts +10 -0
- package/src/generate-object/stream-object.ts +10 -0
- package/src/generate-speech/generated-audio-file.ts +5 -4
- package/src/generate-speech/index.ts +13 -1
- package/src/generate-text/default-generate-text-result.ts +127 -0
- package/src/generate-text/generate-text.ts +5 -123
- package/src/generate-text/tool-approval-signature.ts +7 -4
- package/src/global.ts +3 -2
- package/src/index.ts +1 -1
- package/src/logger/deprecations.ts +72 -0
- package/src/logger/log-warnings.ts +25 -3
- package/src/middleware/extract-reasoning-middleware.ts +25 -6
- package/src/model/as-language-model-v3.ts +4 -0
- package/src/model/resolve-model.ts +45 -14
- package/src/prompt/convert-to-language-model-prompt.ts +7 -1
- package/src/realtime/encode-realtime-frame.ts +7 -2
- package/src/registry/custom-provider.ts +38 -26
- package/src/registry/index.ts +13 -1
- package/src/registry/no-such-provider-error.ts +2 -0
- package/src/registry/provider-registry.ts +56 -29
- package/src/telemetry/create-telemetry-dispatcher.ts +17 -5
- package/src/telemetry/telemetry.ts +35 -19
- package/src/telemetry/tracing-channel.ts +1 -1
- package/src/test/decision-mock-model-v4.ts +35 -0
- package/src/transcribe/index.ts +13 -1
- package/src/transcribe/transcribe.ts +1 -1
- package/src/types/index.ts +1 -0
- package/src/types/language-model.ts +9 -1
- package/src/types/usage.ts +21 -0
- package/src/ui/chat.ts +25 -9
- package/src/ui/convert-to-model-messages.ts +40 -8
- package/src/ui/http-chat-transport.ts +5 -3
- package/src/ui/process-text-stream.ts +5 -1
- package/src/ui/process-ui-message-stream.ts +21 -0
- package/src/ui/text-stream-chat-transport.ts +3 -1
- package/src/ui/ui-messages.ts +8 -0
- package/src/ui/unavailable-tool.ts +17 -0
- package/src/ui/validate-ui-messages.ts +10 -2
- package/docs/07-reference/01-ai-sdk-core/14-evaluate.mdx +0 -74
- package/docs/07-reference/05-ai-sdk-errors/ai-evaluation-unsupported-question-type-error.mdx +0 -31
- package/src/evaluate/evaluate-events.ts +0 -131
- package/src/evaluate/evaluation-provider.ts +0 -6
- package/src/evaluate/evaluation-result.ts +0 -39
- package/src/evaluate/index.ts +0 -13
- package/src/test/evaluation-mock-model-v4.ts +0 -27
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// These codes are stable identifiers. Do not rename or reuse an existing code.
|
|
2
|
+
const deprecationCodes = new Map<string, string>([
|
|
3
|
+
['generateObject', 'AISDK_DEP_GENERATE_OBJECT'],
|
|
4
|
+
['streamObject', 'AISDK_DEP_STREAM_OBJECT'],
|
|
5
|
+
['experimental_generateSpeech', 'AISDK_DEP_EXPERIMENTAL_GENERATE_SPEECH'],
|
|
6
|
+
['experimental_transcribe', 'AISDK_DEP_EXPERIMENTAL_TRANSCRIBE'],
|
|
7
|
+
['"image" content part', 'AISDK_DEP_IMAGE_CONTENT_PART'],
|
|
8
|
+
[
|
|
9
|
+
'"tool-result" content of type "file-data"',
|
|
10
|
+
'AISDK_DEP_TOOL_RESULT_FILE_DATA',
|
|
11
|
+
],
|
|
12
|
+
[
|
|
13
|
+
'"tool-result" content of type "file-url"',
|
|
14
|
+
'AISDK_DEP_TOOL_RESULT_FILE_URL',
|
|
15
|
+
],
|
|
16
|
+
['"tool-result" content of type "file-id"', 'AISDK_DEP_TOOL_RESULT_FILE_ID'],
|
|
17
|
+
[
|
|
18
|
+
'"tool-result" content of type "file-reference"',
|
|
19
|
+
'AISDK_DEP_TOOL_RESULT_FILE_REFERENCE',
|
|
20
|
+
],
|
|
21
|
+
[
|
|
22
|
+
'"tool-result" content of type "image-data"',
|
|
23
|
+
'AISDK_DEP_TOOL_RESULT_IMAGE_DATA',
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
'"tool-result" content of type "image-url"',
|
|
27
|
+
'AISDK_DEP_TOOL_RESULT_IMAGE_URL',
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
'"tool-result" content of type "image-file-id"',
|
|
31
|
+
'AISDK_DEP_TOOL_RESULT_IMAGE_FILE_ID',
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
'"tool-result" content of type "image-file-reference"',
|
|
35
|
+
'AISDK_DEP_TOOL_RESULT_IMAGE_FILE_REFERENCE',
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
'rawInput in output-error UI message parts',
|
|
39
|
+
'AISDK_DEP_UI_MESSAGE_RAW_INPUT',
|
|
40
|
+
],
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Escape punctuation and UTF-16 code units without losing case or collapsing
|
|
45
|
+
* distinct settings. Underscores are escaped too, so `__` separates code parts.
|
|
46
|
+
*/
|
|
47
|
+
function encodeCodePart(value: string): string {
|
|
48
|
+
return value.replace(
|
|
49
|
+
/[^a-zA-Z0-9]/g,
|
|
50
|
+
character =>
|
|
51
|
+
`_${character.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')}`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function getDeprecationCode({
|
|
56
|
+
setting,
|
|
57
|
+
provider,
|
|
58
|
+
}: {
|
|
59
|
+
setting: string;
|
|
60
|
+
provider?: string;
|
|
61
|
+
}): string {
|
|
62
|
+
if (provider == null) {
|
|
63
|
+
return (
|
|
64
|
+
deprecationCodes.get(setting) ??
|
|
65
|
+
`AISDK_DEP_SETTING_${encodeCodePart(setting)}`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Provider codes are scoped to the provider, but not to a particular model or
|
|
70
|
+
// message. This works for third-party providers without changing their spec.
|
|
71
|
+
return `AISDK_DEP_PROVIDER_${encodeCodePart(provider)}__${encodeCodePart(setting)}`;
|
|
72
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Warning } from '../types';
|
|
2
|
+
import { getDeprecationCode } from './deprecations';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* A function for logging warnings.
|
|
@@ -87,21 +88,24 @@ export const FIRST_WARNING_INFO_MESSAGE =
|
|
|
87
88
|
'AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false.';
|
|
88
89
|
|
|
89
90
|
let hasLoggedBefore = false;
|
|
91
|
+
const emittedDeprecationCodes = new Set<string>();
|
|
90
92
|
|
|
91
93
|
function emitWarning({
|
|
92
94
|
message,
|
|
93
95
|
type,
|
|
96
|
+
code,
|
|
94
97
|
}: {
|
|
95
98
|
message: string;
|
|
96
99
|
type: 'DeprecationWarning' | 'Warning';
|
|
100
|
+
code?: string;
|
|
97
101
|
}) {
|
|
98
102
|
if (
|
|
99
103
|
typeof process !== 'undefined' &&
|
|
100
104
|
typeof process.emitWarning === 'function'
|
|
101
105
|
) {
|
|
102
|
-
process.emitWarning(message, { type });
|
|
106
|
+
process.emitWarning(message, code == null ? { type } : { type, code });
|
|
103
107
|
} else {
|
|
104
|
-
console.warn(message);
|
|
108
|
+
console.warn(code == null ? message : `[${code}] ${message}`);
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
|
|
@@ -111,7 +115,9 @@ function emitWarning({
|
|
|
111
115
|
* The behavior can be customized via the `AI_SDK_LOG_WARNINGS` global variable:
|
|
112
116
|
* - If set to `false`, warnings are suppressed.
|
|
113
117
|
* - If set to a function, that function is called with the warnings.
|
|
114
|
-
* - Otherwise, warnings
|
|
118
|
+
* - Otherwise, warnings use `process.emitWarning` when available, falling back
|
|
119
|
+
* to `console.warn`. Deprecations have stable codes and are emitted once per
|
|
120
|
+
* code by the default logger. Custom loggers receive every warning.
|
|
115
121
|
*
|
|
116
122
|
* @param options - The options containing warnings and context.
|
|
117
123
|
* @param options.warnings - The warnings to log.
|
|
@@ -148,6 +154,20 @@ export const logWarnings: LogWarningsFunction = options => {
|
|
|
148
154
|
|
|
149
155
|
// default behavior: log warnings via process.emitWarning if available, otherwise console.warn
|
|
150
156
|
for (const warning of options.warnings) {
|
|
157
|
+
const code =
|
|
158
|
+
warning.type === 'deprecated'
|
|
159
|
+
? getDeprecationCode({
|
|
160
|
+
setting: warning.setting,
|
|
161
|
+
provider: options.provider,
|
|
162
|
+
})
|
|
163
|
+
: undefined;
|
|
164
|
+
if (code != null) {
|
|
165
|
+
if (emittedDeprecationCodes.has(code)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
emittedDeprecationCodes.add(code);
|
|
169
|
+
}
|
|
170
|
+
|
|
151
171
|
const message = formatWarning({
|
|
152
172
|
warning,
|
|
153
173
|
provider: options.provider,
|
|
@@ -156,6 +176,7 @@ export const logWarnings: LogWarningsFunction = options => {
|
|
|
156
176
|
emitWarning({
|
|
157
177
|
message,
|
|
158
178
|
type: warning.type === 'deprecated' ? 'DeprecationWarning' : 'Warning',
|
|
179
|
+
code,
|
|
159
180
|
});
|
|
160
181
|
}
|
|
161
182
|
};
|
|
@@ -165,4 +186,5 @@ export const logWarnings: LogWarningsFunction = options => {
|
|
|
165
186
|
*/
|
|
166
187
|
export const resetLogWarningsState = () => {
|
|
167
188
|
hasLoggedBefore = false;
|
|
189
|
+
emittedDeprecationCodes.clear();
|
|
168
190
|
};
|
|
@@ -3,14 +3,16 @@ import type {
|
|
|
3
3
|
LanguageModelV4StreamPart,
|
|
4
4
|
} from '@ai-sdk/provider';
|
|
5
5
|
import type { LanguageModelMiddleware } from '../types/language-model-middleware';
|
|
6
|
+
import { InvalidArgumentError } from '../error/invalid-argument-error';
|
|
6
7
|
import { createIdMap } from '../util/create-id-map';
|
|
7
8
|
import { getPotentialStartIndex } from '../util/get-potential-start-index';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
|
-
* Extracts
|
|
11
|
+
* Extracts a delimited reasoning section from the generated text and exposes it
|
|
11
12
|
* as a `reasoning` property on the result.
|
|
12
13
|
*
|
|
13
|
-
* @param tagName -
|
|
14
|
+
* @param tagName - An XML tag name (without angle brackets), or literal opening
|
|
15
|
+
* and closing delimiters for formats such as Gemma's thought channel.
|
|
14
16
|
* @param separator - The separator to use between reasoning and text sections.
|
|
15
17
|
* @param startWithReasoning - Whether to start with reasoning tokens.
|
|
16
18
|
*/
|
|
@@ -19,12 +21,26 @@ export function extractReasoningMiddleware({
|
|
|
19
21
|
separator = '\n',
|
|
20
22
|
startWithReasoning = false,
|
|
21
23
|
}: {
|
|
22
|
-
tagName: string;
|
|
24
|
+
tagName: string | { opening: string; closing: string };
|
|
23
25
|
separator?: string;
|
|
24
26
|
startWithReasoning?: boolean;
|
|
25
27
|
}): LanguageModelMiddleware {
|
|
26
|
-
const openingTag =
|
|
27
|
-
|
|
28
|
+
const openingTag =
|
|
29
|
+
typeof tagName === 'string' ? `<${tagName}>` : tagName.opening;
|
|
30
|
+
const closingTag =
|
|
31
|
+
typeof tagName === 'string' ? `</${tagName}>` : tagName.closing;
|
|
32
|
+
|
|
33
|
+
if (openingTag.length === 0 || closingTag.length === 0) {
|
|
34
|
+
throw new InvalidArgumentError({
|
|
35
|
+
parameter: 'tagName',
|
|
36
|
+
value: tagName,
|
|
37
|
+
message: 'Reasoning delimiters must not be empty.',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Delimiters are literal strings, including regex metacharacters such as `|`.
|
|
42
|
+
const escapedOpeningTag = openingTag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
43
|
+
const escapedClosingTag = closingTag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
28
44
|
|
|
29
45
|
return {
|
|
30
46
|
specificationVersion: 'v4',
|
|
@@ -40,7 +56,10 @@ export function extractReasoningMiddleware({
|
|
|
40
56
|
|
|
41
57
|
const text = startWithReasoning ? openingTag + part.text : part.text;
|
|
42
58
|
|
|
43
|
-
const regexp = new RegExp(
|
|
59
|
+
const regexp = new RegExp(
|
|
60
|
+
`${escapedOpeningTag}(.*?)${escapedClosingTag}`,
|
|
61
|
+
'gs',
|
|
62
|
+
);
|
|
44
63
|
const matches = Array.from(text.matchAll(regexp));
|
|
45
64
|
|
|
46
65
|
if (!matches.length) {
|
|
@@ -99,5 +99,9 @@ function convertV2UsageToV3(usage: LanguageModelV2Usage): LanguageModelV3Usage {
|
|
|
99
99
|
text: undefined,
|
|
100
100
|
reasoning: usage.reasoningTokens,
|
|
101
101
|
},
|
|
102
|
+
raw:
|
|
103
|
+
usage.totalTokens == null
|
|
104
|
+
? undefined
|
|
105
|
+
: { totalTokens: usage.totalTokens },
|
|
102
106
|
};
|
|
103
107
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { gateway } from '@ai-sdk/gateway';
|
|
2
2
|
import {
|
|
3
3
|
NoSuchModelError,
|
|
4
|
-
type
|
|
4
|
+
type Experimental_DecisionModelV4 as DecisionModelV4,
|
|
5
5
|
type EmbeddingModelV4,
|
|
6
6
|
type Experimental_SpeechTranslationModelV4,
|
|
7
7
|
type Experimental_VideoModelV4,
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
type SpeechModelV4,
|
|
13
13
|
type TranscriptionModelV4,
|
|
14
14
|
} from '@ai-sdk/provider';
|
|
15
|
-
import type {
|
|
16
|
-
import type {
|
|
15
|
+
import type { DecisionModel } from '../decide/decision-result';
|
|
16
|
+
import type { DecisionProvider } from '../decide/decision-provider';
|
|
17
17
|
import { UnsupportedModelVersionError } from '../error';
|
|
18
18
|
import type { EmbeddingModel } from '../types/embedding-model';
|
|
19
19
|
import type { LanguageModel } from '../types/language-model';
|
|
@@ -217,29 +217,30 @@ export function resolveRerankingModel(model: RerankingModel): RerankingModelV4 {
|
|
|
217
217
|
return asRerankingModelV4(model);
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
export function
|
|
221
|
-
model: EvaluationModel,
|
|
222
|
-
): EvaluationModelV4 {
|
|
220
|
+
export function resolveDecisionModel(model: DecisionModel): DecisionModelV4 {
|
|
223
221
|
if (typeof model === 'string') {
|
|
224
222
|
// Use the original provider so experimental methods and their receiver survive.
|
|
225
223
|
const provider = (globalThis.AI_SDK_DEFAULT_PROVIDER ??
|
|
226
|
-
gateway) as
|
|
224
|
+
gateway) as DecisionProvider;
|
|
227
225
|
|
|
228
|
-
|
|
226
|
+
const factory:
|
|
227
|
+
| ((modelId: string) => Exclude<DecisionModel, string>)
|
|
228
|
+
| undefined = provider.decisionModel ?? provider.evaluationModel;
|
|
229
|
+
if (typeof factory !== 'function') {
|
|
229
230
|
throw new NoSuchModelError({
|
|
230
231
|
modelId: model,
|
|
231
|
-
modelType: '
|
|
232
|
+
modelType: 'decisionModel',
|
|
232
233
|
message:
|
|
233
|
-
'The default provider does not support
|
|
234
|
-
'Pass
|
|
234
|
+
'The default provider does not support decision models. ' +
|
|
235
|
+
'Pass a decision model instance or configure AI_SDK_DEFAULT_PROVIDER with a decisionModel method.',
|
|
235
236
|
});
|
|
236
237
|
}
|
|
237
238
|
|
|
238
|
-
const resolvedModel =
|
|
239
|
+
const resolvedModel = factory.call(provider, model);
|
|
239
240
|
if (resolvedModel == null) {
|
|
240
241
|
throw new NoSuchModelError({
|
|
241
242
|
modelId: model,
|
|
242
|
-
modelType: '
|
|
243
|
+
modelType: 'decisionModel',
|
|
243
244
|
});
|
|
244
245
|
}
|
|
245
246
|
model = resolvedModel;
|
|
@@ -253,10 +254,40 @@ export function resolveEvaluationModel(
|
|
|
253
254
|
});
|
|
254
255
|
}
|
|
255
256
|
|
|
256
|
-
|
|
257
|
+
if ('doDecide' in model) {
|
|
258
|
+
return model;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const legacyModel = model;
|
|
262
|
+
return {
|
|
263
|
+
specificationVersion: legacyModel.specificationVersion,
|
|
264
|
+
provider: legacyModel.provider,
|
|
265
|
+
modelId: legacyModel.modelId,
|
|
266
|
+
supportedQuestionTypes: legacyModel.supportedQuestionTypes,
|
|
267
|
+
doDecide: options => legacyModel.doEvaluate(options),
|
|
268
|
+
};
|
|
257
269
|
}
|
|
258
270
|
|
|
259
271
|
function getGlobalProvider(): ProviderV4 {
|
|
260
272
|
const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? gateway;
|
|
261
273
|
return asProviderV4(provider);
|
|
262
274
|
}
|
|
275
|
+
|
|
276
|
+
/** Internal adapter for deprecated provider factories. */
|
|
277
|
+
export function asEvaluationModel(model: DecisionModelV4): DecisionModelV4 & {
|
|
278
|
+
doEvaluate: DecisionModelV4['doDecide'];
|
|
279
|
+
} {
|
|
280
|
+
if ('doEvaluate' in model && typeof model.doEvaluate === 'function') {
|
|
281
|
+
return model as DecisionModelV4 & {
|
|
282
|
+
doEvaluate: DecisionModelV4['doDecide'];
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
specificationVersion: model.specificationVersion,
|
|
287
|
+
provider: model.provider,
|
|
288
|
+
modelId: model.modelId,
|
|
289
|
+
supportedQuestionTypes: model.supportedQuestionTypes,
|
|
290
|
+
doDecide: options => model.doDecide(options),
|
|
291
|
+
doEvaluate: options => model.doDecide(options),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
@@ -123,7 +123,13 @@ export async function convertToLanguageModelPrompt({
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
lastCombinedMessage.content.push(...message.content);
|
|
126
|
-
lastCombinedMessage.providerOptions =
|
|
126
|
+
lastCombinedMessage.providerOptions =
|
|
127
|
+
lastContentPart == null
|
|
128
|
+
? mergeObjects(
|
|
129
|
+
lastCombinedMessage.providerOptions,
|
|
130
|
+
message.providerOptions,
|
|
131
|
+
)
|
|
132
|
+
: message.providerOptions;
|
|
127
133
|
} else {
|
|
128
134
|
combinedMessages.push(message);
|
|
129
135
|
}
|
|
@@ -3,14 +3,19 @@ export const REALTIME_MAX_FRAME_BYTES = 128 * 1024;
|
|
|
3
3
|
export const REALTIME_MAX_BUFFERED_BYTES = 128 * 1024;
|
|
4
4
|
|
|
5
5
|
export type EncodedRealtimeFrame = {
|
|
6
|
-
data: string | ArrayBuffer | ArrayBufferView | Blob;
|
|
6
|
+
data: string | ArrayBuffer | ArrayBufferView<ArrayBuffer> | Blob;
|
|
7
7
|
byteLength: number;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
/** Serialize once, measuring the exact payload passed to the browser. */
|
|
11
11
|
export function encodeRealtimeFrame(value: unknown): EncodedRealtimeFrame {
|
|
12
|
-
if (value instanceof ArrayBuffer
|
|
12
|
+
if (value instanceof ArrayBuffer)
|
|
13
13
|
return { data: value, byteLength: value.byteLength };
|
|
14
|
+
if (ArrayBuffer.isView(value))
|
|
15
|
+
return {
|
|
16
|
+
data: value as ArrayBufferView<ArrayBuffer>,
|
|
17
|
+
byteLength: value.byteLength,
|
|
18
|
+
};
|
|
14
19
|
if (value instanceof Blob) return { data: value, byteLength: value.size };
|
|
15
20
|
const data = typeof value === 'string' ? value : JSON.stringify(value);
|
|
16
21
|
if (data === undefined)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type
|
|
2
|
+
type Experimental_DecisionModelV4 as DecisionModelV4,
|
|
3
3
|
type EmbeddingModelV4,
|
|
4
4
|
type Experimental_VideoModelV3,
|
|
5
5
|
type Experimental_VideoModelV4,
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
type SpeechModelV4,
|
|
16
16
|
type TranscriptionModelV4,
|
|
17
17
|
} from '@ai-sdk/provider';
|
|
18
|
-
import type {
|
|
19
|
-
import type {
|
|
18
|
+
import type { DecisionModel } from '../decide/decision-result';
|
|
19
|
+
import type { DecisionProvider } from '../decide/decision-provider';
|
|
20
20
|
import { asProviderV4 } from '../model/as-provider-v4';
|
|
21
21
|
import {
|
|
22
22
|
resolveEmbeddingModel,
|
|
@@ -26,7 +26,8 @@ import {
|
|
|
26
26
|
resolveSpeechModel,
|
|
27
27
|
resolveTranscriptionModel,
|
|
28
28
|
resolveVideoModel,
|
|
29
|
-
|
|
29
|
+
resolveDecisionModel,
|
|
30
|
+
asEvaluationModel,
|
|
30
31
|
} from '../model/resolve-model';
|
|
31
32
|
import type { EmbeddingModel } from '../types/embedding-model';
|
|
32
33
|
import type { ImageModel } from '../types/image-model';
|
|
@@ -53,7 +54,7 @@ type ProviderWithOptionalVideoModel = {
|
|
|
53
54
|
* @param {Record<string, SpeechModel>} [options.speechModels] - A record of speech models, where keys are model IDs and values are speech model instances.
|
|
54
55
|
* @param {Record<string, RerankingModel>} [options.rerankingModels] - A record of reranking models, where keys are model IDs and values are reranking model instances.
|
|
55
56
|
* @param {Record<string, VideoModel>} [options.videoModels] - A record of video models, where keys are model IDs and values are video model instances.
|
|
56
|
-
* @param {Record<string,
|
|
57
|
+
* @param {Record<string, DecisionModel>} [options.decisionModels] - Experimental decision models or default-provider model IDs, keyed by alias.
|
|
57
58
|
* @param {FilesV4} [options.files] - A files interface for uploading files.
|
|
58
59
|
* @param {SkillsV4} [options.skills] - A skills interface for uploading skills.
|
|
59
60
|
* @param {ProviderV2 | ProviderV3 | ProviderV4} [options.fallbackProvider] - An optional fallback provider to use when a requested model is not found in the custom provider.
|
|
@@ -72,9 +73,9 @@ export function customProvider<
|
|
|
72
73
|
FILES extends FilesV4 | undefined = undefined,
|
|
73
74
|
SKILLS extends SkillsV4 | undefined = undefined,
|
|
74
75
|
FALLBACK extends ProviderV2 | ProviderV3 | ProviderV4 | undefined = undefined,
|
|
75
|
-
|
|
76
|
+
DECISION_MODELS extends Record<string, DecisionModel> = Record<
|
|
76
77
|
string,
|
|
77
|
-
|
|
78
|
+
DecisionModel
|
|
78
79
|
>,
|
|
79
80
|
>({
|
|
80
81
|
languageModels,
|
|
@@ -84,6 +85,7 @@ export function customProvider<
|
|
|
84
85
|
speechModels,
|
|
85
86
|
rerankingModels,
|
|
86
87
|
videoModels,
|
|
88
|
+
decisionModels: decisionModelsArg,
|
|
87
89
|
evaluationModels,
|
|
88
90
|
files,
|
|
89
91
|
skills,
|
|
@@ -96,7 +98,9 @@ export function customProvider<
|
|
|
96
98
|
speechModels?: SPEECH_MODELS;
|
|
97
99
|
rerankingModels?: RERANKING_MODELS;
|
|
98
100
|
videoModels?: VIDEO_MODELS;
|
|
99
|
-
|
|
101
|
+
decisionModels?: DECISION_MODELS;
|
|
102
|
+
/** @deprecated Use `decisionModels` instead. When both are set, `decisionModels` takes precedence. */
|
|
103
|
+
evaluationModels?: DECISION_MODELS;
|
|
100
104
|
files?: FILES;
|
|
101
105
|
skills?: SKILLS;
|
|
102
106
|
fallbackProvider?: FALLBACK;
|
|
@@ -110,9 +114,11 @@ export function customProvider<
|
|
|
110
114
|
rerankingModel(modelId: ExtractModelId<RERANKING_MODELS>): RerankingModelV4;
|
|
111
115
|
speechModel(modelId: ExtractModelId<SPEECH_MODELS>): SpeechModelV4;
|
|
112
116
|
videoModel(modelId: ExtractModelId<VIDEO_MODELS>): Experimental_VideoModelV4;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
):
|
|
117
|
+
decisionModel(modelId: ExtractModelId<DECISION_MODELS>): DecisionModelV4;
|
|
118
|
+
/** @deprecated Use `decisionModel` instead. */
|
|
119
|
+
evaluationModel(modelId: ExtractModelId<DECISION_MODELS>): DecisionModelV4 & {
|
|
120
|
+
doEvaluate: DecisionModelV4['doDecide'];
|
|
121
|
+
};
|
|
116
122
|
} & (FILES extends FilesV4
|
|
117
123
|
? { files(): FilesV4 }
|
|
118
124
|
: [FALLBACK] extends [{ files: () => FilesV4 }]
|
|
@@ -123,6 +129,7 @@ export function customProvider<
|
|
|
123
129
|
: [FALLBACK] extends [{ skills: () => SkillsV4 }]
|
|
124
130
|
? { skills(): SkillsV4 }
|
|
125
131
|
: { skills?(): SkillsV4 }) {
|
|
132
|
+
const decisionModels = decisionModelsArg ?? evaluationModels;
|
|
126
133
|
const fallbackProvider =
|
|
127
134
|
fallbackProviderArg == null ? undefined : asProviderV4(fallbackProviderArg);
|
|
128
135
|
|
|
@@ -138,9 +145,13 @@ export function customProvider<
|
|
|
138
145
|
videoModel(
|
|
139
146
|
modelId: ExtractModelId<VIDEO_MODELS>,
|
|
140
147
|
): Experimental_VideoModelV4;
|
|
148
|
+
decisionModel(modelId: ExtractModelId<DECISION_MODELS>): DecisionModelV4;
|
|
149
|
+
/** @deprecated Use `decisionModel` instead. */
|
|
141
150
|
evaluationModel(
|
|
142
|
-
modelId: ExtractModelId<
|
|
143
|
-
):
|
|
151
|
+
modelId: ExtractModelId<DECISION_MODELS>,
|
|
152
|
+
): DecisionModelV4 & {
|
|
153
|
+
doEvaluate: DecisionModelV4['doDecide'];
|
|
154
|
+
};
|
|
144
155
|
} = {
|
|
145
156
|
specificationVersion: 'v4',
|
|
146
157
|
languageModel(modelId: ExtractModelId<LANGUAGE_MODELS>): LanguageModelV4 {
|
|
@@ -227,25 +238,26 @@ export function customProvider<
|
|
|
227
238
|
|
|
228
239
|
throw new NoSuchModelError({ modelId, modelType: 'rerankingModel' });
|
|
229
240
|
},
|
|
230
|
-
|
|
231
|
-
modelId
|
|
232
|
-
|
|
233
|
-
if (
|
|
234
|
-
evaluationModels != null &&
|
|
235
|
-
Object.hasOwn(evaluationModels, modelId)
|
|
236
|
-
) {
|
|
237
|
-
return resolveEvaluationModel(evaluationModels[modelId]);
|
|
241
|
+
decisionModel(modelId: ExtractModelId<DECISION_MODELS>): DecisionModelV4 {
|
|
242
|
+
if (decisionModels != null && Object.hasOwn(decisionModels, modelId)) {
|
|
243
|
+
return resolveDecisionModel(decisionModels[modelId]);
|
|
238
244
|
}
|
|
239
245
|
|
|
240
|
-
const provider = fallbackProviderArg as
|
|
241
|
-
|
|
242
|
-
|
|
246
|
+
const provider = fallbackProviderArg as DecisionProvider | undefined;
|
|
247
|
+
const factory:
|
|
248
|
+
| ((modelId: string) => Exclude<DecisionModel, string>)
|
|
249
|
+
| undefined = provider?.decisionModel ?? provider?.evaluationModel;
|
|
250
|
+
if (typeof factory === 'function') {
|
|
251
|
+
const model = factory.call(provider, modelId);
|
|
243
252
|
if (model != null) {
|
|
244
|
-
return
|
|
253
|
+
return resolveDecisionModel(model);
|
|
245
254
|
}
|
|
246
255
|
}
|
|
247
256
|
|
|
248
|
-
throw new NoSuchModelError({ modelId, modelType: '
|
|
257
|
+
throw new NoSuchModelError({ modelId, modelType: 'decisionModel' });
|
|
258
|
+
},
|
|
259
|
+
evaluationModel(modelId: ExtractModelId<DECISION_MODELS>) {
|
|
260
|
+
return asEvaluationModel(this.decisionModel(modelId));
|
|
249
261
|
},
|
|
250
262
|
videoModel(
|
|
251
263
|
modelId: ExtractModelId<VIDEO_MODELS>,
|
package/src/registry/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { ProviderV3, ProviderV4 } from '@ai-sdk/provider';
|
|
2
|
+
import type { DecisionProviderRegistry } from './provider-registry';
|
|
3
|
+
|
|
1
4
|
export { customProvider } from './custom-provider';
|
|
2
5
|
export { NoSuchProviderError } from './no-such-provider-error';
|
|
3
6
|
export {
|
|
@@ -6,4 +9,13 @@ export {
|
|
|
6
9
|
} from './provider-registry';
|
|
7
10
|
export type { ProviderRegistryProvider } from './provider-registry';
|
|
8
11
|
|
|
9
|
-
export type {
|
|
12
|
+
export type { DecisionProviderRegistry as Experimental_DecisionProviderRegistry } from './provider-registry';
|
|
13
|
+
|
|
14
|
+
/** @deprecated Use `Experimental_DecisionProviderRegistry` instead. */
|
|
15
|
+
export type Experimental_EvaluationProviderRegistry<
|
|
16
|
+
PROVIDERS extends Record<string, ProviderV4 | ProviderV3> = Record<
|
|
17
|
+
string,
|
|
18
|
+
ProviderV4 | ProviderV3
|
|
19
|
+
>,
|
|
20
|
+
SEPARATOR extends string = ':',
|
|
21
|
+
> = DecisionProviderRegistry<PROVIDERS, SEPARATOR>;
|
|
@@ -26,6 +26,8 @@ export class NoSuchProviderError extends NoSuchModelError {
|
|
|
26
26
|
| 'speechModel'
|
|
27
27
|
| 'rerankingModel'
|
|
28
28
|
| 'videoModel'
|
|
29
|
+
| 'decisionModel'
|
|
30
|
+
/** @deprecated Use `decisionModel` instead. */
|
|
29
31
|
| 'evaluationModel';
|
|
30
32
|
providerId: string;
|
|
31
33
|
availableProviders: string[];
|