Skip to content

Commit a753b3a

Browse files
authored
feat (provider/anthropic): cache control for tools (#7552)
## Background Caching a subset of tools is currently not possible, see #3820. ## Summary Support cache control for anthropic tools: ```ts const result = await generateText({ model: anthropic('claude-3-5-haiku-latest'), tools: { cityAttractions: tool({ inputSchema: z.object({ city: z.string() }), providerOptions: { anthropic: { cacheControl: { type: 'ephemeral' }, }, }, }), }, messages: [ { role: 'user', content: 'User prompt', }, ], }); ``` ## Verification - [x] Check manually that option is set on the request. ## Related Issues Fixes #3820
1 parent 84343eb commit a753b3a

File tree

12 files changed

+592
-231
lines changed

12 files changed

+592
-231
lines changed

‎.changeset/wild-beans-help.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@ai-sdk/anthropic': patch
3+
'ai': patch
4+
---
5+
6+
feat (provider/anthropic): cache control for tools

‎content/providers/01-ai-sdk-providers/05-anthropic.mdx

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,6 @@ on how to integrate reasoning into your chatbot.
139139

140140
### Cache Control
141141

142-
<Note>
143-
Anthropic cache control was originally a beta feature and required passing an
144-
opt-in `cacheControl` setting when creating the model instance. It is now
145-
Generally Available and enabled by default. The `cacheControl` setting is no
146-
longer needed and will be removed in a future release.
147-
</Note>
148-
149142
In the messages and message parts, you can use the `providerOptions` property to set cache control breakpoints.
150143
You need to set the `anthropic` property in the `providerOptions` object to `{ cacheControl: { type: 'ephemeral' } }` to set a cache control breakpoint.
151144

@@ -211,6 +204,30 @@ const result = await generateText({
211204
});
212205
```
213206

207+
Cache control for tools:
208+
209+
```ts
210+
const result = await generateText({
211+
model: anthropic('claude-3-5-haiku-latest'),
212+
tools: {
213+
cityAttractions: tool({
214+
inputSchema: z.object({ city: z.string() }),
215+
providerOptions: {
216+
anthropic: {
217+
cacheControl: { type: 'ephemeral' },
218+
},
219+
},
220+
}),
221+
},
222+
messages: [
223+
{
224+
role: 'user',
225+
content: 'User prompt',
226+
},
227+
],
228+
});
229+
```
230+
214231
The minimum cacheable prompt length is:
215232

216233
- 1024 tokens for Claude 3.7 Sonnet, Claude 3.5 Sonnet and Claude 3 Opus
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { anthropic } from '@ai-sdk/anthropic';
2+
import { generateText, tool } from 'ai';
3+
import 'dotenv/config';
4+
import { z } from 'zod/v4';
5+
6+
async function main() {
7+
const result = await generateText({
8+
model: anthropic('claude-3-5-haiku-latest'),
9+
tools: {
10+
cityAttractions: tool({
11+
inputSchema: z.object({ city: z.string() }),
12+
providerOptions: {
13+
anthropic: {
14+
cacheControl: { type: 'ephemeral' },
15+
},
16+
},
17+
}),
18+
},
19+
prompt: 'What attractions should I visit in San Francisco?',
20+
});
21+
22+
console.log(JSON.stringify(result.request.body, null, 2));
23+
}
24+
25+
main().catch(console.error);

‎packages/ai/src/generate-text/generate-text.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ describe('generateText', () => {
320320
required: ['value'],
321321
type: 'object',
322322
},
323+
providerOptions: undefined,
323324
},
324325
{
325326
type: 'function',
@@ -332,6 +333,7 @@ describe('generateText', () => {
332333
required: ['somethingElse'],
333334
type: 'object',
334335
},
336+
providerOptions: undefined,
335337
},
336338
]);
337339

@@ -411,6 +413,7 @@ describe('generateText', () => {
411413
required: ['value'],
412414
type: 'object',
413415
},
416+
providerOptions: undefined,
414417
},
415418
]);
416419

@@ -627,6 +630,7 @@ describe('generateText', () => {
627630
required: ['value'],
628631
type: 'object',
629632
},
633+
providerOptions: undefined,
630634
},
631635
]);
632636

@@ -1262,6 +1266,7 @@ describe('generateText', () => {
12621266
"type": "object",
12631267
},
12641268
"name": "tool1",
1269+
"providerOptions": undefined,
12651270
"type": "function",
12661271
},
12671272
],
@@ -1769,6 +1774,7 @@ describe('generateText', () => {
17691774
"type": "object",
17701775
},
17711776
"name": "tool1",
1777+
"providerOptions": undefined,
17721778
"type": "function",
17731779
},
17741780
]
@@ -2124,6 +2130,7 @@ describe('generateText', () => {
21242130
required: ['value'],
21252131
type: 'object',
21262132
},
2133+
providerOptions: undefined,
21272134
},
21282135
{
21292136
type: 'function',
@@ -2135,6 +2142,7 @@ describe('generateText', () => {
21352142
required: ['somethingElse'],
21362143
type: 'object',
21372144
},
2145+
providerOptions: undefined,
21382146
},
21392147
]);
21402148

‎packages/ai/src/generate-text/stream-text.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,7 @@ describe('streamText', () => {
10071007
required: ['value'],
10081008
type: 'object',
10091009
},
1010+
providerOptions: undefined,
10101011
},
10111012
]);
10121013

@@ -5245,6 +5246,7 @@ describe('streamText', () => {
52455246
"type": "object",
52465247
},
52475248
"name": "tool1",
5249+
"providerOptions": undefined,
52485250
"type": "function",
52495251
},
52505252
],
@@ -5319,6 +5321,7 @@ describe('streamText', () => {
53195321
"type": "object",
53205322
},
53215323
"name": "tool1",
5324+
"providerOptions": undefined,
53225325
"type": "function",
53235326
},
53245327
],
@@ -6373,6 +6376,7 @@ describe('streamText', () => {
63736376
"type": "object",
63746377
},
63756378
"name": "tool1",
6379+
"providerOptions": undefined,
63766380
"type": "function",
63776381
},
63786382
],
@@ -9071,6 +9075,7 @@ describe('streamText', () => {
90719075
required: ['value'],
90729076
type: 'object',
90739077
},
9078+
providerOptions: undefined,
90749079
},
90759080
]);
90769081
expect(toolChoice).toStrictEqual({ type: 'required' });
@@ -11244,6 +11249,7 @@ describe('streamText', () => {
1124411249
"type": "object",
1124511250
},
1124611251
"name": "tool1",
11252+
"providerOptions": undefined,
1124711253
"type": "function",
1124811254
},
1124911255
]

0 commit comments

Comments
 (0)