@cokefenta/pi-switch
Lightweight profile switcher for pi models.json
Package details
Install @cokefenta/pi-switch from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@cokefenta/pi-switch- Package
@cokefenta/pi-switch- Version
0.3.6- Published
- Jun 19, 2026
- Downloads
- 848/mo · 848/wk
- Author
- cokefenta
- License
- MIT
- Types
- extension
- Size
- 17.6 MB
- Dependencies
- 0 dependencies · 0 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-switch
TUI + CLI dual-mode profile switcher for pi agent
Manage provider profiles and run a local model-name routing gateway with failover — via an interactive TUI or CLI.
📸 Screenshots
📥 Installation
# npm (recommended)
npm install -g @cokefenta/pi-switch
# or via pi
pi install npm:@cokefenta/pi-switch
Build from source (requires Node.js >= 20, Rust 1.80+):
git clone https://github.com/user/pi-switch.git
cd pi-switch
npm install
npm run build:native
node bin/pi-switch.js tui
🚀 Quick Start
pi-switch tui # Interactive TUI (recommended)
pi-switch doctor # Run environment diagnostics
Essential CLI Commands
# Provider management
pi-switch provider add <name> [--preset <id>] [--api-key <key>]
pi-switch provider list
pi-switch provider show <name>
pi-switch provider delete <name>
pi-switch provider expose <name> <model-ids...> # Expose models to pi agent
pi-switch provider fetch-models <name> # Fetch models from API
# Proxy (gateway)
pi-switch proxy failover <p1,p2,...> # Same-model fallback chain
pi-switch proxy start --daemon # Start proxy daemon
pi-switch proxy status
# Other
pi-switch presets list # List built-in presets
pi-switch config show # Display current config
pi-switch config backups # List backup files
pi-switch config export <passphrase> # Encrypted export
pi-switch config import <path> <passphrase> # Encrypted import
pi-switch stats # View request statistics
✨ Features
| Category | Highlights |
|---|---|
| 🔌 Provider Management | CRUD, duplicate, search/filter, model management, expose to pi agent |
| 💡 Built-in Presets | OpenRouter, Anthropic, DeepSeek, SiliconFlow, OpenAI — add profiles instantly |
| 🌉 Model-Name Gateway | Stateless routing by profile/model in the request body, custom User-Agent, OpenAI ↔ Anthropic conversion, failover, circuit breaker |
| 🖥️ Interactive TUI | ratatui-powered, Dracula theme, mouse support, vim keys (hjkl) |
| 🌐 Bilingual | English / 中文, persisted to config, toggle in Settings |
| 📊 Usage Stats | Per-provider, per-model request metrics & latency |
| 💾 Backup & Sync | Auto-backup on mutation, AES-256-CBC encrypted export/import |
| 🩺 Diagnostics | doctor command checks config, models.json, structure |
🎯 Core Workflow
Gateway Routing & Failover
graph LR
subgraph Setup["⚙️ Setup"]
A[Add Provider] --> B[Configure Models]
B --> C[Expose to Pi]
C --> D[Set Failover Chain]
end
subgraph Runtime["🚀 Runtime"]
E["Request<br/>model: provider-a/gpt-5.4"] --> F{Resolve Route}
F --> G[Try provider-a]
G --> H{Success?}
H -->|✓| I[Response]
H -->|✗ 429/5xx| J[Try provider-b]
J --> K{Success?}
K -->|✓| I
K -->|✗| L[Circuit Breaker]
L --> M[60s Cooldown]
M --> N[Half-Open Probe]
N -->|✓| G
N -->|✗| M
end
Setup --> Runtime
style A fill:#50fa7b,stroke:#50fa7b,color:#282a36
style E fill:#8be9fd,stroke:#8be9fd,color:#282a36
style I fill:#50fa7b,stroke:#50fa7b,color:#282a36
style L fill:#ff5555,stroke:#ff5555,color:#f8f8f2
Step by Step
1. Add a provider (CLI or TUI)
pi-switch provider add provider-a --api openai-completions --base-url https://api.example.com/v1 \
--api-key '$API_KEY' --models gpt-5.4,claude-sonnet-4-5
In TUI: Profiles → a → fill form → Ctrl+S
2. Expose models to pi agent — choose which models appear in ~/.pi/agent/models.json
pi-switch provider expose provider-a gpt-5.4
In TUI: Profiles → select provider → x
3. Start the proxy — it writes a single pi-switch gateway provider to pi
pi-switch proxy failover provider-b,provider-c # optional same-model fallback
pi-switch proxy start --daemon
4. Use in pi — select the pi-switch provider, then pick a profile/model like provider-a/gpt-5.4
How Gateway Routing Works
Requests are routed by the model name in the request body — no out-of-band state, no "current target":
- Model-name routing —
"model": "provider-a/gpt-5.4"resolves to profileprovider-a, real modelgpt-5.4; the proxy rewrites the body before forwarding upstream - Single gateway provider — pi sees one
pi-switchprovider advertising every exposed model asprofile/realModelId; switching model in pi = sending a different model string = instant routing change - Automatic failover — same-model fallback across the configured chain on 429/5xx errors or network failures
- Circuit breaker — after 3 consecutive failures, provider enters 60s cooldown; auto-recovery on half-open probe success
- OpenAI ↔ Anthropic — transparently converts between chat completions and messages APIs
- Custom User-Agent — set a custom User-Agent string (e.g.
Codex/1.0) to pass client checks from upstream channels
🏗️ Architecture
pi-switch/
├── bin/pi-switch.js # CLI entry point
├── index.js # ESM wrapper for native addon
├── pi-switch-native.cjs # NAPI loader (auto platform detection)
├── src-rust/ # Rust native core (napi-rs)
│ ├── lib.rs # NAPI function exports
│ ├── config.rs # Config load/save, types
│ ├── ops.rs # Core operations
│ ├── presets.rs # Built-in provider presets
│ ├── proxy.rs # Proxy server (gateway routing, failover, circuit breaker)
│ ├── daemon.rs # Daemon lifecycle
│ ├── stats.rs # Request log aggregation
│ ├── sync.rs # Encrypted export/import
│ └── tui/ # Interactive terminal UI (ratatui)
│ ├── app.rs # State machine + key handler
│ ├── form.rs # Provider form state
│ ├── i18n.rs # Bilingual (EN/ZH)
│ └── ui/ # Rendering (chrome, pages, overlays)
├── src/ # JavaScript layer (pi extension support)
├── extensions/index.ts # Pi agent extension (/piswitch)
└── Cargo.toml
Config files:
~/.pi-switch/config.json— profiles, proxy settings, failover chain~/.pi-switch/backups/— timestamped auto-backups on every mutation~/.pi/agent/models.json— pi's provider registry (pi-switch writes a single gateway provider)
❓ FAQ
In pi, open /model and pick any advertised profile/model (e.g. provider-a/gpt-5.4). The proxy routes by the model name in each request — no extra step needed.
To add more models, expose them in TUI (Profiles → select provider → x) or via CLI:
pi-switch provider expose <name> <model-id>...
In TUI: Settings → Failover → Enter → enter comma-separated profile names → Enter.
Or via CLI:
pi-switch proxy failover provider-b,provider-c
Profiles in the failover chain that expose the same model are tried in order when the primary fails.
The [proxy] badge indicates this profile is a meta-profile (with "proxy": true). Proxy profiles are used to register a pi provider that points to the local gateway. They are excluded from upstream routing.
In the current gateway mode, proxy profiles are typically not needed — the proxy automatically writes a single pi-switch gateway provider to pi's models.json on startup.
The proxy advertises every exposed model as profile/realModelId under a single pi-switch provider. When pi sends a request with "model": "provider-a/gpt-5.4", the proxy:
- Splits on the first
/— profileprovider-a, real modelgpt-5.4 - Routes to the
provider-aprofile's upstream, rewritingbody.modeltogpt-5.4 - On failure (429/5xx), tries the failover chain for any other profile exposing
gpt-5.4
# 1. Expose models (per profile)
pi-switch provider expose provider-a gpt-5.4
pi-switch provider expose provider-b gpt-5.4
# 2. Set failover chain (optional)
pi-switch proxy failover provider-b
# 3. Start proxy daemon
pi-switch proxy start --daemon
In pi, select the pi-switch provider, then provider-a/gpt-5.4. The model name in each request determines the route — no "target" to manage.
Everything under ~/.pi-switch/. Pi's own registry is ~/.pi/agent/models.json. No data leaves your machine.
🛠️ Development
npm run build:native:debug # Build Rust addon (debug)
npm run build:native # Build Rust addon (release)
cargo build # Rust-only build
cargo clippy # Lint
cargo fmt # Format
cargo test --release --lib # Run unit tests
Note: Stop the TUI/daemon before npm run build:native to avoid file-lock errors on Windows.
🙏 Acknowledgments
- cc-switch — the original TUI-based profile switcher for Claude Code, which pioneered the interactive terminal UI pattern and proxy failover design
- cc-switch-cli — the CLI counterpart, providing a clean command-line interface for provider management
Thanks also to the LINUX DO community for the discussions that sparked this project.
📜 License
MIT