Point your agent at it
Every agent that lets you override its base URL can talk through hlid. Two environment variables cover most of them.
Anthropic-dialect agents
Claude Code, Aider in anthropic mode, and anything built on the Anthropic SDK:
bash
export ANTHROPIC_BASE_URL=http://localhost:8080
export ANTHROPIC_API_KEY=sk-hlid-whatever # your hlid auth_key, or anything if auth is offThe agent will call /v1/messages on hlid. Whatever model it asks for, the registry decides where the request actually goes — including to an OpenAI-dialect backend, translated on the way.
OpenAI-dialect agents
The OpenAI SDK, Continue, Cursor, Aider in openai mode:
bash
export OPENAI_BASE_URL=http://localhost:8080
export OPENAI_API_KEY=sk-hlid-whateverSDKs
python
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="sk-hlid-local")
resp = client.chat.completions.create(
model="llama-3-70b", # routed by your hlid registry
messages=[{"role": "user", "content": "Hello!"}],
)python
from anthropic import Anthropic
client = Anthropic(base_url="http://localhost:8080", api_key="sk-hlid-local")
resp = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=200,
messages=[{"role": "user", "content": "Hello!"}],
)ts
import OpenAI from 'openai'
const client = new OpenAI({
baseURL: 'http://localhost:8080/v1',
apiKey: 'sk-hlid-local',
})
const resp = await client.chat.completions.create({
model: 'llama-3-70b',
messages: [{ role: 'user', content: 'Hello!' }],
})Smoke test with curl
bash
# Passthrough: OpenAI dialect in → OpenAI-dialect backend (no translation)
curl -s http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Say hi"}]}' | jq .
# Cross-dialect: Anthropic dialect in → OpenAI-dialect backend (auto-translated)
curl -s http://localhost:8080/v1/messages \
-H "Content-Type: application/json" \
-d '{"model": "claude-sonnet-4-20250514", "max_tokens": 100, "messages": [{"role": "user", "content": "Say hi"}]}' | jq .
# Streaming (add "stream": true)
curl -s http://localhost:8080/v1/messages \
-H "Content-Type: application/json" \
-d '{"model": "claude-sonnet-4-20250514", "max_tokens": 100, "stream": true, "messages": [{"role": "user", "content": "Tell me a joke"}]}'The model name is the router
Agents don't know about backends — they just name a model. Your registry turns that name into a destination. A useful pattern: keep the model names your agents already use, and add one [[backends]] entry per family. No agent-side changes when a backend moves.