Skip to content

Anthropic /v1/messages → Responses API adapter #8

@HXYerror

Description

@HXYerror

Part of #1. Depends on #4, #5.

Goal

Let Claude Code (and other Anthropic-shape clients) hit `/v1/messages` with an Anthropic body and have copilot-api dispatch all the way to upstream Copilot's `/responses` endpoint when the target model is Codex/o-pro/etc. Today `/v1/messages` only routes to `/chat/completions` (`src/routes/messages/anthropic-to-openai.ts` and friends).

Current state

The Anthropic adapter chain is exclusively chat-completions:

  • `src/routes/messages/non-stream-translation.ts` — Anthropic → OpenAI Chat Completions
  • `src/routes/messages/stream-translation.ts` — same, streaming
  • No translation layer exists for Anthropic ↔ Responses

`AnthropicMessagesPayload.thinking?` (`src/routes/messages/anthropic-types.ts:21–24`) is parsed but silently dropped.

Tasks

  • Add `src/routes/messages/anthropic-to-responses.ts` (request side):
    • Map Anthropic `messages[]` → Responses `input[]`
    • Map Anthropic `tools[]` → Responses tools format (different shape: tools live at top level, not inside messages)
    • Map Anthropic `thinking: { type: "enabled", budget_tokens }` → Responses `reasoning: { effort: "minimal"|"low"|"medium"|"high" }` using budget tiers (litellm's tiers: ≥10k=high, ≥5k=medium, ≥2k=low, else minimal — mirror these)
    • Preserve any prior `thinking` blocks in assistant messages as Responses `reasoning` items with `encrypted_content` from the Anthropic `signature`/`data` field (Preserve encrypted_content for multi-turn reasoning #6)
  • Add response side: Responses `output[]` → Anthropic content blocks
  • Wire the model-mode classifier (Model-to-endpoint routing (chat vs responses) #5) into `/v1/messages` so requests targeting `responses`-mode models go through this new adapter instead of the chat-completions path
  • Add streaming variant (`anthropic-to-responses-stream.ts`) — see Streaming reasoning events translation #10

Acceptance criteria

  • `POST /v1/messages` with `model: "gpt-5.3-codex"` succeeds end-to-end (Claude Code can drive a Codex session)
  • Multi-turn calls preserve reasoning (covered by Preserve encrypted_content for multi-turn reasoning #6's acceptance test)
  • Existing chat-completions path for non-Responses models is unchanged

Reference impl

litellm: `litellm/llms/anthropic/experimental_pass_through/responses_adapters/transformation.py` — `LiteLLMAnthropicToResponsesAPIAdapter`

Metadata

Metadata

Assignees

No one assigned

    Labels

    anthropicAnthropic Messages API compatibilityreasoningReasoning / thinking / encrypted_contentresponses-apiOpenAI /v1/responses API support

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions