---
title: Anthropic
description: Learn how to use the Anthropic provider for the AI SDK.
url: "https://ai-sdk.dev/providers/ai-sdk-providers/anthropic"
docs_index: /llms.txt
---

> For an index of all documentation, see [/llms.txt](/llms.txt).

The [Anthropic](https://www.anthropic.com/) provider contains language model support for the [Anthropic Messages API](https://docs.anthropic.com/claude/reference/messages_post).

## Setup

The Anthropic provider is available in the `@ai-sdk/anthropic` module. You can install it with

```bash
pnpm add @ai-sdk/anthropic
```

## Provider Instance

You can import the default provider instance `anthropic` from `@ai-sdk/anthropic`:

```ts
import { anthropic } from '@ai-sdk/anthropic';
```

If you need a customized setup, you can import `createAnthropic` from `@ai-sdk/anthropic` and create a provider instance with your settings:

```ts
import { createAnthropic } from '@ai-sdk/anthropic';

const anthropic = createAnthropic({
  // custom settings
});
```

You can use the following optional settings to customize the Anthropic provider instance:

- **batchResultDownloads** *object*

  Settings for downloading JSON Lines batch results.

  - **maxLineBytes** *number*

    Maximum UTF-8 bytes per row, excluding the LF delimiter. Defaults to 64 MiB
    (67,108,864 bytes). Must be a positive safe integer. Oversized rows throw a
    `DownloadError` and cancel the download.

- **baseURL** *string*

  Use a different URL prefix for API calls, e.g. to use proxy servers.
  The default prefix is `https://api.anthropic.com/v1`.

- **apiKey** *string*

  API key that is being sent using the `x-api-key` header.
  It defaults to the `ANTHROPIC_API_KEY` environment variable.
  Only one of `apiKey` or `authToken` is required.

- **authToken** *string*

  Auth token that is being sent using the `Authorization: Bearer` header.
  It defaults to the `ANTHROPIC_AUTH_TOKEN` environment variable.
  Only one of `apiKey` or `authToken` is required.

- **headers** *Record\<string,string>*

  Custom headers to include in the requests.

- **fetch** *(input: RequestInfo, init?: RequestInit) => Promise\<Response>*

  Custom [fetch](https://developer.mozilla.org/en-US/docs/Web/API/fetch) implementation.
  Defaults to the global `fetch` function.
  You can use it as a middleware to intercept requests,
  or to provide a custom fetch implementation for e.g. testing.

## Language Models

You can create models that call the [Anthropic Messages API](https://docs.anthropic.com/claude/reference/messages_post) using the provider instance.
The first argument is the model id, e.g. `claude-haiku-5-5`.
Some models have multi-modal capabilities.

```ts
const model = anthropic('claude-haiku-5-5');
```

You can also use the following aliases for model creation:

- `anthropic.languageModel('claude-haiku-5-5')` - Creates a language model
- `anthropic.chat('claude-haiku-5-5')` - Alias for `languageModel`
- `anthropic.messages('claude-haiku-5-5')` - Alias for `languageModel`

You can use Anthropic language models to generate text with the `generateText` function:

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text } = await generateText({
  model: anthropic('claude-haiku-5-5'),
  prompt: 'Write a vegetarian lasagna recipe for 4 people.',
});
```

Anthropic language models can also be used in the `streamText` function
and support structured data generation with [`Output`](/docs/reference/ai-sdk-core/output)
(see [AI SDK Core](/docs/ai-sdk-core)).

### Message-start events

During streaming, each Anthropic `message_start` event is exposed as an
`anthropic.message_start` custom stream part containing the message ID, model,
and raw initial token usage. No provider option is required.

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { streamText } from 'ai';

const result = streamText({
  model: anthropic('claude-haiku-5-5'),
  prompt: 'Say hi in one word.',
});

for await (const part of result.fullStream) {
  if (part.type === 'custom' && part.kind === 'anthropic.message_start') {
    console.log(part.providerMetadata?.anthropic);
  }
}
```

Initial usage may be incomplete; use `result.usage` for final token counts.
Like other custom parts, this event is included in response content and forwarded
to UI message streams. It is ignored when replaying conversation history to Anthropic.

### Provider options

The following optional provider options are available for Anthropic models:

- `disableParallelToolUse` *boolean*

  Optional. Disables the use of parallel tool calls. Defaults to `false`.

  When set to `true`, the model will only call one tool at a time instead of potentially calling multiple tools in parallel.

- `sendReasoning` *boolean*

  Optional. Include reasoning content in requests sent to the model. Defaults to `true`.

  If you are experiencing issues with the model handling requests involving
  reasoning content, you can set this to `false` to omit them from the request.

- `effort` *"low" | "medium" | "high" | "xhigh" | "max"*

  Optional. See [Effort section](#effort) for more details.

- `taskBudget` *object*

  Optional. See [Task Budgets section](#task-budgets) for more details.

- `speed` *"fast" | "standard"*

  Optional. See [Fast Mode section](#fast-mode) for more details.

- `inferenceGeo` *"us" | "global"*

  Optional. See [Data Residency section](#data-residency) for more details.

- `thinking` *object*

  Optional. See [Reasoning section](#reasoning) for more details.

- `toolStreaming` *boolean*

  Whether to enable tool streaming (and structured output streaming). Default to `true`.

- `structuredOutputMode` *"outputFormat" | "jsonTool" | "auto"*

  Determines how structured outputs are generated. Optional.

  - `"outputFormat"`: Use the `output_format` parameter to specify the structured output format.
  - `"jsonTool"`: Use a special `"json"` tool to specify the structured output format.
  - `"auto"`: Use `"outputFormat"` when supported, otherwise fall back to `"jsonTool"` (default).

- `metadata` *object*

  Optional. Metadata to include with the request. See the [Anthropic API documentation](https://platform.claude.com/docs/en/api/messages/create) for details.

  - `userId` *string* - An external identifier for the end-user. Should be a UUID, hash, or other opaque identifier. Must not contain PII.

### Batch

Batch support is experimental and the API may change in patch releases.

Anthropic language models support asynchronous text generation through the
[Message Batches API](https://platform.claude.com/docs/en/build-with-claude/batch-processing).
Pass the Anthropic provider to the AI SDK's [Batch](/docs/ai-sdk-core/batch)
API for the complete workflow, including polling, persistence, and result handling.

Each request specifies its `type` and `model`. Anthropic supports using
different text models within the same batch.

#### Batch Limitations

Anthropic Message Batches do not support the `speed` option or completion
webhooks. Explicit `anthropicBeta` values must be configured when starting the
batch rather than on an individual request. When you provide a `webhookUrl`,
the provider returns an unsupported warning and starts the batch without a
webhook.

### Structured Outputs and Tool Input Streaming

Tool call streaming is enabled by default. You can opt out by setting the
`toolStreaming` provider option to `false`.

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { streamText, tool } from 'ai';
import { z } from 'zod';

const result = streamText({
  model: anthropic('claude-sonnet-5-5'),
  tools: {
    writeFile: tool({
      description: 'Write content to a file',
      inputSchema: z.object({
        path: z.string(),
        content: z.string(),
      }),
      execute: async ({ path, content }) => {
        // Implementation
        return { success: true };
      },
    }),
  },
  prompt: 'Write a short story to story.txt',
});
```

For `claude-sonnet-5-5`, `claude-opus-5-5`, and `claude-fable-5-1`, the
default `"auto"` mode uses native structured outputs through
`output_config.format`. These models reject forced tool use, so the
`"jsonTool"` mode cannot be used with them. If you
request `"jsonTool"` anyway, the provider falls back to `"outputFormat"` and
emits a warning. Likewise, a `required` or named `toolChoice` is downgraded to
`auto` with a warning; instruct the model to use the tool in your prompt and
verify that a tool call was made.

### Effort

Anthropic introduced an `effort` option with `claude-opus-4-5` that affects thinking, text responses, and function calls. Effort defaults to `high` and you can set it to `medium` or `low` to save tokens and to lower time-to-last-token latency (TTLT). `claude-opus-4-7`, `claude-opus-4-8`, `claude-opus-5`, `claude-opus-5-5`, `claude-fable-5`, `claude-fable-5-1`, `claude-sonnet-5`, `claude-sonnet-5-5`, and `claude-haiku-5-5` additionally support `xhigh` for maximum reasoning effort.

On `claude-opus-5` and `claude-haiku-5-5`, thinking can only be disabled at effort levels up to and including `high`. When you combine `thinking: { type: 'disabled' }` with `effort: 'xhigh'` or `effort: 'max'`, the AI SDK lowers the effort to `high` and emits a warning instead of sending a request that the API would reject.

`claude-haiku-5-5` is the first Haiku model with effort levels and supports all
five of them. It uses adaptive thinking and does not support thinking token
budgets: the AI SDK converts `thinking: { type: 'enabled', budgetTokens }` to
`{ type: 'adaptive' }` and emits a warning. Use `effort` to control how much it
thinks. Unlike `claude-sonnet-5-5`, thinking can still be turned off with
`thinking: { type: 'disabled' }`, but only at `low`, `medium`, and `high` effort.
Start at `medium` effort and test other levels rather than carrying over the
settings you used on `claude-haiku-4-5`.

On `claude-opus-5-5`, thinking is always adaptive and cannot be disabled, so
`effort` is the main control for latency and cost. The API default effort for
`claude-opus-5-5` is `medium`. Start there and test other levels rather than
carrying over the setting you used on `claude-opus-5`. Set `maxOutputTokens`
with room for thinking as well as the reply; thinking counts toward the limit
even when its content is not returned.

On `claude-sonnet-5-5`, thinking cannot be turned off either, and the API
default effort is `high`. Its effort levels are not equivalent to those of
`claude-sonnet-5`, so test several levels rather than carrying over your
current setting. For agentic coding and other multi-step tool use, start at
`medium` for well-specified tasks and move to `high` for harder ones. The
lowest thinking setting, [`between_tools`](#between-tools-thinking), is only
accepted at `low`, `medium`, and `high` effort. When you combine it with
`effort: 'xhigh'` or `effort: 'max'`, the AI SDK lowers the effort to `high`
and emits a warning.

```ts {8-10}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text, usage } = await generateText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'How many people will live in the world in 2040?',
  providerOptions: {
    anthropic: {
      effort: 'low',
    } satisfies AnthropicLanguageModelOptions,
  },
});

console.log(text); // resulting text
console.log(usage); // token usage
```

### Fast Mode

Anthropic supports a [`speed` option](https://code.claude.com/docs/en/fast-mode) for `claude-opus-4-6` that enables faster inference with approximately 2.5x faster output token speeds.

```ts {8-10}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text } = await generateText({
  model: anthropic('claude-opus-4-6'),
  prompt: 'Write a short poem about the sea.',
  providerOptions: {
    anthropic: {
      speed: 'fast',
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

The `speed` option accepts `'fast'` or `'standard'` (default behavior).

### Task Budgets

`claude-opus-4-7` supports a `taskBudget` option that informs the model of the total token budget available for an agentic turn. The model uses this information to prioritize work, plan ahead, and wind down gracefully as the budget is consumed.

Task budgets are advisory — they do not enforce a hard token limit. The model will attempt to stay within budget, but actual usage may vary.

```ts {8-13}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text } = await generateText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'Research the pros and cons of Rust vs Go for building CLI tools.',
  providerOptions: {
    anthropic: {
      taskBudget: {
        type: 'tokens',
        total: 400000,
      },
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

For long-running agents that compact and restart context, you can carry the remaining budget forward using the `remaining` field:

```ts
taskBudget: {
  type: 'tokens',
  total: 400000,
  remaining: 215000, // budget left after prior compacted-away contexts
}
```

The `taskBudget` object accepts:

- `type` *"tokens"* - Budget type. Currently only `"tokens"` is supported.
- `total` *number* - Total task budget for the agentic turn. Minimum 20,000.
- `remaining` *number* - Budget left after prior compacted-away contexts. Must be between 0 and `total`. Defaults to `total` if omitted.

### Data Residency

Anthropic supports an [`inferenceGeo` option](https://platform.claude.com/docs/en/build-with-claude/data-residency) that controls where model inference runs for a request.

```ts {8-10}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text } = await generateText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'Summarize the key points of this document.',
  providerOptions: {
    anthropic: {
      inferenceGeo: 'us',
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

The `inferenceGeo` option accepts `'us'` (US-only infrastructure) or `'global'` (default, any available geography).

### Safety Classifiers and Fallbacks

Claude Fable 5 has safeguards that limit its performance in certain areas like cybersecurity, biology, and chemistry, and automated safety checks are run on every request.

Claude Haiku 5.5 has the same biology safeguards as Claude Sonnet 5 and 5.5, plus safeguards that prevent cyber misuse.

Claude Sonnet 5.5 also has safety classifiers enabled, including for cybersecurity, biology, and reasoning extraction. Requests that ask the model to reproduce its internal reasoning in the response text can be declined with the `reasoning_extraction` category; use `thinking: { type: 'adaptive', display: 'summarized' }` and read the reasoning parts instead.

When one of these checks blocks a request, the API does not answer it. Instead it returns a classifier block: a `200` response with a `refusal` stop reason and an optional `stop_details` object describing the category that triggered the block. The AI SDK surfaces this as a `content-filter` finish reason, with the details available on `providerMetadata.anthropic.stopDetails`.

A classifier block looks like this:

```json
{
  "type": "message",
  "model": "claude-fable-5",
  "content": [],
  "stop_reason": "refusal",
  "stop_details": {
    "type": "refusal",
    "category": "cyber",
    "explanation": "This request triggered restrictions on violative cyber content and was blocked under Anthropic's Usage Policy."
  }
}
```

Branch on the finish reason rather than on the presence of `stop_details` — the API may return a refusal with no details at all.

To avoid receiving a classifier block, pass the `fallbacks` option. When the primary model's classifiers block a turn, the API automatically retries it server-side on a fallback model and returns that model's answer. The required beta header is added for you.

The recommended configuration is `fallbacks: 'default'`, which lets the API route the retry to Anthropic's recommended fallback model based on the refusal category and removes the need to migrate when a fallback model is deprecated:

```ts {8-10}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text } = await generateText({
  model: anthropic('claude-fable-5-1'),
  prompt: 'Explain the history of cryptography.',
  providerOptions: {
    anthropic: {
      fallbacks: 'default',
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

You can also pin an explicit fallback chain:

```ts {8-10}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text } = await generateText({
  model: anthropic('claude-fable-5-1'),
  prompt: 'Explain the history of cryptography.',
  providerOptions: {
    anthropic: {
      fallbacks: [{ model: 'claude-fable-5-1' }],
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

Each fallback entry requires a `model` and may additionally override `max_tokens`, `thinking`, `output_config`, and `speed` for that attempt only.

When a fallback serves the turn, it is recorded in the per-model usage breakdown (`usage.iterations`) as a `fallback_message` entry. The AI SDK exposes this breakdown on `providerMetadata.anthropic.iterations`, so you can detect whether a fallback ran:

```ts
// set up `result` with a `streamText` call passing `fallbacks` as shown
// above, then consume the stream

const { iterations } =
  (await result.finalStep).providerMetadata?.anthropic ?? {};
const servedByFallback = iterations?.some(
  iteration => iteration.type === 'fallback_message',
);

console.log('Served by fallback:', servedByFallback);
```

### Dangerous Tool Use Safeguard

The `safeguards` option asks the API to run additional server-side checks as part of the request. The `dangerous_tool_use` safeguard classifies every `tool_use` block in the response for dangerous actions, such as destructive shell commands or data exfiltration, and returns a verdict per tool call. This is the check that Claude Code's auto mode relies on. The `dangerous-tool-use-2026-09-03` beta header is added for you.

```ts {9-16}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText, tool } from 'ai';
import { z } from 'zod';

const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  prompt: 'Use the bash tool to run: echo hello',
  tools: { bash: tool({ inputSchema: z.object({ command: z.string() }) }) },
  providerOptions: {
    anthropic: {
      safeguards: [
        {
          type: 'dangerous_tool_use',
          classifierContext: { v: 1, permission_mode: 'auto' },
        },
      ],
    } satisfies AnthropicLanguageModelOptions,
  },
});

console.log(result.providerMetadata?.anthropic?.safeguardResults);
```

The verdicts are available on `providerMetadata.anthropic.safeguardResults`, one entry per requested safeguard, in the API's wire shape:

```json
[
  {
    "type": "dangerous_tool_use",
    "status": {
      "type": "available",
      "tool_uses": {
        "toolu_01Ti4QpUfhLV6QqCTFVY8C7w": {
          "type": "evaluated",
          "outcome": "not_flagged"
        }
      }
    }
  }
]
```

`status.type` is `available` when the classifier ran; `unsupported` means the API key is not enabled for the beta. Inside `status.tool_uses`, each tool call id maps to `evaluated` (with an `outcome` of `not_flagged` or `flagged`, the latter with an `explanation` such as `[Data Exfiltration]`), `skipped`, or `unavailable` (a transient classifier failure). When streaming, the verdicts arrive on the final `message_delta` event and are exposed on the `finish` part's provider metadata.

Anthropic's platform reference does not document the beta yet; the feature is described from the client side in the Claude Code [auto mode classifier](https://code.claude.com/docs/en/auto-mode-classifier-billing) and [gateway compatibility](https://code.claude.com/docs/en/llm-gateway-protocol#feature-pass-through) guides.

### Reasoning

Anthropic models support extended thinking, where Claude shows its reasoning process before providing a final answer.

#### Adaptive Thinking

For newer models (`claude-sonnet-4-6`, `claude-opus-4-6`, and later), use adaptive thinking.
Claude automatically determines how much reasoning to use based on the complexity of the prompt.

```ts {4,8-10}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text, reasoningText, reasoning } = await generateText({
  model: anthropic('claude-opus-4-6'),
  prompt: 'How many people will live in the world in 2040?',
  providerOptions: {
    anthropic: {
      thinking: { type: 'adaptive' },
    } satisfies AnthropicLanguageModelOptions,
  },
});

console.log(reasoningText); // reasoning text
console.log(reasoning); // reasoning details including redacted reasoning
console.log(text); // text response
```

You can combine adaptive thinking with the `effort` option to control how much reasoning Claude uses:

```ts {6-8}
const { text } = await generateText({
  model: anthropic('claude-opus-4-6'),
  prompt: 'Invent a new holiday and describe its traditions.',
  providerOptions: {
    anthropic: {
      thinking: { type: 'adaptive' },
      effort: 'max', // 'low' | 'medium' | 'high' | 'max'
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

##### Adaptive-Only Models

`claude-sonnet-5-5`, `claude-opus-5-5`, `claude-fable-5`, and
`claude-fable-5-1` always run adaptive thinking. The API rejects
`thinking: { type: 'disabled' }` and budget-based
`thinking: { type: 'enabled' }` for these models. To keep existing code
working, the provider:

- removes `thinking: { type: 'disabled' }` and emits a warning,
- converts `thinking: { type: 'enabled', budgetTokens }` to `{ type: 'adaptive' }` and emits a warning,
- maps the top-level `reasoning: 'none'` option to `effort: 'low'` and emits a warning.

On `claude-sonnet-5-5`, which supports
[`between_tools` thinking](#between-tools-thinking), the provider instead
replaces `thinking: { type: 'disabled' }` with `thinking: { type: 'between_tools' }`
(with a warning) and maps `reasoning: 'none'` to `between_tools` thinking.

Use `effort` to control how much these models think. On `claude-opus-5-5`, set
`effort: 'low'` when time to first token matters, and move to `medium` if
quality drops:

```ts {6-9}
const { text } = await generateText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'Summarize this ticket in one sentence.',
  providerOptions: {
    anthropic: {
      // thinking stays adaptive; effort controls how much the model thinks
      effort: 'low',
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

Responses from adaptive-only models can begin with a thinking block. Read the
response by content type (`text`, `reasoning`, `tool-call`) rather than
assuming the first part is text. Under the default `display: 'omitted'`
setting, thinking blocks are returned with empty text.

##### Between-Tools Thinking

`claude-sonnet-5-5` supports `thinking: { type: 'between_tools' }`, its lowest
thinking setting. The model does no upfront thinking, but the short progress
notes it writes between tool calls are still returned as thinking blocks, each
with a short summary. They are available as reasoning parts and are sent back
unchanged on the next step. `between_tools` accepts no other thinking options
(such as `display` or `blockBinding`) and is only accepted at `low`, `medium`,
and `high` effort. Per-message effort changes via
[mid-conversation system messages](#mid-conversation-system-controls) are not
supported with `between_tools`.

```ts {16-17}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText, isStepCount, tool } from 'ai';
import { z } from 'zod';

const { text, steps } = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  stopWhen: isStepCount(5),
  tools: {
    weather: tool({
      inputSchema: z.object({ city: z.string() }),
      execute: async ({ city }) => ({ city, temperature: 72 }),
    }),
  },
  providerOptions: {
    anthropic: {
      thinking: { type: 'between_tools' },
      effort: 'low',
    } satisfies AnthropicLanguageModelOptions,
  },
  prompt: 'Compare the weather in San Francisco and New York.',
});
```

##### Thinking Display (Opus 4.7+)

Starting with `claude-opus-4-7`, thinking content is omitted from the response by default — thinking blocks are present in the stream but their text is empty. To receive reasoning output, set `display: 'summarized'`:

```ts {5}
const { text, reasoningText } = await generateText({
  model: anthropic('claude-opus-4-8'),
  providerOptions: {
    anthropic: {
      thinking: { type: 'adaptive', display: 'summarized' },
    } satisfies AnthropicLanguageModelOptions,
  },
  prompt: 'How many people will live in the world in 2040?',
});

console.log(reasoningText); // reasoning text (empty without display: 'summarized')
console.log(text);
```

If you stream reasoning to users with `claude-opus-4-7`, the default
`"omitted"` display will cause a long pause before output begins. Set
`display: "summarized"` to restore visible progress during thinking.

##### Thinking Updates

Use `display: 'updates'` with `claude-sonnet-5-5`, `claude-opus-5-5`, or
`claude-fable-5-1` to stream thinking summaries between tool calls. These models
return progress notes between tool calls as thinking blocks rather than text, so
without this setting a long tool-calling turn can look silent. The provider adds
the required `thinking-display-updates-2026-08-18` beta header automatically:

```ts {12-16}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { streamText, tool } from 'ai';
import { z } from 'zod';

const result = streamText({
  model: anthropic('claude-fable-5-1'),
  tools: {
    weather: tool({
      inputSchema: z.object({ city: z.string() }),
    }),
  },
  providerOptions: {
    anthropic: {
      thinking: { type: 'adaptive', display: 'updates' },
    } satisfies AnthropicLanguageModelOptions,
  },
  prompt: 'Compare the weather in San Francisco and New York.',
});
```

##### Thinking Binding Controls

Fable 5.1, Opus 5.5, and Sonnet 5.5 can recover from a thinking-block prefix
mismatch by dropping the mismatched block. Set
`blockBinding.prefixMismatchBehavior` to `drop_block`, or set it to `error` to
reject the request. You can provide block binding by itself to preserve the
model's default thinking mode, or combine it with adaptive thinking. Block
binding is not available with `between_tools` thinking; keep the message
history append-only instead.

```ts {7-11}
const result = await generateText({
  model: anthropic('claude-fable-5-1'),
  prompt: 'Continue from this conversation.',
  providerOptions: {
    anthropic: {
      thinking: {
        blockBinding: {
          prefixMismatchBehavior: 'drop_block',
        },
      },
    } satisfies AnthropicLanguageModelOptions,
  },
});

console.log(result.providerMetadata?.anthropic?.inputTransformations);
```

Dropped blocks are reported in
`providerMetadata.anthropic.inputTransformations` with their `type`, `path`, and
`reason`.

#### Budget-Based Thinking

For earlier models (`claude-opus-4-20250514`, `claude-sonnet-4-20250514`, `claude-sonnet-4-5-20250929`),
use `type: 'enabled'` with an explicit token budget:

```ts {4,8-10}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const { text, reasoningText, reasoning } = await generateText({
  model: anthropic('claude-sonnet-4-5-20250929'),
  prompt: 'How many people will live in the world in 2040?',
  providerOptions: {
    anthropic: {
      thinking: { type: 'enabled', budgetTokens: 12000 },
    } satisfies AnthropicLanguageModelOptions,
  },
});

console.log(reasoningText); // reasoning text
console.log(reasoning); // reasoning details including redacted reasoning
console.log(text); // text response
```

Anthropic's `max_tokens` limit includes both thinking and final text. To reserve
room for both, the provider adds `budgetTokens` to `maxOutputTokens` when
setting `max_tokens`. For known models, the combined value is capped at the
model's maximum output token limit.

With manual thinking (`thinking.type: 'enabled'`), a `required` or named
`toolChoice` falls back to `auto` with a warning. For a named tool choice, only
the selected tool is sent. This also applies when the top-level `reasoning`
option enables manual thinking, including when structured output uses the
internal JSON response tool. Tool use is no longer guaranteed: instruct the
model to use the tool in your prompt and verify that a tool call was made.

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 {7-20}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const result = await generateText({
  model: anthropic('claude-sonnet-4-5-20250929'),
  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 AnthropicLanguageModelOptions,
  },
});

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

#### Context Editing

Context editing strategies selectively remove specific content types from earlier in the conversation to reduce token usage without losing the overall conversation flow.

##### Clear Tool Uses

The `clear_tool_uses_20250919` edit type removes old tool call/result pairs from the conversation history:

- **trigger** - Condition that triggers the clearing (e.g., `{ type: 'input_tokens', value: 10000 }` or `{ type: 'tool_uses', value: 10 }`)
- **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 blocks from earlier turns, keeping only the most recent ones:

- **keep** - How many recent thinking turns to preserve (e.g., `{ type: 'thinking_turns', value: 2 }`) or `'all'` to keep everything

```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 AnthropicLanguageModelOptions,
  },
});
```

#### On-Demand Compaction

Use the `compaction` provider option to ask Anthropic to summarize the supplied
conversation immediately. The provider automatically adds the
`compact-2026-09-04` beta header.

```ts {10-15,21-22}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText, ModelMessage } from 'ai';

const history: ModelMessage[] = [
  { role: 'user', content: 'Help me design a recipe application.' },
  { role: 'assistant', content: 'Start with Recipe and Ingredient.' },
  { role: 'user', content: 'Recipe also needs a title and servings.' },
];

const summary = await generateText({
  model: anthropic('claude-opus-5'),
  messages: history,
  maxOutputTokens: 4096,
  providerOptions: {
    anthropic: {
      compaction: {
        type: 'summarize',
        instructions: 'Preserve all agreed entities and fields.',
      },
    } satisfies AnthropicLanguageModelOptions,
  },
});

if (summary.rawFinishReason === 'compaction') {
  const [compactionMessage] = summary.finalStep.response.messages;

  const continuation = await generateText({
    model: anthropic('claude-opus-5'),
    messages: [
      compactionMessage,
      { role: 'user', content: 'Which fields should be required?' },
    ],
  });

  console.log(continuation.text);
}
```

Anthropic returns the summary as a text part whose
`providerMetadata.anthropic.type` is `compaction`. Its opaque signature is
available as `providerMetadata.anthropic.signature`. Response messages copy
that metadata to `providerOptions`, so passing
`summary.finalStep.response.messages` back to the AI SDK preserves the signed
block and automatically adds the beta header on the continuation request.

Check `rawFinishReason` before reading the response block. Anthropic can return
a successful HTTP response without a summary when summarization ends for
another reason, such as `max_tokens`, `model_context_window_exceeded`,
`tool_use`, `refusal`, or `end_turn`. In that case, keep the existing history
and retry later; the unsuccessful summarization is still included in
`providerMetadata.anthropic.iterations`.

Send exactly one signed compaction block on continuation requests. It must be
the first content block in `messages` and must be replayed without changing its
text or signature. Remove the messages it summarizes before continuing. Keep
the same system prompt and tool definitions on the compaction request that you
use for the conversation, especially when preserving later thinking blocks.

Before requesting compaction, resolve any unfinished tool call from the last
assistant turn. Do not combine `compaction` with `contextManagement`,
`stopSequences`, structured output, a required or named `toolChoice`, or a
`taskBudget.remaining` value. Also omit `taskBudget.remaining` from later
requests that carry the signed block.

On-demand compaction usage is reported in
`providerMetadata.anthropic.iterations`. Sum the iteration usage when
calculating the tokens consumed by the summarization request.

On-demand compaction can also be initiated in a Message Batch. Configure the
`compaction` provider option on the individual batch request; the provider
automatically adds `compact-2026-09-04` to the batch beta header.

For more details, see
[Anthropic's on-demand compaction documentation](https://platform.claude.com/docs/en/build-with-claude/compaction-on-demand).

#### Threshold Compaction

The `compact_20260112` edit type automatically summarizes earlier conversation context when token limits are reached. This is useful for long-running conversations where you want to preserve the essence of earlier exchanges while staying within token limits.

```ts {7-19}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { streamText } from 'ai';

const result = streamText({
  model: anthropic('claude-opus-5-5'),
  messages: conversationHistory,
  providerOptions: {
    anthropic: {
      contextManagement: {
        edits: [
          {
            type: 'compact_20260112',
            trigger: {
              type: 'input_tokens',
              value: 50000, // trigger compaction when input exceeds 50k tokens
            },
            instructions:
              'Summarize the conversation concisely, preserving key decisions and context.',
            pauseAfterCompaction: false,
          },
        ],
      },
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

**Configuration:**

- **trigger** - Condition that triggers compaction (e.g., `{ type: 'input_tokens', value: 50000 }`)
- **instructions** - Custom instructions for how the model should summarize the conversation. Use this to guide the compaction summary towards specific aspects of the conversation you want to preserve.
- **pauseAfterCompaction** - When `true`, the model will pause after generating the compaction summary, allowing you to inspect or process it before continuing. Defaults to `false`.

When compaction occurs, the model generates a summary of the earlier context. This summary appears as a text block with special provider metadata.

##### Detecting Compaction in Streams

When using `streamText`, you can detect compaction summaries by checking the `providerMetadata` on `text-start` events:

```ts
for await (const part of result.stream) {
  switch (part.type) {
    case 'text-start': {
      const isCompaction =
        part.providerMetadata?.anthropic?.type === 'compaction';
      if (isCompaction) {
        console.log('[COMPACTION SUMMARY START]');
      }
      break;
    }
    case 'text-delta': {
      process.stdout.write(part.text);
      break;
    }
  }
}
```

##### Compaction in UI Applications

When using `useChat` or other UI hooks, compaction summaries appear as regular text parts with `providerMetadata`. You can style them differently in your UI:

```tsx
{
  message.parts.map((part, index) => {
    if (part.type === 'text') {
      const isCompaction =
        (part.providerMetadata?.anthropic as { type?: string } | undefined)
          ?.type === 'compaction';

      if (isCompaction) {
        return (
          <div
            key={index}
            className="bg-yellow-100 border-l-4 border-yellow-500 p-2"
          >
            <span className="font-bold">[Compaction Summary]</span>
            <div>{part.text}</div>
          </div>
        );
      }
      return <div key={index}>{part.text}</div>;
    }
  });
}
```

#### 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`);
    } else if (edit.type === 'compact_20260112') {
      console.log('Compaction was applied');
    }
  });
}
```

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.
You need to set the `anthropic` property in the `providerOptions` object to `{ cacheControl: { type: 'ephemeral' } }` to set a cache control breakpoint.

Cache read and cache write (creation) token counts are returned on the standard
`usage` object for both `generateText` and `streamText`. You can access them at
`result.usage.inputTokenDetails.cacheReadTokens` and
`result.usage.inputTokenDetails.cacheWriteTokens`.

```ts {8,18-20,29-32}
import { anthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const errorMessage = '... long error message ...';

const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: 'You are a JavaScript expert.' },
        {
          type: 'text',
          text: `Error message: ${errorMessage}`,
          providerOptions: {
            anthropic: { cacheControl: { type: 'ephemeral' } },
          },
        },
        { type: 'text', text: 'Explain the error message.' },
      ],
    },
  ],
});

console.log(result.text);
console.log(
  'Cache read tokens:',
  result.usage.inputTokenDetails.cacheReadTokens,
);
console.log(
  'Cache write tokens:',
  result.usage.inputTokenDetails.cacheWriteTokens,
);
```

You can also use cache control on system messages by providing multiple system messages at the head of your messages array:

```ts {3,7-9}
const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  messages: [
    {
      role: 'system',
      content: 'Cached system message part',
      providerOptions: {
        anthropic: { cacheControl: { type: 'ephemeral' } },
      },
    },
    {
      role: 'system',
      content: 'Uncached system message part',
    },
    {
      role: 'user',
      content: 'User prompt',
    },
  ],
});
```

Cache control for tools:

```ts
const result = await generateText({
  model: anthropic('claude-haiku-4-5'),
  tools: {
    cityAttractions: tool({
      inputSchema: z.object({ city: z.string() }),
      providerOptions: {
        anthropic: {
          cacheControl: { type: 'ephemeral' },
        },
      },
    }),
  },
  messages: [
    {
      role: 'user',
      content: 'User prompt',
    },
  ],
});
```

#### Longer cache TTL

Anthropic also supports a longer 1-hour cache duration.

Here's an example:

```ts
const result = await generateText({
  model: anthropic('claude-haiku-4-5'),
  messages: [
    {
      role: 'user',
      content: [
        {
          type: 'text',
          text: 'Long cached message',
          providerOptions: {
            anthropic: {
              cacheControl: { type: 'ephemeral', ttl: '1h' },
            },
          },
        },
      ],
    },
  ],
});
```

#### Limitations

The minimum cacheable prompt length is:

- 4096 tokens for Claude Opus 4.5
- 1024 tokens for Claude Opus 4.1, Claude Opus 4, Claude Sonnet 4.5, Claude Sonnet 4, Claude Sonnet 3.7, and Claude Opus 3
- 4096 tokens for Claude Haiku 4.5
- 2048 tokens for Claude Haiku 3.5 and Claude Haiku 3

Shorter prompts cannot be cached, even if marked with `cacheControl`. Any requests to cache fewer than this number of tokens will be processed without caching.

For more on prompt caching with Anthropic, see [Anthropic's Cache Control documentation](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching).

Because the `UIMessage` type (used by AI SDK UI hooks like `useChat`) does not
support the `providerOptions` property, you can use `convertToModelMessages`
first before passing the messages to functions like `generateText` or
`streamText`. For more details on `providerOptions` usage, see
[here](/docs/foundations/prompts#provider-options).

### Bash Tool

The Bash Tool allows running bash commands. By default, the tool executes
commands through the `experimental_sandbox` that you pass to `generateText` or `streamText`:

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText, isStepCount } from 'ai';

const result = await generateText({
  model: anthropic('claude-opus-4-8'),
  tools: {
    bash: anthropic.tools.bash_20250124(),
  },
  experimental_sandbox: {
    description: 'A sandboxed shell environment.',
    run: async ({ command }) => {
      // Run the command in your sandbox and return the result.
      return {
        exitCode: 0,
        stdout: `Executed: ${command}`,
        stderr: '',
      };
    },
  },
  stopWhen: isStepCount(2),
  prompt: 'List the files in the current directory.',
});
```

Parameters:

- `command` (string): The bash command to run. Required unless the tool is being restarted.
- `restart` (boolean, optional): Specifying true will restart this tool.

Two versions are available: `bash_20250124` (recommended) and `bash_20241022`.
Only certain Claude versions are supported.

You can also provide a custom `execute` function when you want to handle bash
execution directly instead of using the request experimental sandbox.

### Memory Tool

The [Memory Tool](https://docs.claude.com/en/docs/agents-and-tools/tool-use/memory-tool) allows Claude to use a local memory, e.g. in the filesystem.
Here's how to create it:

```ts
const memory = anthropic.tools.memory_20250818({
  execute: async action => {
    // Implement your memory command execution logic here
    // Return the result of the command execution
  },
});
```

Only certain Claude versions are supported.

### Text Editor Tool

The Text Editor Tool provides functionality for viewing and editing text files.

```ts
const tools = {
  str_replace_based_edit_tool: anthropic.tools.textEditor_20250728({
    maxCharacters: 10000, // optional
    async execute({ command, path, old_str, new_str, insert_text }) {
      // ...
    },
  }),
} satisfies ToolSet;
```

Different models support different versions of the tool:

- `textEditor_20250728` - For Claude Sonnet 4, Opus 4, and Opus 4.1 (recommended)
- `textEditor_20250124` - For Claude Sonnet 3.7
- `textEditor_20241022` - For Claude Sonnet 3.5

Note: `textEditor_20250429` is deprecated. Use `textEditor_20250728` instead.

Parameters:

- `command` ('view' | 'create' | 'str\_replace' | 'insert' | 'undo\_edit'): The command to run. Note: `undo_edit` is only available in Claude 3.5 Sonnet and earlier models.
- `path` (string): Absolute path to file or directory, e.g. `/repo/file.py` or `/repo`.
- `file_text` (string, optional): Required for `create` command, with the content of the file to be created.
- `insert_line` (number, optional): Required for `insert` command. The line number after which to insert the new string.
- `new_str` (string, optional): New string for `str_replace` command.
- `insert_text` (string, optional): Required for `insert` command, containing the text to insert.
- `old_str` (string, optional): Required for `str_replace` command, containing the string to replace.
- `view_range` (number\[], optional): Optional for `view` command to specify line range to show.

### Computer Tool

The Computer Tool enables control of keyboard and mouse actions on a computer:

```ts
const computerTool = anthropic.tools.computer_20251124({
  displayWidthPx: 1920,
  displayHeightPx: 1080,
  displayNumber: 0, // Optional, for X11 environments
  enableZoom: true, // Optional, enables the zoom action

  execute: async ({ action, coordinate, text, region }) => {
    // Implement your computer control logic here
    // Return the result of the action

    // Example code:
    switch (action) {
      case 'screenshot': {
        // multipart result:
        return {
          type: 'image',
          data: fs
            .readFileSync('./data/screenshot-editor.png')
            .toString('base64'),
        };
      }
      case 'zoom': {
        // region is [x1, y1, x2, y2] defining the area to zoom into
        return {
          type: 'image',
          data: fs.readFileSync('./data/zoomed-region.png').toString('base64'),
        };
      }
      default: {
        console.log('Action:', action);
        console.log('Coordinate:', coordinate);
        console.log('Text:', text);
        return `executed ${action}`;
      }
    }
  },

  // map to tool result content for LLM consumption:
  toModelOutput({ output }) {
    return typeof output === 'string'
      ? [{ type: 'text', text: output }]
      : [{ type: 'file-data', data: output.data, mediaType: 'image/png' }];
  },
});
```

Use `computerToolset_20260801` for Claude Sonnet 5.5 and Opus 5.5 (required),
Opus 5, Sonnet 5, Fable 5, Fable 5.1, and Opus 4.8. Use `computer_20251124`
for Claude Opus 4.5 through Opus 4.7, which support the zoom action. Use
`computer_20250124` for Claude Sonnet 4.5, Haiku 4.5, Opus 4.1, Sonnet 4, Opus
4, and Sonnet 3.7.

#### Computer Toolset

Newer models use the computer toolset instead of a versioned computer tool.
`claude-sonnet-5-5` and `claude-opus-5-5` accept computer use only through the
toolset and reject the older `computer_*` tool types with a 400. The toolset
does not require a beta header and has no display size parameters: coordinates
are always in the pixel space of the screenshots you return. Zoom is enabled by default, and Claude can
return several actions in one turn, each as its own tool call.

The API returns each action as a separate `tool_use` block with
`toolset_name: 'computer'`. The AI SDK maps every action to the toolset tool and
passes the action name as `action`, so `execute` receives the same input shape
as the older computer tools:

```ts
const computerTool = anthropic.tools.computerToolset_20260801({
  // optional: turn individual actions on or off
  configs: {
    zoom: { enabled: false },
  },

  execute: async ({ action, coordinate, text, region }) => {
    switch (action) {
      case 'screenshot': {
        return {
          type: 'image',
          data: fs.readFileSync('./data/screenshot.png').toString('base64'),
        };
      }
      default: {
        console.log('Action:', action, coordinate, text, region);
        return `executed ${action}`;
      }
    }
  },

  toModelOutput({ output }) {
    return typeof output === 'string'
      ? [{ type: 'text', text: output }]
      : [{ type: 'file-data', data: output.data, mediaType: 'image/png' }];
  },
});
```

Parameters:

- `action` ('screenshot' | 'zoom' | 'left\_click' | 'right\_click' | 'middle\_click' | 'double\_click' | 'triple\_click' | 'left\_click\_drag' | 'mouse\_move' | 'left\_mouse\_down' | 'left\_mouse\_up' | 'cursor\_position' | 'scroll' | 'type' | 'key' | 'hold\_key' | 'wait'): The member tool that Claude invoked.
- `coordinate` (number\[], optional): The (x, y) pixel coordinates for click, move, and scroll actions.
- `start_coordinate` (number\[], optional): Where a `left_click_drag` starts.
- `region` (number\[], optional): `[x1, y1, x2, y2]` for the `zoom` action.
- `text` (string, optional): Text to type, the key combination for `key` and `hold_key`, or modifier keys to hold during click and scroll actions.
- `repeat` (number, optional): How many times to press the key for `key`.
- `duration` (number, optional): Seconds for `hold_key` and `wait`.
- `scroll_direction` ('up' | 'down' | 'left' | 'right', optional) and `scroll_amount` (number, optional): For the `scroll` action.
- `configs` (object, optional): Per-action settings keyed by action name. Each entry accepts `enabled` (default `true`) and `deferLoading` (default `false`, for tool search).

Tool calls and results of the toolset are serialized with `toolset_name` when
you pass the message history back. Keep the toolset tool in `tools` on
follow-up requests, or the provider falls back to the `toolsetName` provider
metadata on the tool calls of previous responses. Do not declare the toolset
together with an older `computer_*` tool.

Parameters:

- `action` ('key' | 'type' | 'mouse\_move' | 'left\_click' | 'left\_click\_drag' | 'right\_click' | 'middle\_click' | 'double\_click' | 'screenshot' | 'cursor\_position' | 'zoom'): The action to perform. For versioned computer tools, the `zoom` action is only available with `computer_20251124`. It is also available with `computerToolset_20260801`, where it is enabled by default.
- `coordinate` (number\[], optional): Required for `mouse_move` and `left_click_drag` actions. Specifies the (x, y) coordinates.
- `text` (string, optional): Required for `type` and `key` actions.
- `region` (number\[], optional): Required for `zoom` action. Specifies `[x1, y1, x2, y2]` coordinates for the area to inspect.
- `displayWidthPx` (number): The width of the display in pixels.
- `displayHeightPx` (number): The height of the display in pixels.
- `displayNumber` (number, optional): The display number for X11 environments.
- `enableZoom` (boolean, optional): Enable the zoom action. Only available with `computer_20251124`. Default: `false`.

### Web Search Tool

Anthropic provides a provider-defined web search tool that gives Claude direct access to real-time web content, allowing it to answer questions with up-to-date information beyond its knowledge cutoff.

You can enable web search using the provider-defined web search tool:

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const webSearchTool = anthropic.tools.webSearch_20260318({
  maxUses: 5,
  responseInclusion: 'excluded',
});

const result = await generateText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'What are the latest developments in AI?',
  tools: {
    web_search: webSearchTool,
  },
});
```

Web search must be enabled in your organization's [Console
settings](https://console.anthropic.com/settings/privacy).

#### Sources and Citations

`result.sources` and source stream events expose web-search results. Inline
references are attached separately to generated text as `part.citations`, and
to streamed text as `text-end.citations`. This shared citation representation
includes the referenced URL or document and its supporting passage. If web-search
results are unavailable, web citations also provide source references for
compatibility. Indexed document references retain their existing document source
parts when the original prompt supplies document information.

Raw citations remain available as
`text.providerMetadata.anthropic.citations`, including on streamed `text-end`
events. Import `AnthropicTextProviderMetadata` and `AnthropicCitation` for typed
access. `AnthropicCitation` is a union of `web_search_result_location`,
`search_result_location`, `page_location`, `char_location`, and
`content_block_location`. Document page, character, and block locations refer to
the source document, rather than the generated answer.

```ts
import type { AnthropicTextProviderMetadata } from '@ai-sdk/anthropic';

for (const part of result.content) {
  if (part.type === 'text') {
    console.log(part.citations);
    const metadata = part.providerMetadata as
      | AnthropicTextProviderMetadata
      | undefined;
    for (const citation of metadata?.anthropic.citations ?? []) {
      console.log(citation.type, citation.cited_text);
    }
  }
}
```

#### Configuration Options

Use `webSearch_20260318` for dynamic filtering and response inclusion control.
The older `webSearch_20260209` and `webSearch_20250305` versions remain
available for applications that need their earlier behavior.

The web search tool supports several configuration options:

- **maxUses** *number*

  Maximum number of web searches Claude can perform during the conversation.

- **allowedDomains** *string\[]*

  Optional list of domains that Claude is allowed to search. If provided, searches will be restricted to these domains.

- **blockedDomains** *string\[]*

  Optional list of domains that Claude should avoid when searching.

- **userLocation** *object*

  Optional user location information to provide geographically relevant search results.

- **responseInclusion** *'full' | 'excluded'*

  Available with `webSearch_20260318`. Controls whether search result blocks
  consumed by a completed code execution call in the same turn are included in
  the API response. The default is `'full'`. Use `'excluded'` to omit those
  nested call/result pairs and reduce output token usage.

```ts
const webSearchTool = anthropic.tools.webSearch_20260318({
  maxUses: 3,
  allowedDomains: ['techcrunch.com', 'wired.com'],
  userLocation: {
    type: 'approximate',
    country: 'US',
    region: 'California',
    city: 'San Francisco',
    timezone: 'America/Los_Angeles',
  },
  responseInclusion: 'excluded',
});

const result = await generateText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'Find local news about technology',
  tools: {
    web_search: webSearchTool,
  },
});
```

`responseInclusion: 'excluded'` only omits results consumed by code execution
calls that complete in the same turn. Results from direct calls and from code
execution calls that pause before completing are always returned in full so
they can be sent back on the next turn.

### Web Fetch Tool

Anthropic provides a provider-defined web fetch tool that allows Claude to retrieve content from specific URLs. This is useful when you want Claude to analyze or reference content from a particular webpage or document.

You can enable web fetch using the provider-defined web fetch tool:

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const result = await generateText({
  model: anthropic('claude-opus-5-5'),
  prompt:
    'What is this page about? https://en.wikipedia.org/wiki/Maglemosian_culture',
  tools: {
    web_fetch: anthropic.tools.webFetch_20260318({
      maxUses: 1,
      responseInclusion: 'excluded',
    }),
  },
});
```

### Advisor Tool

Anthropic provides a provider-executed advisor tool that lets an executor model consult a stronger advisor model during generation. This is useful for long-running coding, research, and agentic tasks where a stronger model can provide planning or course correction while the main response is generated by a faster or lower-cost model.

You can enable the advisor tool using `anthropic.tools.advisor_20260301`:

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const result = await generateText({
  model: anthropic('claude-sonnet-4-6'),
  instructions:
    'You have access to an `advisor` tool backed by a stronger reviewer model.',
  prompt:
    'Build a concurrent worker pool in Go with graceful shutdown. Outline the design first.',
  tools: {
    advisor: anthropic.tools.advisor_20260301({
      model: 'claude-opus-4-8',
      maxUses: 3,
      maxTokens: 2048,
    }),
  },
});
```

The AI SDK automatically sends the required `advisor-tool-2026-03-01` beta
header when you include this tool.

#### Configuration Options

The advisor tool supports the following configuration options:

- **model** *string*

  Required. The advisor model ID, such as `claude-opus-4-8`. The advisor model must be at least as capable as the executor model.

- **maxUses** *number*

  Optional. Maximum number of advisor calls allowed in a single request. Once the executor reaches this cap, further advisor calls return an `advisor_tool_result_error` with `errorCode: 'max_uses_exceeded'`, and the executor continues without further advice.

- **maxTokens** *number*

  Optional. Maximum number of tokens the advisor can generate per call, including thinking and text. The minimum is `1024`, and Anthropic recommends starting with `2048`. This limit applies independently to each advisor call and is separate from the request-level `maxOutputTokens`, which controls executor output. Values above the selected advisor model's output limit result in an Anthropic `400` error. When configured, successful advisor results include `stopReason`; check for `stopReason === 'max_tokens'` to detect truncated advice. The field is available on both plaintext and redacted advisor result variants and is preserved across follow-up turns.

- **caching** *object*

  Optional. Enables prompt caching for the advisor's own transcript across calls within a conversation. Use `{ type: 'ephemeral', ttl: '5m' | '1h' }`. This is most useful for longer agent loops where you expect at least three advisor calls.

#### How It Works

The advisor tool is provider-executed, so you do not provide an `execute` function. When the executor model calls `advisor`, Anthropic runs a separate server-side inference with the advisor model. The advisor sees the transcript and returns guidance to the executor, which then continues generating within the same request.

The advisor tool input is always empty. Anthropic constructs the advisor's view from the full transcript automatically.

For multi-turn conversations, pass the full assistant content, including advisor tool results, back on subsequent turns. If you remove the advisor tool from a later request, also remove previous advisor tool results from the message history; otherwise the Anthropic API returns an invalid request error.

#### Streaming

Advisor sub-inferences do not stream. When using `streamText`, the executor stream pauses while the advisor runs, then the advisor result arrives as a single tool result before executor output resumes.

### Tool Search

Anthropic provides provider-defined tool search tools that enable Claude to work with hundreds or thousands of tools by dynamically discovering and loading them on-demand. Instead of loading all tool definitions into the context window upfront, Claude searches your tool catalog and loads only the tools it needs.

There are two variants:

- **BM25 Search** - Uses natural language queries to find tools
- **Regex Search** - Uses regex patterns (Python `re.search()` syntax) to find tools

#### Basic Usage

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText, tool } from 'ai';
import { z } from 'zod';

const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  prompt: 'What is the weather in San Francisco?',
  tools: {
    toolSearch: anthropic.tools.toolSearchBm25_20251119(),

    get_weather: tool({
      description: 'Get the current weather at a specific location',
      inputSchema: z.object({
        location: z.string().describe('The city and state'),
      }),
      execute: async ({ location }) => ({
        location,
        temperature: 72,
        condition: 'Sunny',
      }),
      // Defer tool here - Claude discovers these via the tool search tool
      providerOptions: {
        anthropic: { deferLoading: true },
      },
    }),
  },
});
```

#### Using Regex Search

For more precise tool matching, you can use the regex variant:

```ts
const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  prompt: 'Get the weather data',
  tools: {
    toolSearch: anthropic.tools.toolSearchRegex_20251119(),
    // ... deferred tools
  },
});
```

Claude will construct regex patterns like `weather|temperature|forecast` to find matching tools.

#### Custom Tool Search

You can implement your own tool search logic (e.g., using embeddings or semantic search) by returning `tool-reference` content blocks via `toModelOutput`:

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText, tool } from 'ai';
import { z } from 'zod';

const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  prompt: 'What is the weather in San Francisco?',
  tools: {
    // Custom search tool
    searchTools: tool({
      description: 'Search for tools by keyword',
      inputSchema: z.object({ query: z.string() }),
      execute: async ({ query }) => {
        // Your custom search logic (embeddings, fuzzy match, etc.)
        const allTools = ['get_weather', 'get_forecast', 'get_temperature'];
        return allTools.filter(name => name.includes(query.toLowerCase()));
      },
      toModelOutput: ({ output }) => ({
        type: 'content',
        value: (output as string[]).map(toolName => ({
          type: 'custom' as const,
          providerOptions: {
            anthropic: {
              type: 'tool-reference',
              toolName,
            },
          },
        })),
      }),
    }),

    // Deferred tools
    get_weather: tool({
      description: 'Get the current weather',
      inputSchema: z.object({ location: z.string() }),
      execute: async ({ location }) => ({ location, temperature: 72 }),
      providerOptions: {
        anthropic: { deferLoading: true },
      },
    }),
  },
});
```

This sends `tool_reference` blocks to Anthropic, which loads the corresponding deferred tool schemas into Claude's context.

### Mid-Conversation System Controls

With `claude-sonnet-5-5`, `claude-opus-5-5`, and `claude-fable-5-1`, use an
empty system message to change effort from the next user turn. A separate
system message containing text can provide a turn-scoped reminder with
`clearAt: 'next_user_message'`: its text applies until the next user message. Keep the reminder after a user turn and
before an assistant turn, or at the end of the messages array.
The provider adds the required
`mid-conversation-system-clear-at-2026-08-21` and
`mid-conversation-output-config-2026-07-01` beta headers automatically.

```ts {16-24,29-37}
import { anthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const result = await generateText({
  model: anthropic('claude-fable-5-1'),
  allowSystemInMessages: true,
  messages: [
    {
      role: 'user',
      content: 'Draft a migration plan.',
    },
    {
      role: 'assistant',
      content: 'First, inventory the public API.',
    },
    {
      role: 'system',
      content: '',
      providerOptions: {
        anthropic: {
          effort: 'high',
        },
      },
    },
    {
      role: 'user',
      content: 'Complete the plan.',
    },
    {
      role: 'system',
      content: 'For this turn, verify every compatibility claim.',
      providerOptions: {
        anthropic: {
          clearAt: 'next_user_message',
        },
      },
    },
  ],
});
```

An effort-only system message can use an empty content array at the API level;
in an AI SDK prompt, set `content: ''`. The provider serializes it as
`content: []`. These effort-only messages can appear first or later in the
conversation, including consecutively. The provider preserves their order. The new
level applies from the next user turn until a later message changes it.
Initial instruction text is sent in the top-level `system` field.

Consecutive inline system messages are evaluated as a group. If an effort-only
message is adjacent to a system message containing text, the whole group must
follow Anthropic's [content placement rules](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages#limitations).

Turn-scoped messages with `clearAt` support text only. Put effort updates in a
separate message, as in the example above.

`clearAt` applies only to mid-conversation system messages. On initial system
messages, the provider ignores `clearAt` and effort attached to non-empty
content and emits a warning. Use an empty system message for an initial
per-message effort setting, or the top-level `effort` provider option to
configure effort for the full request.

### Mid-Conversation Tool Changes

With `claude-opus-4-8`, you can add or remove tools between turns of a conversation without invalidating the prompt cache. Attach `toolChanges` to a system message that appears mid-conversation (right before an assistant message or at the end of the messages). The required `mid-conversation-tool-changes-2026-07-01` beta header is added automatically.

Tools referenced by a `tool_addition` must be declared in the `tools` option — typically with `deferLoading: true`, so they are not loaded into context until the addition surfaces them. A `tool_removal` removes a previously available tool from the conversation going forward.

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText, tool } from 'ai';
import { z } from 'zod';

const result = await generateText({
  model: anthropic('claude-opus-4-8'),
  // required for system messages inside `messages`:
  allowSystemInMessages: true,
  tools: {
    get_weather: tool({
      description: 'Get weather',
      inputSchema: z.object({ city: z.string() }),
    }),
    get_forecast: tool({
      description: 'Get 5-day forecast',
      inputSchema: z.object({ city: z.string() }),
      providerOptions: {
        // declared up front but not loaded until a tool_addition surfaces it
        anthropic: { deferLoading: true },
      },
    }),
  },
  messages: [
    { role: 'user', content: 'What tools do you have for weather in Paris?' },
    {
      role: 'system',
      content: '',
      providerOptions: {
        anthropic: {
          toolChanges: [
            { type: 'tool_addition', toolName: 'get_forecast' },
            { type: 'tool_removal', toolName: 'get_weather' },
          ],
        },
      },
    },
  ],
});
```

To change a tool's definition, remove the old definition at the end of one request, then carry the conversation forward with the updated definition in `tools` on the next request.

Tool changes are not supported on the initial system message. The AI SDK
ignores them there and emits a warning — configure the initial tool set via
the `tools` option instead.

### MCP Connectors

Anthropic supports connecting to [MCP servers](https://docs.claude.com/en/docs/agents-and-tools/mcp-connector) as part of their execution.

You can enable this feature with the `mcpServers` provider option:

```ts
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  prompt: `Call the echo tool with "hello world". what does it respond with back?`,
  providerOptions: {
    anthropic: {
      mcpServers: [
        {
          type: 'url',
          name: 'echo',
          url: 'https://echo.mcp.inevitable.fyi/mcp',
          // optional: authorization token
          authorizationToken: mcpAuthToken,
          // optional: tool configuration
          toolConfiguration: {
            enabled: true,
            allowedTools: ['echo'],
          },
        },
      ],
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

The tool calls and results are dynamic, i.e. the input and output schemas are not known.

#### Configuration Options

The web fetch tool supports several configuration options:

- **maxUses** *number*

  The maxUses parameter limits the number of web fetches performed.

- **allowedDomains** *string\[]*

  Only fetch from these domains.

- **blockedDomains** *string\[]*

  Never fetch from these domains.

- **citations** *object*

  Unlike web search where citations are always enabled, citations are optional for web fetch. Set `"citations": {"enabled": true}` to enable Claude to cite specific passages from fetched documents.

- **maxContentTokens** *number*

  The maxContentTokens parameter limits the amount of content that will be included in the context.

- **useCache** *boolean*

  Available with `webFetch_20260318`. Set to `false` to bypass cached content
  and fetch fresh content. The default is `true`; disabling the cache can
  increase latency.

- **responseInclusion** *'full' | 'excluded'*

  Available with `webFetch_20260318`. Controls whether fetch result blocks
  consumed by a completed code execution call in the same turn are included in
  the API response. The default is `'full'`. Direct results and results from
  code execution calls that pause before completing are always returned in full.

#### Error Handling

Web search errors are handled differently depending on whether you're using streaming or non-streaming:

**Non-streaming (`generateText`):**
Web search errors throw exceptions that you can catch:

```ts
try {
  const result = await generateText({
    model: anthropic('claude-opus-5-5'),
    prompt: 'Search for something',
    tools: {
      web_search: webSearchTool,
    },
  });
} catch (error) {
  if (error.message.includes('Web search failed')) {
    console.log('Search error:', error.message);
    // Handle search error appropriately
  }
}
```

**Streaming (`streamText`):**
Web search errors are delivered as error parts in the stream:

```ts
const result = await streamText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'Search for something',
  tools: {
    web_search: webSearchTool,
  },
});

