Agent stack build plans · oh-my-pi · 3 of 5

The routing config

Two files under ~/.omp/agent/ do all of it: config.yml (which model plays which role, fallbacks, scoping) and models.yml (any provider omp doesn’t already know). Model ids are provider-id/model-id; a thinking-effort suffix like :high or :minimal can ride on any of them.

Roles: name the lanes

defaultnormal turns — your main model
smolcheap subagent fan-out; tiny (background chores: titles, memory) falls back to it
slowdeep reasoning, worth frontier prices
planplan mode
commitcommit messages and changelogs — the easiest money you’ll save
advisoroptional second model that reviews every turn — powerful, and it doubles your calls

Also present: vision, designer, task. Assign in config.yml:

modelRoles:
  default: claude-opus-4-6
  smol: "@default"
  slow: openai/gpt-5.5

"@default" aliases another role. A sane first routed config: frontier on default/slow/plan, a small fast model on smol and commit, and stop there for a week. Switch mid-session with /model, cycle the active role’s model with Ctrl+P, or per-launch: omp --model … --smol … --slow … --plan ….

models.yml: add any endpoint

Local box, vLLM server, anything OpenAI-compatible (README’s own example):

providers:
  spark:
    baseUrl: http://192.168.10.223:8000/v1
    api: openai-completions
    apiKey: dummy
    models:
      - id: minimax-m3
        name: MiniMax M3
        contextWindow: 100000
        maxTokens: 32000

Check discovery with omp models spark, then route roles at it (smol: spark/minimax-m3). Ollama, LM Studio and llama.cpp need none of this — they’re auto-detected on their default ports. api also accepts anthropic-messages, openai-responses, google-generative-ai and friends.

Fallback chains: rate limits become a blip

With retry.modelFallback (on by default), a model that keeps 429ing hands its work to the next entry in its chain, and comes back after the cooldown (from the settings docs, verbatim shape):

retry:
  fallbackChains:
    default:
      - anthropic/claude-opus-4-5
      - openai/gpt-5.5
      - google/gemini-3-pro
    smol:
      - openai/gpt-5.5-mini
      - anthropic/claude-haiku-4-5

Keys can be roles, exact provider/model-ids, or provider/* wildcards; an entry like google-vertex/* means “same model, other provider”. Typos don’t fail silently — unknown models and malformed chains are reported as config warnings at startup. Read the warnings.

Scope by directory: privacy routing

enabledModels and disabledProviders accept path-scoped entries — one global config, different rules per tree:

enabledModels:
  - claude-sonnet-4-5            # applies everywhere
  - path: ~/work/high-context
    models:
      - anthropic/claude-opus-4-5

disabledProviders:
  - paths:
      - ~/clients/acme
    providers:
      - openai

The classic use: under a client’s repo, allow only your local models — code never leaves the machine. A scoped entry applies when your cwd is at or under the path.

Watching the money

@oh-my-pi/omp-stats is the project’s local usage dashboard — run it after your first routed week; it turns the simulator’s toy units into your actual spend per role. Round-robin credential stacking (multiple keys per provider, rotated with per-key backoff) is there when one key’s limit becomes the bottleneck.

Disagree? Pin a note on it →