pi-custom-provider
Pi extension for managing custom model providers with discovery, metadata sources, generated config, and Pi-native TUI.
Package details
Install pi-custom-provider from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-custom-provider- Package
pi-custom-provider- Version
0.1.0- Published
- Jul 22, 2026
- Downloads
- 108/mo · 24/wk
- Author
- linioi
- License
- MIT
- Types
- extension
- Size
- 159.7 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-custom-provider
A Pi extension that manages custom model providers through a single command: /provider.
I built this to scratch my own itch: collapsing the setup flow for custom providers into one command. It covers my own use cases well, but there are surely gaps I haven't hit and plenty of room to polish. If you have ideas or suggestions, issues and PRs are welcome.
What it's for
Pi already ships built-in provider presets with correct base URLs and model metadata, so this extension deliberately does not duplicate a preset catalog. It targets everything the presets don't cover:
- OpenAI-compatible proxies
- Self-hosted endpoints (LM Studio, Ollama, vLLM)
- Regional gateways
- Any deployment where you supply the baseUrl, API protocol, and key yourself
Install
From a local checkout:
pi install .
Or try it without installing:
pi -e .
Getting started
Everything runs through /provider. The typical first run looks like this:
- Run
/provider add(or open/providerand pressa). - Edit the complete provider form inside the Provider Manager. The visible Provider ID defaults to
custom-providerand remains user-editable. Use ↑/↓ to move, Enter to edit, and → on Authentication to change its mode after a value is configured. - Explicitly choose an API protocol from Pi's runtime list, or enter a custom protocol id. The extension never infers protocol from the URL.
- Enter the endpoint Base URL and choose authentication: None, environment variable, literal key, or shell command. None is valid for local services such as LM Studio, vLLM, and llama.cpp.
- Choose endpoint discovery or enter exact model IDs manually.
Ctrl+Ttests model discovery; failure of/modelsdoes not imply that chat is incompatible. - Save with
Ctrl+S. The Provider Manager stays open and shows completion; model management and test messages are optional follow-up actions.
Each profile maps to one pi.registerProvider() call. Once added, a profile is generated into Pi's config and registered live in the session.
Commands
/provider Open the Provider Manager overlay
/provider add Add a profile through interactive prompts
/provider list List provider profiles
/provider refresh Refresh all enabled profiles
/provider refresh <id> Refresh a single profile
/provider doctor Diagnose config / cache / generated / custom state
/provider export [path] Write masked effective generated + custom config
/provider open Show the config directory path
The overlay is the primary interface; the subcommands are operational shortcuts for scripting and recovery. Add, edit, refresh, model management, and completion stay inside one overlay session, avoiding dialog teardown and flicker. From the overlay you can also check profile status, clone a profile (y), delete, send an explicit test message, and reach advanced overrides.
Model discovery and metadata
- Discovery works in two modes: endpoint discovery (
discovery.mode: "endpoint"+modelsPath) or manual entry (discovery.mode: "manual"+modelIds). - Parameter Source candidates for each model come from Pi's built-in metadata plus models.dev sync. Unsourced or fuzzy matches are shown as warnings; unsourced models use built-in defaults until verified. The default source is the first sorted candidate, and you can change it from
/provider. - Inclusion policy is
includeAllwith exclusions by default, orincludeOnlywith an explicit list of included ids. - Per-model overrides of arbitrary fields are available through
modelOverridesor the custom override layer.
Custom headers
For endpoints that don't use the default Authorization: Bearer <apiKey> style, a profile can include optional headers. They apply to endpoint discovery and are written into the generated provider config for Pi requests. Header values support the same literal, $ENV_VAR, and !command forms as apiKey. Choose Authentication None when custom headers provide all required authentication.
{
"headers": {
"x-api-key": "$ANTHROPIC_API_KEY"
}
}
Configuration directory
All extension-owned files live under ~/.pi/agent/custom-provider/:
| File | Purpose |
|---|---|
config.json |
Managed user intent |
cache.json |
Discovered endpoint models and metadata candidates |
models.generated.json |
Generated Pi models.json-shaped config |
models.custom.json |
Unrestricted advanced override layer, merged after the generated config |
The directory is created as 0700; extension-owned JSON files are written as 0600. The extension never writes to Pi's native ~/.pi/agent/models.json.
Startup only performs the local generated/custom merge and provider registration; it does not refresh network data. Deleted, disabled, or no-longer-generated providers are unregistered from the live Pi session immediately. Provider rows show cache age, and doctor plus the startup reminder report caches older than the stale threshold (default 7 days; set settings.staleReminderDays in config.json, or settings.staleReminder: false to silence the startup reminder).
Error handling
| Situation | Behavior |
|---|---|
Missing models.generated.json |
Normal onboarding; no custom providers registered |
Invalid models.generated.json |
Registration skipped, but /provider, refresh, doctor, and recovery still work |
Invalid models.custom.json |
Ignored with a warning; generated providers still register |
Invalid config.json |
Already-generated providers still register, but edit/refresh flows enter recovery until fixed |
| Unresolved API protocol | The affected profile is invalid, not generated or registered, with no silent fallback |
Development
npm install
npm run check # typecheck + vitest
Contributions are welcome. This project reflects my personal needs, so if something doesn't fit your setup, open an issue or a PR.