for await (const part of result.textStream) {
  if (part.type === 'error') {
    console.log('Search error:', part.error);
    // Handle search error appropriately
  }
}
```

## Code Execution

Anthropic provides a provider-defined code execution tool that gives Claude direct access to a real Python environment allowing it to execute code to inform its responses.

You can enable code execution using the provider-defined code execution tool:

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const codeExecutionTool = anthropic.tools.codeExecution_20260120();

const result = await generateText({
  model: anthropic('claude-opus-4-20250514'),
  prompt:
    'Calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]',
  tools: {
    code_execution: codeExecutionTool,
  },
});
```

Three versions are available: `codeExecution_20260120` (recommended, does not
require a beta header, supports Claude Opus 4.6, Sonnet 4.6, Sonnet 4.5, and
Opus 4.5), `codeExecution_20250825` (supports Python and Bash with enhanced
file operations), and `codeExecution_20250522` (supports Bash only).

#### Uploading Files for Code Execution

You can upload files via the [Files API](https://docs.anthropic.com/en/docs/build-with-claude/files) and make them available inside the code execution sandbox. First upload the file, then reference it in your message using `containerUpload: true` in the provider options:

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { generateText, uploadFile } from 'ai';
import * as fs from 'fs';

const { providerReference } = await uploadFile({
  api: anthropic.files(),
  data: fs.readFileSync('./data.csv'),
  filename: 'data.csv',
  mediaType: 'text/csv',
});

const result = await generateText({
  model: anthropic('claude-sonnet-4-5'),
  tools: {
    code_execution: anthropic.tools.codeExecution_20250825(),
  },
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: 'Analyze this CSV data' },
        {
          type: 'file',
          mediaType: 'text/csv',
          data: { type: 'reference', reference: providerReference },
          providerOptions: {
            anthropic: { containerUpload: true },
          },
        },
      ],
    },
  ],
});
```

Supported file types include CSV, Excel, JSON, XML, images (JPEG, PNG, GIF, WebP), and text files.

#### Error Handling

Code execution errors are handled differently depending on whether you're using streaming or non-streaming:

**Non-streaming (`generateText`):**
Code execution errors are delivered as tool result parts in the response:

```ts
const result = await generateText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'Execute some Python script',
  tools: {
    code_execution: codeExecutionTool,
  },
});

