fix(recall): skip over-budget facts instead of stopping, and never answer a match with nothing (#3688) (#3704)
The max_tokens filter stopped at the first fact that did not fit the remaining budget, so one long fact evicted every shorter fact ranked behind it, and a budget no fact fits at all (CJK facts of 100-200 tokens against max_tokens=80) returned an empty list — which to an agent reads as "this bank has no such memory". This is the defect #3221 fixed for the source_facts budget in #3419; that fix never reached the fact budget one function over. select_facts_within_budget applies the same rule there — skip, don't stop — and adds the floor that case needs: if not even the top fact fits, it comes back whole and over budget rather than clipped, since MemoryFact carries no truncation flag. max_tokens=0 still means "no facts" (#364). The response surface is unchanged. A "the budget dropped facts" flag was considered and dropped: recall's candidate set carries no relevance cutoff of its own, so on a bank of any size it would be true on nearly every call and tell a caller nothing. The recall log line and trace still report it.
N
Nicolò Boschi committed
1f5006583cd104580209b19d43aa374cb61d7702
Parent: bdee2bc
Committed by GitHub <noreply@github.com>
on 8/24/2026, 11:09:04 AM