Models & the model pool

Slo works with OpenAI, Anthropic, Kimi For Coding and OpenRouter. You can switch models mid-session, set the reasoning level per model, give different sub-agents different models, and pool several so one hitting a limit doesn't stop your run.

Switch models

In the TUI:

/model                    list models, grouped by provider
/model claude-opus-4-8    switch, and remember it for next time
/reasoning                show the current level and what this model supports
/reasoning medium         change it, and remember it
/preferences              show what's saved
/preferences clear        forget it and use the defaults next launch

Each model in the list shows available or requires /auth, so you can see which providers you're signed in to. You can't switch while a prompt is running.

For headless runs, pass it on the command line:

slo run -p "Review the diff" --model claude-sonnet-4-6 --reasoning high

The default model is gpt-5.4. After you sign in to a new provider with /auth, Slo switches to that provider's default.

Models you can pick

ProviderModels
OpenAIgpt-6.1-sol, gpt-6-sol, gpt-6-luna, gpt-6-astra, gpt-5.6-terra, gpt-5.6-sol, gpt-5.6-luna, gpt-5.5, gpt-5.4, gpt-5-codex, gpt-5.3-codex, gpt-5, o3 and more
Anthropicclaude-opus-4-8, claude-opus-4-8-1m-context, claude-sonnet-4-6, claude-sonnet-4-6-1m-context, claude-haiku-4-5, claude-fable
Kimi For Codingkimi-k3, kimi-for-coding, kimi-for-coding-highspeed
OpenRouterAny model your OpenRouter key can use, written openrouter:<model-id>. See OpenRouter.

Run /model for the full, current list.

GPT-6 Luna, Sol and 6.1 Sol

gpt-6-luna, gpt-6-sol and gpt-6.1-sol work with either kind of OpenAI sign-in: a ChatGPT subscription or a Platform API key. Set either up with /auth. Slo doesn't switch between the two on its own, and an OPENAI_API_KEY in your environment wins over a saved ChatGPT sign-in.

All three have a context window of about one million tokens and start at medium reasoning. gpt-6.1-sol always reasons a little, so /reasoning off runs it at low.

OpenRouter

OpenRouter gives one API key access to models from many providers. Slo can use any model your key is allowed to call.

  1. Run /auth, pick OpenRouter and paste your API key. Slo checks the key before saving it.
  2. Run /model refresh to load the models your key can use.
  3. Switch with the full name, openrouter: followed by the OpenRouter model ID.

Two to try:

/model openrouter:typesafe/jev-router
/model openrouter:deepseek/deepseek-v4.1-flash

Headless runs and schedules take the same names:

slo run -p "Summarise the working tree" --model openrouter:deepseek/deepseek-v4.1-flash

A few things to know:

  • The openrouter: prefix decides the route. openrouter:anthropic/... goes through OpenRouter with your OpenRouter key, not through your Anthropic sign-in.
  • The list depends on your key. Slo only offers models that OpenRouter says your key can use. If a model you expect is missing or marked unavailable, run /model refresh. Opening the picker on its own doesn't update it.
  • Reasoning controls vary. When OpenRouter doesn't say what a model supports, /reasoning shows provider default; controls unavailable. That means the provider decides, not that reasoning is off.
  • Output length. If OpenRouter doesn't publish a model's output limit, Slo caps each reply at a safe size (normally 4,096 tokens) rather than guess.

For CI, set SLO_OPENROUTER_API_KEY instead of signing in. See Authentication.

Reasoning levels

Levels are off, minimal, low, medium, high and xhigh. You can also say on for the model's default or max for the highest it supports. If you ask for a level a model doesn't have, Slo uses the closest one and tells you.

A rough guide: high for specs, reviews and tricky debugging. medium for everyday code. low when you're doing lots of small, obvious edits and want speed.

The model pool

A pool is an ordered list of models that Slo treats as one. Every request goes to the first model that's available. If that model is rate limited, out of credit, or its provider has a wobble, Slo moves the request to the next one and keeps going.

Set it with SLO_MODEL_POOL:

export SLO_MODEL_POOL="gpt-5.4,claude-sonnet-4-6,kimi-for-coding"

You need to be signed in to every provider in the list, and the pool needs at least two models.

For finer control, use JSON and set how long a model sits out after a problem:

export SLO_MODEL_POOL='[
  {"model_name": "claude-sonnet-4-6", "priority": 1, "cooldown_seconds": 300, "rate_limit_cooldown_seconds": 30},
  {"model_name": "kimi-for-coding", "priority": 2, "cooldown_seconds": 600, "rate_limit_cooldown_seconds": 60}
]'

cooldown_seconds (default 300) applies when a model runs out of credit. rate_limit_cooldown_seconds (default 60) applies to rate limits and provider errors.

What happens under load

Slo tries three things before giving up:

  1. It paces itself. Before sending, Slo estimates whether a request would break the model's rate window, and waits a moment if so. You'll see Waiting Ns for <model> local rate window.
  2. It reroutes. If a request fails before any output has streamed, the pool sends it to the next model.
  3. It retries. If nothing visible has happened yet in the current step, Slo waits and tries again. You'll see Rate limited by <model>; retrying in Ns.

If every model is cooling down and the retries run out, the run stops with All models in pool are in cooldown and the names of each model. Wait for the cooldowns, or add another model to the pool.

Different models for different phases

In a dynamic workflow, each sub-agent can run its own model and reasoning level. Ask in plain English:

"Use dynamic workflows. Write the spec and do the final review with claude-opus-4-8 on high. Do the coding and tests with claude-sonnet-4-6 on medium."

The orchestrator assigns them per phase. A model name it doesn't recognise is rejected before any sub-agent starts, along with the list of valid names.

Adjusting the catalog

To tweak a model's settings, such as hiding it from /model or changing its rate limits, create ~/.slo/global/model_catalog_overrides.json (or point SLO_MODEL_CATALOG_OVERRIDES_FILE somewhere else):

[{ "model_name": "gpt-4o", "visible_in_picker": false }]

Overrides change existing models. They can't add new ones.