ai 7.0.127 → 7.0.128
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 +18 -0
- package/dist/index.d.ts +213 -153
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +239 -178
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +278 -68
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +340 -61
- 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-getting-started/03-nextjs-pages-router.mdx +1 -1
- package/docs/02-getting-started/07-expo.mdx +1 -1
- package/docs/03-agents/07-workflow-agent.mdx +80 -12
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +44 -0
- package/docs/03-ai-sdk-core/{32-evaluation.mdx → 32-decisions.mdx} +49 -49
- package/docs/03-ai-sdk-core/35-image-generation.mdx +1 -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/06-advanced/09-multistep-interfaces.mdx +1 -1
- 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 +12 -12
- 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-speech/generated-audio-file.ts +5 -4
- package/src/generate-text/default-generate-text-result.ts +127 -0
- package/src/generate-text/generate-text.ts +2 -122
- package/src/global.ts +1 -1
- package/src/index.ts +1 -1
- package/src/middleware/extract-reasoning-middleware.ts +25 -6
- package/src/model/resolve-model.ts +45 -14
- 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/transcribe.ts +1 -1
- package/src/ui/chat.ts +9 -1
- package/src/ui/process-ui-message-stream.ts +21 -0
- 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
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
type ProviderOptions,
|
|
16
16
|
type ToolSet,
|
|
17
17
|
} from '@ai-sdk/provider-utils';
|
|
18
|
-
import {
|
|
18
|
+
import { ToolChoiceViolationError } from '../error';
|
|
19
19
|
import { logWarnings } from '../logger/log-warnings';
|
|
20
20
|
import { resolveLanguageModel } from '../model/resolve-model';
|
|
21
21
|
import type { ModelMessage } from '../prompt';
|
|
@@ -76,6 +76,7 @@ import type {
|
|
|
76
76
|
GenerateTextOnStepFinishCallback,
|
|
77
77
|
GenerateTextOnStepStartCallback,
|
|
78
78
|
} from './generate-text-events';
|
|
79
|
+
import { DefaultGenerateTextResult } from './default-generate-text-result';
|
|
79
80
|
import type { GenerateTextResult } from './generate-text-result';
|
|
80
81
|
import { isToolExecutionAllowedFinishReason } from './is-tool-execution-allowed-finish-reason';
|
|
81
82
|
import type {
|
|
@@ -83,11 +84,9 @@ import type {
|
|
|
83
84
|
OnLanguageModelCallStartCallback,
|
|
84
85
|
} from './language-model-events';
|
|
85
86
|
import { text, type Output } from './output';
|
|
86
|
-
import type { InferCompleteOutput } from './output-utils';
|
|
87
87
|
import { parseToolCall } from './parse-tool-call';
|
|
88
88
|
import type { PrepareStepFunction } from './prepare-step';
|
|
89
89
|
import { prepareStepCallSettings } from './prepare-step-call-settings';
|
|
90
|
-
import { convertToReasoningOutputs } from './reasoning-output';
|
|
91
90
|
import { resolveToolApproval } from './resolve-tool-approval';
|
|
92
91
|
import type { ResponseMessage } from './response-message';
|
|
93
92
|
import { createRestrictedTelemetryDispatcher } from './restricted-telemetry-dispatcher';
|
|
@@ -1687,122 +1686,3 @@ async function executeTools<TOOLS extends ToolSet>({
|
|
|
1687
1686
|
(result): result is NonNullable<typeof result> => result != null,
|
|
1688
1687
|
);
|
|
1689
1688
|
}
|
|
1690
|
-
|
|
1691
|
-
class DefaultGenerateTextResult<
|
|
1692
|
-
TOOLS extends ToolSet,
|
|
1693
|
-
RUNTIME_CONTEXT extends Context,
|
|
1694
|
-
OUTPUT extends Output,
|
|
1695
|
-
> implements GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT> {
|
|
1696
|
-
readonly steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['steps'];
|
|
1697
|
-
readonly totalUsage: LanguageModelUsage;
|
|
1698
|
-
private readonly _output: InferCompleteOutput<OUTPUT> | undefined;
|
|
1699
|
-
|
|
1700
|
-
constructor(options: {
|
|
1701
|
-
initialResponseMessages: Array<ResponseMessage>;
|
|
1702
|
-
steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['steps'];
|
|
1703
|
-
output: InferCompleteOutput<OUTPUT> | undefined;
|
|
1704
|
-
totalUsage: LanguageModelUsage;
|
|
1705
|
-
}) {
|
|
1706
|
-
this.initialResponseMessages = options.initialResponseMessages;
|
|
1707
|
-
this.steps = options.steps;
|
|
1708
|
-
this._output = options.output;
|
|
1709
|
-
this.totalUsage = options.totalUsage;
|
|
1710
|
-
}
|
|
1711
|
-
|
|
1712
|
-
private readonly initialResponseMessages: Array<ResponseMessage>;
|
|
1713
|
-
|
|
1714
|
-
get finalStep() {
|
|
1715
|
-
return this.steps.at(-1)!;
|
|
1716
|
-
}
|
|
1717
|
-
|
|
1718
|
-
get content() {
|
|
1719
|
-
return this.steps.flatMap(step => step.content);
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
get text() {
|
|
1723
|
-
return this.finalStep.text;
|
|
1724
|
-
}
|
|
1725
|
-
|
|
1726
|
-
get files() {
|
|
1727
|
-
return this.steps.flatMap(step => step.files);
|
|
1728
|
-
}
|
|
1729
|
-
|
|
1730
|
-
get reasoningText() {
|
|
1731
|
-
return this.finalStep.reasoningText;
|
|
1732
|
-
}
|
|
1733
|
-
|
|
1734
|
-
get reasoning() {
|
|
1735
|
-
return convertToReasoningOutputs(this.finalStep.reasoning);
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
get toolCalls() {
|
|
1739
|
-
return this.steps.flatMap(step => step.toolCalls);
|
|
1740
|
-
}
|
|
1741
|
-
|
|
1742
|
-
get staticToolCalls() {
|
|
1743
|
-
return this.steps.flatMap(step => step.staticToolCalls);
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
get dynamicToolCalls() {
|
|
1747
|
-
return this.steps.flatMap(step => step.dynamicToolCalls);
|
|
1748
|
-
}
|
|
1749
|
-
|
|
1750
|
-
get toolResults() {
|
|
1751
|
-
return this.steps.flatMap(step => step.toolResults);
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
get staticToolResults() {
|
|
1755
|
-
return this.steps.flatMap(step => step.staticToolResults);
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
get dynamicToolResults() {
|
|
1759
|
-
return this.steps.flatMap(step => step.dynamicToolResults);
|
|
1760
|
-
}
|
|
1761
|
-
|
|
1762
|
-
get sources() {
|
|
1763
|
-
return this.steps.flatMap(step => step.sources);
|
|
1764
|
-
}
|
|
1765
|
-
|
|
1766
|
-
get finishReason() {
|
|
1767
|
-
return this.finalStep.finishReason;
|
|
1768
|
-
}
|
|
1769
|
-
|
|
1770
|
-
get rawFinishReason() {
|
|
1771
|
-
return this.finalStep.rawFinishReason;
|
|
1772
|
-
}
|
|
1773
|
-
|
|
1774
|
-
get warnings() {
|
|
1775
|
-
return this.steps.flatMap(step => step.warnings ?? []);
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
|
-
get providerMetadata() {
|
|
1779
|
-
return this.finalStep.providerMetadata;
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
get response() {
|
|
1783
|
-
return this.finalStep.response;
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
get responseMessages() {
|
|
1787
|
-
return [
|
|
1788
|
-
...this.initialResponseMessages,
|
|
1789
|
-
...this.steps.flatMap(step => step.response.messages),
|
|
1790
|
-
];
|
|
1791
|
-
}
|
|
1792
|
-
|
|
1793
|
-
get request() {
|
|
1794
|
-
return this.finalStep.request;
|
|
1795
|
-
}
|
|
1796
|
-
|
|
1797
|
-
get usage() {
|
|
1798
|
-
return this.totalUsage;
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
|
-
get output() {
|
|
1802
|
-
if (this._output == null) {
|
|
1803
|
-
throw new NoOutputGeneratedError();
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
return this._output;
|
|
1807
|
-
}
|
|
1808
|
-
}
|
package/src/global.ts
CHANGED
|
@@ -9,7 +9,7 @@ declare global {
|
|
|
9
9
|
* String model ids are resolved to the default provider and model id.
|
|
10
10
|
*
|
|
11
11
|
* If not set, the default provider is the Vercel AI gateway provider.
|
|
12
|
-
*
|
|
12
|
+
* An explicitly configured provider must support decision models to use experimental_decide.
|
|
13
13
|
*
|
|
14
14
|
* @see https://ai-sdk.dev/docs/ai-sdk-core/provider-management#global-provider-configuration
|
|
15
15
|
*/
|
package/src/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ export * from './agent';
|
|
|
41
41
|
export * from './batch';
|
|
42
42
|
export * from './embed';
|
|
43
43
|
export * from './error';
|
|
44
|
-
export * from './
|
|
44
|
+
export * from './decide';
|
|
45
45
|
export * from './generate-image';
|
|
46
46
|
export * from './generate-object';
|
|
47
47
|
export * from './generate-speech';
|
|
@@ -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) {
|
|
@@ -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
|
+
}
|
|
@@ -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[];
|