fix(pets): raise generation timeouts for the slow quality-first model path

The quality-first default (OpenAI image via OpenRouter) is slow, and a full
hatch fans out ~8 rows with up to 3 retries each (300s/call) across 2 parallel
waves, so the absolute backend worst case is ~30 min. The old ceilings fired
mid-run:

- per-image HTTP call: 180s -> 300s (a single cold row can exceed 3 min)
- drafts RPC: 240s -> 420s (single wave, no retries — 7 min is ample)
- hatch RPC: 420s -> 1hr (sits above the ~30 min backend worst case)

The hatch ceiling is intentionally well above the realistic max so the frontend
never throws "request timed out" before the backend has exhausted its own
retries. The background-resumable notification path remains the real UX safety
net — the user can close the modal and get pinged on completion.
This commit is contained in:
Brooklyn Nicholson 2026-06-25 00:32:48 -05:00
parent a8e6a4f00b
commit 7078d9d1e2
2 changed files with 13 additions and 6 deletions

View file

@ -22,11 +22,15 @@ import { applyAdoptedPet, type GatewayRequest } from '@/store/pet-gallery'
*/
// Generation is many grounded image calls — far longer than the default 30s RPC
// timeout. Drafts fan out 4 base looks; hatch fans out ~8 animation rows. Even
// parallelized, a cold provider call is slow, so we give these calls real
// headroom (the bug was "request timed out: pet.generate" on the 30s default).
const GENERATE_TIMEOUT_MS = 240_000
const HATCH_TIMEOUT_MS = 420_000
// timeout. Drafts fan out 4 base looks; hatch fans out ~8 animation rows. The
// quality-first default (OpenAI image via OpenRouter) is slow, and each hatch
// row can retry up to 3x (300s/call) across 2 parallel waves, so the absolute
// backend worst case is ~30 min. The hatch ceiling sits above that (1h) so the
// frontend never throws "request timed out" before the backend has actually
// exhausted its own retries — the background-resumable notify path is the real
// UX safety net (the user can close the modal and get pinged on completion).
const GENERATE_TIMEOUT_MS = 420_000
const HATCH_TIMEOUT_MS = 3_600_000
// Filler words to drop when deriving a default name from a free-text prompt.
const NAME_STOPWORDS = new Set([

View file

@ -64,7 +64,10 @@ _ASPECT_RATIOS = {
# so we never overflow the model's limit.
_MAX_REFERENCE_IMAGES = 3
_REQUEST_TIMEOUT = 180.0
# Per single image call. The quality-first default (OpenAI image via OpenRouter)
# is genuinely slow — a single cold row can run well past 3 minutes — so give
# each call real headroom before we treat it as hung and fall back / retry.
_REQUEST_TIMEOUT = 300.0
def _load_image_gen_config() -> Dict[str, Any]: