pi-custom-provider

Pi extension for managing custom model providers with discovery, metadata sources, generated config, and Pi-native TUI.

Packages

Package details

extension

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

Version

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:

  1. Run /provider add (or open /provider and press a).
  2. Edit the complete provider form inside the Provider Manager. The visible Provider ID defaults to custom-provider and remains user-editable. Use ↑/↓ to move, Enter to edit, and → on Authentication to change its mode after a value is configured.
  3. Explicitly choose an API protocol from Pi's runtime list, or enter a custom protocol id. The extension never infers protocol from the URL.
  4. 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.
  5. Choose endpoint discovery or enter exact model IDs manually. Ctrl+T tests model discovery; failure of /models does not imply that chat is incompatible.
  6. 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 includeAll with exclusions by default, or includeOnly with an explicit list of included ids.
  • Per-model overrides of arbitrary fields are available through modelOverrides or 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.