Skip to content

Commit 67ffea5

Browse files
committed
fix(anthropic): inject [Continue] for fresh thinking turn when history lacks thinking blocks
1 parent 9d568fe commit 67ffea5

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

src/rotator_library/anthropic_compat/translator.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,26 @@ def openai_to_anthropic_response(openai_response: dict, original_model: str) ->
497497
}
498498

499499

500+
def _history_supports_thinking(anthropic_messages: List[dict]) -> bool:
501+
for msg in anthropic_messages:
502+
if msg.get("role") != "assistant":
503+
continue
504+
content = msg.get("content", "")
505+
if not isinstance(content, list):
506+
return False
507+
first_block = next((b for b in content if isinstance(b, dict)), None)
508+
if not first_block:
509+
return False
510+
if first_block.get("type") not in ("thinking", "redacted_thinking"):
511+
return False
512+
return True
513+
514+
515+
def _inject_continue_for_fresh_thinking_turn(openai_messages: List[dict]) -> List[dict]:
516+
openai_messages.append({"role": "user", "content": "[Continue]"})
517+
return openai_messages
518+
519+
500520
def translate_anthropic_request(request: AnthropicMessagesRequest) -> Dict[str, Any]:
501521
"""
502522
Translate a complete Anthropic Messages API request to OpenAI format.
@@ -512,9 +532,11 @@ def translate_anthropic_request(request: AnthropicMessagesRequest) -> Dict[str,
512532
"""
513533
anthropic_request = request.model_dump(exclude_none=True)
514534

535+
messages = anthropic_request.get("messages", [])
515536
openai_messages = anthropic_to_openai_messages(
516-
anthropic_request.get("messages", []), anthropic_request.get("system")
537+
messages, anthropic_request.get("system")
517538
)
539+
thinking_compatible = _history_supports_thinking(messages)
518540

519541
openai_tools = anthropic_to_openai_tools(anthropic_request.get("tools"))
520542
openai_tool_choice = anthropic_to_openai_tool_choice(
@@ -551,11 +573,19 @@ def translate_anthropic_request(request: AnthropicMessagesRequest) -> Dict[str,
551573
# Always use max thinking budget (31999) for Claude via Anthropic routes
552574
if request.thinking:
553575
if request.thinking.type == "enabled":
576+
if not thinking_compatible:
577+
openai_messages = _inject_continue_for_fresh_thinking_turn(
578+
openai_messages
579+
)
580+
openai_request["messages"] = openai_messages
554581
openai_request["reasoning_effort"] = "high"
555582
openai_request["thinking_budget"] = 31999
556583
elif request.thinking.type == "disabled":
557584
openai_request["reasoning_effort"] = "disable"
558585
elif _is_opus_model(request.model):
586+
if not thinking_compatible:
587+
openai_messages = _inject_continue_for_fresh_thinking_turn(openai_messages)
588+
openai_request["messages"] = openai_messages
559589
openai_request["reasoning_effort"] = "high"
560590
openai_request["thinking_budget"] = 31999
561591
return openai_request

0 commit comments

Comments
 (0)