If you’ve ever stared at a long list of AI models and thought which one do I pick for this?, this guide is for you.
Start here for the product story: Trash Panda auto-router: what it is and how to run it
Code (public): github.com/jkhall316/trashpanda-router
Trash Panda can choose a model for you while you chat—via a small Docker Desktop app called the router. You point your chat client at it once. You do not need to stop and run PowerShell every time.
The one-sentence idea (for most people)
Run the Trash Panda router container → point your chat app at http://localhost:9999/v1 → use model trashpanda/auto → just chat.
Behind the scenes the router:
- Classifies your message into a job (plan / build / research / chat / create)
- Looks up how much you’re willing to pay for that job (cloud $/M — coding can be higher than chat)
- Contests your installed local models vs affordable cloud models as equals (cloud wins only if better)
- Forwards the chat to Ollama, OpenRouter, or Hugging Face Inference
You stay in the chat window. Optional overrides: /TPCoding, /TPPlan, /TPChat, /TPResearch, /TPCreate (clear with /TPAuto).
Easiest path: Docker router (recommended)
What you need
- Docker Desktop
- Ollama on your PC (for local models) — optional if you only use cloud keys
- Optional keys in a
.envfile:OPENROUTER_API_KEYand/orHF_TOKEN
Start the router
Public install (recommended):
git clone https://github.com/jkhall316/trashpanda-router.git
cd trashpanda-router
copy .env.example .env
docker compose up -d --build
# Then open http://localhost:9999/admin — set VRAM, budget, keys
Full walkthrough + harness wiring: trashpanda-router README · site guide: auto-router 101.
Point your chat app
| Setting | Value |
|---|---|
| Base URL | http://localhost:9999/v1 |
| API key | anything (e.g. sk-local) |
| Model | trashpanda/auto |
Also:
trashpanda/local— force Ollamatrashpanda/cloud— force OpenRouter / Hugging Face
That’s it. Chat normally. Check X-Trashpanda-Job / X-Trashpanda-Route if you want to see which job and backend won.
How the pieces fit
Your chat app
→ Trash Panda router (Docker, localhost:9999)
→ recommend API (trashpandatools.com)
→ then Ollama and/or OpenRouter and/or Hugging Face Inference
Hugging Face here means live Inference (chat), not “only download files.” Ollama may still pull weights that came from Hugging Face.
Prefer buttons instead?
Totally fine — no Docker required:
- Cloud / app menus → Pick a model
- Home GPU / Mac → Local LLM picker
- Browse options → Model directory
Those pages use the same ranking brain. They recommend; you still copy the pick into Cursor or Ollama yourself.
What this is not
| Myth | Reality |
|---|---|
| “Trash Panda hosts every model in the cloud for free.” | No. Your Ollama / OpenRouter / HF account runs the model. |
| “I must use PowerShell every time.” | No. PowerShell is only for debugging the recommend API. |
| “The router replaces Cursor.” | No. Cursor (or Open WebUI, etc.) stays your chat UI — it just talks to the router. |
Advanced: call the recommend API directly (debug)
Use this when you’re testing picks without chatting—or writing an agent that only needs advice.
Don’t use curl with hand-escaped quotes on PowerShell — Windows often mangles the JSON. Use:
# Fair contest (same mode the Docker router uses)
$body = @{
job = "build"
selection = "contest"
maxBlendedUsdPerMillion = 15
prefer = @("local", "cloud")
platform = "openrouter"
hardware = @{ host = "x86"; vramGb = 24 }
installedLocalTags = @("qwen3.5:27b", "gemma4:latest")
limit = 3
} | ConvertTo-Json -Depth 5
$r = Invoke-RestMethod `
-Method POST `
-Uri "https://trashpandatools.com/api/v1/recommend" `
-ContentType "application/json" `
-Body $body
"Winner : $($r.primary.name) [$($r.primary.source)]"
"Why : $($r.contest.reason)"
"Local best : $($r.contest.localBest.name)"
"Cloud best : $($r.contest.cloudBest.name)"
Useful fields: primary, contest, bySource.local / bySource.cloud, pullCommand.
Request fields (same ones the router uses)
| Field | Meaning |
|---|---|
job | plan | build | research | chat | create |
selection | contest (fair) or prefer (ordered) |
maxBlendedUsdPerMillion | Cloud $/M cap for this job (0.35×in + 0.65×out) |
installedLocalTags | Ollama tags already on your machine |
prefer | Allow-list of sources (local / cloud); order ignored in contest |
platform | e.g. cursor, openrouter |
hardware.host | x86 | spark | mac |
hardware.vramGb | Max local VRAM (0 = any) |
budget | 0–100 cost index — prefer mode only |
Live endpoints:
POST https://trashpandatools.com/api/v1/recommendGET https://trashpandatools.com/api/healthGET https://trashpandatools.com/api/v1/models
Common snags
“I got invalid_json in PowerShell.”
Use Invoke-RestMethod as above — or skip PowerShell and use the Docker router.
“Router says no cloud backend.”
Set OPENROUTER_API_KEY and/or HF_TOKEN in .env, or set PREFER=local and run Ollama.
“Ollama model not found.”
With OLLAMA_AUTO_PULL=true the router tries to pull. Or run the pullCommand from a recommend response yourself.
“Cursor didn’t change by itself.”
Point Cursor (or your client) at the router base URL with model trashpanda/auto. Changing only the Cursor dropdown without the router does not call Trash Panda.
Next step
docker compose up -d --buildin the router folder- Point your chat app at
http://localhost:9999/v1· modeltrashpanda/auto - Ask it to help with something real
- Peek at
X-Trashpanda-Routeif you’re curious what it chose
That’s the 101: chat through the router, let Trash Panda pick, keep working.