mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-31 04:07:52 +00:00
The #3217 empty-completion guard throws AIConfigError for a contentless 'length' stop BEFORE callers can observe stopReason === 'length'. Two callers had explicit truncation handling that the throw silently bypassed: - facts/extract.ts: the #2113 retry-once-at-double-cap recovery never fired for a completion that spent the whole cap on internal reasoning (zero text) — the catch absorbed the throw as 'return []', silently losing facts for exactly the case the retry was built for. - chronicle/extract-events.ts: the #2606 'truncated' failure marker degraded to a silent { events: [] } no-op for the same case. Fix: chat() marks the contentless-length AIConfigError; the exported isContentlessLengthError(err) predicate lets both callers branch on it (no message matching). facts extract now routes the throw into the same double-cap retry; chronicle preserves failure: 'truncated'. Tests: end-to-end contentless-length retry through the REAL guard (via the generateText transport, since the chat transport bypasses the guard), plus predicate pins in gateway-empty-completion.test.ts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>