ai 7.0.58 → 7.0.60

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # ai
2
2
 
3
+ ## 7.0.60
4
+
5
+ ### Patch Changes
6
+
7
+ - 79c52ef: Align `ToolLoopAgent` `prepareCall` types with the settings available and honored at runtime.
8
+ - Updated dependencies [3cc1bb6]
9
+ - @ai-sdk/gateway@4.0.48
10
+
11
+ ## 7.0.59
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [401a4ba]
16
+ - Updated dependencies [7af9646]
17
+ - @ai-sdk/provider-utils@5.0.26
18
+ - @ai-sdk/gateway@4.0.47
19
+
3
20
  ## 7.0.58
4
21
 
5
22
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -5122,9 +5122,9 @@ type ToolLoopAgentSettings<CALL_OPTIONS = never, TOOLS extends ToolSet = {}, RUN
5122
5122
  * }),
5123
5123
  * ```
5124
5124
  */
5125
- prepareCall?: (options: Omit<AgentCallParameters<CALL_OPTIONS, NoInfer<TOOLS>, NoInfer<RUNTIME_CONTEXT>>, 'onStepEnd' | 'onStepFinish'> & Pick<ToolLoopAgentSettings<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT, NoInfer<OUTPUT>>, 'model' | 'tools' | 'maxOutputTokens' | 'temperature' | 'topP' | 'topK' | 'presencePenalty' | 'frequencyPenalty' | 'stopSequences' | 'seed' | 'reasoning' | 'headers' | 'instructions' | 'allowSystemInMessages' | 'stopWhen' | 'telemetry' | 'experimental_telemetry' | 'activeTools' | 'toolOrder' | 'toolApproval' | 'experimental_toolCallers' | 'providerOptions' | 'experimental_download' | 'experimental_refineToolInput' | 'include' | 'runtimeContext' | '_internal'> & {
5125
+ prepareCall?: (options: Omit<AgentCallParameters<CALL_OPTIONS, NoInfer<TOOLS>, NoInfer<RUNTIME_CONTEXT>>, 'abortSignal' | 'timeout' | 'onStart' | 'experimental_onStart' | 'onStepStart' | 'experimental_onStepStart' | 'onToolExecutionStart' | 'onToolExecutionEnd' | 'onStepEnd' | 'onStepFinish' | 'onEnd' | 'onFinish'> & Pick<ToolLoopAgentSettings<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT, NoInfer<OUTPUT>>, 'model' | 'tools' | 'toolChoice' | 'maxRetries' | 'maxOutputTokens' | 'temperature' | 'topP' | 'topK' | 'presencePenalty' | 'frequencyPenalty' | 'stopSequences' | 'seed' | 'reasoning' | 'headers' | 'instructions' | 'allowSystemInMessages' | 'stopWhen' | 'telemetry' | 'experimental_telemetry' | 'activeTools' | 'toolOrder' | 'toolApproval' | 'experimental_toolCallers' | 'prepareStep' | 'repairToolCall' | 'experimental_repairToolCall' | 'providerOptions' | 'experimental_download' | 'experimental_refineToolInput' | 'include' | 'runtimeContext' | '_internal'> & {
5126
5126
  toolsContext: InferToolSetContext<TOOLS>;
5127
- }) => MaybePromiseLike<Pick<ToolLoopAgentSettings<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT, NoInfer<OUTPUT>>, 'model' | 'tools' | 'maxOutputTokens' | 'temperature' | 'topP' | 'topK' | 'presencePenalty' | 'frequencyPenalty' | 'stopSequences' | 'seed' | 'reasoning' | 'headers' | 'instructions' | 'allowSystemInMessages' | 'stopWhen' | 'telemetry' | 'experimental_telemetry' | 'activeTools' | 'toolOrder' | 'toolApproval' | 'experimental_toolCallers' | 'providerOptions' | 'experimental_download' | 'experimental_refineToolInput' | 'include' | 'runtimeContext' | '_internal'> & Omit<Prompt, 'system'> & {
5127
+ }) => MaybePromiseLike<Pick<ToolLoopAgentSettings<CALL_OPTIONS, TOOLS, RUNTIME_CONTEXT, NoInfer<OUTPUT>>, 'model' | 'tools' | 'toolChoice' | 'maxRetries' | 'maxOutputTokens' | 'temperature' | 'topP' | 'topK' | 'presencePenalty' | 'frequencyPenalty' | 'stopSequences' | 'seed' | 'reasoning' | 'headers' | 'instructions' | 'allowSystemInMessages' | 'stopWhen' | 'telemetry' | 'experimental_telemetry' | 'activeTools' | 'toolOrder' | 'toolApproval' | 'experimental_toolCallers' | 'prepareStep' | 'repairToolCall' | 'experimental_repairToolCall' | 'providerOptions' | 'experimental_download' | 'experimental_refineToolInput' | 'include' | 'runtimeContext' | '_internal'> & Omit<Prompt, 'system'> & {
5128
5128
  toolsContext: InferToolSetContext<TOOLS>;
5129
5129
  }>;
5130
5130
  };
package/dist/index.js CHANGED
@@ -1143,7 +1143,7 @@ import {
1143
1143
  } from "@ai-sdk/provider-utils";
1144
1144
 
1145
1145
  // src/version.ts
1146
- var VERSION = true ? "7.0.58" : "0.0.0-test";
1146
+ var VERSION = true ? "7.0.60" : "0.0.0-test";
1147
1147
 
1148
1148
  // src/util/download/download.ts
1149
1149
  var download = async ({
@@ -92,7 +92,7 @@ import {
92
92
  } from "@ai-sdk/provider-utils";
93
93
 
94
94
  // src/version.ts
95
- var VERSION = true ? "7.0.58" : "0.0.0-test";
95
+ var VERSION = true ? "7.0.60" : "0.0.0-test";
96
96
 
97
97
  // src/util/download/download.ts
98
98
  var download = async ({
@@ -364,7 +364,8 @@ console.log(preparation.identity);
364
364
  - `harness`: the adapter instance.
365
365
  - `sandbox`: a `HarnessV1SandboxProvider`.
366
366
  - `id`: optional stable agent identifier.
367
- - `instructions`: instructions applied once to a fresh session.
367
+ - `instructions`: instructions appended to the runtime's system or developer
368
+ prompt when supported, or prepended to the first user prompt otherwise.
368
369
  - `stopWhen`: condition(s) for finishing a result slice after a completed
369
370
  harness tool step that can continue into another model step.
370
371
  - `tools`: AI SDK tools executed by the host when the harness calls them.
@@ -5,11 +5,13 @@ description: Use tools with AI SDK harnesses.
5
5
 
6
6
  # Harness Tools
7
7
 
8
- Harnesses have two tool surfaces:
8
+ Harnesses have three tool surfaces:
9
9
 
10
10
  - Built-in tools exposed by the underlying harness runtime, such as file reads,
11
11
  edits, shell commands, and web search.
12
12
  - AI SDK tools that you pass to `HarnessAgent` with the `tools` setting.
13
+ - External MCP tools configured through the harness adapter's `mcpServers`
14
+ setting.
13
15
 
14
16
  This page covers harness-specific behavior. For general AI SDK tool concepts,
15
17
  schemas, tool results, and `tool()` usage, see [Tools](/docs/foundations/tools).
@@ -44,7 +44,7 @@ export async function POST(req: Request) {
44
44
  ## AI SDK UI
45
45
 
46
46
  The hooks, e.g. `useChat` or `useCompletion`, provide a `stop` helper function that can be used to cancel a stream.
47
- This will cancel the stream from the client side to the server.
47
+ This aborts the HTTP request from the client. To also stop the model request on the server, your server runtime must propagate the client disconnect to the request's `AbortSignal`, and your route must forward that signal to the AI SDK Core call as shown above.
48
48
 
49
49
  <Note type="warning">
50
50
  Stream abort functionality is not compatible with stream resumption. If you're
@@ -78,6 +78,27 @@ export default function Chat() {
78
78
  }
79
79
  ```
80
80
 
81
+ ### Vercel
82
+
83
+ On Vercel, [request cancellation](https://vercel.com/docs/functions/functions-api-reference#cancel-requests) is only supported in the Node.js runtime and must be enabled for each function that needs it. Add `supportsCancellation` to the function's configuration in `vercel.json`:
84
+
85
+ ```json filename="vercel.json"
86
+ {
87
+ "functions": {
88
+ "app/api/chat/route.ts": {
89
+ "supportsCancellation": true
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ With cancellation enabled, calling `stop()` aborts the client request, Vercel aborts `req.signal`, and forwarding `req.signal` as `abortSignal` cancels the model request.
96
+
97
+ <Note type="warning">
98
+ Without `supportsCancellation`, `stop()` still stops the client-side stream
99
+ but the server-side generation may continue.
100
+ </Note>
101
+
81
102
  ## Handling stream abort cleanup
82
103
 
83
104
  When streams are aborted, you may need to perform cleanup operations such as persisting partial results or cleaning up resources. The `onAbort` callback provides a way to handle these scenarios on the server side.
@@ -120,9 +120,7 @@ You can see a full example of caching with Redis in a Next.js application in our
120
120
 
121
121
  Alternatively, each AI SDK Core function has special lifecycle callbacks you can use. The one of interest is likely `onEnd`, which is called when the generation is complete. This is where you can cache the full response.
122
122
 
123
- Here's an example of how you can implement caching using Vercel KV and Next.js to cache the OpenAI response for 1 hour:
124
-
125
- This example uses [Upstash Redis](https://upstash.com/docs/redis/overall/getstarted) and Next.js to cache the response for 1 hour.
123
+ Here's an example of how you can use [Upstash Redis](https://upstash.com/redis) and Next.js to cache the OpenAI response for 1 hour:
126
124
 
127
125
  ```tsx filename="app/api/chat/route.ts"
128
126
  import {
@@ -11,13 +11,11 @@ specified timeframe. This simple technique acts as a gatekeeper,
11
11
  preventing excessive usage that can degrade service performance and incur
12
12
  unnecessary costs.
13
13
 
14
- ## Rate Limiting with Vercel KV and Upstash Ratelimit
14
+ ## Rate Limiting with Upstash Redis and Upstash Ratelimit
15
15
 
16
- In this example, you will protect an API endpoint using [Vercel KV](https://vercel.com/storage/kv)
17
- and [Upstash Ratelimit](https://github.com/upstash/ratelimit).
16
+ In this example, you will protect an API endpoint using [Upstash Redis](https://upstash.com/redis) and [Upstash Ratelimit](https://github.com/upstash/ratelimit).
18
17
 
19
18
  ```tsx filename='app/api/generate/route.ts'
20
- import kv from '@vercel/kv';
21
19
  import {
22
20
  createUIMessageStreamResponse,
23
21
  streamText,
@@ -25,6 +23,7 @@ import {
25
23
  } from 'ai';
26
24
  __PROVIDER_IMPORT__;
27
25
  import { Ratelimit } from '@upstash/ratelimit';
26
+ import { Redis } from '@upstash/redis';
28
27
  import { NextRequest } from 'next/server';
29
28
 
30
29
  // Allow streaming responses up to 30 seconds
@@ -32,7 +31,7 @@ export const maxDuration = 30;
32
31
 
33
32
  // Create Rate limit
34
33
  const ratelimit = new Ratelimit({
35
- redis: kv,
34
+ redis: Redis.fromEnv(),
36
35
  limiter: Ratelimit.fixedWindow(5, '30s'),
37
36
  });
38
37
 
@@ -61,6 +60,6 @@ export async function POST(req: NextRequest) {
61
60
 
62
61
  ## Simplify API Protection
63
62
 
64
- With Vercel KV and Upstash Ratelimit, it is possible to protect your APIs
63
+ With Upstash Redis and Upstash Ratelimit, it is possible to protect your APIs
65
64
  from such attacks with ease. To learn more about how Ratelimit works and
66
65
  how it can be configured to your needs, see [Ratelimit Documentation](https://upstash.com/docs/oss/sdks/ts/ratelimit/overview).
@@ -95,6 +95,47 @@ export const maxDuration = 30;
95
95
 
96
96
  You can increase the max duration to 60 seconds on the Hobby Tier. For other tiers, [see the documentation](https://vercel.com/docs/functions/runtimes#max-duration) for limits.
97
97
 
98
+ ### Request Cancellation
99
+
100
+ AI SDK UI helpers such as `useChat` and `useCompletion` abort the client request when you call `stop()`. To propagate that cancellation to a Vercel Function and its model request, you must:
101
+
102
+ 1. Use the Node.js runtime, which is the default for Next.js route handlers.
103
+ 2. Enable [`supportsCancellation`](https://vercel.com/docs/functions/functions-api-reference#cancel-requests) for the route in `vercel.json`.
104
+ 3. Forward the route's `req.signal` to `streamText` or `generateText` as `abortSignal`.
105
+
106
+ For example, enable cancellation for your chat route:
107
+
108
+ ```json filename="vercel.json"
109
+ {
110
+ "functions": {
111
+ "app/api/chat/route.ts": {
112
+ "supportsCancellation": true
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ Then forward the request signal to the AI SDK:
119
+
120
+ ```ts filename="app/api/chat/route.ts" highlight="10"
121
+ import { convertToModelMessages, streamText, type UIMessage } from 'ai';
122
+ __PROVIDER_IMPORT__;
123
+
124
+ export async function POST(req: Request) {
125
+ const { messages }: { messages: UIMessage[] } = await req.json();
126
+
127
+ const result = streamText({
128
+ model: __MODEL__,
129
+ messages: convertToModelMessages(messages),
130
+ abortSignal: req.signal,
131
+ });
132
+
133
+ return result.toUIMessageStreamResponse();
134
+ }
135
+ ```
136
+
137
+ Without `supportsCancellation`, calling `stop()` closes the client-side stream but does not cancel the Vercel Function or model request. See [Stopping Streams](/docs/advanced/stopping-streams) for the complete client and server setup.
138
+
98
139
  ## Security Considerations
99
140
 
100
141
  Given the high cost of calling an LLM, it's important to have measures in place that can protect your application from abuse.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "7.0.58",
3
+ "version": "7.0.60",
4
4
  "type": "module",
5
5
  "description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
6
6
  "license": "Apache-2.0",
@@ -42,9 +42,9 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
+ "@ai-sdk/gateway": "4.0.48",
45
46
  "@ai-sdk/provider": "4.0.7",
46
- "@ai-sdk/provider-utils": "5.0.25",
47
- "@ai-sdk/gateway": "4.0.46"
47
+ "@ai-sdk/provider-utils": "5.0.26"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@edge-runtime/vm": "^5.0.0",
@@ -307,7 +307,18 @@ export type ToolLoopAgentSettings<
307
307
  NoInfer<TOOLS>,
308
308
  NoInfer<RUNTIME_CONTEXT>
309
309
  >,
310
- 'onStepEnd' | 'onStepFinish'
310
+ | 'abortSignal'
311
+ | 'timeout'
312
+ | 'onStart'
313
+ | 'experimental_onStart'
314
+ | 'onStepStart'
315
+ | 'experimental_onStepStart'
316
+ | 'onToolExecutionStart'
317
+ | 'onToolExecutionEnd'
318
+ | 'onStepEnd'
319
+ | 'onStepFinish'
320
+ | 'onEnd'
321
+ | 'onFinish'
311
322
  > &
312
323
  Pick<
313
324
  ToolLoopAgentSettings<
@@ -318,6 +329,8 @@ export type ToolLoopAgentSettings<
318
329
  >,
319
330
  | 'model'
320
331
  | 'tools'
332
+ | 'toolChoice'
333
+ | 'maxRetries'
321
334
  | 'maxOutputTokens'
322
335
  | 'temperature'
323
336
  | 'topP'
@@ -337,6 +350,9 @@ export type ToolLoopAgentSettings<
337
350
  | 'toolOrder'
338
351
  | 'toolApproval'
339
352
  | 'experimental_toolCallers'
353
+ | 'prepareStep'
354
+ | 'repairToolCall'
355
+ | 'experimental_repairToolCall'
340
356
  | 'providerOptions'
341
357
  | 'experimental_download'
342
358
  | 'experimental_refineToolInput'
@@ -354,6 +370,8 @@ export type ToolLoopAgentSettings<
354
370
  >,
355
371
  | 'model'
356
372
  | 'tools'
373
+ | 'toolChoice'
374
+ | 'maxRetries'
357
375
  | 'maxOutputTokens'
358
376
  | 'temperature'
359
377
  | 'topP'
@@ -373,6 +391,9 @@ export type ToolLoopAgentSettings<
373
391
  | 'toolOrder'
374
392
  | 'toolApproval'
375
393
  | 'experimental_toolCallers'
394
+ | 'prepareStep'
395
+ | 'repairToolCall'
396
+ | 'experimental_repairToolCall'
376
397
  | 'providerOptions'
377
398
  | 'experimental_download'
378
399
  | 'experimental_refineToolInput'