npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@superjeason/pi-model-manager

v0.4.0

Published

Pi commands for managing custom model providers with models.dev-first metadata enrichment.

Readme

@superjeason/pi-model-manager

Four pi commands for managing custom model providers in ~/.pi/agent/models.json, with models.dev-first metadata enrichment and request-header disguising.

Commands

/add-provider — interactive wizard

Adds a new OpenAI-compatible provider end-to-end:

  1. Enter provider name, base URL, API key
  2. Choose API type (all built-in pi formats)
  3. Fetches {baseUrl}/models (standard OpenAI format) with a cancellable loader
  4. Multi-select models (Space toggle, Enter confirm, Esc cancel)
    • If /models fetch fails, type model ids manually (comma-separated)
  5. Optionally enrich config from models.dev first, then the built-in pi-ai library (same logic as /sync-model)
  6. Writes the provider to models.json

Then /reload and the new provider appears in /model.

/edit-provider — modify an existing provider

Select a provider (shown with model count and baseUrl), then choose an action:

  • Change API format — pick from built-in API types
  • Manage models
    • Add from /models endpoint, or type ids manually
    • Remove existing models (multi-select + confirm)
    • Adding can enrich from models.dev first, then the built-in library
  • Edit connection — change baseUrl / apiKey
    (current value in the prompt; empty keeps, - removes, Esc cancels)
  • Enrich model config
    • Safe: fill missing fields only
    • Overwrite: clear matched fields then re-fill (reasoning is preserved)
  • Delete provider — remove provider and all models (confirm)

All destructive ops ask for confirmation first.

/sync-model — fill missing model config

Reads models.json, matches each custom model by id against models.dev first, then built-in models loaded at runtime, and fills fields you didn't set:

  • thinkingLevelMap (from models.dev reasoning_options when available; enables max / xhigh thinking levels)
  • cost (from models.dev api.json pricing → pi {input,output,cacheRead,cacheWrite[,tiers]} USD/1M; fills missing or all-zero placeholders)
  • compat (from built-in pi metadata; merged, your values win)
  • maxTokens, contextWindow, reasoning, input (only text/image; pdf/audio/video from models.dev are stripped), name

Only fills missing fields — anything set explicitly is preserved. Idempotent.

Matching prefers canonical families over reseller/gateway clones:

| bare id example | preferred family | |---|---| | gpt-5.5 / o3 | openai | | claude-* | anthropic | | gemini-* | google | | grok-* | xai | | glm-* | zhipuai / zai | | qwen* / qwq* / qvq* | alibaba / qwen / dashscope | | doubao* / seed-1.* | volcengine / bytedance | | mimo-* / xiaomi-mimo* | xiaomi | | minimax* / abab* | minimax | | kimi* / moonshot* | moonshotai |

You can also set an explicit family on the provider or model:

{
  "providers": {
    "cpa": {
      "modelFamily": "openai",
      "models": [
        { "id": "gpt-5.5", "modelFamily": "openai" }
      ]
    }
  }
}
/sync-model              # fill missing fields, write back
/sync-model preview      # show what would change without writing
/sync-model force        # clear enrichable fields, then re-match (rewrites maps)
/sync-model force preview

Tab completion is available for preview / dry-run / force. Use force when an older sparse/wrong thinkingLevelMap is stuck (safe mode never overwrites existing fields).

/disguise — disguise request headers

Makes pi's outgoing requests look like they come from the official Codex CLI or Claude Code CLI, by writing a headers map onto the provider in models.json. pi's core natively merges configured headers into every request and they override pi's default User-Agent: pi-coding-agent. Header values support $ENV_VAR interpolation and !cmd shell commands (same resolution as API keys).

Flow:

  1. Select a provider (the label shows whether it is already disguised and how many headers are set)
  2. Choose a preset:
    • Codex CLIoriginator: codex_cli_rs, User-Agent: codex_cli_rs/<ver> (Arch Unknown; x86_64) kitty, OpenAI-Beta: responses=experimental
    • Claude Codeanthropic-version: 2023-06-01, anthropic-beta: <full token list>, x-app: cli, User-Agent: claude-cli/<ver> (external, cli), anthropic-client-platform: claude-code
    • Custom headers — enter Key: Value (or Key=Value) lines, blank line to finish
    • Clear disguise — remove provider.headers entirely
    • Cancel
  3. For Codex/Claude presets: enter a version for the User-Agent (pre-filled with a default), then optionally merge extra/override headers on top
  4. Preview the current → new header diff
  5. Confirm and write; run /reload

