Gateway¶
The LLM-Rosetta Gateway is an HTTP proxy that translates between LLM provider API formats in real time. Send requests in any supported format — the gateway converts and forwards them to the configured upstream provider.
Client (OpenAI format) ──→ Gateway ──→ Anthropic API
Client (Anthropic format) ──→ Gateway ──→ OpenAI API
Client (Google format) ──→ Gateway ──→ Any provider
Installation¶
The gateway has zero external runtime dependencies — it uses vendored zerodep httpserver and httpclient modules (stdlib-only, single-file).
Quick Start¶
1. Create a config file¶
Create a config.jsonc (JSON with comments):
{
"providers": {
"my-openai": { "type": "openai_chat", "api_key": "${OPENAI_API_KEY}", "base_url": "https://api.openai.com/v1" },
"my-anthropic": { "type": "anthropic", "api_key": "${ANTHROPIC_API_KEY}", "base_url": "https://api.anthropic.com" },
"my-google": { "type": "google", "api_key": "${GOOGLE_API_KEY}", "base_url": "https://generativelanguage.googleapis.com" }
},
"models": {
"gpt-4o": "my-openai",
"gpt-4o-mini": "my-openai",
"claude-sonnet-4-20250514": "my-anthropic",
"gemini-2.0-flash": "my-google"
},
"server": {
"host": "0.0.0.0",
"port": 8765
}
}
Provider names are user-defined strings. The type field specifies the API standard (openai_chat, openai_responses, anthropic, google). See Configuration for full details.
2. Start the gateway¶
# CLI command (after pip install)
llm-rosetta-gateway
# Or specify a config file explicitly
llm-rosetta-gateway --config /path/to/config.jsonc
# Or as a Python module
python -m llm_rosetta.gateway
The gateway auto-discovers config files at these locations (first match wins):
./config.jsonc(current directory)~/.config/llm-rosetta-gateway/config.jsonc~/.llm-rosetta-gateway/config.jsonc
You can also bootstrap a config file using the init or add subcommands. See CLI Reference for all options.
3. Send requests¶
Use any provider's format — the gateway routes based on the model name:
# Send OpenAI-format request, routed to Anthropic
curl http://localhost:8765/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-20250514",
"messages": [{"role": "user", "content": "Hello!"}]
}'
# Send Anthropic-format request, routed to OpenAI
curl http://localhost:8765/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 100
}'
Endpoints¶
| Path | Source Format | Description |
|---|---|---|
POST /v1/chat/completions |
OpenAI Chat | Drop-in for OpenAI SDK |
POST /v1/messages |
Anthropic | Drop-in for Anthropic SDK |
POST /v1/responses |
OpenAI Responses | Drop-in for OpenAI Responses SDK |
POST /v1/embeddings |
OpenAI Embeddings | Passthrough to upstream (no IR conversion) |
POST /v1beta/models/{model}:generateContent |
Google GenAI | Drop-in for Google REST API |
POST /v1beta/models/{model}:streamGenerateContent |
Google GenAI (streaming) | Drop-in for Google streaming |
GET /v1/models |
OpenAI / Anthropic | List configured models with api_standard and capabilities |
GET /v1beta/models |
Google GenAI | List configured models (Google SDK format) |
GET /health |
— | Health check |
GET /admin/ |
— | Admin panel (web UI) |
The endpoint path determines the source format — no auto-detection needed.
Streaming¶
Streaming is supported for all provider combinations. Request streaming the same way you would with the native API:
# OpenAI-format streaming, routed to any provider
curl http://localhost:8765/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-20250514",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": true
}'
The gateway converts SSE chunks in real time between provider formats.
Authentication¶
Protect AI endpoints with a gateway API key in the server config:
Requests must provide the key in the format native to each API standard (Bearer token, x-api-key header, etc.). See Configuration — Gateway API Key for details.
Docker Deployment¶
The gateway is available as a pre-built image on DockerHub:
# Pull from DockerHub and run
docker pull oaklight/llm-rosetta-gateway:latest
docker run -p 8765:8765 -v /path/to/config:/config oaklight/llm-rosetta-gateway
# Or use Docker Compose (see docker/docker-compose.yaml)
cd docker && docker compose up -d
To build from source:
# Build with Makefile (uses local wheel if available, otherwise PyPI)
make build-docker
# Or build manually
docker build -t llm-rosetta-gateway .
Set PUID/PGID environment variables to match your host user's UID/GID. See docker/docker-compose.yaml for the full configuration example.
Admin Panel¶
The gateway includes a built-in web admin panel at /admin/ for managing configuration, monitoring real-time metrics, and viewing request logs. See the Admin Panel page for details.
How It Works¶
The gateway uses LLM-Rosetta's converter pipeline:
1. Incoming request (source format)
2. source_converter.request_from_provider() → IR Request
3. Look up model → target provider
4. target_converter.request_to_provider() → target format
5. Forward to upstream API
6. target_converter.response_from_provider() → IR Response
7. source_converter.response_to_provider() → source format
8. Return to client
For streaming, the same pipeline operates at the SSE chunk level using stream_response_from_provider() and stream_response_to_provider() with StreamContext for stateful conversion.