@reasoning-router/pi0.2.0
Adaptive per-step reasoning effort for the Pi coding agent
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
@reasoning-router/pi
A Pi extension that asks a classifier how much reasoning each Claude request needs and lets Pi place that effort without breaking the prompt cache. Requires Pi 1.0.0 or later and Node.js 24.x.
export REASONING_ROUTER_CLASSIFIER_API_KEY=your-jev-key
pi install npm:@reasoning-router/pi
pi --model reasoning-router/claude-opus-5-5
The * peer range on @earendil-works/pi-coding-agent does not enforce
Pi 1.0.0. An older Pi fails to load the extension because it has no
registerVirtualModel.
The extension adds a virtual model reasoning-router/<id> for each Claude
model the router knows. Each request runs on the matching anthropic/<id>
model with your existing Anthropic login or key; the router only picks its
thinking level. For these mid-conversation-effort models Pi pins
output_config.effort: "high" and states the chosen effort in an effort-only
system message, so changing effort keeps the cached prefix.
- User turns and continuations are classified. A retry reuses the failed
attempt's thinking level. Direct requests, such as compaction, use
REASONING_ROUTER_BASE_EFFORT, or the model's base effort; the variable affects only those requests, not the pinnedhighabove. - The last classified effort is stored in the session, per virtual model, so
previousfallback survives a restart. - A model that Pi lacks, or that Pi cannot give mid-conversation effort, is
rejected with
reasoning-router unsupported_model: .... In Pi 1.0.0 and 1.0.4 that includesclaude-mythos-5-1. - A classification failure in
errorfallback mode rejects the request withreasoning-router classification_failed: .... Cancelling a request never falls back. The messages carry no HTTP status codes, because Pi retries errors that look like transient provider failures. - The classifier endpoint receives the most recent user text, the most recent assistant text, and the names and output excerpts of recent tool results. System messages, thinking blocks, and tool-call arguments are not sent.
GPT-6 models (gpt-6-astra, gpt-6-sol, gpt-6-luna, gpt-6.1-sol) are
routed the same way, to openai/<id>, on a Pi release that includes
pi#10930. Pi then pins
reasoning.effort and sends the chosen effort as configuration_update
items. Older Pi rejects them with unsupported_model. They need an OpenAI API
key: Sign in with ChatGPT is rejected with unsupported_model, because Pi
then changes the request's effort and misses the cache. A none decision on
gpt-6-luna or gpt-6-sol is also sent as request-level effort and misses
the cache. openai-codex models are not routed.
Environment
The extension reads the proxy's variables on the first routed request, not
when Pi loads it. The virtual models are always listed. A missing classifier
key, a legacy variable such as TYPESAFE_API_KEY, or another invalid value
fails that request with reasoning-router invalid_config: ...; Pi keeps
running, and the next request reads the variables again until they are valid.
| Variable | Default | Purpose |
|---|---|---|
REASONING_ROUTER_CLASSIFIER |
jev |
Classifier provider name, such as jev (see classifiers). |
REASONING_ROUTER_CLASSIFIER_API_KEY |
none | Classifier credential, if the provider needs one. |
REASONING_ROUTER_CLASSIFIER_BASE_URL |
provider default | Classifier endpoint; defaults to the provider's. |
REASONING_ROUTER_CLASSIFIER_ACCOUNT_ID |
none | Account ID, for providers that take one. |
REASONING_ROUTER_CLASSIFIER_MODEL |
none | Classifier model, for providers that take one. |
REASONING_ROUTER_CLASSIFICATION_TIMEOUT_MS |
4000 |
Total classification budget, including retries. |
REASONING_ROUTER_MAX_RETRIES |
1 |
Classifier retries after a retryable error (0–10). |
REASONING_ROUTER_FALLBACK_MODE |
fixed |
On failure: fixed, previous (last classified effort, else fixed), or error. |
REASONING_ROUTER_FALLBACK_EFFORT |
high |
Effort for fixed fallback. |
REASONING_ROUTER_BASE_EFFORT |
model default | Effort for direct requests. |
REASONING_ROUTER_DECISIONS_LOG_PATH |
none | Absolute path for a JSONL log of decisions. |
See docs/environment.md for the classifier
credentials. The decision log holds metadata only: model, effort, classifier
latency and attempts, fallback, token usage including cache reads, and
outcome, with no prompt text or credentials.