Documentation / guides
Streaming usage
Observe authoritative stream usage only after the provider stream terminates cleanly.
Streaming usage is terminal metadata, not a chunk. A stream decoder accumulates
provider usage while chunks are read and publishes a stream.StreamResult only
after Next observes clean io.EOF.
Terminal
for {
_, err := reader.Next()
if errors.Is(err, io.EOF) {
break
}
if err != nil {
return err // usage is not authoritative after a failed stream
}
}
result, ok := reader.Result()
if ok && result.Usage != nil {
fmt.Println(result.Usage.OutputTokens)
}
Result is false before EOF, after any non-EOF failure, or when the provider
did not report terminal metadata. Anthropic requires message_stop; OpenAI
uses its terminal usage event and [DONE]; Responses uses completed events;
Gemini and Bedrock collect their final usage events. Missing terminal markers
do not become fabricated usage.
Ownership
StreamReader.Result returns a fresh copy of Usage on every call. Close is
idempotent and must still be called after EOF to release the response body.
The retry decorator stamps establishment attempts into StreamResult.Attempts
without changing mid-stream failure semantics.
Source and proof
Run go test ./stream ./codec/....