@rogeecn/pi-retry
v1.0.3
Published
Normalize unrecognized transient provider errors (e.g. HTTP/2 PROTOCOL_ERROR from cliproxyapi) so pi's agent-level auto-retry kicks in instead of stopping.
Downloads
850
Maintainers
Readme
@rogeecn/pi-retry
Make pi's agent-level auto-retry cover transient provider errors it doesn't recognize —
such as Go HTTP/2 PROTOCOL_ERROR failures from cliproxyapi-style relays — without
modifying pi itself. Implemented with the official pi extension mechanism, so it survives
pi upgrades.
The problem
pi decides whether to auto-retry a failed assistant turn by matching the error message
against a regex whitelist (isRetryableAssistantError): overloaded, 429/5xx,
rate limit, timeout, terminated, socket hang up, fetch failed, ... Anything that
matches none of these ends the run immediately.
A typical unmatched error (cliproxyapi → chatgpt.com backend, Go HTTP/2):
[System Error] Post "https://chatgpt.com/backend-api/codex/responses":
stream error: stream ID 1; PROTOCOL_ERROR; received from peerThis matches nothing in the whitelist, so pi stops instead of retrying.
How it works
On the message_end extension event, when a finalized assistant message has
stopReason: "error" and its errorMessage matches one of the configured patterns,
pi-retry appends a whitelist word (default terminated) to the error message. The
original text is preserved; the appended marker makes the error retryable, and pi then
retries with exponential backoff per your retry settings (retry.maxRetries,
retry.baseDelayMs, retry.maxAgentDelayMs).
Errors on pi's non-retryable blacklist (usage limit, quota exceeded, billing,
insufficient_quota, ...) still never retry — the blacklist takes precedence — so a
misconfigured pattern cannot cause paid retries.
Install
As a pi package (settings.json packages):
"packages": [
"npm:@rogeecn/pi-retry"
]Or drop the extension into ~/.pi/agent/extensions/pi-retry/ (only index.ts is needed).
Configuration
Config file resolution order:
PI_RETRY_CONFIGenvironment variable (supports~and relative paths)- Project-level
.pi/pi-retry.jsonin the current working directory (if it exists) - User-level
~/.pi/agent/pi-retry.json(default)
{
"enabled": true,
"notify": true,
"append": "terminated",
"patterns": [
"PROTOCOL_ERROR",
"stream error: stream ID"
]
}| Field | Default | Meaning |
|---|---|---|
| enabled | true | Master switch |
| notify | true | Show a UI notice when an error is normalized |
| append | "terminated" | Whitelist word appended to the error message |
| patterns | see above | Case-insensitive regexes; a match triggers normalization |
Changes take effect after /retry reload — no pi restart needed.
Commands
| Command | Action |
|---|---|
| /retry | Show status, resolved config path, and patterns |
| /retry on / /retry off | Enable/disable (persisted to the resolved config file) |
| /retry reload | Hot-reload the config file |
| /retry test <text> | Check whether an error message would be normalized |
License
MIT
