Register a custom or variant model (e.g. an OpenRouter ":nitro" / ":floor" / ":exacto" slug) in the Pi Agent so it can be set as the global default. Use when Pi silently falls back to a different model (e.g. moonshotai/kimi-k2.6) after setting defaultModel, or when a model slug isn't in Pi's bundled list. Triggers on "Pi reset my model", "Pi won't use this model", "add a model to Pi", "Pi default keeps reverting".
76
95%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No known issues
Pi's saved default only loads if the exact provider/id exists in its model registry. Pi ships a static bundled list per provider — so OpenRouter routing-shortcut variants (:nitro = sort by throughput, :floor = cheapest, :exacto = quality tool-use) and any brand-new slug are NOT in it. When the default doesn't resolve, Pi silently falls through to its built-in per-provider default (for openrouter that's moonshotai/kimi-k2.6) — looking like Pi "reset" your model. Fix = register the slug as a custom model so find(provider, id) matches.
~/.pi/agent/settings.json — defaultProvider, defaultModel, defaultThinkingLevel~/.pi/agent/models.json — custom models, keyed by provider~/.pi/agent/auth.json — provider credentials (check the provider key exists)auth.json (or an env var like OPENROUTER_API_KEY). No auth → the model is registered but unavailable → still falls back.models.json under providers.<provider>.models. For a built-in provider (openrouter, anthropic, etc.) you only supply metadata — api, baseUrl, and auth are inherited from the bundled defaults. Example:
{
"providers": {
"openrouter": {
"models": [
{
"id": "z-ai/glm-5.2:nitro",
"name": "Z.ai: GLM 5.2 (nitro)",
"reasoning": true,
"thinkingLevelMap": { "xhigh": "xhigh" },
"input": ["text"],
"cost": { "input": 0.95, "output": 3, "cacheRead": 0.18, "cacheWrite": 0 },
"contextWindow": 1048576,
"maxTokens": 32768,
"compat": { "supportsDeveloperRole": false, "thinkingFormat": "openrouter" }
}
]
}
}
}cost/contextWindow/compat from the base model (the variant shares them) — find the bundled entry in <pi-pkg>/node_modules/@earendil-works/pi-ai/dist/providers/<provider>.models.js. Don't hardcode generic 128k/16k if the real model is bigger.settings.json: defaultProvider + defaultModel = the exact id. Leave defaultThinkingLevel as the user has it.pi --list-models | grep <id> shows it, and JSON parses. Optionally smoke-test: pi --provider <p> --model "<id>" "which model are you?".find() is exact provider+id — no fuzzy/colon-stripping for the saved default path. The slug in settings.json and models.json must be byte-identical.settings.json alone. Setting defaultModel to an unregistered slug does nothing — models.json is the actual fix.enabledModels (optional) pins the model picker so Ctrl+P cycling can't drift back: "enabledModels": ["<provider>/<id>:<thinking>"]..pi/settings.json overrides global. If a default reverts only inside one project, check that file first.66860fb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.