@hank-warren/pi-cliproxyapi-provider
Fork of 0xRichardH/pi-cliproxyapi-provider: Pi provider for CLIProxyAPI with model discovery, models.dev enrichment seeded from pi's built-in catalog, Anthropic Messages routing for Claude, Responses routing for Codex, and derived xhigh/max thinking level
Package details
Install @hank-warren/pi-cliproxyapi-provider from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@hank-warren/pi-cliproxyapi-provider- Package
@hank-warren/pi-cliproxyapi-provider- Version
0.1.1- Published
- Sep 10, 2026
- Downloads
- 226/mo · 226/wk
- Author
- hank-warren
- License
- MIT
- Types
- extension
- Size
- 119 KB
- Dependencies
- 0 dependencies · 3 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
pi-cliproxyapi-provider
Published fork. This is
pi-cliproxyapi-provider0.15.23 (MIT, Richard Hao) as forked athank-warren/pi-cliproxyapi-provider@3a4d021, six commits ahead of upstream0xRichardH/pi-cliproxyapi-provider: Anthropic Messages routing for Claude models, automatic refresh of stale models.dev metadata, andxhigh/maxthinking levels derived from models.dev effort lists. The 4.7 MB bundled models.dev seed is gone; first-run metadata comes from pi's own built-in model catalog instead. Never install both this package and the upstream one at once, or the provider is registered twice.
pi-cliproxyapi-provider registers one CLIProxyAPI instance as a pi model provider. It discovers models from CLIProxyAPI's OpenAI-compatible /v1/models endpoint and enriches them with provider-specific metadata from models.dev. Mixed catalogs use OpenAI Completions by default, while GPT-5.6 family models (including Codex variants) and GPT-6 models use the Responses API so pi can read their usage data, and Claude models use the Anthropic Messages API so signed thinking blocks and per-turn thinking effort survive a multi-turn conversation. Canonical /v1/models owners such as openai select the matching provider metadata; aliases can override that selection when a proxy routes billing differently.
Install
pi install npm:@hank-warren/pi-cliproxyapi-provider
Restart pi after installing, then run:
/cliproxyapi config
/login cpa
/model
To try it without installing, from a checkout of this repository:
CLIPROXYAPI_BASE_URL=http://localhost:8317/v1 \
CLIPROXYAPI_API_KEY=your-key \
pi -ne -e ./packages/pi-cliproxyapi-provider --list-models cpa
Configure
Run the interactive command:
/cliproxyapi config
It writes global connection/auth config to:
~/.pi/agent/pi-cliproxyapi-provider/config.json
Environment variables override config:
CLIPROXYAPI_BASE_URL
CLIPROXYAPI_PROVIDER_NAME
CLIPROXYAPI_AUTH_REQUIRED
CLIPROXYAPI_AUTH_HEADER
CLIPROXYAPI_MODELS_DEV_ENABLED
CLIPROXYAPI_METADATA_FALLBACK_PROVIDER
CLIPROXYAPI_API_KEY supplies the discovery credential for non-interactive runs. Set CLIPROXYAPI_METADATA_FALLBACK_PROVIDER=none to disable unresolved-model metadata fallback.
Project config supports metadataFallbackProvider, metadata aliases, and bounded per-model overrides. Set metadataFallbackProvider to null or "none" to disable fallback. Connection and auth settings such as baseUrl, providerName, authRequired, authHeader, and headers must be set in global config or environment variables.
GPT-5.6 / GPT-6 context window
The provider advertises a 272000-token context window for GPT-5.6 and GPT-6 models by default. This matches pi's conservative canonical limit, keeps compaction behaviour consistent with native model definitions, and avoids assuming that every CLIProxyAPI upstream account or route enables the provider's full long-context limit.
To opt into the full context limit reported by models.dev, add this package-specific setting to global ~/.pi/agent/settings.json:
{
"pi-cliproxyapi-provider": {
"gpt56ContextWindow": "full"
}
}
The same setting can be placed in project .pi/settings.json; project settings override global settings. Supported values are:
"canonical"(default): advertise272000tokens and compact at pi's conservative boundary."full": advertise the models.dev context limit, allowing pi to retain substantially more history before compaction.
Use "full" only when the selected CLIProxyAPI route and upstream account actually support that limit. Requests above 272000 input tokens also use the higher models.dev context-pricing tier where one is defined.
Model and display configuration
Run /cliproxyapi config in pi's TUI to edit every package-level settings.json value. The tabbed panel has Connection, Models, and Display sections; it controls the GPT-5.6 context-window mode and whether the model selector shows the published strict tool-schema capability.
{
"pi-cliproxyapi-provider": {
"gpt56ContextWindow": "canonical",
"showStrictMode": false
}
}
showStrictMode defaults to false because the selector stays compact for normal use. Enable it when diagnosing tool-schema behaviour; model details always show Strict tool schema explicitly. Saving through /cliproxyapi config reloads pi. Select Connection to open the endpoint and authentication editor.
Authenticate
Use pi's normal API-key login flow:
/login cpa
If you changed the provider name, use that name instead. For non-interactive runs, set:
export CLIPROXYAPI_API_KEY=your-key
Commands
/cliproxyapi config # tabbed connection, model, and display configuration
/cliproxyapi config connection # open endpoint and authentication editor
/cliproxyapi status # show snapshots, capabilities, and enrichment counts
/cliproxyapi refresh # refresh models and metadata, then update pi immediately
/cliproxyapi refresh models # refresh CLIProxyAPI availability only
/cliproxyapi refresh metadata # refresh models.dev metadata only
/cliproxyapi aliases # show unmatched model IDs for metadata aliases
/cliproxyapi models # inspect effective model settings and set bounded overrides
/cliproxyapi help # show this list
Thinking levels
Pi only offers the extended xhigh and max thinking levels when a model publishes a thinkingLevelMap that names them; without one, every reasoning model stops at high. CLIProxyAPI's /v1/models says nothing about effort, so the package takes the map from the metadata it already has: pi's built-in catalog publishes a finished thinkingLevelMap per model, and a models.dev entry that lacks one has its map derived from reasoning_options — each effort the provider accepts (low … max) maps to itself, and any pi level the provider does not accept maps to null so pi hides just that level. Claude Fable 5.x, Opus 4.7+ and Sonnet 5 therefore expose xhigh and max; Opus 4.6 exposes max but not xhigh; models described only with a thinking budget keep pi's default budget mapping.
off follows the same data. A none effort maps to it, a toggle option leaves it available, and a model with neither (Claude Fable 5.x) marks it null, because the upstream rejects thinking.type = disabled for those models. GPT-5.6 and GPT-6 keep their hand-written maps, which encode details models.dev lacks.
Metadata aliases
Aliases affect metadata only. The package still sends the original CLIProxyAPI model ID to the proxy.
When /v1/models reports a canonical owner such as openai, the package uses that provider's metadata even if models.dev lists the model under several providers. Noncanonical owners can embed a provider hint, so feedmob-opencode-go resolves to opencode-go when that provider publishes the model. If ownership is still unresolved, the package uses OpenRouter metadata by default when there is exactly one matching OpenRouter entry. Set metadataFallbackProvider to another models.dev provider ID, or to null/"none" to disable this fallback. Add an alias when CLIProxyAPI's reported owner or fallback does not match the provider whose limits and pricing apply to your setup.
Add global aliases to:
~/.pi/agent/pi-cliproxyapi-provider/config.json
Add project aliases manually to:
.pi/pi-cliproxyapi-provider/config.json
Project config reads metadataFallbackProvider, modelAliases, and modelOverrides; other fields are ignored.
{
"metadataFallbackProvider": "openrouter",
"modelAliases": {
"claude-opus-4-6-thinking": "anthropic/claude-opus-4-6",
"gpt-5.6-sol": "openai/gpt-5.6-sol"
},
"modelOverrides": {
"gpt-5.6-sol": {
"contextWindow": 512000,
"maxTokens": 32768
}
}
}
Model inspector and overrides
Run /cliproxyapi models in pi's TUI to inspect the models in the current CPA snapshot. The selector shows the effective API, reasoning mode, and context window. The detail view also shows input modalities, cost, thinking levels, and the compatibility values that pi will publish.
Only reasoning, contextWindow, and maxTokens are editable. Values are constrained to safe presets; choose auto to remove an override and restore the derived value after reload. API routing and compatibility stay provider-owned: GPT-5.6/GPT-6 Codex models remain on openai-responses and Claude models on anthropic-messages, while the CLIProxyAPI workaround publishes supportsStrictMode: false.
For CPA Responses requests, the extension also applies the Codex-compatible function-tool wire contract used by pi-codex-conversion: each function tool explicitly carries strict: null. This preserves optional tool arguments such as interactive_shell.listBackground without replacing CPA authentication, transport, discovery, or streaming with the ChatGPT-backed openai-codex-responses provider.
Snapshots and startup
CPA /v1/models: local snapshot at startup, then a background refresh on every model discovery
models.dev metadata: persistent local snapshot, re-fetched in the background once it is a week old
first-run seed: pi's own built-in model catalog, read in-process, no file and no network
Snapshots live under:
~/.cache/pi-cliproxyapi-provider/
Startup registers the provider immediately from the last-known-good local snapshots and never fetches anything itself. With no metadata snapshot on disk it seeds from pi's built-in catalog, so a cold start already has real costs, context windows and thinking levels for the Anthropic, OpenAI, Codex, xAI, Google and OpenRouter models CLIProxyAPI usually fronts. On a first run with no CPA snapshot, pi registers a placeholder until background discovery succeeds.
Every model discovery pi triggers (startup, opening /model) re-checks CLIProxyAPI's model list, and piggybacks a models.dev fetch when the metadata snapshot is stale: either it is still the built-in seed, or the cached fetch is more than seven days old. That is what keeps a newly listed model from rendering with pi's bare fallback metadata (16384 output tokens, text only, zero cost) until someone notices. A fresh snapshot is never re-fetched on its own, so the ~7 MB download stays rare. /cliproxyapi status flags a stale snapshot; /cliproxyapi refresh metadata forces the fetch now.
So the seed is a floor, never a ceiling: the first successful models.dev fetch writes a cache snapshot that supersedes it entirely, and from then on the seed is not consulted again unless that cache is deleted or turns out to be a legacy one without source-provider identity. /cliproxyapi status names the current source — builtin (pi catalog generated <age>) before the first fetch, cache, <age> after it.
Manual refreshes update the running provider immediately; /reload is not required. Failed refreshes retain the last-known-good data independently for each source — a models.dev outage never blocks CLIProxyAPI model discovery.
How metadata is sourced
This section summarises the fork's architecture decision record ("Use CLIProxyAPI for discovery and models.dev for metadata"), which is not shipped as a separate file.
CLIProxyAPI is the only source of availability: the package discovers models from GET <baseUrl>/models and never asks for Management API access, so no powerful management key is needed and the proxy stays the source of truth for what exists. Trusting that endpoint alone is not enough — it returns ids and owners and nothing else — so everything pi needs (context window, output limit, reasoning flag, image support, cost, thinking levels) is enriched from a metadata catalog keyed by <provider>/<model-id>. Downloading that catalog at install time was rejected in the same decision: install-time fetches are brittle and go stale in place.
Two catalogs feed the enrichment, in this order:
- A cached models.dev snapshot under
~/.cache/pi-cliproxyapi-provider/, when one exists and carries source-provider identity. models.dev's provider catalog is used rather than its lab-level one, so provider-specific prices and context-pricing tiers are available. This is the freshness layer: a model listed on models.dev before pi's next release shows up here first. - Pi's built-in model catalog, read through
@earendil-works/pi-ai'sproviders/allsubpath, as the first-run seed — replacing the 4.7 MBdata/models-dev-fallback.jsonfile upstream ships. It is pure static data (no credential, no network, no file of ours), regenerated from models.dev on every pi release, so it can never be older than the pi you are running, and it already carries each model's finishedthinkingLevelMap— which models.dev does not publish at all. Six providers are seeded:anthropic,openai,openai-codex,xai,google,openrouter.openai-codexentries are also registered underopenai/when that key is free, so CLIProxyAPI'sowned_by: openaimatches the Codex-only ids. Any non-cachesnapshot counts as stale, so the first model discovery still upgrades it to a live models.dev fetch.
On a pi whose @earendil-works/pi-ai does not export providers/all — an older release, or a future one that renames it — the read fails soft: the seed is empty, one warning is logged, and every model renders with pi's bare defaults until that first models.dev fetch lands, exactly as it would with no seed at all. Nothing else changes, and upgrading pi closes the gap.
Matching a CLIProxyAPI model id to a catalog entry is identity-first: an explicit alias wins, then an exact id, then a canonical owned_by such as openai, then a provider hint embedded in a noncanonical owner (feedmob-opencode-go → opencode-go, while ken-team-litellm implies no upstream), then a unique normalized suffix. Only if all of that is unresolved does the configured metadataFallbackProvider apply, and only when that provider has exactly one normalized match. Legacy flat caches without source-provider identity are ignored in favour of the seed until a refresh replaces them. Aliases are metadata-only: the registered pi model keeps the original CLIProxyAPI id so requests still route through the proxy correctly.
API routing follows from the same decision. The provider defaults to OpenAI Completions for its mixed catalog; GPT-5.6 and GPT-6 models (including Codex variants) take a model-level Responses override because pi's token and cost accounting needs their Responses usage shape; and Claude models take an Anthropic Messages override because CLIProxyAPI proxies Anthropic upstreams at /v1/messages with signed thinking blocks intact, while the Chat Completions shape can represent neither those signatures nor per-turn thinking effort — so Claude routed through it loses reasoning continuity across a multi-turn tool loop. Those models also publish forceAdaptiveThinking, matching pi's native Claude definitions. Both initial registration and dynamic refreshes publish the same materialised model definitions.
Attribution
Forked from 0xRichardH/pi-cliproxyapi-provider (MIT, Copyright (c) 2026 Richard Hao). See LICENSE.