Docs-truth close for the Phase 2.5 / ADR-0040 Anthropic adapter: verification that SSE translation, anthropic-version, and system-role extraction already shipped, plus minor stream-translate test hardening.
Milestone 4.C.1 — Anthropic Adapter Hardening
Status: Completed
Goal: Track C — Multi-Provider Adapters & Resilience
Phase: 4 — Operator Platform & Multi-Provider
Estimated effort: 3 days
Track: Track C — Multi-Provider Adapters & Resilience
Why This Milestone Exists
The Anthropic adapter already shipped in Phase 2.5 (2.5.G1.M1) and is documented in ADR-0040 (Accepted 2026-08-21): OpenAI-compatible SSE translation, anthropic-version on every request, system-role extraction (leading + mid-conversation fold), and mid-stream event: error → pipe CloseWithError (no JSON-swap). Phase 2.5’s exit gate already checked Anthropic test-depth parity with OpenAI.
This milestone is therefore not a greenfield hardening pass. It closes roadmap drift against live code and adds two small, additive stream-translate test assertions (incomplete mid-stream body; explicit ignore of non-text delta types). No adapter behavior change; no proxy handler/middleware changes.
Non-Goals
- Tool-use / image / vision / thinking passthrough
ANTHROPIC_API_VERSIONenv wiring- Shared parameterized OpenAI/Anthropic stream harness
- Per-org model routing (4.C.2)
- Circuit breaker (4.C.3)
- Azure OpenAI or Bedrock adapters (future)
- Changes to
packages/provider/openai/**orservices/proxy/**handlers/middleware
Shipped surface (already in tree)
Request construction
packages/provider/anthropic/request.go— peel leadingsystemmessages + fold mid-conversation systems into top-levelsystem; rejecttoolrole; deny-by-default passthrough allowlist (text-only).packages/provider/anthropic/client.go—newMessagesRequestsetsx-api-key,anthropic-version,Content-Typeon every Messages call.
Streaming translation
packages/provider/anthropic/stream_translate.go— Anthropic named events → OpenAI-compatible SSE; non-text_deltacontent deltas ignored; mid-streamevent: error→CloseWithError(no[DONE], no fabricated OpenAI error chunk in the pipe body).- Retry does not re-issue after a live stream body has started (
retry.go).
Registry / capabilities
- Built-in IDs:
claude-sonnet-4-5,claude-haiku-4-5,claude-opus-4-5(+ExtraModels). - Capability rows in
capability_catalog.go(context window / streaming flags); tools/vision flags are vendor-capability metadata, not a claim that the adapter implements tool/image passthrough.
Success signals
- Exact-ID
Registry.For("claude-sonnet-4-5")(and sibling Claude IDs) resolves when Anthropic is registered;NewRegistryreturnsErrDuplicateModelon colliding model IDs - Streaming translation emits OpenAI-shaped chunks suitable for ADR-0027 dual-write; mid-stream Anthropic
event: errorterminates the translate pipe as incomplete (nodata: [DONE], no fabricated OpenAI-shaped error chunk) — asserted instream_translate_test.go - Anthropic HTTP / mapped provider errors continue through
provider.MapError/ existing failure paths — no proxy handler special-case for Anthropic - Non-streaming and streaming fixture coverage lives in
packages/provider/anthropic(inline httptest / SSE fixtures; no separate golden-file harness required) - Zero proxy handler or middleware changes for this milestone (docs + Anthropic package tests only)
- Non-text stream deltas (
input_json_delta,thinking_delta,signature_delta) are ignored without leaking into OpenAI-shaped output
Local verification
go test ./packages/provider/anthropic/...go test ./packages/provider/...go test ./services/proxy/...(regression only; no proxy edits)
Prerequisites
- Phase 2.5 Anthropic adapter merged (2.5.G1.M1 / ADR-0040)
packages/provider.Providerinterface stable (M2.1.1)
Last updated on