@es11225599/pi-9router
Pi package that connects to 9router and enriches its models with metadata from models.dev
Package details
Install @es11225599/pi-9router from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@es11225599/pi-9router- Package
@es11225599/pi-9router- Version
0.1.0- Published
- Jun 26, 2026
- Downloads
- 104/mo · 6/wk
- Author
- es1259
- License
- MIT
- Types
- extension
- Size
- 35.3 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-9router
A pi package that connects your agent to 9router and enriches its model catalog with metadata from models.dev.
What it does
- Discovers the models exposed by your local (or remote) 9router instance.
- Looks up each model in the public models.dev API to obtain:
- context window size
- max output tokens
- reasoning / thinking support
- supported input modalities (text, image)
- pricing (input / output / cache read / cache write)
- Registers 9router as a pi provider so you can select models with
/model. - Provides
/9router-status,/9router-refresh,/9router-set-keyand/9router-remove-keycommands.
Installation
Install as a pi package:
pi install git:github.com/es11225599/pi-9router
Or clone and install from the local path:
cd /path/to/pi-9router
pi install .
Configuration
9router does not require an API key by default, so models appear in /model
without any configuration. If your 9router instance is protected by a key, set it
via environment variable:
export NINEROUTER_BASE_URL="http://localhost:20128/v1" # default
export NINEROUTER_API_KEY="<your 9router dashboard API key>"
The API key is created in the 9router dashboard under Settings → API Keys.
If you prefer not to use an environment variable, you can save the key directly from pi with:
/9router-set-key <your-9router-api-key>
The key is stored in pi's auth.json. Use /9router-remove-key to delete it.
Note: If your 9router does not require a key, leave
NINEROUTER_API_KEYunset and do not run/9router-set-key. All discovered models will still be available in/model.
Usage
After installation, 9router models appear in pi automatically. Select one with:
/model 9router/openai/gpt-4o
Then send prompts as usual. pi forwards the request to 9router's OpenAI-compatible endpoint (/v1/chat/completions) using the model id without the provider prefix (e.g. openai/gpt-4o), which is exactly what 9router expects.
Commands
/9router-status— show the configured base URL, discovered model count, API key status and how many models are available in/model./9router-refresh— re-fetch the model list from 9router and re-register the provider./9router-set-key <key>— save the 9router API key to pi'sauth.json./9router-remove-key— remove the saved 9router API key.
How the mapping works
9router models are exposed as alias/modelId, for example:
openai/gpt-4ogemini/gemini-2.5-prokc/anthropic/claude-sonnet-4-20250514(Kilo connection exposing Anthropic models)openrouter/google/gemma-4-26b-a4b-it:free
The extension maps the 9router alias to a models.dev provider id (e.g. gemini → google, kc → kilo), then matches the model id by:
- exact id match
- normalized id match (strips date suffixes such as
-20250514) - model name matching
- nested provider alias matching (e.g.
kc/anthropic/...→anthropic)
Models that cannot be matched fall back to sensible defaults (128k context window, 8k output, no reasoning, zero cost).
Project structure
pi-9router/
├── package.json # npm + pi manifest
├── src/
│ ├── index.ts # extension entry point
│ ├── config.ts # env var / default configuration
│ ├── auth.ts # pi auth.json persistence helpers
│ ├── ninerouter.ts # 9router /v1/models client
│ ├── modelsdev.ts # models.dev API client
│ └── mapping.ts # alias mapping and model enrichment logic
├── scripts/
│ ├── test-mapping.ts # unit test for the mapping
│ ├── test-extension-load.ts # smoke test loading the extension
│ ├── test-auth.ts # test API key persistence
│ └── test-real-mapping.ts # live test against a running 9router
└── README.md
Development
npm install
npm run check # TypeScript type check
npm run test:mapping # test mapping against cached models.dev data
npm run test:auth # test API key persistence
npm run test:extension # smoke test loading the extension
To test against the live 9router instance:
node --import jiti/register scripts/test-real-mapping.ts
License
MIT