mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-24 00:52:24 +00:00
fix(anthropic): strip leaked think tags from messages
This commit is contained in:
parent
ced8b44e3c
commit
0712f8ba6c
3 changed files with 68 additions and 22 deletions
|
|
@ -1621,6 +1621,9 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
if thinking_content is not None:
|
||||
reasoning_content += thinking_content
|
||||
|
||||
if "</think>" in text_content:
|
||||
text_content = text_content.split("</think>", 1)[1].lstrip()
|
||||
|
||||
return (
|
||||
text_content,
|
||||
citations,
|
||||
|
|
|
|||
|
|
@ -1249,10 +1249,14 @@ class LiteLLMAnthropicMessagesAdapter:
|
|||
)
|
||||
|
||||
# Handle text content
|
||||
if choice.message.content is not None:
|
||||
text_content = choice.message.content
|
||||
if isinstance(text_content, str) and "</think>" in text_content:
|
||||
text_content = text_content.split("</think>", 1)[1].lstrip()
|
||||
|
||||
if text_content:
|
||||
new_content.append(
|
||||
AnthropicResponseContentBlockText(
|
||||
type="text", text=choice.message.content
|
||||
type="text", text=text_content
|
||||
).model_dump()
|
||||
)
|
||||
# Handle tool calls (in parallel to text content)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,41 @@ def _should_route_to_responses_api(custom_llm_provider: Optional[str]) -> bool:
|
|||
return custom_llm_provider in _RESPONSES_API_PROVIDERS
|
||||
|
||||
|
||||
def _sanitize_think_tag_text_blocks(
|
||||
response: Union[AnthropicMessagesResponse, AsyncIterator]
|
||||
) -> Union[AnthropicMessagesResponse, AsyncIterator]:
|
||||
if not isinstance(response, dict):
|
||||
return response
|
||||
|
||||
content = response.get("content")
|
||||
if not isinstance(content, list):
|
||||
return response
|
||||
|
||||
sanitized_content: List[Dict[str, Any]] = []
|
||||
for block in content:
|
||||
if not isinstance(block, dict):
|
||||
sanitized_content.append(block)
|
||||
continue
|
||||
|
||||
if block.get("type") != "text":
|
||||
sanitized_content.append(block)
|
||||
continue
|
||||
|
||||
text = block.get("text")
|
||||
if not isinstance(text, str) or "</think>" not in text:
|
||||
sanitized_content.append(block)
|
||||
continue
|
||||
|
||||
cleaned_text = text.split("</think>", 1)[1].lstrip()
|
||||
if cleaned_text:
|
||||
sanitized_block = dict(block)
|
||||
sanitized_block["text"] = cleaned_text
|
||||
sanitized_content.append(sanitized_block)
|
||||
|
||||
response["content"] = sanitized_content
|
||||
return response
|
||||
|
||||
|
||||
####### ENVIRONMENT VARIABLES ###################
|
||||
# Initialize any necessary instances or variables here
|
||||
base_llm_http_handler = BaseLLMHTTPHandler()
|
||||
|
|
@ -286,7 +321,7 @@ async def anthropic_messages(
|
|||
response = await init_response
|
||||
else:
|
||||
response = init_response
|
||||
return response
|
||||
return _sanitize_think_tag_text_blocks(response)
|
||||
|
||||
|
||||
def validate_anthropic_api_metadata(metadata: Optional[Dict] = None) -> Optional[Dict]:
|
||||
|
|
@ -421,10 +456,12 @@ def anthropic_messages_handler(
|
|||
**kwargs,
|
||||
)
|
||||
if _should_route_to_responses_api(custom_llm_provider):
|
||||
return LiteLLMMessagesToResponsesAPIHandler.anthropic_messages_handler(
|
||||
**_shared_kwargs
|
||||
return _sanitize_think_tag_text_blocks(
|
||||
LiteLLMMessagesToResponsesAPIHandler.anthropic_messages_handler(
|
||||
**_shared_kwargs
|
||||
)
|
||||
)
|
||||
return (
|
||||
return _sanitize_think_tag_text_blocks(
|
||||
LiteLLMMessagesToCompletionTransformationHandler.anthropic_messages_handler(
|
||||
**_shared_kwargs
|
||||
)
|
||||
|
|
@ -441,20 +478,22 @@ def anthropic_messages_handler(
|
|||
params=local_vars
|
||||
)
|
||||
)
|
||||
return base_llm_http_handler.anthropic_messages_handler(
|
||||
model=model,
|
||||
messages=messages,
|
||||
anthropic_messages_provider_config=anthropic_messages_provider_config,
|
||||
anthropic_messages_optional_request_params=dict(
|
||||
anthropic_messages_optional_request_params
|
||||
),
|
||||
_is_async=is_async,
|
||||
client=client,
|
||||
custom_llm_provider=custom_llm_provider,
|
||||
litellm_params=litellm_params,
|
||||
logging_obj=litellm_logging_obj,
|
||||
api_key=api_key,
|
||||
api_base=api_base,
|
||||
stream=stream,
|
||||
kwargs=kwargs,
|
||||
return _sanitize_think_tag_text_blocks(
|
||||
base_llm_http_handler.anthropic_messages_handler(
|
||||
model=model,
|
||||
messages=messages,
|
||||
anthropic_messages_provider_config=anthropic_messages_provider_config,
|
||||
anthropic_messages_optional_request_params=dict(
|
||||
anthropic_messages_optional_request_params
|
||||
),
|
||||
_is_async=is_async,
|
||||
client=client,
|
||||
custom_llm_provider=custom_llm_provider,
|
||||
litellm_params=litellm_params,
|
||||
logging_obj=litellm_logging_obj,
|
||||
api_key=api_key,
|
||||
api_base=api_base,
|
||||
stream=stream,
|
||||
kwargs=kwargs,
|
||||
)
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue