better-custom-provider
Pi and Oh My Pi extension for managing custom providers through an interactive wizard.
Package details
Install better-custom-provider from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:better-custom-provider- Package
better-custom-provider- Version
1.4.2- Published
- Aug 28, 2026
- Downloads
- 1,954/mo · 775/wk
- Author
- wudaoshi
- License
- MIT
- Types
- extension
- Size
- 122.9 KB
- Dependencies
- 2 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
better-custom
A better way to manage custom providers for Pi and Oh My Pi (OMP).
An interactive wizard (/custom-provider) that adds, edits, and deletes custom
LLM providers — no hand-editing of config files required.
Features
- Add from the models.dev catalog — pick a known API site (OpenRouter, DeepSeek, Groq, xAI, ...); base URL, model list, and metadata all come from the catalog (official SDK, with a jsDelivr freshness layer and a bundled offline snapshot). No probing at all.
- Add any custom endpoint — OpenAI Chat Completions, OpenAI Responses,
Anthropic Messages, Gemini, or Ollama. Auto-detect probes
/modelsand every known metadata source, or enter models by hand (one id at a time, with a per-model metadata menu pre-filled from the resolved values). - Automatic metadata detection — context window, max output tokens,
image/video input, reasoning support and levels, learned from the gateway
itself (LiteLLM
/model/info+/model_group/info, site public catalogs, OpenAIGET /models/{id}, inline list metadata, Ollama native API) and from models.dev. See How metadata is resolved. - Re-probe to reconcile — query
/modelsagain and review everything in one tri-state list: new models, metadata updates (context 128000 -> 1000000,image [+],max-out 8192 -> 32000), and vanished models flaggedunsupported.[x]apply,[-]keep stored metadata,[ ]remove/skip. - Edit everything afterwards — per-model fields (reasoning ceiling, image input, context window, max output tokens, headers/endpoint override), bulk model delete, provider API flavor, endpoint, rename, delete.
- Sensible, honest defaults — detected values win; guesses are tagged
(
[models.dev]/[local rules]) in the picker; default-filled values are not shown at all. Degenerate catalog limits (maxTokens == contextWindow) are clamped automatically. - Developer-role probe — endpoints that reject the OpenAI
developerrole (e.g. Kimi's subscription endpoint) getcompat.supportsDeveloperRole: falseautomatically, so pi keeps sendingsysteminstead of failing with a 400. - Official-style storage — API keys go to
~/.pi/agent/auth.json(the same file/loginwrites), model declarations tomodels.json. Legacy inlineapiKeyentries migrate automatically. See Storage. - Reasoning levels done right — when the probe learns the provider's exact
effort options, the wizard writes a matching
thinkingLevelMap; new models default to reasoning on at thexhighceiling. - Path-adaptive probing — if
/modelsdoesn't answer on the given base, the/v1variant is tried automatically; non-localhttp://falls back tohttps://. On failure you can retry or switch to manual entry.
Install
pi install npm:better-custom-provider # from npm
pi install https://github.com/real-wudaoshi/better-custom # from GitHub
pi install /path/to/better-custom # from a local checkout
Prefer pi install over copying the folder into ~/.pi/agent/extensions/
manually: pi install runs npm install, so the runtime dependencies
(model-probe, yaml) are present. A manual copy still starts, but YAML
configs degrade to JSON (a valid YAML subset).
Usage
Run /custom-provider in pi, then choose Add provider, Edit provider,
or Delete provider.
Add
- From models.dev catalog — pick a provider, name it, enter the API key (or none), multi-select models. Metadata comes from the catalog.
- Custom endpoint — pick the provider style, enter the endpoint URL, name
it, enter the API key, then:
- Auto-detect from the endpoint — probe
/models+ metadata sources, multi-select models with metadata shown inline; or - Add manually — type an id, adjust its metadata menu (reasoning / image / context window / max output), confirm, next id; blank or esc finishes.
- Auto-detect from the endpoint — probe
Edit
Pick a provider, then: Re-probe for models (reconcile as above), Edit per model, Delete models, Add models manually, API flavor, Endpoint, Rename provider, or Delete provider.
Per-model edits change one field in place — untouched fields (cost, headers, overrides) are preserved.
How metadata is resolved
Every field is resolved in tiers, highest priority first:
- Detected — real data from the gateway: LiteLLM
/model/infoand/model_group/info, New API-styleGET {site}/api/models/public(no auth), OpenAIGET /models/{id}(incl.capabilities.reasoning.effort_options), inline/modelslist metadata (OpenRouter, One API / New APImetafields andsupported_endpoint_types), GeminiinputTokenLimit, Ollama/api/tags+/api/show. - models.dev — exact per-model catalog entries, tagged
[models.dev]. - Local rules — a built-in known-model table (OpenAI, Anthropic, DeepSeek,
Qwen, Kimi, GLM, Gemini, ...), tagged
[local rules]. Ids are normalized first, so relay-decorated ids (bailian/deepseek-v4-pro,gpt-5@20250807,claude-sonnet-4-6[1m]) still match. Extend it via~/.model-probe-rules.json(see model-probe). - API fallback — protocol-level limits (anthropic 200K/32K, google 1M/64K, openai 258K/32K) when nothing else knows them.
- Defaults —
image: false,video: false,reasoning: true.
Only tiers 1–2 ever rewrite an existing entry during re-probe; guesses and defaults are starting points for new models. Video input is tracked and shown as a picker tag, but pi's model config has no video slot, so it is display-only.
Storage
Pi (official split, same as /login):
~/.pi/agent/auth.json— credentials, keyed by provider id ({"type": "api_key", "key": ...});$ENV/!commandreferences work. pi resolves them for any provider id automatically. Selecting "none" writes a"dummy"/"ollama"placeholder so the provider still loads.~/.pi/agent/models.json— provider declarations (baseUrl, api, compat, models). pi only loads custom providers frommodels.json;models-store.jsonis pi's internal catalog cache for built-in providers and is not a place for custom models.- Legacy inline
apiKeyentries migrate toauth.jsonon the next save; deleting a provider removes itsauth.jsonentry, renaming moves it.
OMP: providers and keys stay in models.yml / models.yaml (existing files
keep their format; a fresh config is created as models.yml). Saving YAML
rewrites formatting and drops comments.
Development
Plain TypeScript loaded directly by pi — no build step. Probing lives in the separate model-probe package.
npm run check # syntax-check every source file with node --check
Layout: index.ts (command entry) · src/flows/ (add / edit / delete /
shared) · src/ui/ (pickers, prompts) · src/config.ts (models.json +
auth.json I/O, migration) · src/model-entry.ts (model/provider config
builders) · src/api-key.ts, src/url.ts, src/presets.ts (helpers).
License
MIT