Skip to content

feat: recent Claude models (corrected Vertex IDs), /v1/models improvements, and OpenAI->Anthropic bridge#9

Merged
prasadus92 merged 8 commits into
mainfrom
feat/openai-anthropic-bridge-final
Jun 6, 2026
Merged

feat: recent Claude models (corrected Vertex IDs), /v1/models improvements, and OpenAI->Anthropic bridge#9
prasadus92 merged 8 commits into
mainfrom
feat/openai-anthropic-bridge-final

Conversation

@prasadus92

Copy link
Copy Markdown
Owner

Finalizes the recent-models + endpoints + bridge work for review. CI runs on this PR.

What is in it:

  • Recent Anthropic models on Vertex: Opus 4.8/4.7/4.6 and Sonnet 4.6 (dateless 4.6-generation IDs; the bare id IS the pinned snapshot on Vertex, appending @Date 404s).
  • Corrected pre-existing Vertex IDs: Opus 4.5 -> claude-opus-4-5@20251101 (was @20250929) and Haiku 4.5 -> claude-haiku-4-5@20251001 (was @20250929); both previously 404'd at the Vertex call. Verified against Anthropic 'Claude on Vertex AI' + Google Vertex Model Garden docs.
  • Dropped the about-to-retire Sonnet 4 alias (retires 2026-06-15).
  • /v1/models: OpenAI-compatible created/owned_by fields + per-provider listing endpoints (/anthropic/v1/models, /gemini/v1/models, /gemini/v1beta/models).
  • OpenAI -> Anthropic bridge: Claude reachable via /v1/chat/completions; system/tool/assistant messages, max_tokens/temperature/stop, streaming, and tool calls translated; response-side Claude tool_use mapped back to OpenAI tool_calls (streamed tool_use is text-only for now).
  • Validation fix so the dateless 4.6-gen IDs are not rejected.
  • README (Endpoints table + an OpenAI-SDK -> Claude recipe) + CHANGELOG updated.
  • 52 tests (incl. 30 new bridge tests), ruff clean.

Note: region default stays us-east5; confirm it serves the 4.6-gen models or switch to a global/multi-region endpoint.

gnodet and others added 8 commits June 5, 2026 02:22
…validation

Add model aliases for recently released Claude models:
- Claude Opus 4.6, 4.7, 4.8 (no @Date suffix)
- Claude Sonnet 4.6 (no @Date suffix)
- Claude Sonnet 4 (claude-sonnet-4-20250514)

Fix model validation in _handle_anthropic(): the previous check
`if "@" not in vertex_model` rejects models without a @Date suffix.
Replace with a lookup against known aliases so both formats work.
OpenAI-compatible clients expect 'created' and 'owned_by' fields in
model listings. Set owned_by to the actual provider (anthropic, google,
or the MaaS publisher name).
Clients that set base_url to /anthropic or /gemini now get
model listings from their respective prefix:
  GET /anthropic/v1/models → anthropic models only
  GET /gemini/v1/models    → gemini models only
  GET /gemini/v1beta/models → gemini models only

This fixes Hermes showing '0 models' for vertex-anthropic provider.
…etions

Add translation layer so OpenAI Chat Completions clients can call Claude
models through the /v1 endpoint. Requests are converted to Anthropic
Messages format, sent to Vertex AI, and responses translated back to
OpenAI format.

Supports both streaming (SSE) and non-streaming modes.
New module: openai_anthropic_bridge.py handles all format conversions.
Vertex AI uses two distinct ID conventions split at the Claude 4.6
generation, and several aliases would 404 as previously written:

- 4.6-gen (Opus 4.6/4.7/4.8, Sonnet 4.6) use a DATELESS bare id; the
  bare id is itself the pinned snapshot. These pass through unchanged
  and must NOT carry an @Date suffix (a suffix 404s on Vertex).
- pre-4.6 models carry a snapshot date that Vertex separates with '@',
  not '-' (the '-' form is the Claude-API id and 404s on Vertex).

Corrections:
- Sonnet 4: was mapped to the bare Claude-API id
  'claude-sonnet-4-20250514' which 404s on Vertex; now maps to the
  Vertex id 'claude-sonnet-4@20250514'. (Deprecated, retires
  2026-06-15; remove after that date.)
- Opus 4.5: was '@20250929' (wrong); the Vertex id is '@20251101'.
- Haiku 4.5: was '@20250929' (wrong); the Vertex id is '@20251001'.
- Renamed the dated alias keys for Opus/Haiku 4.5 to match their
  corrected snapshot dates.

Update test_config alias assertions: the old "every id contains '@'"
invariant is wrong for the dateless 4.6-gen ids. Replace it with
generation-aware checks (4.6-gen is bare; pre-4.6 uses '@'-separated
8-digit dates) plus explicit checks for the corrected Sonnet 4 / Opus
4.5 / Haiku 4.5 ids.

Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
Finalize the OpenAI->Anthropic bridge:

Response path (anthropic_to_openai_response):
- Walk the content array once, accumulating both text and tool_use
  blocks. tool_use blocks are now emitted as OpenAI tool_calls with
  function.arguments as a JSON string. Previously tool_use was dropped,
  so finish_reason could be "tool_calls" with no tool_calls array.
- finish_reason is forced to "tool_calls" whenever tool_calls is
  non-empty, so it can never disagree with the array.
- message.content stays null when only tool_calls are present; the
  tool_calls key is omitted entirely when empty.

Streaming path (anthropic_stream_to_openai_stream):
- message_delta is now the sole carrier of finish_reason; message_stop
  emits only the [DONE] sentinel. Previously both emitted a
  finish_reason chunk, which is an invalid double finish_reason for an
  OpenAI stream.
- Thread a stream_id generated once per stream from the caller in
  main.py so the chunk id is stable across chunks. This also removes
  the F541 f-string ('chatcmpl-stream' had no placeholder and was a
  non-unique constant id).
- Document that streamed tool_use translation is intentionally out of
  scope (stateless line translator cannot accumulate input_json_delta);
  non-streaming requests return tool_calls correctly.

Cosmetic:
- Drop a no-op ternary in _convert_message.

Tests:
- Add tests/test_openai_anthropic_bridge.py covering body conversion,
  response tool_calls mapping, and streaming (single finish_reason,
  message_stop -> [DONE] only, stable stream id).
- Update test_maas_unknown_model_rejected to match the unified
  "unknown model '<id>' ... known aliases" error message.

Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
Reflect the shipped alias set: the dateless 4.6-gen ids (Opus 4.6/4.7/
4.8, Sonnet 4.6) pass through unchanged, and the pre-4.6 ids use the
'@'-separated snapshot dates (Opus 4.5 @20251101, Haiku 4.5 @20251001,
Sonnet 4 @20250514). Note the do-not-append-@Date caveat for 4.6-gen
and the Sonnet 4 retirement date.

Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
@prasadus92 prasadus92 merged commit 54c640b into main Jun 6, 2026
2 checks passed
@prasadus92 prasadus92 deleted the feat/openai-anthropic-bridge-final branch June 6, 2026 15:07
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.

2 participants