mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 04:01:56 +00:00
Auto-retry on transient provider errors (overloaded, rate limit, 5xx)
- Add retry logic with exponential backoff (2s, 4s, 8s) in AgentSession - Disable Anthropic SDK built-in retries (maxRetries: 0) to allow app-level handling - TUI shows retry status with Escape to cancel - RPC mode: add set_auto_retry, abort_retry commands and auto_retry_start/end events - Configurable via settings.json: retry.enabled, retry.maxRetries, retry.baseDelayMs - Exclude context overflow errors from retry (handled by compaction) fixes #157
This commit is contained in:
parent
79f5c6d22e
commit
bb445d24f1
11 changed files with 379 additions and 3 deletions
|
|
@ -102,6 +102,10 @@ export class InteractiveMode {
|
|||
private autoCompactionLoader: Loader | null = null;
|
||||
private autoCompactionEscapeHandler?: () => void;
|
||||
|
||||
// Auto-retry state
|
||||
private retryLoader: Loader | null = null;
|
||||
private retryEscapeHandler?: () => void;
|
||||
|
||||
// Hook UI state
|
||||
private hookSelector: HookSelectorComponent | null = null;
|
||||
private hookInput: HookInputComponent | null = null;
|
||||
|
|
@ -806,6 +810,46 @@ export class InteractiveMode {
|
|||
this.ui.requestRender();
|
||||
break;
|
||||
}
|
||||
|
||||
case "auto_retry_start": {
|
||||
// Set up escape to abort retry
|
||||
this.retryEscapeHandler = this.editor.onEscape;
|
||||
this.editor.onEscape = () => {
|
||||
this.session.abortRetry();
|
||||
};
|
||||
// Show retry indicator
|
||||
this.statusContainer.clear();
|
||||
const delaySeconds = Math.round(event.delayMs / 1000);
|
||||
this.retryLoader = new Loader(
|
||||
this.ui,
|
||||
(spinner) => theme.fg("warning", spinner),
|
||||
(text) => theme.fg("muted", text),
|
||||
`Retrying (${event.attempt}/${event.maxAttempts}) in ${delaySeconds}s... (esc to cancel)`,
|
||||
);
|
||||
this.statusContainer.addChild(this.retryLoader);
|
||||
this.ui.requestRender();
|
||||
break;
|
||||
}
|
||||
|
||||
case "auto_retry_end": {
|
||||
// Restore escape handler
|
||||
if (this.retryEscapeHandler) {
|
||||
this.editor.onEscape = this.retryEscapeHandler;
|
||||
this.retryEscapeHandler = undefined;
|
||||
}
|
||||
// Stop loader
|
||||
if (this.retryLoader) {
|
||||
this.retryLoader.stop();
|
||||
this.retryLoader = null;
|
||||
this.statusContainer.clear();
|
||||
}
|
||||
// Show error only on final failure (success shows normal response)
|
||||
if (!event.success) {
|
||||
this.showError(`Retry failed after ${event.attempt} attempts: ${event.finalError || "Unknown error"}`);
|
||||
}
|
||||
this.ui.requestRender();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue