Compatibility Matrix
Client-facing surfaces nexus supports today, how support is proven, and known gaps
This page records which client-facing surfaces nexus supports today, how that support is proven, and which endpoint families are not yet implemented. It describes current behavior only. “Supported” means the route, request/response shape, error envelope, and (where applicable) streaming shape match the referenced provider behavior and are covered by tests; “Partial” means a usable subset ships with named gaps; “Limited by provider” means nexus reports everything the upstream makes available and the remaining gap is in the provider’s own contract, not in nexus; “Not yet supported” means the surface is not implemented.
Protocol-level certification runs against the official OpenAI and Anthropic SDKs in test-suite/compat/ (just test-compat, just test-gateway-cert). Deterministic gateway behavior is covered by in-process integration tests; live-provider checks are opt-in where external behavior matters.
OpenAI-compatible edge (/v1/*)
Section titled “OpenAI-compatible edge (/v1/*)”| Surface | Status | Evidence / notes |
|---|---|---|
POST /v1/chat/completions (JSON + SSE) |
Supported | Official OpenAI SDK certification in test-suite/compat/; streaming usage capture and OpenAI-shaped errors. |
GET /v1/models |
Supported | Tenant-visible registry catalog (not a full upstream dump). Each model carries a capabilities object; capabilities.responses reports native upstream Responses support, and POST /v1/responses also serves models whose capabilities.chat is true through the provider’s chat adapter. |
POST /v1/responses (text, streaming, tools, structured outputs) |
Supported | OpenAI-routed dispatch. An endpoint whose registry row serves chat but not Responses (Anthropic, Bedrock, and Azure AI Foundry deployments without a Responses flag), and every Bedrock Mantle Claude model whatever its Responses flag (GET /v1/models still reports responses from that flag), is served through that provider’s chat adapter: the request is translated to chat completions and the result back to a Responses object or Responses SSE. That path translates instructions, message and function-call items, text/image/file content parts, function tools (a namespace tool’s member functions become top-level chat functions, renamed <namespace>__<name> only when a name is already taken; calls to them come back with their namespace, and tools:namespace is named in x-nexus-dropped-params) and tool_choice, max_output_tokens, and text.format (as response_format), and forwards reasoning.effort (as reasoning_effort), temperature, top_p, top_logprobs, parallel_tool_calls, metadata, store, user, service_tier, prompt_cache_key, and safety_identifier to the provider’s chat adapter, whose field policy applies exactly as on /v1/chat/completions (see the request field policy row); other Responses-only request fields and reasoning and compaction input items are dropped, and previous_response_id, conversation, tools other than functions and namespaces of functions, and any other input item type are refused with HTTP 400. A streamed bridged response emits the OpenAI Responses event sequence; its response.output_text.done, response.refusal.done, response.content_part.done, response.function_call_arguments.done, and response.output_item.done events carry the accumulated text and arguments, identical to the items in the terminal response.completed or response.incomplete event. |
Request field policy (x-nexus-dropped-params) |
Supported | Passthrough adapters (OpenAI, Azure AI Foundry, Bedrock Mantle on its OpenAI protocol, and Anthropic or Bedrock Mantle Claude for requests on the native /anthropic edge) forward every request field and leave validation to the upstream; an upstream 4xx is returned unchanged. Translating adapters (Anthropic and Bedrock Mantle Claude for OpenAI-shaped requests, Bedrock Converse) carry the fields their translation maps. A hint field with no place in the target (parallel_tool_calls, seed, store, metadata, user, unknown keys, and reasoning_effort on a Converse model family with no known spelling for it) is dropped and named in the comma-separated x-nexus-dropped-params response header. A field whose meaning would be lost if dropped (n above 1, logprobs: true, a response_format the target cannot express) is refused for that candidate with HTTP 400 invalid_request_error naming error.param; the refusal leaves fallback eligible, so a later candidate that carries the field serves the request. |
POST /v1/embeddings |
Supported | OpenAI string, string-array, token-id, and nested token-id inputs; encoding_format float/base64; dimensions; user passthrough. Azure Foundry uses the OpenAI embeddings wire format on the deployment embeddings URL. Native Bedrock Titan Text Embeddings V2 translates InvokeModel into the OpenAI embeddings envelope (string/string-array; token ids and all non-float encoding formats are rejected). Multi-input Titan calls are bounded fan-out: successful calls observed before an aggregate failure are recorded and charged exactly once, while the aggregate error is not replayed or routed to a fallback. Anthropic embeddings remain unsupported. |
POST /v1/files lifecycle + content |
Supported | nexus-owned artifact storage. |
POST /v1/vector_stores lifecycle |
Supported | nexus-owned metadata + bytes; includes create/list/get/modify/delete plus file attach (POST .../files), list, and detach (DELETE .../files/{file_id}). |
POST /v1/vector_stores/{id}/search |
Supported | nexus-native chunking, embeddings, and pgvector search. |
Hosted file_search on /v1/responses |
Supported | Retrieval is nexus-native; the rewritten request dispatches on /v1/responses to any endpoint that serves it, including chat-only endpoints served through the chat-completions bridge. Any provider can call direct vector-store search. |
POST /v1/images/generations |
Supported | Capability-gated per registry model. Token-priced image models record provider-reported image usage; request-priced image models, including xAI grok-imagine-*, record an estimated request-rate cost for each returned image. Both upstream URL and base64 outputs pass through. xAI rejects OpenAI’s size argument upstream. |
POST /v1/images/edits |
Supported | Multipart proxy; capability-gated per registry model (gpt-image family, dall-e-2). |
POST /v1/images/variations |
Supported | Multipart proxy; dall-e-2 only per the registry capability rows. |
| Image / vision usage accounting | Limited by provider | Image-generation accounting ships, including the text_tokens / image_tokens input split the Images API reports. Chat and Responses report no image-token breakdown — prompt_tokens_details carries audio_tokens and cached_tokens, Responses input_tokens_details carries cached_tokens — so image input on those surfaces is counted inside the text input line rather than as its own modality. The limit is in what the providers report, not in what the gateway reads. |
| Reasoning-token attribution | Partial | completion_tokens_details.reasoning_tokens and the Responses output_tokens_details.reasoning_tokens are recorded per request and returned on the query record, the gRPC record, and webhook exports. Attribution only: providers count reasoning inside the output tokens and bill it at the output rate, so it produces no cost line of its own and moves no billed counter. A breakdown the gateway cannot read costs the breakdown alone and leaves the usage billable. Reads on OpenAI and OpenAI-shaped upstreams, which is where the breakdown is reported. Anthropic and Bedrock report none — Anthropic’s usage block carries input, output, cache and web-search counters only, and counts thinking inside the output tokens — so the count is zero on those routes, including for thinking requests served by Anthropic. |
POST /v1/traces/ingest |
Supported (acknowledged) | Accepts OpenAI Agents SDK trace exports and returns a success envelope; the payload is not persisted. Native trace storage is the OTLP trace-ingest service. |
Azure AI Foundry backend (azure-foundry/<model> on POST /v1/chat/completions and POST /v1/embeddings) |
Supported | Chat, streaming, and tool calls to Azure OpenAI and Foundry-hosted deployments via connection metadata (resource, API version, deployment map) with api-key auth; tool support is the deployment’s, and an upstream refusal is surfaced unchanged. Chat sends the request’s max_tokens as max_completion_tokens, which reasoning deployments require; an explicit max_completion_tokens wins when both are present. Embeddings use /openai/deployments/{deployment}/embeddings with the same api-key auth and echo the catalog model name. On /v1/responses a deployment whose registry row does not claim Responses is served through the chat adapter. Embedded integration tests assert the deployment URL and header shape. |
OpenAI paid hosted tools (web_search, computer_use, code_interpreter, image_generation) |
Not supported | Rejected with 400 bad_request when the route includes an OpenAI candidate: OpenAI prices these per call internally and reports no countable usage field, so nexus cannot meter them. Matched by family prefix, so dated and preview revisions (web_search_preview, web_search_preview_2025_03_11) are rejected too. The Chat Completions spelling of paid web search — a top-level web_search_options object on the *-search-preview models — is rejected on the same grounds. A tools shape nexus cannot inspect — not an array, an element that is not an object, or a non-string type — is forwarded for the provider to reject, since it cannot invoke a hosted tool and so bills nothing. The error names the other candidates in the route so the caller can retry with one explicitly; nexus does not substitute a model on the caller’s behalf. Setting NEXUS_GATEWAY_ALLOW_UNMETERED_HOSTED_TOOLS=1 on the gateway skips this check and forwards the tools to the provider unmetered: token usage is still recorded, but per-call tool fees are not, so the setting is for BYOK deployments where the provider bills the tenant directly and must not be enabled with NEXUS_GATEWAY_PTB=1. Hosted file_search is unaffected (retrieval is nexus-native, see above). |
Gemini POST /v1beta/models/gemini-pro:generateContent |
Stubbed | Returns 501 Not Implemented. |
| Batches | Not yet supported | — |
POST /v1/moderations |
Supported | OpenAI upstreams only; capability-gated per registry model, so a route whose candidates do not advertise moderations is rejected before dispatch with 400 no_compatible_candidate. Priced as zero-cost. |
| Audio (speech-to-text / TTS) | Not yet supported | — |
| Fine-tuning | Not yet supported | — |
| Realtime | Not yet supported | — |
| Assistants / Threads / Runs | Not yet supported | — |
Unimplemented /v1/* routes (including the “Not yet supported” families above) return HTTP 404 with the OpenAI error envelope.
Native Anthropic edge (/anthropic/*)
Section titled “Native Anthropic edge (/anthropic/*)”| Surface | Status | Evidence / notes |
|---|---|---|
POST /anthropic/v1/messages (non-streaming + streaming) |
Supported | Native Anthropic request/response and error envelopes; cross-provider routing behind the edge. Anthropic targets receive the full native request body. A non-Anthropic target receives only the translated fields (model, messages, system, max_tokens, stop sequences, temperature, top_p, tools, tool_choice, stream); every other top-level field, including metadata (metadata.user_id is not mapped to user), is not sent and is named in x-nexus-dropped-params. A turn that ends on a stop sequence reports stop_reason: "stop_sequence" and names the matched sequence. Set ANTHROPIC_BASE_URL to the gateway /anthropic base. |
POST /anthropic/v1/messages/count_tokens |
Supported | — |
Anthropic via /v1/chat/completions (translation) |
Supported | OpenAI-shape in, Anthropic-shape out, including streaming text and tool calls. Streamed tool calls carry delta.role on the opening chunk and 0-based tool_calls[].index ordinals independent of Anthropic content-block position. A message name is dropped on every role, since Anthropic accepts only role and content. |
| Native fidelity (end-to-end prompt-cache accounting) | Supported | Native-field preservation, anthropic-beta forwarding, thinking served by Anthropic upstreams first (and dropped and reported on any other), and cache read/write token pricing at registry rates all ship. |
| Structured outputs on Anthropic upstreams | Partial | Anthropic has no response_format, so a json_object or json_schema request is steered by system prompt: the schema is quoted in the prompt and the model is asked to return only JSON. Nothing validates the reply against the schema, so an Anthropic-routed response can be JSON that does not satisfy it, or not JSON at all. OpenAI-routed json_schema with strict is unaffected. |
Bare POST /v1/messages |
Not supported (by design) | Returns 404 with the OpenAI error envelope; use the /anthropic edge so the OpenAI and Anthropic dialects do not collide. |
Clients and frameworks (tested)
Section titled “Clients and frameworks (tested)”| Client / framework | Status | Evidence |
|---|---|---|
| Official OpenAI SDK (Python/TS) | Certified | test-suite/compat/ SDK suites. |
| Official Anthropic SDK (Python/TS) | Certified path | test-suite/compat/ Anthropic certification. |
| LibreChat | Partial | Chat, embeddings, and models work, as does GPT reasoning with function tools and vision: the chat→Responses bridge flattens image_url objects to the string URL Responses requires. Anthropic-routed streaming tools and post-tool turns no longer need the client-side delta.role patch or tool-message name stripping; the gateway emits the OpenAI shape directly. |
| vortexcode (VS Code extension) | Working | Operator-confirmed daily-driver flow (chat, responses, models). |
data-codex (openai-agents 0.12.3) |
Working | Tested end-to-end 2026-06-17: streamed Responses agent loop, native vector-store search and file_search, aux chat completions, and embeddings. |
How to reproduce
Section titled “How to reproduce”# Protocol certification against the official SDKs (requires a running gateway)just test-compatjust test-gateway-cert
# Behaviour-focused router suite (streaming, fallback, tools, long-context, structured output)just testFor the per-service surface that backs these claims, see docs/architecture/services.md.
