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

pi-bedrouter

v0.6.0

Published

Pi extension for bedrouter: starts the cost-aware Bedrock model router, registers it as a provider, and shows which model served each request

Readme

pi-bedrouter

A Pi extension for bedrouter, the cost-aware model router in front of AWS Bedrock. It makes the router a first-class part of a Pi session:

  • finds bedrouter (a configured checkout, or the npm dependency this package ships with) and installs or builds it when it is missing
  • starts the server when it is not already running, seeding .env and bedrouter.json from bedrouter's examples on first run
  • registers a bedrouter provider in Pi whose models come straight from bedrouter.json: one auto model plus each enabled rung in the stack
  • switches the session to bedrouter/auto when the server is healthy, so nobody has to pick a model
  • shows what served each request in the footer, live: routed model vs requested, class and deciding signal, the classifier's note, and the session's running cost against what the requested model would have cost
  • totals the whole session: every request carries Pi's session id (x-bedrouter-session), so bedrouter can add up the session across conversation keys, compaction and sub-agent calls; /bedrouter usage shows spend, what the asked-for model would have cost, and the breakdown by route
  • /bedrouter for everything else: status, start/stop/restart, doctor and the per-rung entitlement probe, the savings report, the last N decisions, pi-agents fit notes
⇄ gpt-oss-120b ≠ gpt-oss-20b  explore·clf:explore  $0.0412 saved $0.0188 (31%)  ↑1

Install

pi install npm:pi-bedrouter          # once published
# or, from a checkout:
pi install /path/to/pi-bedrouter     # or add the path to "packages" in ~/.pi/agent/settings.json

The package depends on bedrouter (a git dependency with a build step), so npm install inside it produces a runnable bedrouter binary. If you already have a bedrouter checkout you'd rather use, point at it (below) and the dependency is ignored.

Bedrouter needs AWS credentials that can call Bedrock; see its README for the aws sso login recipe. pi-bedrouter does not touch credentials, it just starts the server in a directory that has a .env.

Settings

~/.pi/agent/pi-bedrouter.json (all optional; /bedrouter config creates it with defaults):

| Key | Default | Meaning | | --- | --- | --- | | path | the bedrouter dependency | A bedrouter checkout or install to use instead | | home | path if set, else ~/.bedrouter | Working directory for the server: .env, bedrouter.json, bedrouter.log.jsonl, server.log | | port | 20129 | Port to run / expect the server on (BEDROUTER_PORT overrides) | | autoStart | true | Start the server on session start when it is not running | | autoSelect | "auto" | Model id to select when no higher-precedence choice exists ("auto", a rung alias, or false to leave the model alone) | | debug | false | Start the server with BEDROUTER_DEBUG=1 (per-request trace in server.log) | | footer | true | Show the routing status line in Pi's footer | | providerName | "bedrouter" | Provider name registered in Pi | | stopOnExit | "if-started-here" | What happens to the server when Pi quits (/reload and session switches never stop it). if-started-here: stop it if this session started it and no other client sent a request in the last 5 minutes; always: stop it whenever this session started it; never: leave it running. Pi tears down its UI before extensions are told about the quit, so this cannot be a prompt; the policy is shown when the server is started and in /bedrouter status | | healthPollS | 15 | Seconds between background health checks. A dead server flips the footer to bedrouter: DOWN and, with autoStart, is restarted (at most once a minute); 0 disables the poll |

Example for a developer with a checkout:

{ "path": "~/projects/ai/bedrouter", "autoSelect": "auto" }

Automatic selection applies only when the session did not name a provider or model and Pi's defaultProvider is absent or bedrouter. An explicit --provider/--model choice or a different defaultProvider leaves the session on that provider and does not start the bedrouter server. Set PI_BEDROUTER_AUTOSELECT=0 to disable automatic startup and selection for one process. The provider remains registered, so /model, --list-models, and a later switch to bedrouter/* still work; switching later starts the server when autoStart is enabled.

Commands

| Command | Does | | --- | --- | | /bedrouter or /bedrouter status | Install location, server health (pid, version, region, classifier), registered models, current model, last decision | | /bedrouter start / stop / restart | Manage the server. It is shared by every Pi session, so stop affects all of them; see stopOnExit for what happens when Pi quits | | /bedrouter install | npm install the dependency, or npm run build a checkout that has no dist/ | | /bedrouter doctor | Which credential source resolved, expiry, and the loaded stack | | /bedrouter probe | One 1-token request per rung: which models this AWS account can actually invoke | | /bedrouter usage | This Pi session so far: requests, tokens, spend (models + classifier), what the asked-for model would have cost, saved/over, and a per-route table. Whole-session totals need bedrouter ≥ 0.3; against an older server it shows the current conversation and says so. usage all lists recent sessions on the server (* marks this one) | | /bedrouter report [--since t] [--session key] [--json] | Savings report over the decision log (all clients, all sessions; --session narrows it to one) | | /bedrouter log [n] | The last n routing decisions, one line each | | /bedrouter models | Re-read bedrouter.json and re-register the provider (after editing the stack) | | /bedrouter fitnotes | Merge model notes into ~/.pi/agent/workflows.json so the pi-agents planner defaults to bedrouter/auto and only pins premium rungs for planning/review | | /bedrouter config | Show (and create) the settings file |

How the footer works

Bedrouter echoes every routing decision in response headers (x-bedrouter-model, -requested, -class, -reason, -conversation, -classifier). Pi hands extensions those headers in the after_provider_response event, so the status line updates the moment a response starts, before any tokens stream. When the turn ends, the extension asks bedrouter for the session's running totals (GET /v1/sessions/:id, keyed by the Pi session id the extension sends on every request as x-bedrouter-session; on a bedrouter older than 0.3 it falls back to the current conversation, GET /v1/conversations/:key) and appends cost: spend so far, then the routing effect against what the same tokens would have cost on the model the client asked for: saved $x (n%), same as asked-for, or +$x over asked-for (routed up) when the router chose a stronger rung. The classifier's one-off call is shown separately (classifier $0.0004) rather than counted against routing. ↑n counts escalations in this session. The line clears when you switch to a non-bedrouter model. A background health check (every healthPollS seconds) keeps it honest between turns: if the server dies the line reads bedrouter: DOWN and, with autoStart on, the extension restarts it and says so.

Under a coding agent every request carries tools and a large system prompt, so you will see execute and explore decided by keywords or the classifier, then sticky for the rest of the session, up:kw:explore when an explicit design question moves the conversation up, and escalations after failures. trivial shows up for bare chat clients, not for Pi.

Model ids

auto hands the whole choice to bedrouter's ordered, capability-filtered stack. Every enabled rung is also registered for explicit pinning. Pi reads each model's API, input modes, context window, output cap, and price from the capability block returned by /v1/models; bedrouter's log and /bedrouter report record what was actually charged.

If your ~/.pi/agent/settings.json has an enabledModels allowlist, add bedrouter/auto (and any rungs you want visible) or the provider's models will be hidden.

Development

npm install
npm run typecheck
npm test                                        # pure tests
BEDROUTER_TEST_PATH=~/projects/ai/bedrouter npm test   # also exercises locate/start against a built checkout

Layout: extensions/index.ts (the extension: events, provider registration, /bedrouter), src/bedrouter.ts (locate/install/start/stop/health/run), src/models.ts (config → Pi models, fit notes), src/footer.ts (headers → status line), src/settings.ts.

Publishing

Both packages are on npm: bedrouter (the server, with the bedrouter binary) and pi-bedrouter (this extension, which depends on it). The pi-package keyword makes the extension discoverable at pi.dev/packages. Release order when both change: publish bedrouter first, bump the dependency range here, then publish pi-bedrouter.