Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/curvy-scissors-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ai-sdk/anthropic': patch
---

add context_management for anthropic
91 changes: 91 additions & 0 deletions content/providers/01-ai-sdk-providers/05-anthropic.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,97 @@ console.log(text); // text response
See [AI SDK UI: Chatbot](/docs/ai-sdk-ui/chatbot#reasoning) for more details
on how to integrate reasoning into your chatbot.

### Context Management

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.

You can configure context management using the `contextManagement` provider option:

```ts highlight="7-20"
import { anthropic, AnthropicProviderOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const result = await generateText({
model: anthropic('claude-3-7-sonnet-20250219'),
prompt: 'Continue our conversation...',
providerOptions: {
anthropic: {
contextManagement: {
edits: [
{
type: 'clear_tool_uses_20250919',
trigger: { type: 'input_tokens', value: 10000 },
keep: { type: 'tool_uses', value: 5 },
clearAtLeast: { type: 'input_tokens', value: 1000 },
clearToolInputs: true,
excludeTools: ['important_tool'],
},
],
},
} satisfies AnthropicProviderOptions,
},
});

// Check what was cleared
console.log(result.providerMetadata?.anthropic?.contextManagement);
```

#### Clear Tool Uses

The `clear_tool_uses_20250919` edit type removes old tool calls from the conversation history:

- **trigger** - Condition that triggers the clearing (e.g., `{ type: 'input_tokens', value: 10000 }`)
- **keep** - How many recent tool uses to preserve (e.g., `{ type: 'tool_uses', value: 5 }`)
- **clearAtLeast** - Minimum amount to clear (e.g., `{ type: 'input_tokens', value: 1000 }`)
- **clearToolInputs** - Whether to clear tool input parameters (boolean)
- **excludeTools** - Array of tool names to never clear

#### Clear Thinking

The `clear_thinking_20251015` edit type removes thinking/reasoning content:

```ts
const result = await generateText({
model: anthropic('claude-opus-4-20250514'),
prompt: 'Continue reasoning...',
providerOptions: {
anthropic: {
thinking: { type: 'enabled', budgetTokens: 12000 },
contextManagement: {
edits: [
{
type: 'clear_thinking_20251015',
keep: { type: 'thinking_turns', value: 2 },
},
],
},
} satisfies AnthropicProviderOptions,
},
});
```

#### Applied Edits Metadata

After generation, you can check which edits were applied in the provider metadata:

```ts
const metadata = result.providerMetadata?.anthropic?.contextManagement;

if (metadata?.appliedEdits) {
metadata.appliedEdits.forEach(edit => {
if (edit.type === 'clear_tool_uses_20250919') {
console.log(`Cleared ${edit.clearedToolUses} tool uses`);
console.log(`Freed ${edit.clearedInputTokens} tokens`);
} else if (edit.type === 'clear_thinking_20251015') {
console.log(`Cleared ${edit.clearedThinkingTurns} thinking turns`);
console.log(`Freed ${edit.clearedInputTokens} tokens`);
}
});
}
```

For more details, see [Anthropic's Context Management documentation](https://docs.anthropic.com/en/docs/build-with-claude/context-management).

### Cache Control

In the messages and message parts, you can use the `providerOptions` property to set cache control breakpoints.
Expand Down
114 changes: 114 additions & 0 deletions examples/ai-core/src/generate-text/anthropic-context-management.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { anthropic, AnthropicProviderOptions } from '@ai-sdk/anthropic';
import { generateText, tool } from 'ai';
import { z } from 'zod';
import { run } from '../lib/run';

run(async () => {
const result = await generateText({
model: anthropic('claude-haiku-4-5'),
messages: [
{
role: 'user',
content: 'What is the weather in San Francisco?',
},
{
role: 'assistant',
content: [
{
type: 'tool-call',
toolCallId: 'tool_1',
toolName: 'weather',
input: { location: 'San Francisco' },
},
],
},
{
role: 'tool',
content: [
{
type: 'tool-result',
toolCallId: 'tool_1',
toolName: 'weather',
output: {
type: 'json',
value: { temperature: 72, condition: 'sunny' },
},
},
],
},
{
role: 'user',
content: 'What about New York?',
},
{
role: 'assistant',
content: [
{
type: 'tool-call',
toolCallId: 'tool_2',
toolName: 'weather',
input: { location: 'New York' },
},
],
},
{
role: 'tool',
content: [
{
type: 'tool-result',
toolCallId: 'tool_2',
toolName: 'weather',
output: {
type: 'json',
value: { temperature: 65, condition: 'cloudy' },
},
},
],
},
{
role: 'user',
content: 'compare the two cities.',
},
],
tools: {
weather: tool({
description: 'Get the weather of a location',
inputSchema: z.object({
location: z.string().describe('The location to get the weather for'),
}),
execute: async ({ location }) => ({
location,
temperature: 72 + Math.floor(Math.random() * 21) - 10,
condition: 'sunny',
}),
}),
},
providerOptions: {
anthropic: {
contextManagement: {
edits: [
{
type: 'clear_tool_uses_20250919',
trigger: {
type: 'input_tokens',
value: 1000,
},
keep: {
type: 'tool_uses',
value: 1,
},
clearAtLeast: {
type: 'input_tokens',
value: 500,
},
clearToolInputs: true,
excludeTools: ['important_tool'],
},
],
},
} satisfies AnthropicProviderOptions,
},
});

console.log('request body:', JSON.stringify(result.request.body, null, 2));
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ exports[`AnthropicMessagesLanguageModel > doGenerate > agent skills > should exp
},
],
},
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -44,6 +45,7 @@ exports[`AnthropicMessagesLanguageModel > doGenerate > code execution 20250825 >
"id": "container_011CU6rVteVhydYXRyNs6G1M",
"skills": null,
},
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -290,6 +292,7 @@ Both files have been exported and are ready for download!",
"id": "container_011CUJar2mdkMcv7daEVAQw2",
"skills": null,
},
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -4885,6 +4888,7 @@ The presentation has",
},
],
},
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -9928,6 +9932,7 @@ Both",
"id": "container_011CUJb5Pk4kFWskBpuCjwXj",
"skills": null,
},
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -11225,6 +11230,7 @@ The Fibonacci sequence starts with 0, ",
"id": "container_011CU6pTr2hLT47seQ5Xs4yj",
"skills": null,
},
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -11849,6 +11855,7 @@ exports[`AnthropicMessagesLanguageModel > doStream > json schema response format
"anthropic": {
"cacheCreationInputTokens": 0,
"container": null,
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -11949,6 +11956,7 @@ It simply echoed back",
"anthropic": {
"cacheCreationInputTokens": 0,
"container": null,
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -12140,6 +12148,7 @@ exports[`AnthropicMessagesLanguageModel > doStream > tool search tool > bm25 var
"anthropic": {
"cacheCreationInputTokens": 0,
"container": null,
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -12227,6 +12236,7 @@ exports[`AnthropicMessagesLanguageModel > doStream > tool search tool > bm25 var
"anthropic": {
"cacheCreationInputTokens": 0,
"container": null,
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -12416,6 +12426,7 @@ exports[`AnthropicMessagesLanguageModel > doStream > tool search tool > regex va
"anthropic": {
"cacheCreationInputTokens": 0,
"container": null,
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -12532,6 +12543,7 @@ The weather in",
"anthropic": {
"cacheCreationInputTokens": 0,
"container": null,
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -12927,6 +12939,7 @@ The page also discusses",
"anthropic": {
"cacheCreationInputTokens": 0,
"container": null,
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down Expand Up @@ -13661,6 +13674,7 @@ The main tech story today appears to be Apple's significant",
"anthropic": {
"cacheCreationInputTokens": 0,
"container": null,
"contextManagement": null,
"stopSequence": null,
"usage": {
"cache_creation": {
Expand Down
58 changes: 58 additions & 0 deletions packages/anthropic/src/anthropic-message-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,62 @@ export interface AnthropicMessageMetadata {
version: string;
}> | null;
} | null;

/**
* Context management response.
*
* Information about context management strategies applied during the request.
*/
contextManagement: {
/**
* List of context management edits that were applied.
* Each item in the array is a specific type of context management edit.
*/
appliedEdits: Array<
/**
* Represents an edit where a certain number of tool uses and input tokens were cleared.
*/
| {
/**
* The type of context management edit applied.
* Possible value: 'clear_tool_uses_20250919'
*/
type: 'clear_tool_uses_20250919';

/**
* Number of tool uses that were cleared by this edit.
* Minimum: 0
*/
clearedToolUses: number;

/**
* Number of input tokens cleared by this edit.
* Minimum: 0
*/
clearedInputTokens: number;
}
/**
* Represents an edit where a certain number of thinking turns and input tokens were cleared.
*/
| {
/**
* The type of context management edit applied.
* Possible value: 'clear_thinking_20251015'
*/
type: 'clear_thinking_20251015';

/**
* Number of thinking turns that were cleared by this edit.
* Minimum: 0
*/
clearedThinkingTurns: number;

/**
* Number of input tokens cleared by this edit.
* Minimum: 0
*/
clearedInputTokens: number;
}
>;
} | null;
}
Loading
Loading