Oh My Pi Config Generator

Generate Oh My Pi models.yml and settings.yml: define a custom provider and route the default, smol, plan and commit roles to different models. Free.

Advertisement

Oh My Pi config generator: models.yml providers and settings.yml role routing for omp

Oh My Pi — the omp coding agent — makes a design choice most agents do not: it splits which providers exist from which model does which job. Providers are declared in ~/.omp/agent/models.yml. Routing lives in ~/.omp/agent/settings.yml. This generator writes both, side by side, updating live as you type. It runs entirely in your browser with no upload step.

That split is the whole point of the tool. Most agents give you one model setting and you live with it: pay for a frontier model on every turn, including the ones that write a commit message. Oh My Pi lets you route a commit message to something cheap and a planning turn to something expensive, in four lines of YAML. Getting those four lines right is what this generator is for.

Prerequisite: Bun

Oh My Pi runs on Bun, and the custom-provider feature in models.yml requires Bun 1.3.14 or newer — the tool states this in the form itself. Two install routes are offered:

RouteCommand
Bunbun install -g @oh-my-pi/pi-coding-agent
curlcurl -fsSL https://omp.sh/install | sh

If provider declarations appear to be ignored after you write models.yml, check your Bun version before you debug the YAML.

models.yml: declaring a provider

The first tab writes a providers map with a single named entry. Fill in a provider name, choose an API type, give it a base URL, pick an auth style, and you get something like:

# ~/.omp/agent/models.yml
providers:
  my-gateway:
    baseUrl: https://gateway.example.com/v1
    api: openai-completions
    apiKey: "${MY_GATEWAY_API_KEY}"
    discovery:
      type: openai-models-list

The api field is the protocol the endpoint speaks, and Oh My Pi supports five natively rather than forcing everything through an OpenAI-compatible shim:

ValueWhat it targets
openai-completionsOpenAI-compatible chat completions — vLLM, proxies, gateways, most self-hosted servers
openai-responsesOpenAI's Responses API
anthropic-messagesThe Anthropic Messages API directly
google-generative-aiThe Gemini API
google-vertexGoogle Vertex AI

Being able to name the native protocol matters when you are pointing at a first-party endpoint rather than a compatibility layer — you get the provider's own request shape rather than whatever a translation layer chose to drop.

The API key variable name is derived from your provider name

This is the detail most likely to catch you out. With API-key auth, the generator does not write your key. It writes a shell-expansion reference whose variable name is computed from the provider name you typed: uppercased, with every run of non-alphanumeric characters replaced by an underscore, leading and trailing underscores stripped, and _API_KEY appended.

Provider name you typeVariable the file expects
my-gatewayMY_GATEWAY_API_KEY
internal.llmINTERNAL_LLM_API_KEY
vllm prodVLLM_PROD_API_KEY
(left blank)MY_GATEWAY_API_KEY, from the my-gateway fallback

So rename the provider and the expected variable changes with it. Export the matching variable in your shell and the file itself never contains a secret, which makes it safe to commit to a dotfiles repository.

The two other auth choices skip that entirely. none writes auth: none and is what you want for a local server that does not authenticate. oauth writes auth: oauth and defers to a browser flow instead of a static key.

One conditional line: the discovery block with type: openai-models-list is only written for openai-completions. That is the endpoint that exposes a models-list route Oh My Pi can enumerate, so the agent can discover what the gateway serves rather than making you list every model by hand. The other four API types do not get it.

settings.yml: routing work to the right model

The second tab writes a modelRoles map. Four roles are exposed, each taking a provider/model string:

RoleUsed forPlaceholder shown
defaultStandard turns — the bulk of the workanthropic/claude-sonnet-4-5
smolCheap subagentsopenai/gpt-4.1-mini
planPlanning modeanthropic/claude-opus-4-5
commitCommit messagesopenai/gpt-4.1-mini

Leave a field blank and the generator writes its placeholder, so the file is always complete and valid. The economic logic behind the split is straightforward once it is laid out: plan gets the strongest model because a bad plan wastes every turn that follows it; default gets a capable mid-tier model because it runs most often; smol and commit get something small because summarising a diff or fanning out a subagent does not need a frontier model. If you route all four to the same model you have Oh My Pi configured as an ordinary single-model agent — which works, but leaves its main advantage unused.

