ai_sdk_anthropic 3.0.0
ai_sdk_anthropic: ^3.0.0 copied to clipboard
Anthropic provider for AI SDK Dart. Use Claude models (claude-sonnet, claude-haiku, claude-opus) for text generation, streaming, tools, and structured output.
ai_sdk_anthropic examples #
Installation #
dart pub add ai_sdk_dart ai_sdk_anthropic
The top-level anthropic factory reads
const String.fromEnvironment('ANTHROPIC_API_KEY'). Use it with
fvm dart run --define=ANTHROPIC_API_KEY=sk-ant-... bin/app.dart, or read
Platform.environment['ANTHROPIC_API_KEY'] yourself and pass apiKey: to
AnthropicProvider in server and CLI apps.
Text generation #
import 'package:ai_sdk_dart/ai_sdk_dart.dart';
import 'package:ai_sdk_anthropic/ai_sdk_anthropic.dart';
final result = await generateText(
model: anthropic('claude-sonnet-4-5'),
prompt: 'Explain quantum entanglement in one sentence.',
);
print(result.text);
print('tokens used: ${result.usage}');
Streaming #
import 'dart:io';
final result = await streamText(
model: anthropic('claude-sonnet-4-5'),
prompt: 'Write a short poem about Dart.',
);
await for (final chunk in result.textStream) {
stdout.write(chunk);
}
System prompt #
final result = await generateText(
model: anthropic('claude-sonnet-4-5'),
system: 'You are a concise assistant. Reply in at most two sentences.',
prompt: 'What is the Dart programming language?',
);
print(result.text);
instructions is the current canonical top-level instruction parameter;
system remains a supported fallback and is used above for continuity with
older code. Prefer instructions in new code:
final result = await generateText(
model: anthropic('claude-sonnet-4-5'),
instructions: 'You are a concise assistant. Reply in at most two sentences.',
prompt: 'What is the Dart programming language?',
);
print(result.text);
Reasoning controls #
The core reasoning: parameter (LanguageModelV4Reasoning, from
package:ai_sdk_provider) works across providers:
import 'package:ai_sdk_provider/ai_sdk_provider.dart';
final result = await generateText(
model: anthropic('claude-fable-5-1'),
reasoning: LanguageModelV4Reasoning.high,
prompt: 'Solve step by step: if 3x + 5 = 20, what is x?',
);
print(result.text);
print(result.reasoningText);
For Anthropic-specific control over the thinking budget, use
AnthropicThinkingOptions via providerOptions:
final result = await generateText(
model: anthropic('claude-sonnet-4-5'),
prompt: 'Solve step by step: if 3x + 5 = 20, what is x?',
maxOutputTokens: 16000,
providerOptions: {
'anthropic': AnthropicThinkingOptions(budgetTokens: 10000).toMap(),
},
);
print(result.reasoningText);
AnthropicLanguageModelOptions wraps thinking, prompt caching, and adaptive
effort together:
final result = await generateText(
model: anthropic('claude-sonnet-4-5'),
prompt: 'Solve step by step: if 3x + 5 = 20, what is x?',
maxOutputTokens: 16000,
providerOptions: {
'anthropic': AnthropicLanguageModelOptions(
thinking: AnthropicThinkingOptions(budgetTokens: 10000),
cacheControl: AnthropicCacheControlOptions(ttl: '5m'),
).toMap(),
},
);
Signed reasoning replay #
Anthropic's extended-thinking blocks carry a signature on
LanguageModelV4ReasoningPart so the model can verify its own prior reasoning
in a follow-up turn. Don't read or reconstruct the signature yourself — carry
result.responseMessages through unchanged as history and Anthropic verifies
it:
const question = ModelMessage(
role: ModelMessageRole.user,
content: 'Solve step by step: if 3x + 5 = 20, what is x?',
);
final first = await generateText(
model: anthropic('claude-fable-5-1'),
reasoning: LanguageModelV4Reasoning.high,
messages: [question],
);
final second = await generateText(
model: anthropic('claude-fable-5-1'),
reasoning: LanguageModelV4Reasoning.high,
messages: [
question,
...first.responseMessages.map(ModelMessage.fromProvider),
const ModelMessage(role: ModelMessageRole.user, content: 'Now check your work.'),
],
);
print(second.text);
Tagged reasoning middleware #
extractReasoningMiddleware extracts <think> tags from text. It does not
enable Claude's native thinking API, which the adapter handles directly:
final model = wrapLanguageModel(
model: anthropic('claude-sonnet-4-5'),
middleware: extractReasoningMiddleware(tagName: 'think'),
);
final result = await generateText(
model: model,
prompt: 'Solve step by step: if 3x + 5 = 20, what is x?',
);
print('Answer : ${result.text}');
print('Reasoning: ${result.reasoningText}');
Tools (multi-step agent) #
final result = await generateText(
model: anthropic('claude-sonnet-4-5'),
prompt: 'What is the weather in London?',
maxSteps: 5,
tools: {
'getWeather': tool<Map<String, dynamic>, String>(
description: 'Get current weather for a city.',
inputSchema: Schema<Map<String, dynamic>>(
jsonSchema: const {
'type': 'object',
'properties': {'city': {'type': 'string'}},
'required': ['city'],
},
fromJson: (json) => json,
),
execute: (input, _) async => 'Cloudy, 14°C in ${input['city']}',
),
},
);
print(result.text);
Structured output #
final result = await generateText<Map<String, dynamic>>(
model: anthropic('claude-haiku-4-5'),
prompt: 'Give me the capital and population of France as JSON.',
output: Output.object(
schema: Schema<Map<String, dynamic>>(
jsonSchema: const {
'type': 'object',
'properties': {
'capital': {'type': 'string'},
'population': {'type': 'number'},
},
},
fromJson: (json) => json,
),
),
);
print(result.output); // {capital: Paris, population: 68000000}
Middleware — default settings #
final model = wrapLanguageModel(
model: anthropic('claude-sonnet-4-5'),
middleware: defaultSettingsMiddleware(
temperature: 0.3,
maxOutputTokens: 512,
),
);
final result = await generateText(
model: model,
prompt: 'Summarise the Dart language in three bullet points.',
);
print(result.text);
Runnable example apps #
examples/basic— Dart CLIexamples/advanced_app— Flutter app with Anthropic provider switcher