mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-17 20:52:15 +03:00
A combo target that stalls past comboTargetTimeoutMs is aborted by buildTargetTimeoutRunner, which swallows the resulting rejection behind its synthetic 524. Nothing marks the account unavailable — correctly, since a stall is not a quota/auth failure — so the #6219 eviction on the generic markAccountUnavailable -> shouldFallback path in chat.ts never ran. The session pin therefore survived its full TTL and every following request in that session was handed straight back to the account that had just stalled. Seen in production on combo "coding" [priority]: one codex account pinned for a 30-minute TTL, four consecutive requests, four 120s timeouts, "all targets exhausted" each time, while four sibling codex accounts stayed healthy and unused. Classify the abort reason (new dependency-free leaf comboAbortReasons.ts) and evict the connection-matched pin. Only a genuine per-model timeout evicts: a client disconnect or a hedge cancellation says nothing about account health, so those keep the pin and its prompt-cache locality. Eviction is best-effort and never breaks the dispatch path. The dispatch itself moves into a new seam, chatDispatch.ts, which merges the per-model abort signal into the outgoing request, runs executeChatWithBreaker, and owns the eviction on both the rejection and failed-result paths. Keeping that logic out of the frozen god-file leaves chat.ts one line SHORTER than before (1844 -> 1843). Co-authored-by: alexey.nazarov@softmg.ru <alexey.nazarov@softmg.ru> Co-authored-by: fenix007 <fenix007@users.noreply.github.com> Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>