Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 19 additions & 20 deletions pydantic_ai_slim/pydantic_ai/models/anthropic.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@
from datetime import datetime, timezone
from typing import Any, Literal, Union, cast, overload

from anthropic.types.beta import (
BetaCitationsDelta,
BetaCodeExecutionToolResultBlock,
BetaCodeExecutionToolResultBlockParam,
BetaInputJSONDelta,
BetaServerToolUseBlockParam,
BetaWebSearchToolResultBlockParam,
)
from typing_extensions import assert_never

from pydantic_ai.builtin_tools import CodeExecutionTool, WebSearchTool
Expand Down Expand Up @@ -47,24 +39,21 @@
from ..providers import Provider, infer_provider
from ..settings import ModelSettings
from ..tools import ToolDefinition
from . import (
Model,
ModelRequestParameters,
StreamedResponse,
check_allow_model_requests,
download_item,
get_user_agent,
)
from . import Model, ModelRequestParameters, StreamedResponse, check_allow_model_requests, download_item, get_user_agent

try:
from anthropic import NOT_GIVEN, APIStatusError, AsyncAnthropic, AsyncStream
from anthropic.types.beta import (
BetaBase64PDFBlockParam,
BetaBase64PDFSourceParam,
BetaCitationsDelta,
BetaCodeExecutionTool20250522Param,
BetaCodeExecutionToolResultBlock,
BetaCodeExecutionToolResultBlockParam,
BetaContentBlock,
BetaContentBlockParam,
BetaImageBlockParam,
BetaInputJSONDelta,
BetaMessage,
BetaMessageParam,
BetaMetadataParam,
Expand All @@ -78,6 +67,7 @@
BetaRawMessageStreamEvent,
BetaRedactedThinkingBlock,
BetaServerToolUseBlock,
BetaServerToolUseBlockParam,
BetaSignatureDelta,
BetaTextBlock,
BetaTextBlockParam,
Expand All @@ -94,6 +84,7 @@
BetaToolUseBlockParam,
BetaWebSearchTool20250305Param,
BetaWebSearchToolResultBlock,
BetaWebSearchToolResultBlockParam,
)
from anthropic.types.beta.beta_web_search_tool_20250305_param import UserLocation
from anthropic.types.model_param import ModelParam
Expand Down Expand Up @@ -246,7 +237,9 @@ async def _messages_create(
) -> BetaMessage | AsyncStream[BetaRawMessageStreamEvent]:
# standalone function to make it easier to override
tools = self._get_tools(model_request_parameters)
tools += self._get_builtin_tools(model_request_parameters)
builtin_tools, tool_headers = self._get_builtin_tools(model_request_parameters)
tools += builtin_tools

tool_choice: BetaToolChoiceParam | None

