From 7877a1bcc931628f8c668ec0feec0917c1c31a93 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Sun, 15 Feb 2026 22:06:30 -0800 Subject: [PATCH] fix(models): retry timeout errors by default --- .../analysis/2026-02-16-codebase-audit-report.md | 1 + docs/plans/state.json | 12 ++++++++++++ src/models/retry.test.ts | 4 ++-- src/models/retry.ts | 3 --- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/plans/analysis/2026-02-16-codebase-audit-report.md b/docs/plans/analysis/2026-02-16-codebase-audit-report.md index 9fe0fdf..05bee21 100644 --- a/docs/plans/analysis/2026-02-16-codebase-audit-report.md +++ b/docs/plans/analysis/2026-02-16-codebase-audit-report.md @@ -17,6 +17,7 @@ Scope: Production-risk-first audit of bugs, code improvements, and feature oppor - ✅ F-014 addressed: `ModelRouter.setOnTierChange` now preserves existing listeners instead of replacing them, removing destructive listener-setter behavior. - ✅ F-002 addressed: `config.patch` now supports durable persistence via atomic write + backup when daemon has a concrete config path, and response includes `persisted`/`persistError` so UI can distinguish runtime-only vs disk-persisted updates. - ◑ F-003 partially addressed: tool execution now has an `AbortSignal` contract and executor triggers abort on timeout; host `shell.exec` and sandbox docker exec now respond to cancellation. Additional high-risk tools still need explicit cancellation coverage for full closure. +- ✅ F-015 addressed: retry defaults no longer classify timeout-style failures as non-retryable, improving resilience for transient timeout conditions. ## Executive Summary diff --git a/docs/plans/state.json b/docs/plans/state.json index ec6c6c6..15da73d 100644 --- a/docs/plans/state.json +++ b/docs/plans/state.json @@ -2565,6 +2565,18 @@ "docs/plans/analysis/2026-02-16-codebase-audit-report.md" ], "test_status": "pnpm test:run src/tools/executor.test.ts src/tools/builtin/shell.test.ts + pnpm typecheck passing" + }, + "audit-followup-retry-timeout-defaults": { + "status": "completed", + "date": "2026-02-16", + "updated": "2026-02-16", + "summary": "Adjusted retry defaults so timeout-style errors are treated as retryable by default, improving resilience for transient provider/network timeouts.", + "files_modified": [ + "src/models/retry.ts", + "src/models/retry.test.ts", + "docs/plans/analysis/2026-02-16-codebase-audit-report.md" + ], + "test_status": "pnpm test:run src/models/retry.test.ts + pnpm typecheck passing" } }, "overall_progress": { diff --git a/src/models/retry.test.ts b/src/models/retry.test.ts index 85f5a79..ee958b8 100644 --- a/src/models/retry.test.ts +++ b/src/models/retry.test.ts @@ -8,9 +8,9 @@ describe('isRetryable', () => { expect(isRetryable(error, DEFAULT_RETRY_CONFIG.nonRetryablePatterns)).toBe(true); }); - it('returns false for timeout errors', () => { + it('returns true for timeout errors (transient)', () => { const error = new Error('Request timed out after 20000ms'); - expect(isRetryable(error, DEFAULT_RETRY_CONFIG.nonRetryablePatterns)).toBe(false); + expect(isRetryable(error, DEFAULT_RETRY_CONFIG.nonRetryablePatterns)).toBe(true); }); it('returns false for authentication errors', () => { diff --git a/src/models/retry.ts b/src/models/retry.ts index cb69d7d..5fc2fbc 100644 --- a/src/models/retry.ts +++ b/src/models/retry.ts @@ -26,9 +26,6 @@ export const DEFAULT_RETRY_CONFIG: RetryConfig = { 'context_length_exceeded', 'content_policy', 'does not support', - 'timeout', - 'timed out', - 'request aborted', ], };