mirror of
https://github.com/hwchase17/langchain.git
synced 2026-06-09 10:17:00 +00:00
fix(anthropic): prevent crash with cache_control and empty message content (#34025)
This commit is contained in:
@@ -1008,27 +1008,27 @@ class ChatAnthropic(BaseChatModel):
|
|||||||
|
|
||||||
system, formatted_messages = _format_messages(messages)
|
system, formatted_messages = _format_messages(messages)
|
||||||
|
|
||||||
# If cache_control is provided in kwargs, add it to last message
|
# If cache_control is provided in kwargs, add it to the last message with
|
||||||
# and content block.
|
# content (Anthropic requires cache_control to be nested within a message
|
||||||
if "cache_control" in kwargs and formatted_messages:
|
# block).
|
||||||
if isinstance(formatted_messages[-1]["content"], list):
|
cache_control = kwargs.pop("cache_control", None)
|
||||||
formatted_messages[-1]["content"][-1]["cache_control"] = kwargs.pop(
|
if cache_control and formatted_messages:
|
||||||
"cache_control"
|
for formatted_message in reversed(formatted_messages):
|
||||||
)
|
content = formatted_message.get("content")
|
||||||
elif isinstance(formatted_messages[-1]["content"], str):
|
if isinstance(content, list) and content:
|
||||||
formatted_messages[-1]["content"] = [
|
content[-1]["cache_control"] = cache_control
|
||||||
{
|
break
|
||||||
"type": "text",
|
if isinstance(content, str):
|
||||||
"text": formatted_messages[-1]["content"],
|
formatted_message["content"] = [
|
||||||
"cache_control": kwargs.pop("cache_control"),
|
{
|
||||||
}
|
"type": "text",
|
||||||
]
|
"text": content,
|
||||||
else:
|
"cache_control": cache_control,
|
||||||
pass
|
}
|
||||||
|
]
|
||||||
# If cache_control remains in kwargs, it would be passed as a top-level param
|
break
|
||||||
# to the API, but Anthropic expects it nested within a message
|
# If we didn't find a message with content we silently drop the control.
|
||||||
_ = kwargs.pop("cache_control", None)
|
# Anthropic would reject a payload with empty content blocks.
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"model": self.model,
|
"model": self.model,
|
||||||
|
|||||||
@@ -1505,6 +1505,7 @@ def test_cache_control_kwarg() -> None:
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
assert isinstance(messages[-1].content, str) # test no mutation
|
||||||
|
|
||||||
messages = [
|
messages = [
|
||||||
HumanMessage("foo"),
|
HumanMessage("foo"),
|
||||||
@@ -1528,6 +1529,23 @@ def test_cache_control_kwarg() -> None:
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
assert "cache_control" not in messages[-1].content[-1] # test no mutation
|
||||||
|
|
||||||
|
|
||||||
|
def test_cache_control_kwarg_skips_empty_messages() -> None:
|
||||||
|
llm = ChatAnthropic(model=MODEL_NAME)
|
||||||
|
|
||||||
|
messages = [HumanMessage("foo"), AIMessage(content=[])]
|
||||||
|
payload = llm._get_request_payload(messages, cache_control={"type": "ephemeral"})
|
||||||
|
assert payload["messages"] == [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": [
|
||||||
|
{"type": "text", "text": "foo", "cache_control": {"type": "ephemeral"}}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{"role": "assistant", "content": []},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_context_management_in_payload() -> None:
|
def test_context_management_in_payload() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user