@ai-sdk/gateway 4.0.92 → 4.0.95
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 +23 -0
- package/dist/index.d.ts +183 -9
- package/dist/index.js +364 -222
- package/dist/index.js.map +1 -1
- package/docs/00-ai-gateway.mdx +192 -4
- package/package.json +3 -3
- package/src/gateway-evaluation-model.ts +16 -2
- package/src/gateway-provider-options.ts +209 -7
- package/src/gateway-tools.ts +18 -0
- package/src/index.ts +3 -0
- package/src/tool/browserbase-fetch.ts +157 -0
- package/src/tool/browserbase-search.ts +137 -0
package/docs/00-ai-gateway.mdx
CHANGED
|
@@ -985,6 +985,132 @@ token-efficient content controls. Deep synthesis modes and generated summaries
|
|
|
985
985
|
are intentionally not exposed yet because they have separate pricing from
|
|
986
986
|
standard Search.
|
|
987
987
|
|
|
988
|
+
#### Browserbase Search
|
|
989
|
+
|
|
990
|
+
The Browserbase Search tool enables models to search the web using [Browserbase's Search API](https://docs.browserbase.com/reference/api/web-search). It is executed by AI Gateway and returns fast, structured search results without opening a browser session.
|
|
991
|
+
|
|
992
|
+
```ts
|
|
993
|
+
import { gateway, generateText } from 'ai';
|
|
994
|
+
|
|
995
|
+
const result = await generateText({
|
|
996
|
+
model: 'openai/gpt-5.6-luna',
|
|
997
|
+
prompt:
|
|
998
|
+
'Find official guidance on traveling with power banks on U.S. flights. Return the most relevant page titles and URLs.',
|
|
999
|
+
tools: {
|
|
1000
|
+
browserbase_search: gateway.tools.browserbaseSearch(),
|
|
1001
|
+
},
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
console.log(result.text);
|
|
1005
|
+
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
|
|
1006
|
+
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
You can configure the maximum number of results returned by each search:
|
|
1010
|
+
|
|
1011
|
+
```ts
|
|
1012
|
+
import { gateway, generateText } from 'ai';
|
|
1013
|
+
|
|
1014
|
+
const result = await generateText({
|
|
1015
|
+
model: 'openai/gpt-5.6-luna',
|
|
1016
|
+
prompt:
|
|
1017
|
+
'Find three recent reviews comparing e-readers for outdoor reading. Return their titles and URLs.',
|
|
1018
|
+
tools: {
|
|
1019
|
+
browserbase_search: gateway.tools.browserbaseSearch({
|
|
1020
|
+
numResults: 3,
|
|
1021
|
+
}),
|
|
1022
|
+
},
|
|
1023
|
+
});
|
|
1024
|
+
|
|
1025
|
+
console.log(result.text);
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
The Browserbase Search tool supports this optional configuration option:
|
|
1029
|
+
|
|
1030
|
+
- **numResults** _number_
|
|
1031
|
+
|
|
1032
|
+
Maximum number of search results to return (1-25, default: 10).
|
|
1033
|
+
|
|
1034
|
+
The tool works with both `generateText` and `streamText`.
|
|
1035
|
+
|
|
1036
|
+
#### Browserbase Fetch
|
|
1037
|
+
|
|
1038
|
+
The Browserbase Fetch tool enables models to retrieve page content using [Browserbase's Fetch API](https://docs.browserbase.com/platform/fetch/overview). It is a lightweight option for pages that do not require JavaScript execution or browser interaction, and it supports raw, Markdown, and schema-driven JSON output.
|
|
1039
|
+
|
|
1040
|
+
```ts
|
|
1041
|
+
import { gateway, generateText } from 'ai';
|
|
1042
|
+
|
|
1043
|
+
const result = await generateText({
|
|
1044
|
+
model: 'openai/gpt-5.6-luna',
|
|
1045
|
+
prompt:
|
|
1046
|
+
'Fetch https://www.nps.gov/yose/planyourvisit/halfdome.htm and summarize the permit requirements and main safety warnings.',
|
|
1047
|
+
tools: {
|
|
1048
|
+
browserbase_fetch: gateway.tools.browserbaseFetch(),
|
|
1049
|
+
},
|
|
1050
|
+
});
|
|
1051
|
+
|
|
1052
|
+
console.log(result.text);
|
|
1053
|
+
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
|
|
1054
|
+
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
You can configure the output format and request behavior. For example, use JSON extraction to return content matching a JSON Schema:
|
|
1058
|
+
|
|
1059
|
+
```ts
|
|
1060
|
+
import { gateway, generateText } from 'ai';
|
|
1061
|
+
|
|
1062
|
+
const result = await generateText({
|
|
1063
|
+
model: 'openai/gpt-5.6-luna',
|
|
1064
|
+
prompt:
|
|
1065
|
+
'Fetch https://www.nps.gov/yose/planyourvisit/halfdome.htm and extract its page title, whether a permit is required, and three safety tips.',
|
|
1066
|
+
tools: {
|
|
1067
|
+
browserbase_fetch: gateway.tools.browserbaseFetch({
|
|
1068
|
+
allowRedirects: true,
|
|
1069
|
+
format: 'json',
|
|
1070
|
+
schema: {
|
|
1071
|
+
type: 'object',
|
|
1072
|
+
properties: {
|
|
1073
|
+
pageTitle: { type: 'string' },
|
|
1074
|
+
permitRequired: { type: 'boolean' },
|
|
1075
|
+
safetyTips: {
|
|
1076
|
+
type: 'array',
|
|
1077
|
+
items: { type: 'string' },
|
|
1078
|
+
maxItems: 3,
|
|
1079
|
+
},
|
|
1080
|
+
},
|
|
1081
|
+
required: ['pageTitle', 'permitRequired', 'safetyTips'],
|
|
1082
|
+
},
|
|
1083
|
+
}),
|
|
1084
|
+
},
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1087
|
+
console.log(result.text);
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
The Browserbase Fetch tool supports these optional configuration options:
|
|
1091
|
+
|
|
1092
|
+
- **format** _'raw' | 'markdown' | 'json'_
|
|
1093
|
+
|
|
1094
|
+
Output format for the fetched content. `raw` returns the upstream response body unchanged and is the default. `markdown` converts the page to Markdown. `json` performs structured extraction and requires `schema`.
|
|
1095
|
+
|
|
1096
|
+
- **schema** _object_
|
|
1097
|
+
|
|
1098
|
+
JSON Schema describing the desired structured content. Only used when `format` is `json`.
|
|
1099
|
+
|
|
1100
|
+
- **allowRedirects** _boolean_
|
|
1101
|
+
|
|
1102
|
+
Follow HTTP redirects. Defaults to `false`.
|
|
1103
|
+
|
|
1104
|
+
- **proxies** _boolean_
|
|
1105
|
+
|
|
1106
|
+
Route the request through Browserbase's proxy network. Defaults to `false`.
|
|
1107
|
+
|
|
1108
|
+
- **allowInsecureSsl** _boolean_
|
|
1109
|
+
|
|
1110
|
+
Bypass TLS certificate verification. Defaults to `false`; only enable it for trusted hosts.
|
|
1111
|
+
|
|
1112
|
+
The Fetch API does not execute JavaScript. Use a browser session for interactive or JavaScript-rendered pages. The tool works with both `generateText` and `streamText`.
|
|
1113
|
+
|
|
988
1114
|
#### Tako Search
|
|
989
1115
|
|
|
990
1116
|
The Tako Search tool enables models to search the web and Tako's curated knowledge graph in a single call using [Tako's Search API](https://docs.tako.com/documentation/integrating-tako/search/overview). This tool is executed by the AI Gateway and returns token-efficient web excerpts, plus knowledge-graph results that carry structured data, premium source attribution, and an embed-ready visualization.
|
|
@@ -1346,12 +1472,16 @@ The following gateway provider options are available:
|
|
|
1346
1472
|
|
|
1347
1473
|
When `sort` is active, the response's `providerMetadata.gateway.routing.sort` object contains the sort option used, the resulting execution order, per-provider metric values, and any providers that were deprioritized.
|
|
1348
1474
|
|
|
1349
|
-
- **models** _string[]_
|
|
1475
|
+
- **models** _string[] | [GatewayModelFallback, ...string[]]_
|
|
1350
1476
|
|
|
1351
|
-
Specifies fallback models
|
|
1477
|
+
Specifies fallback models in attempt order. String entries keep their existing behavior: the gateway tries them when the primary model fails or is unavailable. Evaluation requests can also start the list with one conditional `{ model, when }` entry to retry a successful but uncertain evaluation with another model. Only the first entry can be conditional, and only one conditional entry is allowed. If the primary model fails, the gateway also advances to the conditional entry under its existing error fallback behavior. Conditional entries are rejected on non-evaluation requests. Type evaluation options with `GatewayEvaluationProviderOptions`, since `GatewayProviderOptions` only accepts string entries.
|
|
1352
1478
|
|
|
1353
1479
|
Example: `models: ['openai/gpt-5.4-nano', 'google/gemini-3.8-flash']` will try the fallback models in order if the primary model fails.
|
|
1354
1480
|
|
|
1481
|
+
A direct condition uses `{ question, confidenceBelow }` for Choice and Score questions, or `{ question, probabilityBetween: [minimum, maximum] }` for Boolean questions. Boolean probability is P(true), not confidence in the selected Boolean outcome. Bounds are inclusive, finite, ordered, and within `[0, 1]`.
|
|
1482
|
+
|
|
1483
|
+
Combine conditions with `{ any: [...] }`, `{ all: [...] }`, or `{ atLeast: { count, conditions: [...] } }`. Each condition list holds 1 to 20 conditions. `atLeast.count` must be an integer from `1` through the number of conditions. Conditions nest at most 5 levels deep. Question IDs and the conditional `model` are 1 to 256 characters. The SDK checks these bounds before sending the request, and the gateway also checks that each question exists and has a kind that matches its condition. String error fallbacks may follow the conditional entry.
|
|
1484
|
+
|
|
1355
1485
|
- **user** _string_
|
|
1356
1486
|
|
|
1357
1487
|
Optional identifier for the end user on whose behalf the request is being made. This is used for spend tracking and attribution purposes, allowing you to track usage per end-user in your application.
|
|
@@ -1390,13 +1520,14 @@ The following gateway provider options are available:
|
|
|
1390
1520
|
|
|
1391
1521
|
The unique identifier for the entity against which quota is tracked. Used for quota management and enforcement purposes.
|
|
1392
1522
|
|
|
1393
|
-
- **has** _Array<'implicit-caching' | 'reasoning' | 'tool-use' | 'vision' | `quantization:${string}` | `!quantization:${string}`>_
|
|
1523
|
+
- **has** _Array<'implicit-caching' | 'reasoning' | 'structured-output' | 'tool-use' | 'vision' | `quantization:${string}` | `!quantization:${string}`>_
|
|
1394
1524
|
|
|
1395
1525
|
Restricts routing to provider models that have all of the specified capabilities. Applies to both BYOK and system credentials, since the capability is a property of the model rather than the credential. If no provider model for the requested model satisfies the capabilities, the request fails. Unsupported values are rejected.
|
|
1396
1526
|
|
|
1397
1527
|
Supported capabilities:
|
|
1398
1528
|
- `'implicit-caching'` — models that perform automatic (implicit) prompt caching.
|
|
1399
1529
|
- `'reasoning'` — models that support reasoning.
|
|
1530
|
+
- `'structured-output'` — models that support schema-constrained output.
|
|
1400
1531
|
- `'tool-use'` — models that support tool calling.
|
|
1401
1532
|
- `'vision'` — models that accept image input.
|
|
1402
1533
|
|
|
@@ -1481,6 +1612,63 @@ const { text } = await generateText({
|
|
|
1481
1612
|
// 4. Return the result from the first model that succeeds
|
|
1482
1613
|
```
|
|
1483
1614
|
|
|
1615
|
+
#### Conditional Evaluation Fallbacks Example
|
|
1616
|
+
|
|
1617
|
+
Conditional model entries are available only for evaluation requests. Keep the
|
|
1618
|
+
configuration under `providerOptions.gateway.models`. `experimental_evaluate`
|
|
1619
|
+
does not have a top-level fallback option.
|
|
1620
|
+
|
|
1621
|
+
```ts
|
|
1622
|
+
import type { GatewayEvaluationProviderOptions } from '@ai-sdk/gateway';
|
|
1623
|
+
import { experimental_evaluate } from 'ai';
|
|
1624
|
+
|
|
1625
|
+
const questions = {
|
|
1626
|
+
department: {
|
|
1627
|
+
type: 'choice',
|
|
1628
|
+
instructions: 'Which team should handle this?',
|
|
1629
|
+
criteria: { billing: 'Charges and refunds', support: 'Other requests' },
|
|
1630
|
+
},
|
|
1631
|
+
requestsRefund: {
|
|
1632
|
+
type: 'boolean',
|
|
1633
|
+
instructions: 'Is the customer requesting money back?',
|
|
1634
|
+
},
|
|
1635
|
+
} as const;
|
|
1636
|
+
|
|
1637
|
+
const result = await experimental_evaluate({
|
|
1638
|
+
model: 'typesafe-ai/jev',
|
|
1639
|
+
state: 'I was charged twice. Please refund the duplicate.',
|
|
1640
|
+
questions,
|
|
1641
|
+
providerOptions: {
|
|
1642
|
+
gateway: {
|
|
1643
|
+
models: [
|
|
1644
|
+
{
|
|
1645
|
+
model: 'openai/gpt-5.6-sol',
|
|
1646
|
+
when: {
|
|
1647
|
+
any: [
|
|
1648
|
+
{ question: 'department', confidenceBelow: 0.6 },
|
|
1649
|
+
{
|
|
1650
|
+
question: 'requestsRefund',
|
|
1651
|
+
probabilityBetween: [0.4, 0.6],
|
|
1652
|
+
},
|
|
1653
|
+
],
|
|
1654
|
+
},
|
|
1655
|
+
},
|
|
1656
|
+
],
|
|
1657
|
+
} satisfies GatewayEvaluationProviderOptions<keyof typeof questions>,
|
|
1658
|
+
},
|
|
1659
|
+
});
|
|
1660
|
+
|
|
1661
|
+
// The model that produced the answers, the fallback when the condition matched.
|
|
1662
|
+
console.log(result.response.modelId);
|
|
1663
|
+
console.log(JSON.stringify(result.providerMetadata?.gateway?.routing, null, 2));
|
|
1664
|
+
```
|
|
1665
|
+
|
|
1666
|
+
When the condition matches, `result.response.modelId` names the fallback model,
|
|
1667
|
+
and `providerMetadata.gateway.routing.modelAttempts` lists the primary and
|
|
1668
|
+
fallback attempts. The successful attempt of each stage carries its own
|
|
1669
|
+
`generationId`, `usage`, and cost fields, and the first fallback attempt lists
|
|
1670
|
+
the questions that triggered it in `triggeredBy`.
|
|
1671
|
+
|
|
1484
1672
|
#### Zero Data Retention Example
|
|
1485
1673
|
|
|
1486
1674
|
Set `zeroDataRetention` to true to route requests to providers with zero data retention agreements with Vercel for AI Gateway. BYOK credentials are skipped by default, since your provider agreements differ from Vercel's. When this filter is on, AI Gateway routes only to providers Vercel has ZDR agreements with for the model. If you have BYOK keys marked as ZDR, those keys are tried first, then AI Gateway falls back to its system credentials. You are responsible for the accuracy of that marking. Applies to both account-wide and request-level ZDR. The request fails if no ZDR-eligible credentials are available. When `zeroDataRetention` is `false` or not specified, there is no enforcement of restricting routing. Request-level ZDR is only available for Vercel Pro and Enterprise plans.
|
|
@@ -1540,7 +1728,7 @@ const { text } = await generateText({
|
|
|
1540
1728
|
|
|
1541
1729
|
#### Filtering by Model Capability
|
|
1542
1730
|
|
|
1543
|
-
Set `has` to restrict routing to provider models that have the specified capabilities. This applies to both BYOK and system credentials, since the capability is a property of the model rather than the credential. `'implicit-caching'` limits routing to models that perform automatic prompt caching, `'vision'` limits routing to models that accept image input, `'reasoning'` limits routing to models that support reasoning, and `'tool-use'` limits routing to models that support tool calling. Weight-format conditions (`'quantization:fp8'` to require, `'!quantization:fp8'` to exclude) limit routing by the serving provider's recorded weight format. If no provider model for the requested model satisfies the capabilities, the request fails.
|
|
1731
|
+
Set `has` to restrict routing to provider models that have the specified capabilities. This applies to both BYOK and system credentials, since the capability is a property of the model rather than the credential. `'implicit-caching'` limits routing to models that perform automatic prompt caching, `'vision'` limits routing to models that accept image input, `'reasoning'` limits routing to models that support reasoning, `'structured-output'` limits routing to models that support schema-constrained output, and `'tool-use'` limits routing to models that support tool calling. Weight-format conditions (`'quantization:fp8'` to require, `'!quantization:fp8'` to exclude) limit routing by the serving provider's recorded weight format. If no provider model for the requested model satisfies the capabilities, the request fails.
|
|
1544
1732
|
|
|
1545
1733
|
```ts
|
|
1546
1734
|
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/gateway",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "4.0.
|
|
4
|
+
"version": "4.0.95",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@ai-sdk/provider": "4.0.18",
|
|
34
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
34
|
+
"@ai-sdk/provider-utils": "5.0.49",
|
|
35
35
|
"@vercel/oidc": "3.2.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@ai-sdk/test-server": "2.0.
|
|
38
|
+
"@ai-sdk/test-server": "2.0.2",
|
|
39
39
|
"@types/node": "22.19.19",
|
|
40
40
|
"@vercel/ai-tsconfig": "0.0.0",
|
|
41
41
|
"tsup": "^8.5.1",
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
createJsonResponseHandler,
|
|
9
9
|
getErrorMessage,
|
|
10
10
|
lazySchema,
|
|
11
|
+
parseProviderOptions,
|
|
11
12
|
postJsonToApi,
|
|
12
13
|
resolve,
|
|
13
14
|
zodSchema,
|
|
@@ -17,6 +18,7 @@ import { z } from './zod';
|
|
|
17
18
|
import { asGatewayError } from './errors';
|
|
18
19
|
import { parseAuthMethod } from './errors/parse-auth-method';
|
|
19
20
|
import type { GatewayConfig } from './gateway-config';
|
|
21
|
+
import { gatewayEvaluationProviderOptionsSchema } from './gateway-provider-options';
|
|
20
22
|
|
|
21
23
|
export class GatewayEvaluationModel implements EvaluationModelV4 {
|
|
22
24
|
readonly specificationVersion = 'v4';
|
|
@@ -44,6 +46,15 @@ export class GatewayEvaluationModel implements EvaluationModelV4 {
|
|
|
44
46
|
}: Parameters<EvaluationModelV4['doEvaluate']>[0]): Promise<
|
|
45
47
|
Awaited<ReturnType<EvaluationModelV4['doEvaluate']>>
|
|
46
48
|
> {
|
|
49
|
+
const gatewayOptions = await parseProviderOptions({
|
|
50
|
+
provider: 'gateway',
|
|
51
|
+
providerOptions,
|
|
52
|
+
schema: gatewayEvaluationProviderOptionsSchema,
|
|
53
|
+
});
|
|
54
|
+
const validatedProviderOptions =
|
|
55
|
+
gatewayOptions == null
|
|
56
|
+
? providerOptions
|
|
57
|
+
: { ...providerOptions, gateway: gatewayOptions };
|
|
47
58
|
const resolvedHeaders = this.config.headers
|
|
48
59
|
? await resolve(this.config.headers)
|
|
49
60
|
: undefined;
|
|
@@ -63,7 +74,9 @@ export class GatewayEvaluationModel implements EvaluationModelV4 {
|
|
|
63
74
|
body: {
|
|
64
75
|
state,
|
|
65
76
|
questions,
|
|
66
|
-
...(
|
|
77
|
+
...(validatedProviderOptions
|
|
78
|
+
? { providerOptions: validatedProviderOptions }
|
|
79
|
+
: {}),
|
|
67
80
|
},
|
|
68
81
|
successfulResponseHandler: createJsonResponseHandler(
|
|
69
82
|
gatewayEvaluationResponseSchema,
|
|
@@ -84,7 +97,7 @@ export class GatewayEvaluationModel implements EvaluationModelV4 {
|
|
|
84
97
|
providerMetadata:
|
|
85
98
|
responseBody.providerMetadata as unknown as SharedV4ProviderMetadata,
|
|
86
99
|
response: {
|
|
87
|
-
modelId: this.modelId,
|
|
100
|
+
modelId: responseBody.model ?? this.modelId,
|
|
88
101
|
headers: responseHeaders,
|
|
89
102
|
body: rawValue,
|
|
90
103
|
},
|
|
@@ -152,6 +165,7 @@ const gatewayEvaluationResponseSchema = lazySchema(() =>
|
|
|
152
165
|
zodSchema(
|
|
153
166
|
z.object({
|
|
154
167
|
answers: z.record(z.string(), gatewayEvaluationAnswerSchema),
|
|
168
|
+
model: z.string().optional(),
|
|
155
169
|
rounding: z
|
|
156
170
|
.object({
|
|
157
171
|
probabilityDecimals: z.number().optional(),
|
|
@@ -1,4 +1,50 @@
|
|
|
1
|
+
import { lazySchema, zodSchema } from '@ai-sdk/provider-utils';
|
|
2
|
+
import type { ZodType } from 'zod/v4';
|
|
3
|
+
import { z } from './zod';
|
|
4
|
+
|
|
1
5
|
// https://vercel.com/docs/ai-gateway/provider-options
|
|
6
|
+
export const EVALUATION_FALLBACK_MAX_CONDITION_DEPTH = 5;
|
|
7
|
+
export const EVALUATION_FALLBACK_MAX_CONDITIONS_PER_LIST = 20;
|
|
8
|
+
export const EVALUATION_FALLBACK_MAX_QUESTION_LENGTH = 256;
|
|
9
|
+
export const EVALUATION_FALLBACK_MAX_MODEL_LENGTH = 256;
|
|
10
|
+
|
|
11
|
+
export const gatewayEvaluationProviderOptionsSchema = lazySchema(() =>
|
|
12
|
+
zodSchema(
|
|
13
|
+
z
|
|
14
|
+
.object({
|
|
15
|
+
models: gatewayModelFallbacksSchema.optional(),
|
|
16
|
+
})
|
|
17
|
+
.catchall(z.unknown()),
|
|
18
|
+
),
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A condition on the primary model's answers. `QUESTION_ID` narrows
|
|
23
|
+
* `question` to your question IDs. Groups nest at most five levels deep,
|
|
24
|
+
* which the SDK checks at runtime.
|
|
25
|
+
*/
|
|
26
|
+
export type EvaluationFallbackCondition<QUESTION_ID extends string = string> =
|
|
27
|
+
| ExclusiveCondition<{ question: QUESTION_ID; confidenceBelow: number }>
|
|
28
|
+
| ExclusiveCondition<{
|
|
29
|
+
question: QUESTION_ID;
|
|
30
|
+
probabilityBetween: [number, number];
|
|
31
|
+
}>
|
|
32
|
+
| ExclusiveCondition<{ any: EvaluationFallbackConditionList<QUESTION_ID> }>
|
|
33
|
+
| ExclusiveCondition<{ all: EvaluationFallbackConditionList<QUESTION_ID> }>
|
|
34
|
+
| ExclusiveCondition<{
|
|
35
|
+
atLeast: {
|
|
36
|
+
count: number;
|
|
37
|
+
conditions: EvaluationFallbackConditionList<QUESTION_ID>;
|
|
38
|
+
};
|
|
39
|
+
}>;
|
|
40
|
+
|
|
41
|
+
export type GatewayModelFallback<QUESTION_ID extends string = string> =
|
|
42
|
+
| string
|
|
43
|
+
| {
|
|
44
|
+
model: string;
|
|
45
|
+
when: EvaluationFallbackCondition<QUESTION_ID>;
|
|
46
|
+
};
|
|
47
|
+
|
|
2
48
|
export type GatewayProviderOptions = {
|
|
3
49
|
/**
|
|
4
50
|
* Service-owned options may be added by the Gateway without requiring an SDK
|
|
@@ -19,16 +65,18 @@ export type GatewayProviderOptions = {
|
|
|
19
65
|
* Restrict routing to provider models that satisfy every given entry.
|
|
20
66
|
*
|
|
21
67
|
* Entries are capability tags (`'implicit-caching'`, `'reasoning'`,
|
|
22
|
-
* `'tool-use'`, `'vision'`
|
|
23
|
-
*
|
|
24
|
-
* `'
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
68
|
+
* `'tool-use'`, `'vision'` (image input), `'structured-output'`
|
|
69
|
+
* (schema-constrained output)) or weight-format conditions:
|
|
70
|
+
* `'quantization:fp8'` requires the serving provider to report that weight
|
|
71
|
+
* format, `'!quantization:fp8'` excludes it (providers with no recorded
|
|
72
|
+
* format still pass an exclusion). Format values are an open space but must
|
|
73
|
+
* match `[a-zA-Z0-9._-]{1,32}` and compare case-insensitively. Unknown
|
|
74
|
+
* capability names are rejected by the Gateway with a 400.
|
|
28
75
|
*/
|
|
29
76
|
has?: Array<
|
|
30
77
|
| 'implicit-caching'
|
|
31
78
|
| 'reasoning'
|
|
79
|
+
| 'structured-output'
|
|
32
80
|
| 'tool-use'
|
|
33
81
|
| 'vision'
|
|
34
82
|
| `quantization:${string}`
|
|
@@ -41,7 +89,11 @@ export type GatewayProviderOptions = {
|
|
|
41
89
|
*/
|
|
42
90
|
idempotencyKey?: string;
|
|
43
91
|
|
|
44
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Array of model slugs specifying fallback models to use in order.
|
|
94
|
+
* Conditional entries are only valid on evaluation requests, see
|
|
95
|
+
* `GatewayEvaluationProviderOptions`.
|
|
96
|
+
*/
|
|
45
97
|
models?: string[];
|
|
46
98
|
|
|
47
99
|
/** Array of provider slugs that are the only ones allowed to be used. */
|
|
@@ -73,3 +125,153 @@ export type GatewayProviderOptions = {
|
|
|
73
125
|
/** Filter to providers with zero data retention agreements. */
|
|
74
126
|
zeroDataRetention?: boolean;
|
|
75
127
|
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Gateway provider options for evaluation requests. Same as
|
|
131
|
+
* `GatewayProviderOptions`, except `models` may start with one conditional
|
|
132
|
+
* `{ model, when }` entry followed by string error fallbacks.
|
|
133
|
+
*
|
|
134
|
+
* The SDK validates `models` strictly before sending the request, so new
|
|
135
|
+
* condition shapes need an SDK release. Other keys pass through unchanged.
|
|
136
|
+
*/
|
|
137
|
+
export type GatewayEvaluationProviderOptions<
|
|
138
|
+
QUESTION_ID extends string = string,
|
|
139
|
+
> = GatewayProviderOptionsWithoutModels & {
|
|
140
|
+
models?: GatewayModelFallbackList<QUESTION_ID>;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
type EvaluationFallbackConditionList<QUESTION_ID extends string> = [
|
|
144
|
+
EvaluationFallbackCondition<QUESTION_ID>,
|
|
145
|
+
...EvaluationFallbackCondition<QUESTION_ID>[],
|
|
146
|
+
];
|
|
147
|
+
|
|
148
|
+
type ConditionKey =
|
|
149
|
+
| 'question'
|
|
150
|
+
| 'confidenceBelow'
|
|
151
|
+
| 'probabilityBetween'
|
|
152
|
+
| 'any'
|
|
153
|
+
| 'all'
|
|
154
|
+
| 'atLeast';
|
|
155
|
+
|
|
156
|
+
// Rules out the other shapes' keys, so a condition can't mix two shapes.
|
|
157
|
+
type ExclusiveCondition<CONDITION> = CONDITION & {
|
|
158
|
+
[KEY in Exclude<ConditionKey, keyof CONDITION>]?: never;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
type GatewayProviderOptionsWithoutModels = {
|
|
162
|
+
[KEY in keyof GatewayProviderOptions as KEY extends 'models'
|
|
163
|
+
? never
|
|
164
|
+
: KEY]: GatewayProviderOptions[KEY];
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
type ConditionalGatewayModelFallback<QUESTION_ID extends string> = Exclude<
|
|
168
|
+
GatewayModelFallback<QUESTION_ID>,
|
|
169
|
+
string
|
|
170
|
+
>;
|
|
171
|
+
|
|
172
|
+
type GatewayModelFallbackList<QUESTION_ID extends string> =
|
|
173
|
+
| string[]
|
|
174
|
+
| [ConditionalGatewayModelFallback<QUESTION_ID>, ...string[]];
|
|
175
|
+
|
|
176
|
+
const probabilitySchema = z.number().finite().min(0).max(1);
|
|
177
|
+
const questionSchema = z
|
|
178
|
+
.string()
|
|
179
|
+
.min(1)
|
|
180
|
+
.max(EVALUATION_FALLBACK_MAX_QUESTION_LENGTH);
|
|
181
|
+
const directConditionSchema = z.union([
|
|
182
|
+
z
|
|
183
|
+
.object({
|
|
184
|
+
question: questionSchema,
|
|
185
|
+
confidenceBelow: probabilitySchema,
|
|
186
|
+
})
|
|
187
|
+
.strict(),
|
|
188
|
+
z
|
|
189
|
+
.object({
|
|
190
|
+
question: questionSchema,
|
|
191
|
+
probabilityBetween: z
|
|
192
|
+
.array(probabilitySchema)
|
|
193
|
+
.length(2)
|
|
194
|
+
.refine(([minimum, maximum]) => minimum <= maximum, {
|
|
195
|
+
message:
|
|
196
|
+
'probabilityBetween minimum must be less than or equal to maximum',
|
|
197
|
+
}),
|
|
198
|
+
})
|
|
199
|
+
.strict(),
|
|
200
|
+
]) as ZodType<EvaluationFallbackCondition>;
|
|
201
|
+
|
|
202
|
+
const groupBeyondMaxDepthSchema = z
|
|
203
|
+
.union([
|
|
204
|
+
z.object({ any: z.unknown() }),
|
|
205
|
+
z.object({ all: z.unknown() }),
|
|
206
|
+
z.object({ atLeast: z.unknown() }),
|
|
207
|
+
])
|
|
208
|
+
.superRefine((_, context) => {
|
|
209
|
+
context.addIssue({
|
|
210
|
+
code: 'custom',
|
|
211
|
+
message: `conditions can be nested at most ${EVALUATION_FALLBACK_MAX_CONDITION_DEPTH} levels deep`,
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const conditionalModelFallbackSchema = z
|
|
216
|
+
.object({
|
|
217
|
+
model: z.string().min(1).max(EVALUATION_FALLBACK_MAX_MODEL_LENGTH),
|
|
218
|
+
when: conditionSchema(1),
|
|
219
|
+
})
|
|
220
|
+
.strict();
|
|
221
|
+
|
|
222
|
+
const gatewayModelFallbacksSchema = z
|
|
223
|
+
.array(z.union([z.string(), conditionalModelFallbackSchema]))
|
|
224
|
+
.superRefine((entries, context) => {
|
|
225
|
+
const conditionalIndexes = entries.flatMap((entry, index) =>
|
|
226
|
+
typeof entry === 'string' ? [] : [index],
|
|
227
|
+
);
|
|
228
|
+
if (conditionalIndexes.length > 1) {
|
|
229
|
+
context.addIssue({
|
|
230
|
+
code: 'custom',
|
|
231
|
+
message: 'models supports at most one conditional evaluation fallback',
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
if (conditionalIndexes[0] !== undefined && conditionalIndexes[0] !== 0) {
|
|
235
|
+
context.addIssue({
|
|
236
|
+
code: 'custom',
|
|
237
|
+
message:
|
|
238
|
+
'a conditional evaluation fallback must be the first models entry',
|
|
239
|
+
path: [conditionalIndexes[0]],
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
function conditionSchema(depth: number): ZodType<EvaluationFallbackCondition> {
|
|
245
|
+
if (depth === EVALUATION_FALLBACK_MAX_CONDITION_DEPTH) {
|
|
246
|
+
return z.union([
|
|
247
|
+
directConditionSchema,
|
|
248
|
+
groupBeyondMaxDepthSchema,
|
|
249
|
+
]) as ZodType<EvaluationFallbackCondition>;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const childConditionSchema = conditionSchema(depth + 1);
|
|
253
|
+
const conditionListSchema = z
|
|
254
|
+
.array(childConditionSchema)
|
|
255
|
+
.min(1)
|
|
256
|
+
.max(EVALUATION_FALLBACK_MAX_CONDITIONS_PER_LIST);
|
|
257
|
+
|
|
258
|
+
return z.union([
|
|
259
|
+
directConditionSchema,
|
|
260
|
+
z.object({ any: conditionListSchema }).strict(),
|
|
261
|
+
z.object({ all: conditionListSchema }).strict(),
|
|
262
|
+
z
|
|
263
|
+
.object({
|
|
264
|
+
atLeast: z
|
|
265
|
+
.object({
|
|
266
|
+
count: z.number().int().min(1),
|
|
267
|
+
conditions: conditionListSchema,
|
|
268
|
+
})
|
|
269
|
+
.strict()
|
|
270
|
+
.refine(({ count, conditions }) => count <= conditions.length, {
|
|
271
|
+
message: 'atLeast count cannot exceed the number of conditions',
|
|
272
|
+
path: ['count'],
|
|
273
|
+
}),
|
|
274
|
+
})
|
|
275
|
+
.strict(),
|
|
276
|
+
]) as ZodType<EvaluationFallbackCondition>;
|
|
277
|
+
}
|
package/src/gateway-tools.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { browserbaseFetch } from './tool/browserbase-fetch';
|
|
2
|
+
import { browserbaseSearch } from './tool/browserbase-search';
|
|
1
3
|
import { exaSearch } from './tool/exa-search';
|
|
2
4
|
import { parallelSearch } from './tool/parallel-search';
|
|
3
5
|
import { perplexitySearch } from './tool/perplexity-search';
|
|
@@ -7,6 +9,22 @@ import { takoSearch } from './tool/tako-search';
|
|
|
7
9
|
* Gateway-specific provider-defined tools.
|
|
8
10
|
*/
|
|
9
11
|
export const gatewayTools = {
|
|
12
|
+
/**
|
|
13
|
+
* Fetch page content using Browserbase's lightweight Fetch API.
|
|
14
|
+
*
|
|
15
|
+
* Supports raw, Markdown, and schema-driven JSON output as well as redirects,
|
|
16
|
+
* proxy routing, and TLS controls.
|
|
17
|
+
*/
|
|
18
|
+
browserbaseFetch,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Search the web using Browserbase's Search API for fast, structured results.
|
|
22
|
+
*
|
|
23
|
+
* Returns titles, URLs, and available publication metadata without requiring
|
|
24
|
+
* a browser session.
|
|
25
|
+
*/
|
|
26
|
+
browserbaseSearch,
|
|
27
|
+
|
|
10
28
|
/**
|
|
11
29
|
* Search the web using Exa for current information and token-efficient
|
|
12
30
|
* excerpts optimized for agent workflows.
|
package/src/index.ts
CHANGED
|
@@ -47,6 +47,9 @@ export type {
|
|
|
47
47
|
GatewayProviderMetadata,
|
|
48
48
|
} from './gateway-provider-metadata';
|
|
49
49
|
export type {
|
|
50
|
+
EvaluationFallbackCondition,
|
|
51
|
+
GatewayEvaluationProviderOptions,
|
|
52
|
+
GatewayModelFallback,
|
|
50
53
|
GatewayProviderOptions,
|
|
51
54
|
/** @deprecated Use `GatewayProviderOptions` instead. */
|
|
52
55
|
GatewayProviderOptions as GatewayLanguageModelOptions,
|