Skip to content

Commit 120dba8

Browse files
committed
add doc and refactor to switch
1 parent 270d08d commit 120dba8

File tree

5 files changed

+405
-286
lines changed

5 files changed

+405
-286
lines changed

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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,97 @@ console.log(text); // text response
208208
See [AI SDK UI: Chatbot](/docs/ai-sdk-ui/chatbot#reasoning) for more details
209209
on how to integrate reasoning into your chatbot.
210210

211+
### Context Management
212+
213+
Anthropic's Context Management feature allows you to automatically manage conversation context by clearing tool uses or thinking content when certain conditions are met. This helps optimize token usage and manage long conversations more efficiently.
214+
215+
You can configure context management using the `contextManagement` provider option:
216+
217+
```ts highlight="7-20"
218+
import { anthropic, AnthropicProviderOptions } from '@ai-sdk/anthropic';
219+
import { generateText } from 'ai';
220+
221+
const result = await generateText({
222+
model: anthropic('claude-3-7-sonnet-20250219'),
223+
prompt: 'Continue our conversation...',
224+
providerOptions: {
225+
anthropic: {
226+
contextManagement: {
227+
edits: [
228+
{
229+
type: 'clear_tool_uses_20250919',
230+
trigger: { type: 'input_tokens', value: 10000 },
231+
keep: { type: 'tool_uses', value: 5 },
232+
clearAtLeast: { type: 'input_tokens', value: 1000 },
233+
clearToolInputs: true,
234+
excludeTools: ['important_tool'],
235+
},
236+
],
237+
},
238+
} satisfies AnthropicProviderOptions,
239+
},
240+
});
241+
242+
// Check what was cleared
243+
console.log(result.providerMetadata?.anthropic?.contextManagement);
244+
```
245+
246+
#### Clear Tool Uses
247+
248+
The `clear_tool_uses_20250919` edit type removes old tool calls from the conversation history:
249+
250+
- **trigger** - Condition that triggers the clearing (e.g., `{ type: 'input_tokens', value: 10000 }`)
251+
- **keep** - How many recent tool uses to preserve (e.g., `{ type: 'tool_uses', value: 5 }`)
252+
- **clearAtLeast** - Minimum amount to clear (e.g., `{ type: 'input_tokens', value: 1000 }`)
253+
- **clearToolInputs** - Whether to clear tool input parameters (boolean)
254+
- **excludeTools** - Array of tool names to never clear
255+
256+
#### Clear Thinking
257+
258+
The `clear_thinking_20251015` edit type removes thinking/reasoning content:
259+
260+
```ts
261+
const result = await generateText({
262+
model: anthropic('claude-opus-4-20250514'),
263+
prompt: 'Continue reasoning...',
264+
providerOptions: {
265+
anthropic: {
266+
thinking: { type: 'enabled', budgetTokens: 12000 },
267+
contextManagement: {
268+
edits: [
269+
{
270+
type: 'clear_thinking_20251015',
271+
keep: { type: 'thinking_blocks', value: 2 },
272+
},
273+
],
274+
},
275+
} satisfies AnthropicProviderOptions,
276+
},
277+
});
278+
```
279+
280+
#### Applied Edits Metadata
281+
282+
After generation, you can check which edits were applied in the provider metadata:
283+
284+
```ts
285+
const metadata = result.providerMetadata?.anthropic?.contextManagement;
286+
287+
if (metadata?.appliedEdits) {
288+
metadata.appliedEdits.forEach(edit => {
289+
if (edit.type === 'clear_tool_uses_20250919') {
290+
console.log(`Cleared ${edit.clearedToolUses} tool uses`);
291+
console.log(`Freed ${edit.clearedInputTokens} tokens`);
292+
} else if (edit.type === 'clear_thinking_20251015') {
293+
console.log(`Cleared ${edit.clearedThinkingBlocks} thinking blocks`);
294+
console.log(`Freed ${edit.clearedInputTokens} tokens`);
295+
}
296+
});
297+
}
298+
```
299+
300+
For more details, see [Anthropic's Context Management documentation](https://docs.anthropic.com/en/docs/build-with-claude/context-management).
301+
211302
### Cache Control
212303

213304
In the messages and message parts, you can use the `providerOptions` property to set cache control breakpoints.

examples/ai-core/src/generate-text/anthropic-context-management.ts

Lines changed: 116 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -4,126 +4,128 @@ import 'dotenv/config';
44
import { z } from 'zod';
55

66
async function main() {
7-
const result = await generateText({
8-
model: anthropic('claude-3-7-sonnet-20250219'),
9-
messages: [
10-
{
11-
role: 'user',
12-
content: 'What is the weather in San Francisco?'
13-
},
14-
{
15-
role: 'assistant',
16-
content: [
17-
{
18-
type: 'tool-call',
19-
toolCallId: 'tool_1',
20-
toolName: 'weather',
21-
input: { location: 'San Francisco' },
22-
}
23-
]
24-
},
25-
{
26-
role: 'tool',
27-
content: [
28-
{
29-
type: 'tool-result',
30-
toolCallId: 'tool_1',
31-
toolName: 'weather',
32-
output: {
33-
type: 'json',
34-
value: { temperature: 72, condition: 'sunny' }
35-
}
36-
}
37-
]
38-
},
39-
{
40-
role: 'user',
41-
content: 'What about New York?'
7+
const result = await generateText({
8+
model: anthropic('claude-3-7-sonnet-20250219'),
9+
messages: [
10+
{
11+
role: 'user',
12+
content: 'What is the weather in San Francisco?',
13+
},
14+
{
15+
role: 'assistant',
16+
content: [
17+
{
18+
type: 'tool-call',
19+
toolCallId: 'tool_1',
20+
toolName: 'weather',
21+
input: { location: 'San Francisco' },
22+
},
23+
],
24+
},
25+
{
26+
role: 'tool',
27+
content: [
28+
{
29+
type: 'tool-result',
30+
toolCallId: 'tool_1',
31+
toolName: 'weather',
32+
output: {
33+
type: 'json',
34+
value: { temperature: 72, condition: 'sunny' },
4235
},
43-
{
44-
role: 'assistant',
45-
content: [
46-
{
47-
type: 'tool-call',
48-
toolCallId: 'tool_2',
49-
toolName: 'weather',
50-
input: { location: 'New York' }
51-
}
52-
]
36+
},
37+
],
38+
},
39+
{
40+
role: 'user',
41+
content: 'What about New York?',
42+
},
43+
{
44+
role: 'assistant',
45+
content: [
46+
{
47+
type: 'tool-call',
48+
toolCallId: 'tool_2',
49+
toolName: 'weather',
50+
input: { location: 'New York' },
51+
},
52+
],
53+
},
54+
{
55+
role: 'tool',
56+
content: [
57+
{
58+
type: 'tool-result',
59+
toolCallId: 'tool_2',
60+
toolName: 'weather',
61+
output: {
62+
type: 'json',
63+
value: { temperature: 65, condition: 'cloudy' },
5364
},
65+
},
66+
],
67+
},
68+
{
69+
role: 'user',
70+
content: 'compare the two cities.',
71+
},
72+
],
73+
tools: {
74+
weather: tool({
75+
description: 'Get the weather of a location',
76+
inputSchema: z.object({
77+
location: z.string().describe('The location to get the weather for'),
78+
}),
79+
execute: async ({ location }) => ({
80+
location,
81+
temperature: 72 + Math.floor(Math.random() * 21) - 10,
82+
condition: 'sunny',
83+
}),
84+
}),
85+
},
86+
providerOptions: {
87+
anthropic: {
88+
contextManagement: {
89+
edits: [
5490
{
55-
role: 'tool',
56-
content: [
57-
{
58-
type: 'tool-result',
59-
toolCallId: 'tool_2',
60-
toolName: 'weather',
61-
output: {
62-
type: 'json',
63-
value: { temperature: 65, condition: 'cloudy' }
64-
}
65-
}
66-
]
91+
type: 'clear_tool_uses_20250919',
92+
trigger: {
93+
type: 'input_tokens',
94+
value: 1000,
95+
},
96+
keep: {
97+
type: 'tool_uses',
98+
value: 1,
99+
},
100+
clearAtLeast: {
101+
type: 'input_tokens',
102+
value: 500,
103+
},
104+
clearToolInputs: true,
105+
excludeTools: ['important_tool'],
67106
},
68-
{
69-
role: 'user',
70-
content: 'compare the two cities.'
71-
}
72-
],
73-
tools: {
74-
weather: tool({
75-
description: 'Get the weather of a location',
76-
inputSchema: z.object({
77-
location: z.string().describe('The location to get the weather for')
78-
}),
79-
execute: async ({ location }) => ({
80-
location,
81-
temperature: 72 + Math.floor(Math.random() * 21) - 10,
82-
condition: 'sunny'
83-
})
84-
})
107+
],
85108
},
86-
providerOptions: {
87-
anthropic: {
88-
contextManagement: {
89-
edits: [
90-
{
91-
type: 'clear_tool_uses_20250919',
92-
trigger: {
93-
type: 'input_tokens',
94-
value: 1000
95-
},
96-
keep: {
97-
type: 'tool_uses',
98-
value: 1
99-
},
100-
clearAtLeast: {
101-
type: 'input_tokens',
102-
value: 500
103-
},
104-
clearToolInputs: true,
105-
excludeTools: ['important_tool']
106-
}
107-
]
108-
}
109-
} satisfies AnthropicProviderOptions
110-
}
111-
});
109+
} satisfies AnthropicProviderOptions,
110+
},
111+
});
112112

113-
console.log('Text:');
114-
console.log(result.text);
115-
console.log();
113+
console.log('Text:');
114+
console.log(result.text);
115+
console.log();
116116

117-
console.log('Context Management:');
118-
console.log(JSON.stringify(
119-
result.providerMetadata?.anthropic?.contextManagement,
120-
null,
121-
2
122-
));
123-
console.log();
117+
console.log('Context Management:');
118+
console.log(
119+
JSON.stringify(
120+
result.providerMetadata?.anthropic?.contextManagement,
121+
null,
122+
2,
123+
),
124+
);
125+
console.log();
124126

125-
console.log('Usage:');
126-
console.log(JSON.stringify(result.usage, null, 2));
127-
};
127+
console.log('Usage:');
128+
console.log(JSON.stringify(result.usage, null, 2));
129+
}
128130

129-
main().catch(console.error);
131+
main().catch(console.error);

packages/anthropic/src/anthropic-message-metadata.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ export interface AnthropicMessageMetadata {
4848
contextManagement: {
4949
appliedEdits: Array<
5050
| {
51-
type: 'clear_tool_uses_20250919';
52-
clearedToolUses: number;
53-
clearedInputTokens: number;
54-
}
51+
type: 'clear_tool_uses_20250919';
52+
clearedToolUses: number;
53+
clearedInputTokens: number;
54+
}
5555
| {
56-
type: 'clear_thinking_20251015';
57-
clearedThinkingTurns: number;
58-
clearedInputTokens: number;
59-
}
56+
type: 'clear_thinking_20251015';
57+
clearedThinkingTurns: number;
58+
clearedInputTokens: number;
59+
}
6060
>;
6161
} | null;
6262
}

0 commit comments

Comments
 (0)