@ai-sdk/gateway 4.0.131 → 4.0.133

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.
@@ -1422,6 +1422,100 @@ for await (const part of result.stream) {
1422
1422
  }
1423
1423
  ```
1424
1424
 
1425
+ #### DeepSeek Search and Fetch
1426
+
1427
+ Use `gateway.tools.deepseekSearch()` to search the web and
1428
+ `gateway.tools.deepseekFetch()` to retrieve a page as Markdown. Both tools call
1429
+ DeepSeek's standalone Search/Fetch APIs from AI Gateway and work with supported
1430
+ tool-calling models from any provider. They are separate from a model's built-in
1431
+ web search. No additional model provider package is required.
1432
+
1433
+ ```ts
1434
+ import { gateway, generateText } from 'ai';
1435
+
1436
+ const result = await generateText({
1437
+ model: 'openai/gpt-6-luna',
1438
+ prompt: 'Search for DeepSeek API documentation and fetch a relevant page.',
1439
+ tools: {
1440
+ deepseek_search: gateway.tools.deepseekSearch({
1441
+ count: 5,
1442
+ needContent: true,
1443
+ }),
1444
+ deepseek_fetch: gateway.tools.deepseekFetch(),
1445
+ },
1446
+ });
1447
+
1448
+ console.log(result.text);
1449
+ console.log(result.toolResults);
1450
+ for (const part of result.content) {
1451
+ if (part.type === 'tool-error') console.error('Tool error:', part.error);
1452
+ }
1453
+ ```
1454
+
1455
+ The Search tool supports the following optional configuration options:
1456
+
1457
+ - **query** _string_
1458
+
1459
+ Pin the search query; otherwise the model chooses it. Queries contain 1–128 Unicode characters and cannot be all whitespace.
1460
+
1461
+ - **count** _number_
1462
+
1463
+ Number of results, 1–50 (default: 10).
1464
+
1465
+ - **needContent** _boolean_
1466
+
1467
+ Include available page content (default: false).
1468
+
1469
+ - **oriQuestion** _string | null_
1470
+
1471
+ Original question, 1–128 Unicode characters. `null` means not provided.
1472
+
1473
+ - **localization** _string_
1474
+
1475
+ IP address used to localize results; developer configuration only.
1476
+
1477
+ The model-facing input uses `query`, `count`, `need_content`, and `ori_question`.
1478
+ Queries support search operators including `site:`, `-site:`, `lang:`, `after:`,
1479
+ `before:`, and quoted phrases. Search returns `{ results }`, containing ranked
1480
+ URLs, titles, snippets, summaries, optional page content, and nullable site/date
1481
+ metadata. An empty `results` array is a successful search with no matches.
1482
+
1483
+ Fetch accepts an HTTP(S) `url` up to 8,192 characters, without a username or
1484
+ password, and returns `{ content, title? }`. The content is Markdown. You can
1485
+ pin the URL with `gateway.tools.deepseekFetch({ url: 'https://example.com' })`.
1486
+ The Fetch tool supports the following optional configuration option:
1487
+
1488
+ - **url** _string_
1489
+
1490
+ Pin the HTTP(S) URL; otherwise the model chooses it.
1491
+
1492
+ Tool failures appear as `tool-error` parts in `result.content` (for
1493
+ `generateText`) or `result.stream` (for `streamText`). Inspect `part.error`
1494
+ there; failures are not included in `result.toolResults`.
1495
+
1496
+ The tools also work with `streamText`:
1497
+
1498
+ ```ts
1499
+ import { gateway, streamText } from 'ai';
1500
+
1501
+ const result = streamText({
1502
+ model: 'openai/gpt-6-luna',
1503
+ prompt: 'Search for DeepSeek API documentation and fetch a relevant page.',
1504
+ tools: {
1505
+ deepseek_search: gateway.tools.deepseekSearch(),
1506
+ deepseek_fetch: gateway.tools.deepseekFetch(),
1507
+ },
1508
+ });
1509
+
1510
+ for await (const part of result.stream) {
1511
+ if (part.type === 'text-delta') process.stdout.write(part.text);
1512
+ if (part.type === 'tool-error') console.error('Tool error:', part.error);
1513
+ }
1514
+ ```
1515
+
1516
+ See the [DeepSeek API guide](https://api-docs.deepseek.com/guides/search/) for the
1517
+ underlying APIs.
1518
+
1425
1519
  ### Custom Reporting
1426
1520
 
1427
1521
  Track usage per end-user and categorize requests with tags, then query the data through the reporting API.
@@ -1527,7 +1621,7 @@ The AI Gateway provider accepts provider options that control routing behavior a
1527
1621
 
1528
1622
  ### Gateway Provider Options
1529
1623
 
1530
- You can use the `gateway` key in `providerOptions` to control how AI Gateway routes requests:
1624
+ You can use the `gateway` key in `providerOptions` to control how AI Gateway routes requests. Without any routing options, AI Gateway picks providers based on recent uptime and latency and falls back to other providers that serve the same model, so most applications don't need to set them.
1531
1625
 
1532
1626
  ```ts