const toolErrors = result.content?.filter(
  content => content.type === 'tool-error',
);

toolErrors?.forEach(error => {
  console.error('Tool execution error:', {
    toolName: error.toolName,
    toolCallId: error.toolCallId,
    error: error.error,
  });
});
```

**Streaming (`streamText`):**
Code execution errors are delivered as error parts in the stream:

```ts
const result = await streamText({
  model: anthropic('claude-opus-5-5'),
  prompt: 'Execute some Python script',
  tools: {
    code_execution: codeExecutionTool,
  },
});
for await (const part of result.textStream) {
  if (part.type === 'error') {
    console.log('Code execution error:', part.error);
    // Handle code execution error appropriately
  }
}
```

### Programmatic Tool Calling

[Programmatic Tool Calling](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/programmatic-tool-calling) allows Claude to write code that calls your tools programmatically within a code execution container, rather than requiring round trips through the model for each tool invocation. This reduces latency for multi-tool workflows and decreases token consumption.

To enable programmatic tool calling, use the `allowedCallers` provider option on tools that you want to be callable from within code execution:

```ts {13-17}
import {
  anthropic,
  forwardAnthropicContainerIdFromLastStep,
} from '@ai-sdk/anthropic';
import { generateText, tool, isStepCount } from 'ai';
import { z } from 'zod';

const result = await generateText({
  model: anthropic('claude-sonnet-4-5'),
  stopWhen: isStepCount(10),
  prompt:
    'Get the weather for Tokyo, Sydney, and London, then calculate the average temperature.',
  tools: {
    code_execution: anthropic.tools.codeExecution_20260120(),

    getWeather: tool({
      description: 'Get current weather data for a city.',
      inputSchema: z.object({
        city: z.string().describe('Name of the city'),
      }),
      execute: async ({ city }) => {
        // Your weather API implementation
        return { temp: 22, condition: 'Sunny' };
      },
      // Enable this tool to be called from within code execution
      providerOptions: {
        anthropic: {
          allowedCallers: ['code_execution_20260120'],
        },
      },
    }),
  },

  // Propagate container ID between steps for code execution continuity
  prepareStep: forwardAnthropicContainerIdFromLastStep,
});
```

In this flow:

1. Claude writes Python code that calls your `getWeather` tool multiple times in parallel
2. The SDK automatically executes your tool and returns results to the code execution container
3. Claude processes the results in code and generates the final response

Programmatic tool calling requires `claude-sonnet-4-6`, `claude-sonnet-4-5`,
`claude-opus-4-6`, or `claude-opus-4-5` models and uses the
`code_execution_20260120` or `code_execution_20250825` tool.

#### Pruning Programmatic Tool History

When pruning removes a code execution call but keeps a tool call that references
it through `caller.toolId`, the provider omits the dangling caller metadata from
history before a subsequent user message and emits a warning. The retained tool
calls and results are still sent to Anthropic; the removed code execution history
is not restored.

Tool-result messages do not end a turn. Caller metadata in an active tool
continuation is preserved, so keep the source code execution call when returning
programmatic tool results.

#### Container Persistence

When using programmatic tool calling across multiple steps, you need to preserve the container ID between steps using `prepareStep`. You can use the `forwardAnthropicContainerIdFromLastStep` helper function to do this automatically. The container ID is available in `providerMetadata.anthropic.container.id` after each step completes.

## Agent Skills

[Anthropic Agent Skills](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview) enable Claude to perform specialized tasks like document processing (PPTX, DOCX, PDF, XLSX) and data analysis. Skills run in a sandboxed container and require the code execution tool to be enabled.

### Using Built-in Skills

Anthropic provides several built-in skills:

- **pptx** - Create and edit PowerPoint presentations
- **docx** - Create and edit Word documents
- **pdf** - Process and analyze PDF files
- **xlsx** - Work with Excel spreadsheets

To use skills, you need to:

1. Enable the code execution tool
2. Specify the container with skills in `providerOptions`

```ts {6-8,10-23}
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const result = await generateText({
  model: anthropic('claude-sonnet-4-5'),
  tools: {
    code_execution: anthropic.tools.codeExecution_20260120(),
  },
  prompt: 'Create a presentation about renewable energy with 5 slides',
  providerOptions: {
    anthropic: {
      container: {
        skills: [
          {
            type: 'anthropic',
            skillId: 'pptx',
            version: 'latest', // optional
          },
        ],
      },
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

### Custom Skills

You can also use custom skills by specifying `type: 'custom'`:

```ts {11-15}
const result = await generateText({
  model: anthropic('claude-sonnet-4-5'),
  tools: {
    code_execution: anthropic.tools.codeExecution_20260120(),
  },
  prompt: 'Use my custom skill to process this data',
  providerOptions: {
    anthropic: {
      container: {
        skills: [
          {
            type: 'custom',
            skillId: 'my-custom-skill-id',
            version: '1.0', // optional
          },
        ],
      },
    } satisfies AnthropicLanguageModelOptions,
  },
});
```

Skills use progressive context loading and execute within a sandboxed
container with code execution capabilities.

### PDF support

Anthropic Claude models support reading PDF files.
You can pass PDF files as part of the message content using the `file` type:

Option 1: URL-based PDF document

```ts
const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  messages: [
    {
      role: 'user',
      content: [
        {
          type: 'text',
          text: 'What is an embedding model according to this document?',
        },
        {
          type: 'file',
          data: new URL(
            'https://github.com/vercel/ai/blob/main/examples/ai-functions/data/ai.pdf?raw=true',
          ),
          mimeType: 'application/pdf',
        },
      ],
    },
  ],
});
```

Option 2: Base64-encoded PDF document

```ts
const result = await generateText({
  model: anthropic('claude-sonnet-5-5'),
  messages: [
    {
      role: 'user',
      content: [
        {
          type: 'text',
          text: 'What is an embedding model according to this document?',
        },
        {
          type: 'file',
          data: fs.readFileSync('./data/ai.pdf'),
          mediaType: 'application/pdf',
        },
      ],
    },
  ],
});
```

The model will have access to the contents of the PDF file and
respond to questions about it.
The PDF file should be passed using the `data` field,
and the `mediaType` should be set to `'application/pdf'`.

### Model Capabilities

| Model               | Image Input | Object Generation | Tool Usage | Computer Use | Web Search | Tool Search | Compaction |
| ------------------- | ----------- | ----------------- | ---------- | ------------ | ---------- | ----------- | ---------- |
| `claude-opus-5-5`   | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-opus-5`     | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-sonnet-5-5` | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-sonnet-5`   | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-haiku-5-5`  | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-fable-5-1`  | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-fable-5`    | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-opus-4-8`   | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-opus-4-7`   | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-opus-4-6`   | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           | ✓          |
| `claude-sonnet-4-6` | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           |            |
| `claude-opus-4-5`   | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           |            |
| `claude-haiku-4-5`  | ✓           | ✓                 | ✓          | ✓            | ✓          |             |            |
| `claude-sonnet-4-5` | ✓           | ✓                 | ✓          | ✓            | ✓          | ✓           |            |
| `claude-opus-4-1`   | ✓           | ✓                 | ✓          | ✓            | ✓          |             |            |
| `claude-opus-4-0`   | ✓           | ✓                 | ✓          | ✓            | ✓          |             |            |
| `claude-sonnet-4-0` | ✓           | ✓                 | ✓          | ✓            | ✓          |             |            |

The table above lists popular models. Please see the [Anthropic
docs](https://docs.anthropic.com/en/docs/about-claude/models) for a full list
of available models. The table above lists popular models. You can also pass
any available provider model ID as a string if needed.

## Decision Models

Create an experimental decision model with `anthropic.decisionModel(modelId)`.
It uses the Messages API's structured-output support for Choice, Score, and Boolean
questions. `claude-haiku-4-5-20251001` is one supported model.

```ts
import { anthropic } from '@ai-sdk/anthropic';
import { experimental_decide } from 'ai';

const { answers } = await experimental_decide({
  model: anthropic.decisionModel('claude-haiku-4-5-20251001'),
  state: 'I was charged twice.',
  questions: {
    requestsRefund: {
      type: 'boolean',
      instructions: 'Is the customer requesting money back?',
    },
    department: {
      type: 'choice',
      instructions: 'Which team should handle this?',
      criteria: { billing: 'Charges and refunds', support: 'Other requests' },
    },
  },
});
```

Choice labels are preserved exactly, and Scores are finite fractional positions
on the ordered rubric. Anthropic does not support numeric bounds in its native
output schema, so the adapter describes them in the prompt and validates them
after parsing. Invalid answers, refusals, and truncation fail the entire call.

The adapter returns no probability distributions for Choice or Score. Boolean
answers contain prompted estimates of P(true), validated to be finite and in
`[0, 1]`. These estimates are not guaranteed to be calibrated. Apply thresholds
in application code, for example `answers.requestsRefund.probability >= 0.5`.
It respects
`createAnthropic` configuration and forwards `providerOptions.anthropic`, including
`structuredOutputMode`. Supported models use native structured output by default;
`jsonTool` uses the existing Messages JSON-tool fallback. Usage, warnings,
response information, and provider metadata are preserved.
See [Decisions](/docs/ai-sdk-core/decisions).

Decision models can also be accessed through `customProvider` aliases or
`createProviderRegistry().decisionModel('provider:model')`. Direct string IDs
use Gateway by default, or an explicitly configured default provider with an
`decisionModel` method. See
[model aliases and registries](/docs/ai-sdk-core/decisions#model-aliases-and-registries).

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)