# Stream Transport Helpers

The Go AI SDK provides transport-oriented helpers for converting stream results into HTTP-friendly payloads and reading them back.

## `CreateTextStreamResponse`

```go
func CreateTextStreamResponse(ctx context.Context, result *ai.StreamTextResult) (*http.Response, error)
```

Returns an `*http.Response` with a plain text body (`text/plain; charset=utf-8`) built from text chunks.

## `PipeTextStreamToResponse`

```go
func PipeTextStreamToResponse(ctx context.Context, result *ai.StreamTextResult, w io.Writer) error
```

Writes text chunks to `w` as plain UTF-8 text.

## `CreateUIMessageStream`

```go
func CreateUIMessageStream(ctx context.Context, result *ai.StreamTextResult, opts ...ai.UIMessageStreamResultOptions) (<-chan ai.UIMessageChunk, <-chan error)
```

Converts stream chunks to UI message chunks.

## `CreateUIMessageStreamResponse`

```go
func CreateUIMessageStreamResponse(ctx context.Context, result *ai.StreamTextResult, opts ...ai.UIMessageStreamResultOptions) (*http.Response, error)
```

Returns an `*http.Response` with Server-Sent Events (`text/event-stream`) UI message chunks.

## `PipeUIMessageStreamToResponse`

```go
func PipeUIMessageStreamToResponse(ctx context.Context, result *ai.StreamTextResult, w io.Writer, opts ...ai.UIMessageStreamResultOptions) error
```

Writes UI message chunks as Server-Sent Events.

### Keep-alive

`CreateUIMessageStreamResponseWithInit` and `PipeUIMessageStreamToResponseWithInit` accept a `*ai.UIMessageStreamResponseInit` with a `KeepAliveMs *time.Duration` field. When set to a positive duration, the pipeline writes an opening `: stream-open\n\n` SSE comment immediately — so a reverse proxy sees the response start right away instead of buffering an empty connection — and then a `: keep-alive\n\n` comment whenever that duration elapses with no other write, resetting on every real chunk:

```go
keepAlive := 15 * time.Second
err := ai.PipeUIMessageStreamToResponseWithInit(ctx, result, w, &ai.UIMessageStreamResponseInit{
    KeepAliveMs: &keepAlive,
})
```

`ReadUIMessageStream` and `ReadUIMessages` already skip SSE comment lines (any line starting with `:`), so a client reading a keep-alive-enabled stream needs no changes.

## `ReadUIMessageStream`

```go
func ReadUIMessageStream(r io.Reader) ([]ai.UIMessageChunk, error)
```

Reads Server-Sent Events UI chunk payloads from a reader.

## `ConsumeStream`

```go
func ConsumeStream(ctx context.Context, stream provider.TextStream) error
```

Consumes a stream until completion or context cancellation.