if not tools:
Expand All @@ -264,8 +257,10 @@ async def _messages_create(

try:
extra_headers = model_settings.get('extra_headers', {})
for k, v in tool_headers.items():
extra_headers.setdefault(k, v)
extra_headers.setdefault('User-Agent', get_user_agent())
extra_headers.setdefault('anthropic-beta', 'code-execution-2025-05-22')

return await self.client.beta.messages.create(
max_tokens=model_settings.get('max_tokens', 4096),
system=system_prompt or NOT_GIVEN,
Expand Down Expand Up @@ -352,8 +347,11 @@ async def _process_streamed_response(
def _get_tools(self, model_request_parameters: ModelRequestParameters) -> list[BetaToolParam]:
return [self._map_tool_definition(r) for r in model_request_parameters.tool_defs.values()]

def _get_builtin_tools(self, model_request_parameters: ModelRequestParameters) -> list[BetaToolUnionParam]:
def _get_builtin_tools(
self, model_request_parameters: ModelRequestParameters
) -> tuple[list[BetaToolUnionParam], dict[str, str]]:
tools: list[BetaToolUnionParam] = []
extra_headers: dict[str, str] = {}
for tool in model_request_parameters.builtin_tools:
if isinstance(tool, WebSearchTool):
user_location = UserLocation(type='approximate', **tool.user_location) if tool.user_location else None
Expand All @@ -367,12 +365,13 @@ def _get_builtin_tools(self, model_request_parameters: ModelRequestParameters) -
)
)
elif isinstance(tool, CodeExecutionTool): # pragma: no branch
extra_headers['anthropic-beta'] = 'code-execution-2025-05-22'
tools.append(BetaCodeExecutionTool20250522Param(name='code_execution', type='code_execution_20250522'))
else: # pragma: no cover
raise UserError(
f'`{tool.__class__.__name__}` is not supported by `AnthropicModel`. If it should be, please file an issue.'
)
return tools
return tools, extra_headers

async def _map_message(self, messages: list[ModelMessage]) -> tuple[str, list[BetaMessageParam]]: # noqa: C901
"""Just maps a `pydantic_ai.Message` to a `anthropic.types.MessageParam`."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interactions:
- api.anthropic.com
method: POST
parsed_body:
max_tokens: 1024
max_tokens: 4096
messages:
- content:
- text: How much is 3 * 12390?
Expand All @@ -34,7 +34,7 @@ interactions:
connection:
- keep-alive
content-length:
- '927'
- '994'
content-type:
- application/json
strict-transport-security:
Expand All @@ -43,12 +43,12 @@ interactions:
- chunked
parsed_body:
container:
expires_at: '2025-05-26T13:30:45.703429+00:00'
id: container_011CPW9LpfbF8dmXMvVNCiQJ
expires_at: '2025-08-14T12:35:01.802902Z'
id: container_011CS7XodG8mEYj1PnST46H5
content:
- text: I'll calculate 3 * 12390 for you.
type: text
- id: srvtoolu_01CPfaeVC7ju4VsdzxjSLDrY
- id: srvtoolu_01PZTDQyDyxVNeVikBoNo2fb
input:
code: |-
result = 3 * 12390
Expand All @@ -62,21 +62,24 @@ interactions:
stdout: |
3 * 12390 = 37170
type: code_execution_result
tool_use_id: srvtoolu_01CPfaeVC7ju4VsdzxjSLDrY
tool_use_id: srvtoolu_01PZTDQyDyxVNeVikBoNo2fb
type: code_execution_tool_result
- text: The answer is **37,170**.
- text: 3 * 12390 = 37,170
type: text
id: msg_015H6Emn2T8vZhE52mU2jF1U
id: msg_01RJnbK7VMxvS2SyvtyJAQVU
model: claude-sonnet-4-20250514
role: assistant
stop_reason: end_turn
stop_sequence: null
type: message
usage:
cache_creation:
ephemeral_1h_input_tokens: 0
ephemeral_5m_input_tokens: 0
cache_creation_input_tokens: 0
cache_read_input_tokens: 0
input_tokens: 1630
output_tokens: 105
output_tokens: 109
server_tool_use:
web_search_requests: 0
service_tier: standard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interactions:
- api.anthropic.com
method: POST
parsed_body:
max_tokens: 1024
max_tokens: 4096
messages:
- content:
- text: Hello, how can I help you?
Expand All @@ -36,7 +36,7 @@ interactions:
connection:
- keep-alive
content-length:
- '671'
- '777'
content-type:
- application/json
strict-transport-security:
Expand All @@ -46,26 +46,29 @@ interactions:
parsed_body:
content:
- text: |-
I can't physically give you a potato since I'm a computer program. However, I can:
I can't physically give you a potato since I'm a digital assistant. However, I can:

1. Help you find recipes that use potatoes
2. Give you tips on how to select, store, or cook potatoes
3. Share information about different potato varieties
4. Provide guidance on growing potatoes
2. Give you tips on how to select, store, or prepare potatoes
3. Share information about different types of potatoes
4. Suggest where you might buy potatoes locally

What specifically would you like to know about potatoes?
What specific information about potatoes would be most helpful to you?
type: text
id: msg_01UjnDmX3B57Drosu49sMteT
id: msg_01PAZFa5ciacA9ptgEDMbkZM
model: claude-3-5-sonnet-20241022
role: assistant
stop_reason: end_turn
stop_sequence: null
type: message
usage:
cache_creation:
ephemeral_1h_input_tokens: 0
ephemeral_5m_input_tokens: 0
cache_creation_input_tokens: 0
cache_read_input_tokens: 0
input_tokens: 41
output_tokens: 82
output_tokens: 88
service_tier: standard
status:
code: 200
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interactions:
- api.anthropic.com
method: POST
parsed_body:
max_tokens: 1024
max_tokens: 4096
messages:
- content:
- text: What is the capital of France?
Expand All @@ -32,7 +32,7 @@ interactions:
connection:
- keep-alive
content-length:
- '354'
- '433'
content-type:
- application/json
strict-transport-security:
Expand All @@ -43,13 +43,16 @@ interactions:
content:
- text: The capital of France is Paris.
type: text
id: msg_01BznVNBje2zyfpCfNQCD5en
id: msg_01Fg1JVgvCYUHWsxrj9GkpEv
model: claude-3-opus-20240229
role: assistant
stop_reason: end_turn
stop_sequence: null
type: message
usage:
cache_creation:
ephemeral_1h_input_tokens: 0
ephemeral_5m_input_tokens: 0
cache_creation_input_tokens: 0
cache_read_input_tokens: 0
input_tokens: 20
Expand Down
Loading