Skip to content

fix: accept system role in messages[] and handle built-in Anthropic tools#79

Open
HtetOoWaiYan wants to merge 1 commit into
fuergaosi233:mainfrom
HtetOoWaiYan:fix/system-role-and-builtin-tools
Open

fix: accept system role in messages[] and handle built-in Anthropic tools#79
HtetOoWaiYan wants to merge 1 commit into
fuergaosi233:mainfrom
HtetOoWaiYan:fix/system-role-and-builtin-tools

Conversation

@HtetOoWaiYan

Copy link
Copy Markdown

Summary

Two fixes for 422 validation errors introduced by newer Claude models and Anthropic built-in tools.

Fix 1: Accept system role in messages[] (closes #26)

ClaudeMessage.role was Literal["user", "assistant"], which caused Pydantic to reject requests with a 422 before they reached the converter.

Newer Claude models (e.g. claude-opus-4-8) send interleaved system-role messages inside the messages[] array, not only via the top-level system field. Example request that was being rejected:

{
  "messages": [
    {"role": "user",   "content": "..."},
    {"role": "system", "content": "..."},
    {"role": "user",   "content": "..."}
  ]
}

Changes:

  • ClaudeMessage.role now accepts "system" as a valid value
  • request_converter.py handles role: "system" messages in the loop, converting them to OpenAI system messages instead of silently dropping them

Fix 2: Handle built-in Anthropic tools (closes #67)

Built-in Anthropic tools like web_search_20250305 and computer_use_20251201 are sent without an input_schema. Since ClaudeTool.input_schema was a required field, this caused a 422 immediately.

Changes:

  • ClaudeTool.input_schema is now Optional (defaults to None)
  • New optional fields type and max_uses added to ClaudeTool to accept the full built-in tool shape
  • The converter skips tools with no input_schema (logging a debug message) rather than attempting to forward them to the OpenAI endpoint, which wouldn't understand them anyway

Note: Full execution of built-in tools (web search, computer use) would require the proxy to act as a tool executor, which is out of scope for this fix. This change prevents the crash and degrades gracefully.

Test plan

  • Send a request with a system-role message inside messages[] — should return 200 instead of 422
  • Send a request with tools: [{"type": "web_search_20250305", "name": "web_search", "max_uses": 3}] — should return 200 instead of 422 (tool will be skipped/not forwarded)
  • Normal user/assistant/tool-use flows unaffected

Two related 422 validation fixes:

1. ClaudeMessage.role now accepts "system" in addition to "user" and
   "assistant". Newer Claude models (e.g. claude-opus-4-8) send
   interleaved system-role messages inside the messages[] array rather
   than exclusively via the top-level system field. Pydantic was
   rejecting these requests before they reached the converter.

2. ClaudeTool.input_schema is now Optional (default None) and two new
   optional fields (type, max_uses) are added to accommodate built-in
   Anthropic tools such as web_search_20250305 and computer_use_20251201
   that carry no input_schema. The converter now skips these tools
   (logging a debug message) rather than crashing with a 422.

Fixes fuergaosi233#26 (422 error with streaming API / newer models)
Fixes fuergaosi233#67 (Web Search tool causes 422 due to missing input_schema)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Web Search not working 使用轨迹流动的api时,出现422错误

1 participant