2 min lesson
The prompt
Rebuild the main list in "The prompt", then say what each item changes.
Step 1 of 2
The promptDrill
Implement a consumer for a streaming token endpoint. It opens an SSE connection to a model provider, yields tokens as they arrive and has to survive the messy reality of a hot path: a slow first byte, a connection that dies mid-stream and a caller who cancels.
- Stream tokens from a mock provider that emits Server-Sent Events and may stall or drop the connection partway through.
- Enforce a time-to-first-token timeout and a separate idle timeout between tokens - a stream that goes quiet for 2s is dead, not slow.
- Support cancellation from the caller so an abandoned editor request stops consuming a provider slot immediately.
- On a retriable failure before any token has streamed, retry with exponential backoff and full jitter, bounded by a total retry budget.
Interactive diagram. Step through it with the Next and Previous controls below, or Tab to a region to read its detail.
The first-token gate is the line your whole retry policy hangs on.
Learn more
Full explanation
Full explanation
Narrate the boundary you will not cross before you write a line: “Once I've streamed a token to the user, I won't blind-retry - that would duplicate output in the editor. Retries only apply to failures before first token.” Stating the idempotency rule up front is the senior signal. It shows you know the failure modes are the problem, not the happy path.
Learn more
References
A reference solve (TypeScript)
A reference solve (TypeScript)One correct shape
type Token = { text: string }; interface StreamOpts { ttftMs: number; // budget to first token idleMs: number; // max gap between tokens maxRetries: number; // retry budget (pre-first-token only) signal?: AbortSignal; } async function* streamTokens( open: (signal: AbortSignal) => Promise<AsyncIterable<Token>>, opts: StreamOpts, ): AsyncGenerator<Token> { for (let attempt = 0; ; attempt++) { const ctrl = new AbortController(); const onAbort = () => ctrl.abort(); opts.signal?.addEventListener("abort", onAbort, { once: true }); let sawToken = false; try { const stream = await withTimeout(open(ctrl.signal), opts.ttftMs, ctrl); let deadline = opts.idleMs; for await (const tok of stream) { sawToken = true; yield tok; // user has now seen output deadline = opts.idleMs; } return; // clean end of stream } catch (err) { // Once a token streamed, a retry would duplicate output: fail loudly. if (sawToken || opts.signal?.aborted) throw err; if (attempt >= opts.maxRetries || !retriable(err)) throw err; const backoff = Math.random() * Math.min(2 ** attempt * 100, 2_000); await sleep(backoff, opts.signal); } finally { opts.signal?.removeEventListener("abort", onAbort); } } }
Three places candidates leak: a timeout that never aborts the underlying socket (so the slot is held even after you give up), a retry that fires after a token already streamed and a backoff with no jitter that synchronizes every client into a thundering retry at the same instant. If your solve has any of these, that is your study gap, not a nitpick.
Learn more
Advanced table
Score your own tape
Score your own tapeSelf-rubric
- Dimension
- Correctness
- Pass looks like
- Tokens stream in order, clean end terminates, cancel stops consumption
- Red flag
- Buffers the whole response then returns it
- Dimension
- Failure handling
- Pass looks like
- TTFT and idle timeouts both abort the socket; retry only pre-first-token
- Red flag
- One timeout for everything; retries after partial output
- Dimension
- Complexity reasoning
- Pass looks like
- Says backoff is bounded, budget caps total wait, jitter named
- Red flag
- Unbounded retries or fixed backoff
- Dimension
- Reviewable code
- Pass looks like
- Named constants, one responsibility per function, no dead branches
- Red flag
- Magic numbers, nested try/catch soup
- Dimension
- Narration
- Pass looks like
- Explained the idempotency rule and each accept/reject of AI output
- Red flag
- Pasted a block and could not explain a line
| Dimension | Pass looks like | Red flag |
|---|---|---|
| Correctness | Tokens stream in order, clean end terminates, cancel stops consumption | Buffers the whole response then returns it |
| Failure handling | TTFT and idle timeouts both abort the socket; retry only pre-first-token | One timeout for everything; retries after partial output |
| Complexity reasoning | Says backoff is bounded, budget caps total wait, jitter named | Unbounded retries or fixed backoff |
| Reviewable code | Named constants, one responsibility per function, no dead branches | Magic numbers, nested try/catch soup |
| Narration | Explained the idempotency rule and each accept/reject of AI output | Pasted a block and could not explain a line |
Watch your screen recording with this open. Mark the timestamp of each red flag.