omp packages

@floez-werk/piagent-realtime-provider-maxtokens0.1.4

Pi extension: clamps max_completion_tokens for OpenRouter requests to the smallest provider endpoint limit, so OpenRouter's length filter stops excluding providers.

GitHub Actions Published 6 days ago MIT ~224 downloads/mo

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.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

piagent-realtime-provider-maxtokens

npm license CI changelog

Rewrites the output limit of OpenRouter requests to the smallest limit among the model's provider endpoints, so OpenRouter stops filtering out endpoints that publish a lower limit than the catalogue maximum. Routing itself stays with OpenRouter: no provider is pinned and models.json is never touched.

Table of contents

Behavior

OpenRouter only routes a request to providers that can serve a response of the requested length. Pi sends max_completion_tokens (or max_tokens, depending on the model's compat.maxTokensField) from model.maxTokens, and for OpenRouter models that value is the model-wide maximum from the catalogue. Every endpoint with a lower output limit is therefore removed before routing.

The extension rewrites that field in the outgoing payload to the smallest output limit among the model's provider endpoints. The limit is read from OpenRouter's public model endpoints route and cached per model on disk, so a request never waits for a lookup.

Example, deepseek/deepseek-v4.1-flash (31 endpoints, catalogue maximum 943718):

before after
max_completion_tokens sent 943718 131072
endpoints OpenRouter may route to only those publishing the maximum all 31

Nothing else changes: the request keeps its provider routing object, other providers are untouched, and a failed or missing lookup falls back to the configured cap instead of blocking the request.

Status line

Text Meaning
MT:131k Limit that will be sent: the smallest output limit across the model's endpoints
MT:131k* No fresh cache entry - the fallback cap is in use while a lookup runs
MT:131k (Dig 944k) Provider that served the last response (Dig) and its own limit (944k)
MT:off The extension is disabled

The value is colour-coded by how much the request was reduced:

Band Colour setting Default
Nothing reduced, or below clampWarnPercent color white
Reduced by clampWarnPercent up to clampAlertPercent colorClamped 136 (dark yellow)
Reduced by more than clampAlertPercent colorClampedHeavy orange
Reduced by more than clampCriticalPercent colorClampedCritical #ff8080

The deviation is (value Pi would send - value sent) / value Pi would send, in percent. Colours accept palette names (white, yellow, orange, red, green, cyan, magenta, blue, gray, none), #rgb / #rrggbb, a 256-colour number, and bold: / reverse: prefixes.

The parenthetical is controlled by statusProviderLimit (on/off) and statusProviderLimitTag (show or hide the three-letter tag). It stays empty until a response reported the serving provider.

Showing the colour in pi-powerline-footer

The aggregate extension_statuses segment applies its own colour and drops these escape codes, so the status needs its own item with selfColorize: true:

"powerline": {
  "customItems": [
    { "id": "maxtokens", "statusKey": "provider-maxtokens", "position": "right",
      "hideWhenMissing": true, "excludeFromExtensionStatuses": true, "selfColorize": true }
  ]
}

excludeFromExtensionStatuses keeps the status out of the aggregate segment, so it is rendered once, with its own colour. Without Powerline the status is rendered by Pi itself and the colour always applies.

Diagnostic log

With log: true the extension appends one line per event to ~/.pi/agent/provider-maxtokens.log:

2026-10-06T23:36:08.657Z lookup.start      {"modelId":"...","url":"https://openrouter.ai/api/v1/models/.../endpoints"}
2026-10-06T23:36:08.676Z cache.expired     {"modelId":"...","cap":131072,"ageMinutes":120,"ttlMinutes":60}
2026-10-06T23:36:08.676Z request.decision  {"modelId":"...","field":"max_completion_tokens","from":943718,"cap":131072,"reduced":true}
2026-10-06T23:36:08.690Z response.provider {"modelId":"...","provider":"DigitalOcean","providerLimit":943718}
2026-10-06T23:36:08.738Z lookup.response   {"modelId":"...","status":200,"durationMs":81,"endpointCount":30,"cap":131072,"providers":{"digitalocean":943718,...}}
2026-10-06T23:36:08.738Z cache.stored      {"modelId":"...","cap":131072,"endpointCount":30}

Events: cache.hit, cache.miss, cache.expired, lookup.start, lookup.skipped, lookup.response, lookup.http-error, lookup.no-limits, lookup.failed, cache.stored, request.decision, response.provider. Logging never blocks a request, and a write that fails is ignored.

Installation

Local (development):

pi -e ./extensions/realtime-provider-maxtokens.ts

As a pi package (GitHub or npm):

pi install git:git@github.com:FloezWerk/piagent-realtime-provider-maxtokens.git
# or
pi install npm:@floez-werk/piagent-realtime-provider-maxtokens

The npm package is listed in the pi package catalog automatically (keyword pi-package).

Commands

Command Effect
/provider-maxtokens or /provider-maxtokens status State, TTL, fallback cap, log state, cache size, the selected model's cached limit, the cap in use, the value that will be sent, the serving provider with its own limit, the last clamp and the reduction count of this session
/provider-maxtokens on Rewrite outgoing payloads (persisted)
/provider-maxtokens off Leave payloads untouched (persisted)
/provider-maxtokens toggle Toggle (persisted)
/provider-maxtokens refresh Re-resolve the limits of the session's scoped OpenRouter models
/provider-maxtokens clear Drop the cache; requests use the fallback cap until the next lookup
/provider-maxtokens ttl <minutes> Cache TTL in minutes (persisted, default 60)
/provider-maxtokens cap <tokens> Fallback cap (persisted, default 131072)
/provider-maxtokens min List the configured per-model minimums
/provider-maxtokens min <model-id> Show the minimum of one model
/provider-maxtokens min <model-id> <tokens> Never send less than this for that model (persisted)
/provider-maxtokens min <model-id> none Remove the minimum (persisted)
/provider-maxtokens log on / off Write the diagnostic log (persisted, default off)

After changes in a running session: /reload.

Configuration

Settings live under the root key provider-maxtokens in Pi's shared ~/.pi/agent/settings.json and are written by the commands above:

Key Default Meaning
enabled true Rewrite the outgoing output limit
ttlMinutes 60 Age after which a cached limit is refreshed
fallbackCap 131072 Limit used when no fresh entry exists or a lookup fails
minByModel {} Per-model lower bound for the limit that is sent, keyed by model id
log false Append the diagnostic log
statusProviderLimit true Show the serving provider's own limit in the status line
statusProviderLimitTag true Include the three-letter provider tag in that parenthetical
color white Colour while nothing is reduced
colorClamped 136 Colour while the reduction is at or below clampAlertPercent
colorClampedHeavy orange Colour while the reduction is above clampAlertPercent
clampWarnPercent 1 Reduction in percent from which the warning colour applies
clampAlertPercent 10 Reduction in percent above which the heavy colour applies
colorClampedCritical #ff8080 Colour while the reduction is above clampCriticalPercent
clampCriticalPercent 50 Reduction in percent above which the critical colour applies

The per-model cache is stored in ~/.pi/agent/provider-maxtokens-cache.json, the diagnostic log in ~/.pi/agent/provider-maxtokens.log. Only the extension's own keys are written; the rest of settings.json is preserved.

Dependencies

@earendil-works/pi-ai, @earendil-works/pi-coding-agent and @earendil-works/pi-tui are bundled by pi and are therefore only declared as peerDependencies.

Changelog

Notable changes per version are documented in CHANGELOG.md. Every tagged release (vX.Y.Z) is published to npm and appears as a GitHub release with the package tarball.

0.1.4 - 2026-10-13

Fixed

  • The status line now shows the serving provider for Claude models routed through OpenRouter (Anthropic message API).

Full history and all versions: CHANGELOG.md