Skip to content

Commit cb4e539

Browse files
oscar-bromanKludex
andcommitted
Don't send empty messages to Anthropic (#1027)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
1 parent 360de87 commit cb4e539

File tree

4 files changed

+104
-2
lines changed

4 files changed

+104
-2
lines changed

pydantic_ai_slim/pydantic_ai/models/anthropic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ async def _map_message(self, messages: list[ModelMessage]) -> tuple[str, list[Be
373373
is_error=True,
374374
)
375375
user_content_params.append(retry_param)
376-
anthropic_messages.append(BetaMessageParam(role='user', content=user_content_params))
376+
if len(user_content_params) > 0:
377+
anthropic_messages.append(BetaMessageParam(role='user', content=user_content_params))
377378
elif isinstance(m, ModelResponse):
378379
assistant_content_params: list[
379380
BetaTextBlockParam
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
interactions:
2+
- request:
3+
headers:
4+
accept:
5+
- application/json
6+
accept-encoding:
7+
- gzip, deflate
8+
connection:
9+
- keep-alive
10+
content-length:
11+
- '281'
12+
content-type:
13+
- application/json
14+
host:
15+
- api.anthropic.com
16+
method: POST
17+
parsed_body:
18+
max_tokens: 1024
19+
messages:
20+
- content:
21+
- text: Hello, how can I help you?
22+
type: text
23+
role: assistant
24+
- content:
25+
- text: I need a potato!
26+
type: text
27+
role: user
28+
model: claude-3-5-sonnet-latest
29+
stream: false
30+
system: |+
31+
You are a helpful assistant.
32+
33+
uri: https://api.anthropic.com/v1/messages?beta=true
34+
response:
35+
headers:
36+
connection:
37+
- keep-alive
38+
content-length:
39+
- '671'
40+
content-type:
41+
- application/json
42+
strict-transport-security:
43+
- max-age=31536000; includeSubDomains; preload
44+
transfer-encoding:
45+
- chunked
46+
parsed_body:
47+
content:
48+
- text: |-
49+
I can't physically give you a potato since I'm a computer program. However, I can:
50+
51+
1. Help you find recipes that use potatoes
52+
2. Give you tips on how to select, store, or cook potatoes
53+
3. Share information about different potato varieties
54+
4. Provide guidance on growing potatoes
55+
56+
What specifically would you like to know about potatoes?
57+
type: text
58+
id: msg_01UjnDmX3B57Drosu49sMteT
59+
model: claude-3-5-sonnet-20241022
60+
role: assistant
61+
stop_reason: end_turn
62+
stop_sequence: null
63+
type: message
64+
usage:
65+
cache_creation_input_tokens: 0
66+
cache_read_input_tokens: 0
67+
input_tokens: 41
68+
output_tokens: 82
69+
service_tier: standard
70+
status:
71+
code: 200
72+
message: OK
73+
version: 1

tests/models/test_anthropic.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,34 @@ def test_usage(message_callback: Callable[[], BetaMessage | BetaRawMessageStream
10421042
assert _map_usage(message_callback()) == usage
10431043

10441044

1045+
@pytest.mark.vcr()
1046+
async def test_anthropic_model_empty_message_on_history(allow_model_requests: None, anthropic_api_key: str):
1047+
"""The Anthropic API will error if you send an empty message on the history.
1048+
1049+
Check <https://github.com/pydantic/pydantic-ai/pull/1027> for more details.
1050+
"""
1051+
m = AnthropicModel('claude-3-5-sonnet-latest', provider=AnthropicProvider(api_key=anthropic_api_key))
1052+
agent = Agent(m, instructions='You are a helpful assistant.')
1053+
1054+
result = await agent.run(
1055+
'I need a potato!',
1056+
message_history=[
1057+
ModelRequest(parts=[], instructions='You are a helpful assistant.', kind='request'),
1058+
ModelResponse(parts=[TextPart(content='Hello, how can I help you?')], kind='response'),
1059+
],
1060+
)
1061+
assert result.output == snapshot("""\
1062+
I can't physically give you a potato since I'm a computer program. However, I can:
1063+
1064+
1. Help you find recipes that use potatoes
1065+
2. Give you tips on how to select, store, or cook potatoes
1066+
3. Share information about different potato varieties
1067+
4. Provide guidance on growing potatoes
1068+
1069+
What specifically would you like to know about potatoes?\
1070+
""")
1071+
1072+
10451073
@pytest.mark.vcr()
10461074
async def test_anthropic_web_search_tool(allow_model_requests: None, anthropic_api_key: str):
10471075
m = AnthropicModel('claude-3-5-sonnet-latest', provider=AnthropicProvider(api_key=anthropic_api_key))

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)