@bytonylee/free-router
v1.2.1
Published
Free model router — discover, ping, and configure free AI models for OpenCode / OpenClaw
Maintainers
Readme
Free model router CLI - discover, ping, and configure free AI models for OpenCode / OpenClaw.

Install
npx @bytonylee/free-router
# or
npm i -g @bytonylee/free-router
# or
bunx @bytonylee/free-router
# or
bun install -g @bytonylee/free-routerRun
free-routerOn first run, a setup wizard prompts for API keys (ESC to skip any provider).
If you accept the in-app update prompt (Y), free-router now updates globally and
restarts automatically, so you can continue without running free-router again.
Ways to use free-router
- First-run onboarding wizard
Launch
free-router, open provider websites in-browser from the wizard, paste keys, and start. - Interactive model search + launch
Use
/to filter models, thenEnterto update OpenCode config and openopencode. - Quick API key rescue from main screen
Press
A(orRfor expired/missing provider) to jump into key editing with auto browser opening for missing keys. - Full settings workflow
Press
Pto edit keys, toggle providers, run live key tests, and onboard missing keys provider-by-provider. - Non-interactive best-model selection
Run
free-router --bestto print the best responding model ID for scripts.
Providers
| Provider | Free key |
| -------------- | ------------------------------------------------------------------------------------ |
| NVIDIA NIM | build.nvidia.com - prefix nvapi- |
| OpenRouter | openrouter.ai/settings/keys - prefix sk-or- |
API key priority: environment variable → ~/.free-router.json → keyless ping (latency still shown).
NVIDIA_API_KEY=nvapi-xxx free-router
OPENROUTER_API_KEY=sk-or-xxx free-router
# Optional: pause auto re-sorting while you scroll (milliseconds)
FREE_ROUTER_SCROLL_SORT_PAUSE_MS=2500 free-router
# Optional: disable rolling metrics cache and force legacy recompute path
FREE_ROUTER_METRICS_CACHE=0 free-routerTUI
The interactive TUI pings all models in parallel every 2 seconds and shows live latency, uptime, and verdict. The selected row uses a stable marker, and redraws are deferred while the terminal is unfocused to avoid background-tab blinking.
Columns
| Column | Description |
| ---------- | -------------------------------------------------------------- |
| # | Rank |
| Tier | Capability tier derived from SWE-bench score (S+ → C) |
| Provider | NIM or OpenRouter |
| Model | Display name |
| Ctx | Context window size |
| AA | Arena Elo / intelligence score |
| Avg | Rolling average latency (HTTP 200 only) |
| Lat | Latest measured ping latency |
| Up% | Uptime percentage this session |
| Verdict | Condition summary (✓ Perfect / ✓ Normal / x Overloaded / …) |
Default ranking: availability first, then higher tier first (S+ → S → A+ …), then lower latency.
Search bar provider badges:
Name:✓key exists and looks healthyName:✗provider appears expired/no-authName:○key missing
The ? help overlay and A API-key editor use the same terminal header/footer
chrome as the main list. Their mode tags stay left-aligned, and help body text
uses the same foreground color as the table rows.
Keyboard shortcuts
Navigation
| Key | Action |
| --------------- | -------------- |
| ↑ / k | Move up |
| ↓ / j | Move down |
| PgUp / PgDn | Page up / down |
| g | Jump to top |
| G | Jump to bottom |
Actions
| Key | Action |
| -------------- | ---------------------------------------------------------- |
| Enter | Save config + open current model in opencode |
| / | Search / filter models (Enter in search = open opencode) |
| A | Quick API key add/change (opens key editor in Settings) |
| R | Edit API key for likely expired/missing provider |
| T | Cycle tier filter: All → S+ → S → A+ → … |
| P | Settings screen (edit keys, toggle providers, test) |
| W / X | Faster / slower ping interval |
| ? | Help overlay |
| q / Ctrl+C | Quit |
Sort (press to sort, press again to reverse)
| Key | Column |
| --- | ------------------ |
| 0 | Priority (default) |
| 1 | Tier |
| 2 | Provider |
| 3 | Model name |
| 4 | Avg latency |
| 5 | Latest ping |
| 6 | Uptime % |
| 7 | Context window |
| 8 | Verdict |
| 9 | AA Intelligence |
OpenCode handoff
Pressing Enter on a model writes the OpenCode config and immediately opens opencode.
If OpenCode fallback remaps the provider (for example NIM Stepfun → OpenRouter)
and the effective provider key is missing, free-router asks:
Add API key now? (Y/n, default: Y).
If model metadata says the selected model is unsupported by the known target
support list, free-router falls back to NVIDIA NIM deepseek-ai/deepseek-v4-pro
as the default high-performance model.
Configs written:
- OpenCode CLI →
~/.config/opencode/opencode.json - OpenClaw →
~/.openclaw/openclaw.json
Existing configs are backed up before writing.
When free-router launches OpenCode, it now sets OPENCODE_CLI_RUN_MODE=true
by default (unless you already set it) to reduce startup log noise from
plugin auto-update checks in the OpenCode TUI.
If you want OpenCode's default startup hook behavior instead, launch free-router with:
OPENCODE_CLI_RUN_MODE=false free-routerSettings screen (P)
Tip: press A from the main list to jump directly into API key editing.
Tip: if a selected provider has no key, free-router auto-opens that provider key page
in browser (once per provider per settings session), including when you move selection.
| Key | Action |
| --------------------- | ---------------------------------- |
| ↑ / ↓ / j / k | Navigate providers |
| Enter | Edit API key inline |
| Space | Toggle provider enabled / disabled |
| T | Fire a live test ping |
| D | Delete key for this provider |
| ESC | Back to main list |
Flags
| Flag | Behavior |
| --------------- | ------------------------------------------------------------- |
| (none) | Interactive TUI |
| --best | Non-interactive: ping 4 rounds, print best model ID to stdout |
| --help / -h | Show help |
--best scripted usage
# Print best model ID after ~10 s analysis
free-router --best
# Capture in a variable
MODEL=$(free-router --best)
echo "Best model: $MODEL"Requires at least one API key to be configured. Selection tri-key sort: status=up → lowest avg latency → highest uptime.
Config
Stored at ~/.free-router.json (permissions 0600).
{
"apiKeys": {
"nvidia": "nvapi-xxx",
"openrouter": "sk-or-xxx"
},
"providers": {
"nvidia": { "enabled": true },
"openrouter": { "enabled": true }
},
"ui": {
"scrollSortPauseMs": 1500
}
}ui.scrollSortPauseMs sets how long (ms) auto re-sorting stays paused after navigation input.
FREE_ROUTER_SCROLL_SORT_PAUSE_MS overrides config. Set to 0 to disable pause.
Tier scale (SWE-bench Verified)
| Tier | Score | Description | | ------ | ------ | ------------------ | | S+ | ≥ 70% | Elite frontier | | S | 60–70% | Excellent | | A+ | 50–60% | Great | | A | 40–50% | Good | | A- | 35–40% | Decent | | B+ | 30–35% | Average | | B | 20–30% | Below average | | C | < 20% | Lightweight / edge |
Verdict legend
| Verdict | Trigger | | ------------ | ------------------------- | | x Overloaded | Last HTTP code = 429 | | x Unstable | Was up, now failing | | x Not Active | Never responded | | - Pending | Waiting for first success | | ✓ Perfect | Avg < 400 ms | | ✓ Normal | Avg < 1000 ms | | x Slow | Avg < 3000 ms | | x Very Slow | Avg < 5000 ms | | x Unusable | Avg ≥ 5000 ms |
Development notes
- TypeScript source of truth:
src/ - ESLint config is TypeScript:
eslint.config.ts - Runtime JS output is generated only in
dist/vianpm run build
License
MIT License. See LICENSE.
