Who it's for — what to expect

routsi means different things depending on what you're plugging into it. Five concrete profiles, each with the exact behavior you get and the setup that gets you there — every claim below is live-verified against real upstreams, not just unit-tested.

1 · App builders on the OpenAI SDK

What to expect: point your existing OpenAI SDK's base URL at routsi, send model: "auto", change nothing else. Easy questions get classified LOW and go to a cheap model; hard ones get classified HIGH and escalate to a stronger model or a full agent. A conversation pins to whatever level it first escalates to and never downgrades mid-thread — so a thread that got smart once stays smart.

models.yaml
tiers:
  cheap: gpt-cheap
  strong: gpt-strong

That's the whole setup. See How auto decides for the exact classification rules and the auto-routing scenario for a copy-paste curl.

2 · Teams running coding agents

What to expect: Devin, Codex, Copilot, and Claude Code each become an addressable model over the same /v1/chat/completions endpoint — no separate integration per agent. Send a X-Conversation-Id and routsi owns the memory: Devin gets a real resumed session (first turn runs devin -p and captures the session id, every later turn in that conversation runs devin -r <session> -p — live-verified: turn 2 recalled turn 1's content with no history resent). Codex/Copilot/Claude Code don't have a native session concept yet, so routsi renders the transcript into the prompt each call instead — same client-side contract, slightly different mechanics under the hood.

Streaming caveat: these CLIs only print a final answer, so routsi fakes SSE off the completed result — you get one delta chunk with the whole text, not token-by-token. Don't expect incremental UI unless the answerer is an API model.

models.yaml
- name: devin
  type: devin
  provider: cognition
  variants: [sonnet, opus]

- name: codex
  type: codex
  provider: openai

- name: claude
  type: claude
  provider: anthropic

Full config shape (custom bin:/args:/permission_mode:) in Agents as models; the session-resume mechanics in the agent-session scenario.

3 · Self-hosters & privacy-minded

What to expect: one Go binary you run yourself — routsi install sets up a keep-alive service (launchd on macOS, systemd --user on Linux) with restart-on-failure, no root required. Provider keys live in your process env or a local .env, referenced by name in config, never logged or printed. Nothing calls home; there's no SaaS hop between your client and the upstream provider. Bearer-token auth and mutual TLS are both opt-in config blocks, off by default.

enable auth
auth:
  tokens_env: ROUTSI_TOKENS   # export ROUTSI_TOKENS="tok1,tok2"

See Auth & mTLS and .env secrets for the full setup.

4 · Distributed / BYO-agent setups

What to expect: a teammate runs routsi worker run --queue my-codex --agent 'codex exec -' on their own machine. That registers a named queue that becomes a normal routable model (model: "my-codex") — the worker polls outbound over plain HTTP, so it works behind NAT with no inbound port to open, and their credentials never leave their box. One worker per queue, non-streaming, at-most-once delivery in v1; a request fast-503s if no worker has polled recently instead of hanging forever.

on the worker's machine
routsi worker run --queue my-codex --agent 'codex exec -'

There's also an agent-driven mode (routsi worker register|poll|answer) for a live Claude Code/Codex session to answer with its own reasoning instead of shelling to a subprocess — see Pull-workers and the pull-worker scenario.

5 · Mixing in native Anthropic/Gemini APIs

What to expect: a forward model with style: anthropic or style: gemini gets wire-translated through the toolnexus client instead of raw byte passthrough. You get the same conversation contract as the CLI agents — pass X-Conversation-Id and routsi manages the transcript for you (toolnexus's own conversation store, live-verified: a second turn recalled a fact from the first with no history resent); omit it and the client resends full history as usual. Streaming is faked off the completed response here too, same caveat as agents.

models.yaml — anthropic
- name: claude
  type: forward
  style: anthropic
  base_url: https://api.anthropic.com
  api_key_env: ANTHROPIC_API_KEY
  upstream_model: claude-sonnet-5

One real gotcha: style: gemini doesn't speak Gemini's native REST format — the underlying toolnexus client only implements openai and anthropic wire shapes, so anything else silently falls through to an OpenAI-shaped request. That works fine, but only if base_url points at Google's OpenAI-compatibility endpoint, not the native API root:

models.yaml — gemini (the base_url that actually works)
- name: gemini-flash
  type: forward
  style: gemini
  base_url: https://generativelanguage.googleapis.com/v1beta/openai
  api_key_env: GEMINI_API_KEY
  upstream_model: gemini-2.5-flash

Pointing base_url at bare https://generativelanguage.googleapis.com (the native root) will 404 on every request — routsi still sends a well-formed OpenAI-style call, Gemini's native API just doesn't answer at that path.

Next: models.yaml →