@ai-sdk/provider-utils 5.0.0-beta.4 → 5.0.0-beta.6
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 +30 -11
- package/dist/index.d.mts +55 -3
- package/dist/index.d.ts +55 -3
- package/dist/index.js +68 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +65 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -4
- package/src/index.ts +5 -0
- package/src/map-reasoning-to-provider.ts +105 -0
- package/src/types/assistant-model-message.ts +2 -0
- package/src/types/content-part.ts +20 -0
- package/src/types/index.ts +1 -0
- package/src/validate-download-url.ts +7 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/provider-utils",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.6",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@standard-schema/spec": "^1.1.0",
|
|
37
37
|
"eventsource-parser": "^3.0.6",
|
|
38
|
-
"@ai-sdk/provider": "4.0.0-beta.
|
|
38
|
+
"@ai-sdk/provider": "4.0.0-beta.4"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "20.17.24",
|
|
@@ -69,9 +69,7 @@
|
|
|
69
69
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
70
70
|
"build:watch": "pnpm clean && tsup --watch",
|
|
71
71
|
"clean": "del-cli dist *.tsbuildinfo",
|
|
72
|
-
"lint": "eslint \"./**/*.ts*\"",
|
|
73
72
|
"type-check": "tsc --build",
|
|
74
|
-
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
75
73
|
"test": "pnpm test:node && pnpm test:edge",
|
|
76
74
|
"test:update": "pnpm test:node -u",
|
|
77
75
|
"test:watch": "vitest --config vitest.node.config.js",
|
package/src/index.ts
CHANGED
|
@@ -25,6 +25,11 @@ export * from './is-abort-error';
|
|
|
25
25
|
export { isNonNullable } from './is-non-nullable';
|
|
26
26
|
export { isUrlSupported } from './is-url-supported';
|
|
27
27
|
export * from './load-api-key';
|
|
28
|
+
export {
|
|
29
|
+
isCustomReasoning,
|
|
30
|
+
mapReasoningToProviderBudget,
|
|
31
|
+
mapReasoningToProviderEffort,
|
|
32
|
+
} from './map-reasoning-to-provider';
|
|
28
33
|
export { loadOptionalSetting } from './load-optional-setting';
|
|
29
34
|
export { loadSetting } from './load-setting';
|
|
30
35
|
export { type MaybePromiseLike } from './maybe-promise-like';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { LanguageModelV4CallOptions, SharedV4Warning } from '@ai-sdk/provider';
|
|
2
|
+
|
|
3
|
+
export type ReasoningLevel = Exclude<
|
|
4
|
+
LanguageModelV4CallOptions['reasoning'],
|
|
5
|
+
'none' | 'provider-default' | undefined
|
|
6
|
+
>;
|
|
7
|
+
|
|
8
|
+
export function isCustomReasoning(
|
|
9
|
+
reasoning: LanguageModelV4CallOptions['reasoning'],
|
|
10
|
+
): reasoning is Exclude<
|
|
11
|
+
LanguageModelV4CallOptions['reasoning'],
|
|
12
|
+
'provider-default' | undefined
|
|
13
|
+
> {
|
|
14
|
+
return reasoning !== undefined && reasoning !== 'provider-default';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Maps a top-level reasoning level to a provider-specific effort string using
|
|
19
|
+
* the given effort map. Pushes a compatibility warning if the reasoning level
|
|
20
|
+
* maps to a different string, or an unsupported warning if the level is not
|
|
21
|
+
* present in the map.
|
|
22
|
+
*
|
|
23
|
+
* @returns The mapped effort string, or `undefined` if the level is not
|
|
24
|
+
* supported.
|
|
25
|
+
*/
|
|
26
|
+
export function mapReasoningToProviderEffort<T extends string>({
|
|
27
|
+
reasoning,
|
|
28
|
+
effortMap,
|
|
29
|
+
warnings,
|
|
30
|
+
}: {
|
|
31
|
+
reasoning: ReasoningLevel;
|
|
32
|
+
effortMap: Partial<Record<ReasoningLevel, T>>;
|
|
33
|
+
warnings: SharedV4Warning[];
|
|
34
|
+
}): T | undefined {
|
|
35
|
+
const mapped = effortMap[reasoning];
|
|
36
|
+
|
|
37
|
+
if (mapped == null) {
|
|
38
|
+
warnings.push({
|
|
39
|
+
type: 'unsupported',
|
|
40
|
+
feature: 'reasoning',
|
|
41
|
+
details: `reasoning "${reasoning}" is not supported by this model.`,
|
|
42
|
+
});
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (mapped !== reasoning) {
|
|
47
|
+
warnings.push({
|
|
48
|
+
type: 'compatibility',
|
|
49
|
+
feature: 'reasoning',
|
|
50
|
+
details: `reasoning "${reasoning}" is not directly supported by this model. mapped to effort "${mapped}".`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return mapped;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const DEFAULT_REASONING_BUDGET_PERCENTAGES: Record<ReasoningLevel, number> = {
|
|
58
|
+
minimal: 0.02,
|
|
59
|
+
low: 0.1,
|
|
60
|
+
medium: 0.3,
|
|
61
|
+
high: 0.6,
|
|
62
|
+
xhigh: 0.9,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Maps a top-level reasoning level to an absolute token budget by multiplying
|
|
67
|
+
* the model's max output tokens by a percentage from the budget percentages
|
|
68
|
+
* map. The result is clamped between `minReasoningBudget` (default 1024) and
|
|
69
|
+
* `maxReasoningBudget`. Pushes an unsupported warning if the level is not
|
|
70
|
+
* present in the budget percentages map.
|
|
71
|
+
*
|
|
72
|
+
* @returns The computed token budget, or `undefined` if the level is not
|
|
73
|
+
* supported.
|
|
74
|
+
*/
|
|
75
|
+
export function mapReasoningToProviderBudget({
|
|
76
|
+
reasoning,
|
|
77
|
+
maxOutputTokens,
|
|
78
|
+
maxReasoningBudget,
|
|
79
|
+
minReasoningBudget = 1024,
|
|
80
|
+
budgetPercentages = DEFAULT_REASONING_BUDGET_PERCENTAGES,
|
|
81
|
+
warnings,
|
|
82
|
+
}: {
|
|
83
|
+
reasoning: ReasoningLevel;
|
|
84
|
+
maxOutputTokens: number;
|
|
85
|
+
maxReasoningBudget: number;
|
|
86
|
+
minReasoningBudget?: number;
|
|
87
|
+
budgetPercentages?: Partial<Record<ReasoningLevel, number>>;
|
|
88
|
+
warnings: SharedV4Warning[];
|
|
89
|
+
}): number | undefined {
|
|
90
|
+
const pct = budgetPercentages[reasoning];
|
|
91
|
+
|
|
92
|
+
if (pct == null) {
|
|
93
|
+
warnings.push({
|
|
94
|
+
type: 'unsupported',
|
|
95
|
+
feature: 'reasoning',
|
|
96
|
+
details: `reasoning "${reasoning}" is not supported by this model.`,
|
|
97
|
+
});
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return Math.min(
|
|
102
|
+
maxReasoningBudget,
|
|
103
|
+
Math.max(minReasoningBudget, Math.round(maxOutputTokens * pct)),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
@@ -103,6 +103,26 @@ export interface ReasoningPart {
|
|
|
103
103
|
providerOptions?: ProviderOptions;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Custom content part of a prompt. It contains no standardized payload beyond
|
|
108
|
+
* provider-specific options.
|
|
109
|
+
*/
|
|
110
|
+
export interface CustomPart {
|
|
111
|
+
type: 'custom';
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The kind of custom content, in the format `{provider}-{provider-type}`.
|
|
115
|
+
*/
|
|
116
|
+
kind: string;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Additional provider-specific metadata. They are passed through
|
|
120
|
+
* to the provider from the AI SDK and enable provider-specific
|
|
121
|
+
* functionality that can be fully encapsulated in the provider.
|
|
122
|
+
*/
|
|
123
|
+
providerOptions?: ProviderOptions;
|
|
124
|
+
}
|
|
125
|
+
|
|
106
126
|
/**
|
|
107
127
|
* Reasoning file content part of a prompt. It contains a file generated as part of reasoning.
|
|
108
128
|
*/
|
package/src/types/index.ts
CHANGED
|
@@ -18,11 +18,16 @@ export function validateDownloadUrl(url: string): void {
|
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
//
|
|
21
|
+
// data: URLs are inline content, so they do not trigger a network fetch or SSRF risk.
|
|
22
|
+
if (parsed.protocol === 'data:') {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Only allow http and https network protocols
|
|
22
27
|
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
23
28
|
throw new DownloadError({
|
|
24
29
|
url,
|
|
25
|
-
message: `URL scheme must be http or
|
|
30
|
+
message: `URL scheme must be http, https, or data, got ${parsed.protocol}`,
|
|
26
31
|
});
|
|
27
32
|
}
|
|
28
33
|
|