Ask and plan answers stream through the AI SDK's createAgentUIStream, agent turns run as a WorkflowAgent whose resume cursor counts UI chunks, and no package implements a custom Workflow World.
The assistant answers in two ways. Ask and plan turns run in the request and stream straight to the browser. Agent turns run as a durable workflow, so they survive a closed tab, wait for approvals and can be stopped from another device.
The direct path built its own pipeline around ToolLoopAgent: it converted and budgeted the model messages before the call, saved partial answers from each step's raw result and decided by hand whether the stream had failed. AI SDK 7 ships createAgentUIStream, which validates the UI messages, converts them, runs the agent and reports each finished step and the end of the stream as UI messages.
The workflow path wrote raw ModelCallStreamPart values to the run's stream and converted them to UI chunks when a client read them. Clients reconnected with the raw chunk position, but WorkflowChatTransport counts the UI chunks it receives, and one raw part does not map to one UI chunk. A reconnect could replay or skip part of the answer. Stop also returned from the workflow without aborting the model call, so the agent kept writing after the user stopped it.
createAgentUIStream with the thread's UI messages and keeps createUIMessageStreamResponse for the response, with consumeSseStream, the chat headers and the keep-alive.
prepareStep. The first step prunes and bounds the model messages and puts the summary of dropped messages in the instructions.onUIMessageStepEnd saves the partial answer after each step, and onEnd saves the final answer from event.responseMessage and reads event.outcome to tell a finished stream from a failed or aborted one.WorkflowAgent and its raw stream, with a UI chunk cursor contract.
createModelCallToUIChunkTransform({ uiStartIndex }), so startIndex counts UI chunks on every reconnect.streamChunkCount, the number of UI chunks the conversion has emitted for the stored raw parts before the stream closes. The client sends it back as startIndex.x-workflow-stream-tail-index.abortSignal and waits for the agent to settle before the workflow returns.@workflow/world-vercel and local development uses @workflow/world-local, so the World v4 to v5 migration does not apply and better-supabase/workflow-sdk/world stays unused.resumeStreamResponse does not fit the UI chunk cursor. docs/agents/better-supabase.md lists what the helper needs before CentraKit adopts it.Last updated on