1533
1627
  import type { GatewayProviderOptions } from '@ai-sdk/gateway';
@@ -1538,8 +1632,7 @@ const { text } = await generateText({
1538
1632
  prompt: 'Explain quantum computing',
1539
1633
  providerOptions: {
1540
1634
  gateway: {
1541
- order: ['vertex', 'anthropic'], // Try Vertex AI first, then Anthropic
1542
- only: ['vertex', 'anthropic'], // Only use these providers
1635
+ order: ['vertex', 'anthropic'], // Try Vertex AI first, then Anthropic, then other providers
1543
1636
  } satisfies GatewayProviderOptions,
1544
1637
  },
1545
1638
  });
@@ -1557,6 +1650,8 @@ The following gateway provider options are available:
1557
1650
 
1558
1651
  Restricts routing to only the specified providers. When set, the gateway will never route to providers not in this list, even if they would otherwise be available.
1559
1652
 
1653
+ Because unlisted providers are never tried, the request fails instead of falling back when the listed providers are unavailable. When the requirement is about data handling or a model capability, `zeroDataRetention`, `disallowPromptTraining`, or `has` filter by that requirement while keeping every qualifying provider eligible.
1654
+
1560
1655
  Example: `only: ['anthropic', 'vertex']` will only allow routing to Anthropic or Vertex AI.
1561
1656
 
1562
1657
  - **sort** _'cost' | 'ttft' | 'tps'_
@@ -1669,7 +1764,7 @@ The following gateway provider options are available:
1669
1764
  });
1670
1765
  ```
1671
1766
 
1672
- You can combine these options to have fine-grained control over routing and tracking:
1767
+ You can combine these options to have fine-grained control over routing and tracking. For example, prefer Vertex AI while keeping fallbacks, and require zero data retention:
1673
1768
 
1674
1769
  ```ts
1675
1770
  import type { GatewayProviderOptions } from '@ai-sdk/gateway';