The form's own help text notes that a role string can carry an effort suffix, in the range :low through :xhigh — so anthropic/claude-opus-4-5:xhigh for the plan role expresses "the biggest model, thinking hardest, but only where planning happens". The generator passes whatever you type through verbatim, so suffixes are supported by typing them.

How the two files connect

The link between them is the prefix. A role value of vllm-prod/qwen3-coder means "the model qwen3-coder, reached through the provider called vllm-prod" — and vllm-prod has to be a name omp recognises, either one of its built-in providers or the one you declared in models.yml. That is the entire contract between the files, and it is why the placeholders in the routing tab use built-in prefixes like anthropic/ and openai/: those work without declaring anything.

Which gives you a useful sequencing rule. If you only want to route between providers omp already knows about, you can ignore the models.yml tab entirely and write just settings.yml. You only need the provider tab when you are adding an endpoint omp has no built-in knowledge of — a self-hosted server, a corporate gateway, an inference proxy, a router in front of several vendors.

The generator writes one provider per file, which covers the common case. Adding a second is a matter of copying the indented block under providers: and giving it a different key; the map takes as many entries as you like. Remember that each one derives its own API-key variable name from its key, so two providers means two exports.

Base URL conventions

The base URL field takes whatever your endpoint expects, and the placeholder https://gateway.example.com/v1 reflects the most common shape. For openai-completions endpoints the /v1 suffix is the convention almost every compatible server follows — vLLM, LM Studio, Ollama's compatibility surface, and most proxies all serve the OpenAI routes below /v1. Omitting it is the usual cause of a 404 on every request while the host itself is plainly reachable.

The native API types are a different matter: an anthropic-messages or google-vertex endpoint has its own path convention, so take the base URL from that provider's own documentation rather than assuming /v1. Leave the field blank and the generator writes the placeholder so the YAML stays valid while you go and find the real value.

Fallback

The final toggle, on by default, appends:

retry:
  modelFallback: true

This lets omp fall back to another model when one errors, rather than dropping the turn. With four roles pointing at potentially four different providers, any single provider's rate limit or outage would otherwise stall you; fallback is what makes a multi-provider setup more resilient than a single-provider one rather than four times as fragile. Turn it off if you need to know for certain which model produced a given output — benchmarking, auditing, or reproducing a bug report.

Worked example: self-hosted default, frontier planner

Declare a provider named vllm-prod with API type openai-completions and base URL http://10.0.0.9:8000/v1, auth by API key. Then set default to vllm-prod/qwen3-coder, leave plan pointed at anthropic/claude-opus-4-5, and leave smol and commit on their mini defaults. You now have the routine coding turns running on your own hardware at no per-token cost, the planning turn on a frontier model where it earns its price, and the throwaway work on something cheap — with VLLM_PROD_API_KEY exported in your shell and no secret in either file.

When omp ignores your YAML

  • The provider is not picked up. Check Bun 1.3.14 or newer first, then the file path — ~/.omp/agent/models.yml, not ~/.omp/models.yml.
  • Auth fails with a correct-looking file. The expected variable name is derived from the provider name. Rename the provider and you must rename the export too.
  • A role does nothing. The provider prefix in provider/model must match a provider omp knows — either a built-in one or the name you declared in models.yml. A typo in the prefix is not a YAML error.
  • YAML broke after hand-editing. Indentation is two spaces per level throughout the generated files, and YAML is unforgiving about tabs. Regenerate rather than patch.
  • Model discovery is missing. The discovery block is only emitted for openai-completions; the other API types do not use it.
  • Output is inconsistent between runs. Model fallback is probably on and a provider is intermittently erroring. Turn it off while you diagnose.

Both files have copy and download buttons, and Reset returns the form to defaults. Note what this tool does not produce: there is no project context file and no MCP picker here, so — unlike the Claude Code, Codex and Gemini generators — there is no AI-assist panel anywhere in it. Every line of both outputs is deterministic YAML assembled from your inputs.

This tool is provided for informational and educational purposes only. All processing happens in your browser — no data is sent to or stored on our servers. While we strive for accuracy, we make no warranties about the completeness or reliability of results.