Skip to content
yottacode v0.4.0 is out! ๐ŸŽ‰ See the release notes โ†—
Configuring models

Configuring models

A model id tells yottacode which model to send each turn to. Model names are provider-specific.

Set the startup model

Environment variable:

export YOTTACODE_MODEL=<your-model-id>

Flag:

yottacode --model <your-model-id> --base-url https://api.openai.com/v1 --api-key sk-...

Config file:

[active]
provider      = "openai"
default_model = "<your-model-id>"

Switch models in the TUI

/model <your-model-id>

This changes the active model for the current session and rebuilds the adapter. It does not necessarily rewrite your shell environment.

Manage default models from the CLI

yottacode model list
yottacode model list --all
yottacode model use <your-model-id>
yottacode model fetch
yottacode model fetch openai

model use updates the configured active default_model.

Fetch live models

yottacode model fetch openai

This calls the provider /models endpoint and prints the merged model list. It is useful when checking auth, endpoint shape, or whether a newly released model is visible to your account.

Reasoning models

Some models expose reasoning streams or summaries:

Provider/model familyBehavior
OpenAI o1*, o3*, o4*, gpt-5*Routed to Responses API when appropriate
openai-auth account modelsUse the ChatGPT-authenticated backend and surface reasoning summaries where available
copilot account modelsUse the GitHub Copilot backend; available models depend on subscription tier (Free/Pro/Pro+)
xAI Grok reasoning modelsReasoning content is surfaced when present
Ollama thinking modelsReasoning fields are surfaced when the OpenAI shim provides them
Standard chat modelsStream final content only

Use --reasoning-effort low|medium|high when the selected provider/model supports it.

Hosted tools by model/provider

Hosted provider tools depend on provider support, not just the model name.

  • OpenAI: web_search default-on; code_interpreter optional
  • xAI: web_search and x_search default-on; code_interpreter optional
  • Ollama/custom OpenAI-compatible: no hosted provider tools; local yottacode tools still work

Cache-safe task routing

Routing lets yottacode assign work to two explicit roles:

  • advisor โ€” the reasoning/planning/design model.
  • implementer โ€” the fast coding model used for auto-mode work, delegated subagents, and summarization.

It is opt-in, configurable from the TUI with /advisor (recommended โ€” see below) or by hand via the [router] block in ~/.yottacode/config.toml:

[router]
  mode              = "auto"                          # off | manual | auto
  advisor_model     = "anthropic:claude-opus-4-6"
  implementer_model = "anthropic:claude-haiku-4-5"

advisor_model / implementer_model use the same "<provider>" or "<provider>:<model>" grammar as the multi-provider router’s candidates. Both are required when mode is not off. Provider names refer to your [[providers]] blocks, and the model must be listed in that provider’s models (typos are rejected at load time). Legacy smart_model and fast_model still load as aliases for advisor and implementer, but new writes use the role-named keys. Reasoning effort is session-wide: set it with /effort or --reasoning-effort, not with per-role router fields.

Failover chains

Each slot can be a failover chain instead of a single model โ€” give it the plural form with a primary followed by fallbacks:

[router]
  mode               = "auto"
  implementer_model  = "anthropic:claude-haiku-4-5"                   # single is fine
  advisor_models     = ["anthropic:claude-opus-4-6", "openai:gpt-4o"] # primary, then fallback
  health_window_seconds    = 60
  health_failure_threshold = 3

The first entry is always the primary โ€” chains dispatch in written order (the policy knob orders the multi-provider candidates router only, not these slots). On an error before any output the call falls through to the next entry, sharing the health knobs with the multi-provider router (a flapping provider is skipped until it recovers). There is no router-level timeout โ€” a hung call is bounded by the underlying adapter/provider timeouts, not by the chain. So an advisor consultation, subagent, or summarization call survives a role-model outage instead of failing. A slot uses the singular or the plural form, not both.

When a fallover happens it’s surfaced loudly, the same way main-thread fallbacks already are โ€” a warm-yellow line tagged with where it occurred:

โ†ป fallback [consult_advisor]: anthropic/claude-opus-4-6 โ†’ openai/gpt-4o [fallback-chain]: <reason>
โ†ป fallback [summarize]: anthropic/claude-haiku-4-5 โ†’ openai/gpt-4o-mini: <reason>

