Skip to content

About

A Pi extension that exposes stable alias/* role models backed by configurable provider/model chains.

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Repository files navigation

Pi Model Fallback Aliases

npm version npm downloads CI codecov Node.js License

A Pi extension that exposes stable alias/* role models backed by configurable provider/model chains. It adds pre-output failover, shared cooldowns, latency controls, footer status, and durable transcript warnings without owning target-provider credentials.

Install

Requires Node 22.19 or newer and Pi. Development and validation use @earendil-works/pi-ai 0.84.4, @earendil-works/pi-coding-agent 0.84.4, and @earendil-works/pi-tui 0.85.1.

pi install npm:pi-model-fallback-alias

Run /reload in a live session after installation or changes to $settings or alias definitions, including target chains.

Configuration

Aliases live in <agent-dir>/model-alias.json, normally ~/.pi/agent/model-alias.json. Set PI_MODEL_ALIAS_MAP to use another file.

{
  "$settings": {
    "statusRefreshMs": 2000
  },
  "$defaults": {
    "timeouts": {
      "firstEventMs": 30000,
      "stallMs": 60000,
      "commitMs": 90000
    },
    "cooldown": { "baseMs": 300000, "capMs": 3600000, "resetSuccesses": 3 }
  },
  "coder": [
    "provider-a/model-primary",
    "alias/fallback"
  ],
  "fallback": [
    "provider-b/model-secondary",
    "provider-c/model-tertiary"
  ]
}

Each key registers alias/<key> as a Pi model. A value can be a model string, an ordered array, or an object with targets, timeouts, and cooldown.

timeouts applies while another target remains:

  • firstEventMs is the maximum wait for the first stream event.
  • stallMs is the maximum gap between pre-commit stream events.
  • commitMs is the maximum total time before output commits.

cooldown.baseMs defaults to 5 minutes, cooldown.capMs defaults to 1 hour, and cooldown.resetSuccesses defaults to 1 successful terminal stream before clearing a target's cooldown state. $defaults.cooldownResetSuccesses is a legacy, defaults-only shorthand for $defaults.cooldown.resetSuccesses; set one or the other, not both.

Set $settings.statusRefreshMs to control how often the footer rechecks shared cooldown state. It defaults to 2000 milliseconds and must be an integer from 1 to 60000. Invalid settings warn and use the default without disabling aliases. $settings and alias definitions, including target chains, load on /reload. Model selection and failover refresh the footer immediately. Timeout and cooldown policy fields are re-read at the start of each stream; if the current map is invalid, the alias uses its last valid policy and emits a warning.

Nested aliases are flattened at load time. Loops are allowed and collapse during expansion. Duplicate concrete targets keep their first position in each flattened chain. A loop with no reachable concrete target produces an unusable empty chain. Missing aliases skip only the invalid reference and produce a warning. Other top-level keys prefixed with $, such as $comment, are treated as metadata and ignored.

Use an alias anywhere Pi accepts a model reference:

{
  "defaultProvider": "alias",
  "defaultModel": "coder"
}

Behavior

  • Failover advances on resolution, authentication, connection, and HTTP errors until output commits. It never swaps providers after text or tool output is visible.
  • Start and thinking events are buffered before commit, so a failed attempt cannot leave partial protocol state behind.
  • Failed concrete targets enter an exponential cooldown. State is shared by aliases and Pi processes. Cooled targets are skipped while alternatives remain and retried before final exhaustion.
  • Per-role latency limits can cover time to first event, event stalls, and the total pre-commit interval. A timeout is active only while another target remains.
  • The alias model mirrors the selected target's context window, output limit, and cost. Assistant messages preserve the logical alias identity while responseModel records the concrete model.
  • /model-alias-reset-cooldown clears shared cooldown state.
  • /model-alias-targets [role] renders all flattened fallback chains, or one selected role, in the transcript.
  • /model-alias-latency-report [role] renders attempt statistics in the transcript.

State and logs

Runtime state is outside the installed package. The default directory is:

<agent-dir>/state/pi-model-fallback-alias/

Set PI_MODEL_ALIAS_STATE_DIR to an absolute or relative path to override it. The directory contains:

  • cooldown-state.json, atomically replaced and reloaded by modification time.
  • pi-model-alias-debug.jsonl, a rotating troubleshooting and latency log.

The active log rotates after 1 MiB and retained archives expire after seven days. Configure positive integer overrides with PI_MODEL_ALIAS_LOG_MAX_BYTES and PI_MODEL_ALIAS_LOG_RETENTION_DAYS.

From a checkout or local package directory, run the standalone report with:

node --import ./scripts/pi-resolve.mjs scripts/latency-report.mjs [log-path ...]

The loader in scripts/pi-resolve.mjs resolves Pi packages from PI_ROOT, local node_modules, or a global Pi install.

With no arguments, the report reads the default debug log and its retained rotated files. Optional log paths replace the default and include each path's retained files.

Logs contain alias roles, target references, durations, status codes, and allowlisted request or trace identifiers. They do not record authorization headers, cookies, request payloads, response bodies, alias configuration, or provider credentials. Review logs before sharing them because model names and request identifiers can still be operationally sensitive.

Authentication and security

The extension's alias provider returns a fixed non-secret API-key value only to mark aliases available to Pi's registry. Streaming discards that value and resolves the selected target through Pi's provider registry.

When forwarding request options, target authentication replaces caller authentication. The extension removes caller authorization, x-api-key, api-key, x-goog-api-key, and anthropic-* headers. Other caller headers only fill gaps left by target authentication. This prevents credentials from one provider from crossing a failover boundary.

Pi extensions run with the Pi process's permissions. Review the source and configuration before installation. See SECURITY.md for private reporting.

Troubleshooting

  • Alias is missing: verify the map path and JSON, then run /reload.
  • Restored session cannot find an alias: restore the role, select a current model, or start a new session.
  • Footer looks stale: verify $settings.statusRefreshMs, run /reload, inspect transcript warnings, or run /model-alias-reset-cooldown.
  • Policy edit is temporarily invalid: existing aliases use their last valid policy and warn once per distinct failure. Replace configuration atomically to keep concurrent processes aligned.
  • Investigating provider failures: correlate an allowlisted request or trace identifier with the record timestamp and provider/model. No credential or response body is written to the log.

Development

npm ci
npm run check

npm run check runs the test suite under c8 with all production TypeScript files included, enforces 95% statements, lines, functions, and branches, writes text and coverage/lcov.info reports, then runs type checking and package validation. The only narrow coverage exclusion is src/fallback/types.ts, which contains TypeScript type declarations only and emits no executable JavaScript. Generated coverage output is ignored by Git. Development dependencies pin @earendil-works/pi-ai and @earendil-works/pi-coding-agent to 0.84.4, and @earendil-works/pi-tui to 0.85.1. Runtime Pi packages remain optional wildcard peer dependencies because Pi supplies them when loading the extension. Continuous integration tests Node 22.19 and Node 24.

Releases use semantic versioning. Release Please maintains the release pull request from semantic commits; merging it creates the GitHub release and publishes to npm with OpenID Connect (OIDC) provenance. Follow RELEASING.md.

Repository: https://github.com/unrelentingfox/pi-model-fallback-alias

License

MIT. See LICENSE.

About

A Pi extension that exposes stable alias/* role models backed by configurable provider/model chains.

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages