Browse Source

docs: remove stale 429 fallback spec

Michael Henke 1 month ago
parent
commit
554ea72fe1
1 changed files with 0 additions and 104 deletions
  1. 0 104
      docs/superpowers/specs/2026-07-05-delegate-task-429-fallback.md

+ 0 - 104
docs/superpowers/specs/2026-07-05-delegate-task-429-fallback.md

@@ -1,104 +0,0 @@
-# Delegate Task 429 Retry + Fallback
-
-## Problem
-
-When the orchestrator delegates to a subagent via the `task` tool, the spawned
-session can receive `429 Too Many Requests`. OpenCode internally retries
-(because `ApiError.isRetryable` is `true` for 429), emitting `session.status`
-events with `type: "retry"`. With no limit on internal retries and no model
-swap, the session freezes indefinitely.
-
-The existing `ForegroundFallbackManager` already handles events from ALL
-sessions (foreground + subagent), but:
-
-1. It was **disabled** when `runtimeChains` was empty (no model arrays
-   configured) — even though it could still abort sessions on exhaustion.
-2. It immediately aborted on the first 429 — no backoff letting OpenCode's
-   internal retry handle transient spikes.
-3. When chain was empty, it returned silently instead of aborting — leaving
-   the session to freeze.
-
-## Strategy
-
-**Retry with backoff, then intervene.** When a session hits 429:
-
-1. If OpenCode is retrying internally (`status.type === "retry"`), let it —
-   track the retry count from the `attempt` field in the `session.status`
-   event.
-2. After `maxRetries` consecutive 429s, intervene: abort the current prompt
-   and swap to the next model in the fallback chain (via `promptAsync`).
-3. If no fallback chain is configured, just abort — stops the freeze, surfaces
-   error to the orchestrator.
-
-This works for both foreground and subagent sessions because:
-
-- `promptAsync` is a real SDK endpoint (`POST /session/{id}/prompt_async`,
-  verified in `@opencode-ai/sdk` types) and works on any session.
-- The ForegroundFallbackManager already processes events from all sessions.
-- Subagent and foreground both emit the same `session.status` events.
-
-## Implementation
-
-### Files Changed
-
-| File | Change |
-|------|--------|
-| `src/config/schema.ts` | Add `maxRetries` to `FailoverConfigSchema` (default: 3) |
-| `src/hooks/foreground-fallback/index.ts` | Add `maxRetries` constructor param, `sessionRetries` tracking map, retry tracking in `session.status` handler, abort-on-chain-exhaustion in `tryFallback` |
-| `src/index.ts` | Enable manager without `runtimeChains`, pass `config.fallback?.maxRetries` |
-
-### Config Schema
-
-```typescript
-// In FailoverConfigSchema (src/config/schema.ts)
-export const FailoverConfigSchema = z.object({
-  enabled: z.boolean().default(true),
-  timeoutMs: z.number().min(0).default(15000),
-  retryDelayMs: z.number().min(0).default(500),
-  maxRetries: z.number().int().min(0).default(3).describe(
-    'Number of consecutive 429/rate-limit responses tolerated on the ' +
-    'same model before aborting (or swapping to the next fallback ' +
-    'model when a chain is configured).',
-  ),
-  retry_on_empty: z.boolean().default(true),
-}).strict();
-```
-
-### ForegroundFallbackManager Changes
-
-1. **`sessionRetries` map** — tracks consecutive 429s per session, reset on
-   model swap or session deletion.
-
-2. **`session.status` handler** — when `status.type === "retry"` and the
-   message matches rate-limit keywords, increments the retry counter instead
-   of immediately falling back. Only intervenes after `maxRetries - 1`
-   internal retries.
-
-3. **`tryFallback` chain-exhaustion path** — when `resolveChain` returns empty
-   (no fallback models configured), calls `abortSessionWithTimeout` instead of
-   returning silently. This stops OpenCode's infinite retry loop.
-
-4. **`session.deleted` handler** — cleans up `sessionRetries` entry.
-
-### Usage
-
-```jsonc
-// ~/.config/opencode/oh-my-opencode-slim.jsonc
-{
-  "fallback": {
-    "enabled": true,        // default: true
-    "maxRetries": 3,         // default: 3 — let 3 internal retries, then intervene
-    "retryDelayMs": 500      // base delay for OpenCode's internal backoff
-  },
-  "agents": {
-    "explorer": {
-      "model": ["openai/gpt-4o", "anthropic/claude-sonnet-4"] // fallback chain
-    }
-  }
-}
-```
-
-## Verification
-
-All 1350 existing tests pass. No new files added — only 3 existing files
-modified.