Skip to content

fix: route anthropic-messages models to /v1/messages instead of /chat/completions - #19

Open
gitawego wants to merge 1 commit into
getpipher:mainfrom
gitawego:fix/anthropic-messages-api-routing
Open

fix: route anthropic-messages models to /v1/messages instead of /chat/completions#19
gitawego wants to merge 1 commit into
getpipher:mainfrom
gitawego:fix/anthropic-messages-api-routing

Conversation

@gitawego

@gitawego gitawego commented Aug 3, 2026

Copy link
Copy Markdown

Problem

The vision delegate hard-codes the OpenAI-compatible endpoint POST {baseUrl}/chat/completions for every vision model (lib/delegate.tscallVisionModel), ignoring the model's registered api type.

For models registered as api: "anthropic-messages" — e.g. minimax-cn/MiniMax-M3 with baseUrl: https://api.minimaxi.com/anthropic — the resulting URL https://api.minimaxi.com/anthropic/chat/completions doesn't exist. The request fails with:

Vision tool error: Vision model returned 404: 404 page not found

Reproduced live:

URL Result
api.minimaxi.com/anthropic/chat/completions (what the delegate builds) 404 page not found
api.minimaxi.com/anthropic/v1/messages (correct Anthropic Messages route) 200

This also means any Anthropic-Messages-family vision model (MiniMax, Claude, Qwen Anthropic-compat endpoints, …) can never be used as the vision model, regardless of config correctness.

Fix

Make the request API-aware:

  • api: "anthropic-messages"POST {baseUrl}/v1/messages with the Messages schema:
    • image passed as a source.base64 content block (media_type + data)
    • systemPrompt as a top-level system field (not a messages entry)
    • no temperature / reasoning_effort (not part of the Messages schema)
    • response parsed from the content[] array — first text block, with a thinking-block fallback for reasoning-only replies
  • everything else → unchanged OpenAI /chat/completions path (data-URL image, system message, reasoning_effort for reasoning models)

Tests

6 new tests in tests/delegate.test.ts covering: endpoint URL, Anthropic body shape, system-field placement, content[] response parsing (text + thinking fallback), error surfacing, and reasoning_effort omission.

tests/delegate.test.ts: 39 passed
Full suite (serialized): 357/359 passed (2 pre-existing timing flakes on slow filesystems: disk-LRU mtime race + wall-clock batch assertions — unrelated to this change, pass in CI/isolated runs)

Also verified end-to-end against the real minimax-cn/MiniMax-M3 endpoint (200 OK with a live request to .../anthropic/v1/messages).

Notes

  • Retry/fallback behavior is unchanged; the error message for a 4xx (like this 404) still surfaces the status + body excerpt.
  • openai-responses / openai-codex-responses models still use the /chat/completions compat path — this PR deliberately scopes to the Anthropic-Messages fix; the OpenAI-responses shape can be a follow-up if needed.

…/completions

The delegate hard-coded the OpenAI-compatible POST {baseUrl}/chat/completions
for every vision model, ignoring the model's registered api type. Models
registered as "anthropic-messages" (e.g. MiniMax M3 at
api.minimaxi.com/anthropic) 404 with "404 page not found" because that
base URL has no /chat/completions route.

Now the request is API-aware:
- api=anthropic-messages -> POST {baseUrl}/v1/messages with the Messages
  schema: image as source.base64 blocks, system prompt as a top-level
  "system" field, response parsed from content[] text blocks (with a
  thinking-block fallback for reasoning-only replies).
- everything else -> unchanged OpenAI /chat/completions path (including
  reasoning_effort for reasoning models).

Adds 6 delegate tests covering URL, body shape, system field placement,
response parsing, error surfacing, and reasoning_effort omission.
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.

1 participant