# Streaming overview

> Consume provider-neutral content chunks and authoritative terminal metadata.

- Path: `Guides > Inference > Streaming > Overview`
- Human: https://looprig.com/docs/guides/inference/streaming
- Machine index: https://looprig.com/llms.txt

Inference streaming has two layers: a wire framer yields `StreamFrame` values, then a semantic decoder maps frames to sealed `content.Chunk` values. A `StreamReader` exposes both as a pull iterator and keeps terminal metadata separate from the last chunk.

## Stream lifecycle

```mermaid
%%{init: {"theme":"base","themeVariables":{"background":"#111827","primaryColor":"#1f2937","primaryTextColor":"#f8fafc","primaryBorderColor":"#64748b","lineColor":"#94a3b8","secondaryColor":"#0f172a","tertiaryColor":"#172033","fontFamily":"Inter, ui-sans-serif, system-ui, sans-serif"}}}%%
sequenceDiagram
    participant C as Caller
    participant R as StreamReader
    participant P as Provider body
    C->>R: Next()
    R->>P: read frame
    P-->>R: Chunk
    R-->>C: content.Chunk
    C->>R: Next() until io.EOF
    R-->>C: clean EOF and Result()
    C->>R: Close()
```

Always call `Close`, even after clean EOF. Any non-EOF failure permanently fails the reader and makes `Result` unavailable. Clean EOF is the only point at which a terminal result producer is consulted.

```go
reader, err := client.Stream(ctx, request)
if err != nil {
	return err
}
defer reader.Close()
for {
	chunk, err := reader.Next()
	if errors.Is(err, io.EOF) {
		break
	}
	if err != nil {
		return err
	}
	consume(chunk) // render or accumulate the provider-neutral chunk
}
```

The Harness [streaming response step](/docs/guides/harness/step/streaming-response.md) is the canonical consumer when a Harness loop renders these chunks.

## Proof

- Source: [`inference/stream/stream.go`](https://github.com/looprig/inference/blob/main/stream/stream.go), [`inference/stream/chunkstream.go`](https://github.com/looprig/inference/blob/main/stream/chunkstream.go), [`core/content/chunk.go`](https://github.com/looprig/core/blob/main/content/chunk.go)
- Tests: [`inference/stream/stream_test.go`](https://github.com/looprig/inference/blob/main/stream/stream_test.go), [`inference/stream/chunkstream_test.go`](https://github.com/looprig/inference/blob/main/stream/chunkstream_test.go)

Related: [StreamReader](/docs/guides/inference/streaming/stream-reader.md), [Chunks](/docs/guides/inference/streaming/chunks.md), [Terminal stream results](/docs/guides/inference/streaming/terminal-results.md).
