Reference

Lossy protocol conversions

What is not preserved when inbound and outbound wires differ.

Any shipped inbound protocol can reach any shipped outbound protocol. That pivot is not always lossless. The cases below are known; claiming fidelity outside this list is how a bridge gets trusted more than it deserves.

Same-protocol requests keep provider field shapes. Cross-protocol requests translate through a shared request shape, request, response, and stream chunks, and only the fields both wires can express survive.

What it looks like

An OpenAI client can call acme/claude even when that alias resolves to Anthropic. The caller keeps speaking chat completions (or responses); the gateway translates. Worked examples are on Calling the gateway.

await client.chat.completions.create({
  model: "acme/claude",
  messages: [{ role: "user", content: "Say hello" }],
})

On the OpenAI wire, tools and images use /v1/responses. chat.completions inbound is text-only.

Known losses

DirectionWhat changesWhy
any → google.generateTool call ids become gc_*Gemini has no call ids on the wire; we synthesise them
google.generate → anyTool results arrive name-only until pairingGemini answers by function name, not id
any → google.generateTool result order may changeGemini requires results in pending call order
any → anyTool names longer than 64 chars are truncated with a hash suffixProvider name limits; truncation is injective
any → anthropic.messagesresponseFormat is refusedAnthropic Messages has no response_format here
any → openai.responsesstop is refusedResponses has no stop sequences
openai.responses inboundprevious_response_id and conversation are refusedPass input items explicitly; the gateway is stateless
any → non-Anthropicthinking / redacted_thinking / cache_control droppedBest-effort: kept when decoded; omitted on wires that cannot express them
reasoning dialect mismatchWrong dialect omitted (effort vs maxTokens)Best-effort: outbound writes only the dialect it supports