docs: design for Claude Code support via Anthropic Messages API#98
Conversation
Signed-off-by: Ashwin Giridharan <girida@amazon.com>
|
|
||
| `agentic-api` today serves one stateful inference surface: the OpenAI-compatible Responses API (`/v1/responses`, with its supporting `/v1/conversations` and `/v1/models` routes), including persistence, `previous_response_id` continuation, gateway tool execution, and the multi-turn tool loop built around it. Codex works because Codex also speaks Responses; the only client-specific work was preserving Codex's `namespace` tool shape (see [Codex CLI Integration](./codex-integration.md)). | ||
|
|
||
| Claude Code speaks a different protocol — the Anthropic Messages API (`/v1/messages`). Supporting it is therefore not a tool-shape adaptation like Codex; it means exposing a stateful Messages surface and giving it the same value-add Responses has today. The model-facing half of that is already solved: vLLM implements Messages natively, and a live spike confirms it accepts everything Claude Code sends (see [Verification](#verification)). What remains is gateway work, and it is narrower than Responses was — a server-side tool loop that executes gateway-owned tools without exposing them to the client, reusing the existing execution core rather than forking it (ROADMAP §4). |
There was a problem hiding this comment.
the sentence exposing a stateful Messages surface and giving it the same value-add Responses has today implies that gateway requires maintain a stateful v1/messages endpoint with rehydration and persistence path. while anthropic messages api is entirely statesless in the document in section ##Statelessness and value-add discuss this more clearly that whether gateway wants to handle maintain history and rehydration is optional. but I think it is better to just keep it stateless since claude always sends full history to /v1/messages endpoint.
so need to be more clear and explicit that gateway does not use any storage layer means no rehydration/persistence for /v1/messages only mapping of tool calls and request/response payloads.
There was a problem hiding this comment.
Reworked per this — agreed, the gateway shouldn't imply persistence.
The Summary now leads with statelessness and lists exactly what the gateway implements (proxy routes / protocol contract / server-side tool loop), and there's a dedicated "The gateway stays stateless" section stating plainly that it holds no conversation state: no storage, no rehydration, no persistence, no previous_response_id analog. Persistence is now an explicit non-goal, not a deferred phase. I also reframed the plan as tracker-able stages with #99 marked as the landed Stage 1.
Following up on the Slack thread: I'll open a parent tracking issue for the whole integration linked to this PR, with a sub-issue per stage.
…llm-project#99 Signed-off-by: Ashwin Giridharan <girida@amazon.com>
…isting streaming Signed-off-by: Ashwin Giridharan <girida@amazon.com>
Signed-off-by: Ashwin Giridharan <girida@amazon.com>
## Summary - add transparent Anthropic Messages proxy routes for `/v1/messages` and `/v1/messages/count_tokens` - preserve raw request bodies, query parameters, Anthropic/Claude Code headers, upstream statuses, JSON responses, SSE streams, and error bodies - keep the existing Responses proxy API compatible while adding a path-aware internal proxy helper - add recording-upstream integration coverage using Claude Code-style client-owned `WebSearch`/`WebFetch` tools and arbitrary request fields - cover the protocol-contract requirements tracked in issue #114: verbatim block-first `system` forwarding, open-list `anthropic-beta` forwarding, and unchanged `anthropic-version` ## Test Plan - `cargo fmt -- --check` - `cargo clippy --all-targets -- -D warnings` - `cargo test -p agentic-server --test messages_test` - `cargo test -p agentic-server` - `git diff --check` PR #98 provides the design and live-spike evidence for the follow-up Phase 2 server-side tool loop: gateway tools must be injected only into upstream vLLM requests, executed inside Agentic API, and hidden from Claude Code. This PR intentionally remains the transparent proxy floor; no gateway-owned web-search execution is included. --------- Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>
Summary
A design proposal for supporting Claude Code as a client of
agentic-api, the natural next client after Codex.Codex works because it speaks the same Responses API
agentic-apialready serves. Claude Code speaks a different protocol — the Anthropic Messages API (/v1/messages) — whichagentic-apidoes not serve yet. Supporting it means exposing a stateful Messages surface and giving it the same value-add Responses has, reusing the existing execution core rather than forking it (ROADMAP §4).The doc's central finding, established by a live spike (see Test Plan): the gateway's value-add for Claude Code — server-side execution of gateway-owned tools like
web_search/MCP — is real, but reachable only through a server-side tool loop that keeps gateway-owned tools invisible to the client. Claude Code executes everytool_useagainst its own local registry and errors on anything it didn't declare, so advertising a gateway tool to the client cannot work; the gateway must run the loop itself and surface only the final message. This is the same hide-the-call pattern the Responses path uses.The doc also captures the Anthropic gateway protocol contract (error forwarding, header handling, the system-prompt attribution block — the places a naive proxy goes wrong), scopes a phased plan, and records what the spike settled vs. what remains open (the API-agnostic loop factoring, owned by the pending Layering ADR).
This is a docs-only change — one new file,
docs/design/claude-code-integration.md. Opening as a draft to socialize the direction before any implementation.Test Plan
The design's premise was verified live rather than assumed, in two rounds:
vLLM speaks Messages (vLLM-direct). Against a vLLM server,
/v1/messagesreturns Anthropic-shaped bodies, streams the correct SSE event sequence (includingthinking_delta), and does tool use. The real Claude Code CLI drives it end to end viaANTHROPIC_BASE_URL— a plain turn and a full client-owned tool round trip — with no gateway in the path. Corroborated by vLLM's own Claude Code doc.What a gateway can do (gateway-in-path). The real
@anthropic-ai/claude-codeCLI (2.1.208) was pointed at a throwaway probe gateway sitting in front of vLLM 0.25.1 (Qwen/Qwen3-30B-A3B-FP8, hermes parser). Three experiments:No such tool available, confirming it never round-trips a tool it didn't declare.claude -psession completed a gateway-executed tool turn with no client-side error. The executor was stubbed, so this proves the loop-and-hiding mechanics; wiring a real executor is Phase 1's first acceptance test.Capability probe: vLLM 0.25.1 accepts every advanced field Claude Code sends (
thinking,output_config,context_management,metadata) at HTTP 200, alone and combined — no field-level400hazard on current vLLM.Mermaid diagram renders via
mmdc; internal anchors and relative links resolve. Pre-commit excludes.md, so CI is DCO + the standard Rust build (no code touched).