From 95b9557845971cc8fc45d766a76697a3189f708e Mon Sep 17 00:00:00 2001 From: Makisuo Date: Sat, 8 Aug 2026 15:21:25 +0200 Subject: [PATCH] fix(api): stop asserting which fiber won in the turn-retry test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fixture emits 8 chars — under DELTA_BATCH_SIZE — then fails the stream, so whether that text ever reached a consumer is a race between the provider failure and the 16ms DELTA_BATCH_WINDOW. groupedWithin drops a pending buffer on upstream failure, but a window that fires first ships it. Locally the failure always won; on a loaded CI runner the timer won and retractChars was a correct 8 against an asserted 0. Assert the invariant instead: retractChars equals exactly the text flushed before the marker, and the reader's fold lands on the retry's text alone. Holds on either side of the race. The deterministic exact-retraction case is still pinned by the neighbouring test, which fills a whole batch and flushes on the size cap regardless of timing. --- apps/api/src/chat/loop/turn.test.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/api/src/chat/loop/turn.test.ts b/apps/api/src/chat/loop/turn.test.ts index 397d493f9..38f9f4157 100644 --- a/apps/api/src/chat/loop/turn.test.ts +++ b/apps/api/src/chat/loop/turn.test.ts @@ -350,19 +350,28 @@ const fold = (events: ReadonlyArray): string => }, "") describe("runChatTurn retry", () => { - it("retracts nothing when the failed attempt's batch never flushed", async () => { + it("retracts exactly what a sub-batch attempt had flushed, whatever that was", async () => { const result = await Effect.runPromise( collect([{ events: [textDelta("Hello wo")], fail: true }, [textDelta("Hello world."), finish()]]), ) - // `Stream.groupedWithin` drops its pending buffer on an upstream failure rather than - // flushing it, so a provider that dies inside one batching window emitted nothing and there - // is nothing to take back. The marker is still emitted — it is also the progress signal. + // Below `DELTA_BATCH_SIZE`, so whether this attempt emitted anything is a race between the + // provider's failure and the 16ms window: `Stream.groupedWithin` drops a pending buffer on an + // upstream failure, but a window that fires first ships it. Both are correct — the invariant + // is that the marker takes back exactly what reached a consumer and no more, so the reader's + // fold lands on the retry's text alone. Asserting a literal count here would be asserting + // which fiber won. const retracted = retries(result.events) assert.lengthOf(retracted, 1) - assert.equal(retracted[0]?.type === "turn-retry" ? retracted[0].retractChars : undefined, 0) + const at = result.events.findIndex((event) => event.type === "turn-retry") + const marker = result.events[at] + const flushedBefore = textOf(result.events.slice(0, at)) + assert.equal( + marker?.type === "turn-retry" ? marker.retractChars : undefined, + flushedBefore.length, + ) assert.equal(result.calls, 2) - assert.equal(textOf(result.events), "Hello world.") + assert.equal(fold(result.events), "Hello world.") assert.lengthOf(terminal(result.events), 1) })