WorkflowChatTransport
API Reference for the WorkflowChatTransport class.
A ChatTransport implementation for useChat that enables automatic stream reconnection for workflow-based chat apps. It posts messages to a chat endpoint, extracts the x-workflow-run-id response header, and reconnects to a /{runId}/stream endpoint on interruption (network failures, page refreshes, function timeouts).
Unlike DefaultChatTransport which assumes the full response arrives in a single HTTP request, WorkflowChatTransport is designed for the Workflow SDK where the initial response stream may be interrupted by function timeouts. The transport automatically detects missing finish events and reconnects to resume from where the stream left off.
Import
import { WorkflowChatTransport } from "@ai-sdk/workflow/client"
Constructor
Parameters
api?:
{api}/{runId}/stream. Default: '/api/chat'.fetch?:
maxConsecutiveErrors?:
initialStartIndex?:
onChatSendMessage?:
onChatEnd?:
prepareSendMessagesRequest?:
prepareReconnectToStreamRequest?:
Methods
sendMessages()
Sends messages to the chat endpoint via POST and returns a streaming response. If the stream is interrupted (no finish event received), the transport automatically reconnects via GET to {api}/{runId}/stream?startIndex={chunkIndex} to resume from where it left off.
The POST request includes the messages as JSON and expects the response to include an x-workflow-run-id header identifying the workflow run.
chatId:
trigger:
messageId:
messages:
abortSignal:
Returns
Returns a Promise<ReadableStream<UIMessageChunk>> that includes chunks from both the initial POST response and any automatic reconnection.
reconnectToStream()
Reconnects to an existing chat stream that was previously interrupted. Useful for resuming after a page refresh or when the client needs to re-establish a connection.
chatId:
abortSignal:
startIndex?:
Returns
Returns a Promise<ReadableStream<UIMessageChunk> | null>.
How Reconnection Works
The transport follows this flow:
- POST to
{api}with messages. The response must include anx-workflow-run-idheader. - Stream the SSE response, counting chunks as they arrive.
- Detect interruption: If the stream closes without a
finishevent (e.g., function timeout, network error), the transport knows the response is incomplete. - Reconnect via GET to
{api}/{runId}/stream?startIndex={chunkIndex}to resume from the last received chunk. - Retry: If the reconnection stream also interrupts, retry up to
maxConsecutiveErrorstimes. - Complete: Once a
finishevent is received, callonChatEndand close the stream.
Negative Start Index
When initialStartIndex is negative (e.g., -50), the transport sends it as-is in the first reconnection request. The server should resolve this to an absolute position and return the x-workflow-stream-tail-index response header so the transport can compute the correct position for subsequent retries.
If the header is missing or invalid, the transport falls back to replaying from the beginning (startIndex=0).
Negative indexes require a durable server stream whose stored objects are
already UIMessageChunk objects. The raw WorkflowAgent conversion shown
below supports non-negative indexes only.
Server Requirements
For WorkflowChatTransport to work, your server must provide two endpoints:
POST {api} (e.g., /api/chat)
- Accept messages as JSON body
- Return an SSE stream of
UIMessageChunkevents - Include an
x-workflow-run-idresponse header
GET {api}/{runId}/stream (e.g., /api/chat/{runId}/stream)
- Accept a
startIndexquery parameter - Return the SSE stream starting from the given chunk index
- For negative
startIndex, resolve to the tail and includex-workflow-stream-tail-indexresponse header
See the WorkflowAgent guide for complete endpoint examples.
Examples
Basic Usage with useChat
With Callbacks
Server-Side Endpoints (Next.js)
This WorkflowAgent endpoint replays raw ModelCallStreamPart objects from
index 0, then applies the transport's non-negative cursor after converting
them to UIMessageChunk objects. Negative start indexes require a durable
stream whose stored objects are already UIMessageChunk objects.