The status chip and subagent cards still show the primary. The /advisor picker has a Fallback row: Enter sets it (a one-model fallback), d clears it. Chains longer than two stay in config.toml โ€” the picker shows (+N more) and preserves them.

The implementer slot has no fallback row in the picker. An implementer_models chain set by hand in config.toml is still honored; it is just not surfaced in the picker.

Configuring from the TUI: /advisor

You don’t have to edit the file by hand. /advisor opens a picker with rows โ€” Routing, Advisor model, Implementer, Fallback โ€” that all act in place (the picker stays open). Toggle the Routing row on/off, and open the model rows to pick from your configured models (the embedded catalog plus any providers.models). You can enable routing first and choose the models below โ€” routing turns on once both are set โ€” or pick the models and then toggle on. Selections persist to config.toml and apply live; picking a catalog model also records it in that provider’s providers.models so the write validates. /advisor on and /advisor off are quick shortcuts for the toggle.

Configuring the advisor model also switches your active model. When you set (or change) the Advisor model and close the picker, your main conversation switches to that model โ€” the advisor model is your primary reasoning model, so this keeps the two in sync (the same as running /model <advisor>). Closing without changing the advisor model leaves your active model untouched.

While routing is active, the status bar keeps the active model as the primary label and shows routing mode as the next status segment (auto when auto routing is active). It does not show a separate routing: chip or an advisor:implementer pair in the main status display. Configuring the advisor model still switches your active model to it (see above), so advisor-led interactive turns remain aligned with the configured advisor while the mode segment makes routing state visible without crowding the model/provider label.

Plan mode is the exception only in that it still shows the actual advisor model as the active model; routing state remains visible through the same separate auto status segment instead of a separate routing chip.

Why this saves money (and never costs more)

In an agentic loop the dominant cost is re-sending the full context (system prompt + files + history) on every turn. Prompt caching makes repeat turns on the same model cheap โ€” cache reads are a fraction of the input price. Switching the main-thread model mid-conversation would throw that cache away on both models and cost more, so yottacode only changes the active model at explicit session/mode boundaries such as startup, /plan, /auto, /model, or a /advisor picker selection.

Routing also targets contexts that never shared the main thread’s cache in the first place:

  • Subagents each build a fresh, isolated context window.
  • Advisor consultations are isolated no-tool calls.
  • Summarization / compaction is a single isolated call.

Modes

modeBehavior
off (default)Routing disabled. Everything runs on your active model. Fully backward compatible.
manualResolves advisor_model / implementer_model, but only routes a subagent when its definition declares an explicit model: (see subagents.md). Non-annotated agents inherit your active model, exactly as with routing off.
autoSession startup and /plan use advisor_model. Auto-mode work, summarization / history compaction, and every delegated subagent use implementer_model. Implementer-style subagents can call consult_advisor for bounded design/debugging help. An explicit model: on an agent definition overrides this.

The split is deliberate: planning and design should happen on the advisor; routine implementation and isolated child work can run on the faster implementer. If the implementer gets stuck, consult_advisor gives it a bounded no-tools path to ask the advisor without recursively spawning another agent. That tool is available to implementer subagents and to the top-level conversation while auto mode is driving the main session with the implementer; advisor-led sessions and plan mode do not expose it. Your reasoning-effort selection remains global via /effort, so roles do not fight over hidden effort settings.

Seeing what ran where

The model a subagent ran on is shown in the /subagents picker and on each subagent’s completion card (โ€ฆ ยท on claude-haiku-4-5), so you can confirm at a glance which role handled each task.

Note: yottacode does not yet aggregate per-model token totals or cost across a session โ€” token figures shown are per-subagent estimates.

Relationship to the multi-provider router

The same [router] block also hosts the multi-provider failover router (enabled, candidates, policy, health knobs), which dispatches each main-thread turn across candidates with fallback. That is a separate, orthogonal feature: failover is about resilience across providers; task routing (mode / advisor_model / implementer_model) is about assigning isolated work to roles. They can be configured independently.

No silent fallback

If the model or base URL is missing, yottacode exits with a clear error. It does not silently default to localhost or a paid cloud provider.

Choosing a model

Practical starting points:

  • Local/privacy-first: Ollama with Qwen, Llama, or DeepSeek models
  • General coding: a strong OpenAI-compatible coding model
  • Deep planning: a reasoning model, with higher latency/cost
  • Scripting/CI: cheaper fast model plus low --max-iterations

Use /doctor or yottacode doctor when a model is configured but not visible to the provider.