requireContent
function requireContent<T>( provider, chunks, opts?): AsyncGenerator<T>;Defined in: core/src/watchdog.ts:212
Reject a turn that completed without an answer.
A stream that ends with no text and no tool call is a failure wearing a
success’s clothes: stop_reason: end_turn with zero content blocks, which
the vendors emit under load, or a thinking block that ate the whole
max_tokens. Nothing throws, so nothing retries. The caller simply shows a
person an empty answer, and the only trace is a bill.
Reasoning is not an answer. It still streams the moment it arrives, so a reader can watch the model think, but a turn that only thought has said nothing. Counting it as content is how a review capped at 2,048 tokens on a high-effort model passed this guard 22 times in a row in production: every token went to thinking, the answer was an empty string, and the app’s JSON parse failed on it with nothing to say why.
Classified by what fixes it. A length finish is the caller’s own cap:
invalid, so nothing retries it into the same cap and no backup model is
cooled down for it. The fix is a larger maxTokens or a lower effort. Any
other empty turn is overload, because that is both true and useful: it is
theirs and temporary, so it is transient (the same model, retried, usually
answers) and backup-eligible (a model that keeps doing it should be walked
away from). Until something streams, the empty frames are held back, so the
retry rule still holds: retry only while nothing was emitted.
Type Parameters
Section titled “Type Parameters”| Type Parameter |
|---|
T extends ProviderChunk |
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
provider |
string |
chunks |
AsyncIterable<T> |
opts |
{ afterToolResult?: boolean; } |
opts.afterToolResult? |
boolean |
Returns
Section titled “Returns”AsyncGenerator<T>