Rebase onto upstream (a4d95fd)
#12
@@ -68,21 +68,87 @@ class AnthropicOAuthProvider(LLMProvider):
|
|||||||
self,
|
self,
|
||||||
messages: list[dict[str, Any]]
|
messages: list[dict[str, Any]]
|
||||||
) -> tuple[str | None, list[dict[str, Any]]]:
|
) -> tuple[str | None, list[dict[str, Any]]]:
|
||||||
"""Prepare messages, extracting system prompt and adding Claude Code identity.
|
"""Prepare messages: extract system prompt and convert OpenAI format to Anthropic.
|
||||||
|
|
||||||
Returns (system_prompt, messages_without_system)
|
The agent loop produces messages in OpenAI format:
|
||||||
|
- assistant msgs with tool_calls [{type:"function", function:{name, arguments}}]
|
||||||
|
- tool role msgs with tool_call_id, name, content
|
||||||
|
|
||||||
|
Anthropic API expects:
|
||||||
|
- assistant msgs with content blocks [{type:"tool_use", id, name, input}]
|
||||||
|
- user msgs with content blocks [{type:"tool_result", tool_use_id, content}]
|
||||||
|
|
||||||
|
Returns (system_prompt, anthropic_messages)
|
||||||
"""
|
"""
|
||||||
system_parts = [get_claude_code_system_prefix()]
|
system_parts = [get_claude_code_system_prefix()]
|
||||||
filtered_messages = []
|
converted: list[dict[str, Any]] = []
|
||||||
|
|
||||||
for msg in messages:
|
for msg in messages:
|
||||||
if msg.get("role") == "system":
|
role = msg.get("role")
|
||||||
|
|
||||||
|
if role == "system":
|
||||||
system_parts.append(msg.get("content", ""))
|
system_parts.append(msg.get("content", ""))
|
||||||
else:
|
continue
|
||||||
filtered_messages.append(msg)
|
|
||||||
|
if role == "assistant" and msg.get("tool_calls"):
|
||||||
|
# Convert OpenAI tool_calls to Anthropic content blocks
|
||||||
|
content_blocks: list[dict[str, Any]] = []
|
||||||
|
text = msg.get("content")
|
||||||
|
if text:
|
||||||
|
content_blocks.append({"type": "text", "text": text})
|
||||||
|
for tc in msg["tool_calls"]:
|
||||||
|
func = tc.get("function", {})
|
||||||
|
args = func.get("arguments", "{}")
|
||||||
|
if isinstance(args, str):
|
||||||
|
try:
|
||||||
|
args = json.loads(args)
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
args = {}
|
||||||
|
content_blocks.append({
|
||||||
|
"type": "tool_use",
|
||||||
|
"id": tc.get("id", ""),
|
||||||
|
"name": func.get("name", ""),
|
||||||
|
"input": args,
|
||||||
|
})
|
||||||
|
converted.append({"role": "assistant", "content": content_blocks})
|
||||||
|
continue
|
||||||
|
|
||||||
|
if role == "tool":
|
||||||
|
# Convert tool result to Anthropic user message with tool_result block
|
||||||
|
tool_result_block = {
|
||||||
|
"type": "tool_result",
|
||||||
|
"tool_use_id": msg.get("tool_call_id", ""),
|
||||||
|
"content": msg.get("content", ""),
|
||||||
|
}
|
||||||
|
# Merge into previous user message if it already has tool_result blocks
|
||||||
|
if converted and converted[-1].get("role") == "user":
|
||||||
|
prev_content = converted[-1].get("content")
|
||||||
|
if isinstance(prev_content, list):
|
||||||
|
prev_content.append(tool_result_block)
|
||||||
|
continue
|
||||||
|
converted.append({"role": "user", "content": [tool_result_block]})
|
||||||
|
continue
|
||||||
|
|
||||||
|
if role == "user":
|
||||||
|
content = msg.get("content", "")
|
||||||
|
# Merge text into previous user message if it has tool_result blocks
|
||||||
|
# (handles the "Reflect on the results" interleaved message)
|
||||||
|
if converted and converted[-1].get("role") == "user":
|
||||||
|
prev_content = converted[-1].get("content")
|
||||||
|
if isinstance(prev_content, list):
|
||||||
|
if isinstance(content, str):
|
||||||
|
prev_content.append({"type": "text", "text": content})
|
||||||
|
elif isinstance(content, list):
|
||||||
|
prev_content.extend(content)
|
||||||
|
continue
|
||||||
|
converted.append({"role": role, "content": content})
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Pass through other messages (assistant without tool_calls, etc.)
|
||||||
|
converted.append(msg)
|
||||||
|
|
||||||
system_prompt = "\n\n".join(system_parts)
|
system_prompt = "\n\n".join(system_parts)
|
||||||
return system_prompt, filtered_messages
|
return system_prompt, converted
|
||||||
|
|
||||||
def _convert_tools_to_anthropic(
|
def _convert_tools_to_anthropic(
|
||||||
self,
|
self,
|
||||||
|
|||||||
Reference in New Issue
Block a user