The Codex preset targets openai-responses providers (originator + OpenAI-Beta). The Claude preset targets anthropic-messages providers (anthropic-version/anthropic-beta). Applying a Claude preset to an OpenAI-format provider is allowed but won't make sense — pick the preset that matches the upstream's expected protocol.

Default versions (DEFAULT_CODEX_VERSION, DEFAULT_CLAUDE_VERSION) and the anthropic-beta token list are constants at the top of index.ts; edit them to keep current.

Why

Custom providers don't inherit authoritative model metadata. models.dev exposes model limits (context, output), modalities, reasoning, and provider-level reasoning_options; pi's built-in registry can also provide compat details. Without thinkingLevelMap, the max / xhigh thinking levels may be unavailable or clamped. These commands fill that in by matching model ids.

Install

pi install git:github.com/superjeason/pi-model-manager
# or
pi install npm:@superjeason/pi-model-manager
# or local path
pi install ./pi-model-manager

Then /reload.

Multi-select controls

| Key | Action | |-----|--------| | Space | Toggle current item | | ↑ / ↓ | Move cursor | | PageUp / PageDown | Page | | Home / End | First / last | | Enter | Confirm selection | | Esc / Ctrl+C | Cancel (uses pi's tui.select.cancel plus low-level matchesKey("escape"); returns without changes) | | type | Filter list (Unicode supported) | | Backspace | Clear filter char | | Ctrl+A | Select all visible (uses low-level matchesKey("ctrl+a")) | | Ctrl+D | Deselect all (uses low-level matchesKey("ctrl+d")) |

Selection is tracked by model id, so filtering does not scramble checks. In non-TUI modes (RPC/print), falls back to one-by-one Add/Skip prompts. Cancel is never treated as "fall back to one-by-one".

Requirements & Notes

  • /add-provider prefers a standard OpenAI-compatible /models endpoint
    (GET {baseUrl}/models{"data":[{"id":"..."}]}).
    baseUrl with or without trailing /v1 both work.
    If the endpoint is missing (e.g. anthropic-messages / google-generative-ai), type ids manually.
  • The API format picker is built dynamically at runtime from pi's api-provider registry (getApiProviders() from @earendil-works/pi-ai/compat), so it always matches the running pi: the 10 built-in formats (openai-completions, openai-responses, anthropic-messages, google-generative-ai, google-vertex, mistral-conversations, openai-codex-responses, azure-openai-responses, bedrock-converse-stream, pi-messages) plus any custom API types registered by other extensions. No hardcoded list to go stale.
  • models.json must be pure JSON (no // comments).
  • Overwriting an existing provider prompts for confirmation; other providers untouched.
  • Enrich only adds missing fields; manual edits are never clobbered (unless you choose overwrite / /sync-model force).
  • Metadata source order: models.dev models.json + api.json first (canonical family preferred), then pi built-in registry.
  • Bare ids like gpt-5.5 prefer openai/gpt-5.5 over reseller copies (vivgrid, 302ai, …).
  • Optional modelFamily on provider or model overrides family inference.
  • cost is filled when missing or all zeros (common custom-provider placeholders); non-zero user costs are kept.
  • models.dev models.json has limits/modalities; pricing usually comes from api.json and is merged in.
  • models.dev responses are cached under ~/.cache/pi-model-manager/ for 7 days; stale cache is used if refresh fails.
  • Uses pi theme tokens for multi-select colors and focus state (selectedBg, accent, success, dim, muted, warning).
  • Focused rows use a full-width selectedBg band plus an accent bar (); checked rows use [x] without stealing focus.
  • Runtime deps: Node built-ins only; peer: @earendil-works/pi-coding-agent (provides pi-tui).

Structure

pi-model-manager/
├── index.ts         # /add-provider + /edit-provider + /sync-model + /disguise
├── enrich.ts        # shared model-matching & config-filling
├── multi-select.ts  # themed multi-select TUI component
├── package.json
└── README.md