coach: keep cancelled-turn markers out of the plan fold too

The facts fold already skips the empty assistant row a cancelled turn
leaves behind; the plan fold read it as a blank turn and spent one of
its recent-turn slots on nothing. Same skip, same reason. Also state
the accepted one-slot slack a late rate-limit refund can leave in a
freshly opened window. Refs #781.
This commit is contained in:
Marc-André Bombeck committed 2026-08-13 07:11:32 +02:00
1 parent 47b0d340b7
commit ff88dd1f8f
2 files changed
+9

No files matched your search

+3
View File
@@ -276,6 +276,9 @@ async function loadRecentTurns(
for (const m of [...row.messages].reverse()) {
const content = decryptOrNull(m.encryptedContent);
if (content === null) continue;
// #781 — skip empty bodies: a cancelled-turn marker (an empty assistant
// row closing an aborted turn) carries nothing to extract from.
if (!content.trim()) continue;
turns.push({ role: m.role, content });
}
return turns;
+6
View File
@@ -61,6 +61,12 @@ export async function checkRateLimit(
* once `reset_at` has passed the counter is stale and a decrement would bleed
* into the NEXT window's budget, so an expired row is left untouched. Never
* drops below zero (concurrent refunds after a window flip are a no-op).
*
* Known slack: if the charge's window expires and a new request opens the
* NEXT window before a late refund lands, the refund decrements that fresh
* window instead — at most one extra slot there, only on failure paths that
* never reached the metered work. Accepted; carrying the charge's `reset_at`
* through every failure path is not worth one slot of slack.
*/
export async function refundRateLimit(key: string): Promise<void> {
await prisma.$executeRaw`