@@ -1681,7 +1776,7 @@ const { text } = await generateText({
1681
1776
  providerOptions: {
1682
1777
  gateway: {
1683
1778
  order: ['vertex'], // Prefer Vertex AI
1684
- only: ['anthropic', 'vertex'], // Only allow these providers
1779
+ zeroDataRetention: true, // Only route to providers with zero data retention agreements
1685
1780
  } satisfies GatewayProviderOptions,
1686
1781
  },
1687
1782
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ai-sdk/gateway",
3
3
  "private": false,
4
- "version": "4.0.131",
4
+ "version": "4.0.133",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "sideEffects": false,
@@ -1,8 +1,8 @@
1
1
  export type GatewayDecisionModelId =
2
2
  | 'baseten/elephant-1'
3
+ | 'baseten/joey-1'
3
4
  | 'baseten/mammoth-1'
4
5
  | 'convaiinnovations/laya'
5
- | 'convaiinnovations/laya-free'
6
6
  | 'liquid/d1'
7
7
  | 'liquid/d1-ultra'
8
8
  | 'microsoft/microsoft-decision-1'
@@ -59,7 +59,6 @@ export type GatewayModelId =
59
59
  | 'anthropic/claude-sonnet-5-batch'
60
60
  | 'anthropic/claude-sonnet-5.5'
61
61
  | 'anthropic/claude-sonnet-5.5-batch'
62
- | 'arcee-ai/trinity-large-thinking'
63
62
  | 'bytedance/seed-1.6'
64
63
  | 'bytedance/seed-1.8'
65
64
  | 'bytedance/seed-2.1-turbo'
@@ -120,11 +119,12 @@ export type GatewayModelId =
120
119
  | 'inclusionai/ling-3.0-flash-sante'
121
120
  | 'inclusionai/ling-3.0-flash-vl'
122
121
  | 'inclusionai/ling-3.1-flash'
122
+ | 'inclusionai/ling-3.1-flash-1019'
123
123
  | 'inference-net/schematron-v2-small'
124
124
  | 'inference-net/schematron-v2-turbo'
125
125
  | 'interfaze/interfaze-beta'
126
126
  | 'liquid/lfm2.5-24b-a2b'
127
- | 'meituan/longcat-2.5-preview'
127
+ | 'meituan/longcat-2.5'
128
128
  | 'meta/llama-3.1-70b'
129
129
  | 'meta/llama-3.1-8b'
130
130
  | 'meta/llama-3.3-70b'
@@ -262,7 +262,6 @@ export type GatewayModelId =
262
262
  | 'particle/particle-1'
263
263
  | 'perplexity/sonar'
264
264
  | 'poolside/laguna-s-2.1'
265
- | 'poolside/laguna-s-2.1-free'
266
265
  | 'quiverai/arrow-2'
267
266
  | 'quiverai/arrow-2-telos'
268
267
  | 'reflection/beam'
@@ -319,5 +318,6 @@ export type GatewayModelId =
319
318
  | 'zai/glm-5.3-fast'
320
319
  | 'zai/glm-5.3-flash'
321
320
  | 'zai/glm-5.3-flashx'
321
+ | 'zai/glm-5.3-flashx-legal'
322
322
  | 'zai/glm-5v-turbo'
323
323
  | (string & {});
@@ -1,5 +1,7 @@
1
1
  import { browserbaseFetch } from './tool/browserbase-fetch';
2
2
  import { browserbaseSearch } from './tool/browserbase-search';
3
+ import { deepseekFetch } from './tool/deepseek-fetch';
4
+ import { deepseekSearch } from './tool/deepseek-search';
3
5
  import { exaSearch } from './tool/exa-search';
4
6
  import { parallelSearch } from './tool/parallel-search';
5
7
  import { perplexitySearch } from './tool/perplexity-search';
@@ -25,6 +27,18 @@ export const gatewayTools = {
25
27
  */
26
28
  browserbaseSearch,
27
29
 
30
+ /**
31
+ * Fetch a page as Markdown through DeepSeek's standalone Fetch API.
32
+ * Executed by AI Gateway for any model, separate from native model web search.
33
+ */
34
+ deepseekFetch,
35
+
36
+ /**
37
+ * Search the web through DeepSeek's standalone Search API.
38
+ * Executed by AI Gateway for any model, separate from native model web search.
39
+ */
40
+ deepseekSearch,
41
+
28
42
  /**
29
43
  * Search the web using Exa for current information and token-efficient
30
44
  * excerpts optimized for agent workflows.
@@ -0,0 +1,68 @@
1
+ import {
2
+ createProviderExecutedToolFactory,
3
+ lazySchema,
4
+ zodSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from '../zod';
7
+ import {
8
+ gatewayToolErrorSchema,
9
+ type GatewayToolError,
10
+ } from './gateway-tool-error';
11
+
12
+ export interface DeepSeekFetchConfig {
13
+ /** Pin the target URL instead of allowing the model to choose it. */
14
+ url?: string;
15
+ }
16
+
17
+ export interface DeepSeekFetchInput {
18
+ url: string;
19
+ }
20
+
21
+ export interface DeepSeekFetchResponse {
22
+ title?: string | null;
23
+ /** Page content as Markdown. */
24
+ content: string;
25
+ }
26
+
27
+ export type DeepSeekFetchOutput = DeepSeekFetchResponse | GatewayToolError;
28
+
29
+ const deepseekFetchInputSchema = lazySchema(() =>
30
+ zodSchema(
31
+ z.object({
32
+ url: z
33
+ .string()
34
+ .describe(
35
+ 'URL to fetch, at most 8192 characters; HTTP(S) only, without a username or password.',
36
+ ),
37
+ }),
38
+ ),
39
+ );
40
+
41
+ const deepseekFetchOutputSchema = lazySchema(() =>
42
+ zodSchema(
43
+ z.union([
44
+ z
45
+ .object({
46
+ title: z.string().nullish(),
47
+ content: z.string(),
48
+ })
49
+ .passthrough(),
50
+ gatewayToolErrorSchema(),
51
+ ]),
52
+ ),
53
+ );
54
+
55
+ export const deepseekFetchToolFactory = createProviderExecutedToolFactory<
56
+ DeepSeekFetchInput,
57
+ DeepSeekFetchOutput,
58
+ DeepSeekFetchConfig
59
+ >({
60
+ id: 'gateway.deepseek_fetch',
61
+ inputSchema: deepseekFetchInputSchema,
62
+ outputSchema: deepseekFetchOutputSchema,
63
+ });
64
+
65
+ export const deepseekFetch = (
66
+ config: DeepSeekFetchConfig = {},
67
+ ): ReturnType<typeof deepseekFetchToolFactory> =>
68
+ deepseekFetchToolFactory(config);
@@ -0,0 +1,118 @@
1
+ import {
2
+ createProviderExecutedToolFactory,
3
+ lazySchema,
4
+ zodSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from '../zod';
7
+ import {
8
+ gatewayToolErrorSchema,
9
+ type GatewayToolError,
10
+ } from './gateway-tool-error';
11
+
12
+ export interface DeepSeekSearchConfig {
13
+ /** Pin the query instead of allowing the model to choose it. */
14
+ query?: string;
15
+ /** Maximum number of results, 1–50 (default: 10). */
16
+ count?: number;
17
+ /** Include available page content (default: false). */
18
+ needContent?: boolean;
19
+ /** Original question, 1–128 Unicode characters; null means absent. */
20
+ oriQuestion?: string | null;
21
+ /** Developer-configured IP address for result localization. */
22
+ localization?: string;
23
+ }
24
+
25
+ export interface DeepSeekSearchInput {
26
+ query: string;
27
+ count?: number;
28
+ need_content?: boolean;
29
+ ori_question?: string | null;
30
+ }
31
+
32
+ export interface DeepSeekSearchResult {
33
+ authority?: number | null;
34
+ content?: string | null;
35
+ date?: string | null;
36
+ rerank_score?: number | null;
37
+ site_icon?: string | null;
38
+ site_name?: string | null;
39
+ snippet?: string | null;
40
+ summary?: string | null;
41
+ title?: string | null;
42
+ url?: string | null;
43
+ }
44
+
45
+ export interface DeepSeekSearchResponse {
46
+ results: DeepSeekSearchResult[];
47
+ }
48
+
49
+ export type DeepSeekSearchOutput = DeepSeekSearchResponse | GatewayToolError;
50
+
51
+ const deepseekSearchInputSchema = lazySchema(() =>
52
+ zodSchema(
53
+ z.object({
54
+ query: z
55
+ .string()
56
+ .describe(
57
+ 'Web search query, 1 to 128 Unicode characters. Supports site:, -site:, lang:, after:, before:, and quoted phrases.',
58
+ ),
59
+ count: z
60
+ .number()
61
+ .int()
62
+ .optional()
63
+ .describe('Number of results, 1 to 50 (default: 10).'),
64
+ need_content: z
65
+ .boolean()
66
+ .optional()
67
+ .describe('Include available page content (default: false).'),
68
+ ori_question: z
69
+ .string()
70
+ .nullable()
71
+ .optional()
72
+ .describe('Original user question, 1 to 128 Unicode characters.'),
73
+ }),
74
+ ),
75
+ );
76
+
77
+ const deepseekSearchOutputSchema = lazySchema(() =>
78
+ zodSchema(
79
+ z.union([
80
+ z
81
+ .object({
82
+ results: z.array(
83
+ z
84
+ .object({
85
+ authority: z.number().nullish(),
86
+ content: z.string().nullish(),
87
+ date: z.string().nullish(),
88
+ rerank_score: z.number().nullish(),
89
+ site_icon: z.string().nullish(),
90
+ site_name: z.string().nullish(),
91
+ snippet: z.string().nullish(),
92
+ summary: z.string().nullish(),
93
+ title: z.string().nullish(),
94
+ url: z.string().nullish(),
95
+ })
96
+ .passthrough(),
97
+ ),
98
+ })
99
+ .passthrough(),
100
+ gatewayToolErrorSchema(),
101
+ ]),
102
+ ),
103
+ );
104
+
105
+ export const deepseekSearchToolFactory = createProviderExecutedToolFactory<
106
+ DeepSeekSearchInput,
107
+ DeepSeekSearchOutput,
108
+ DeepSeekSearchConfig
109
+ >({
110
+ id: 'gateway.deepseek_search',
111
+ inputSchema: deepseekSearchInputSchema,
112
+ outputSchema: deepseekSearchOutputSchema,
113
+ });
114
+
115
+ export const deepseekSearch = (
116
+ config: DeepSeekSearchConfig = {},
117
+ ): ReturnType<typeof deepseekSearchToolFactory> =>
118
+ deepseekSearchToolFactory(config);
@@ -0,0 +1,39 @@
1
+ import { z } from '../zod';
2
+
3
+ export interface GatewayToolError {
4
+ error:
5
+ | 'api_error'
6
+ | 'configuration_error'
7
+ | 'execution_error'
8
+ | 'gateway_rate_limit'
9
+ | 'invalid_input'
10
+ | 'rate_limit'
11
+ | 'timeout'
12
+ | 'unknown'
13
+ | 'unknown_tool';
14
+ message: string;
15
+ statusCode?: number;
16
+ retryAfter?: string;
17
+ statusText?: string;
18
+ }
19
+
20
+ export const gatewayToolErrorSchema = () =>
21
+ z
22
+ .object({
23
+ error: z.enum([
24
+ 'api_error',
25
+ 'configuration_error',
26
+ 'execution_error',
27
+ 'gateway_rate_limit',
28
+ 'invalid_input',
29
+ 'rate_limit',
30
+ 'timeout',
31
+ 'unknown',
32
+ 'unknown_tool',
33
+ ]),
34
+ message: z.string(),
35
+ statusCode: z.number().optional(),
36
+ retryAfter: z.string().optional(),
37
+ statusText: z.string().optional(),
38
+ })
39
+ .passthrough();
@@ -4,6 +4,10 @@ import {
4
4
  zodSchema,
5
5
  } from '@ai-sdk/provider-utils';
6
6
  import { z } from '../zod';
7
+ import {
8
+ gatewayToolErrorSchema,
9
+ type GatewayToolError,
10
+ } from './gateway-tool-error';
7
11
 
8
12
  const parallelSearchModes = [
9
13
  'turbo',
@@ -153,23 +157,7 @@ export interface ParallelSearchResponse {
153
157
  session_id?: string;
154
158
  }
155
159
 
156
- export interface ParallelSearchError {
157
- /** Error type */
158
- error:
159
- | 'api_error'
160
- | 'configuration_error'
161
- | 'execution_error'
162
- | 'gateway_rate_limit'
163
- | 'invalid_input'
164
- | 'rate_limit'
165
- | 'timeout'
166
- | 'unknown'
167
- | 'unknown_tool';
168
- /** HTTP status code if applicable */
169
- statusCode?: number;
170
- /** Human-readable error message */
171
- message: string;
172
- }
160
+ export type ParallelSearchError = GatewayToolError;
173
161
 
174
162
  export interface ParallelSearchInput {
175
163
  /**
@@ -375,21 +363,7 @@ const parallelSearchOutputSchema = lazySchema(() =>
375
363
  session_id: z.string().optional(),
376
364
  }),
377
365
  // Error response
378
- z.object({
379
- error: z.enum([
380
- 'api_error',
381
- 'configuration_error',
382
- 'execution_error',
383
- 'gateway_rate_limit',
384
- 'invalid_input',
385
- 'rate_limit',
386
- 'timeout',
387
- 'unknown',
388
- 'unknown_tool',
389
- ]),
390
- statusCode: z.number().optional(),
391
- message: z.string(),
392
- }),
366
+ gatewayToolErrorSchema(),
393
367
  ]),
394
368
  ),
395
369
  );
@@ -4,6 +4,10 @@ import {
4
4
  zodSchema,
5
5
  } from '@ai-sdk/provider-utils';
6
6
  import { z } from '../zod';
7
+ import {
8
+ gatewayToolErrorSchema,
9
+ type GatewayToolError,
10
+ } from './gateway-tool-error';
7
11
 
8
12
  export type TakoSearchEffort = 'deep' | 'fast' | 'instant';
9
13
 
@@ -246,18 +250,7 @@ export interface TakoSearchResponse {
246
250
  related?: Array<Record<string, unknown>> | null;
247
251
  }
248
252
 
249
- export interface TakoSearchError {
250
- error:
251
- | 'api_error'
252
- | 'configuration_error'
253
- | 'execution_error'
254
- | 'invalid_input'
255
- | 'rate_limit'
256
- | 'timeout'
257
- | 'unknown_tool';
258
- statusCode?: number;
259
- message: string;
260
- }
253
+ export type TakoSearchError = GatewayToolError;
261
254
 
262
255
  export type TakoSearchOutput = TakoSearchError | TakoSearchResponse;
263
256
 
@@ -570,19 +563,7 @@ const takoSearchOutputSchema = lazySchema(() =>
570
563
  related: z.array(z.object({}).passthrough()).nullish(),
571
564
  })
572
565
  .passthrough(),
573
- z.object({
574
- error: z.enum([
575
- 'api_error',
576
- 'configuration_error',
577
- 'execution_error',
578
- 'invalid_input',
579
- 'rate_limit',
580
- 'timeout',
581
- 'unknown_tool',
582
- ]),
583
- statusCode: z.number().optional(),
584
- message: z.string(),
585
- }),
566
+ gatewayToolErrorSchema(),
586
567
  ]),
587
568
  ),
588
569
  );