@georgebashi/pi-retry

pi extension: auto-retry transient streaming errors + /retry command

Package details

extension

Install @georgebashi/pi-retry from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@georgebashi/pi-retry
Package
@georgebashi/pi-retry
Version
0.1.1
Published
Feb 19, 2026
Downloads
38/mo · 12/wk
Author
georgebashi
License
MIT
Types
extension
Size
18.3 KB
Dependencies
0 dependencies · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-retry

A pi extension that retries failed LLM responses — automatically for transient streaming errors, manually via /retry or just pressing Enter.

Features

Auto-retry transient errors

When an LLM response fails with a transient streaming error (e.g. "aborted" from an upstream proxy/gateway), the extension automatically retries with exponential backoff:

  • Delays: 2s → 4s → 8s
  • Max attempts: 3
  • No history pollution: The failed response is invisible to the model (pi's transform-messages strips aborted/errored assistant messages). The retry trigger uses display: false so it's hidden in the TUI.

Only errors not already handled by pi's built-in retry are retried (overloaded, rate limit, 429, 5xx, etc. are left to pi). User-initiated aborts (ESC) are never auto-retried — use /retry or Enter for those.

Manual retry: /retry

Type /retry after any error or abort to re-invoke the LLM. The model starts fresh from the last user message — it never sees the failed partial response.

Manual retry: press Enter

After an error or user-initiated abort (ESC), just press Enter on an empty editor to retry. This is the fastest path for the common "oops, I shouldn't have cancelled" scenario.

This works by intercepting raw terminal input via pi's onTerminalInput hook. The Enter keypress is consumed only when all of these are true:

  • The editor is empty
  • The editor has focus (no modal/selector/overlay is open)
  • The agent is idle
  • The last response was an error or abort

Otherwise Enter behaves normally — including when a model selector, confirm dialog, session picker, or any other modal UI is displayed.

Installation

As a pi package (recommended)

pi install npm:@georgebashi/pi-retry

Or from a local checkout:

pi install /path/to/pi-retry

For development/testing

pi -e /path/to/pi-retry/index.ts

Logging

Every retry attempt is logged to ~/.pi/logs/pi-retry.jsonl with:

  • Provider, model, model ID, API type, thinking level
  • Stop reason and error message
  • Attempt number and delay
  • Working directory and session ID

Event types: retry, retry_succeeded, retry_exhausted, manual_retry.

How it works

  1. agent_end event — Checks if the last assistant message has a retryable error. If so, waits with backoff and sends a hidden sendMessage with triggerTurn: true.

  2. context event — Strips the hidden retry trigger message before the LLM sees it. The aborted assistant message is already stripped by pi's transform-messages.

  3. onTerminalInput hook — Intercepts Enter on empty editor to trigger manual retry. Consumes the keypress so it doesn't reach the editor.

  4. /retry command — Explicit retry for when you want to be deliberate about it.

  5. turn_end event — Resets the retry counter when a successful response comes through.