SIGN IN SIGN UP

fix(consolidation): classify batch LLM failures instead of retrying everything (#3684) (#3783)

The batch loop caught bare `Exception` and re-sent a byte-identical payload up
to `consolidation_max_attempts` times, on top of the provider's own ladder —
3 x 4 = 12 generations for one deterministic failure, and up to 15x that again
once adaptive bisection halved the batch down to single memories.

Split the failures by shape:

- `ProviderRateLimitResetError` now propagates. It is a control signal: the
  provider said when quota reopens and `execute_task` turns it into a
  `DeferOperation` scheduled for exactly then. Swallowing it meant the defer
  never fired, bisection re-hit the same quota wall on every sub-batch, and each
  memory was stamped `consolidation_failed_at` — the exclusion predicate for
  pending consolidation, cleared only by a bank-wide reset. A transient quota
  exhaustion permanently orphaned those facts. `fact_extraction` already
  re-raises it for this reason.
- A 401/403 propagates too. Same shape: a wrong key would mark every memory in
  the bank permanently failed.
- `json.JSONDecodeError`, `ValidationError`, `OutputTooLongError` and
  provider-flagged non-retryable errors fail the batch immediately. Consolidation
  pins temperature 0.0 and the payload is identical, so the re-send asks a greedy
  decoder the same question. The batch is still reported failed, so bisection —
  which does vary the input — still runs.
- Transport-shaped failures keep the full budget and now back off between
  attempts; previously a rate limit was re-sent immediately, three times.
N
Nicolò Boschi committed
ad6312a512119c45a5dd67c43dccb6d391de2609
Parent: 71894da
Committed by GitHub <noreply@github.com> on 8/25/2026, 9:22:08 AM