Generating Text and Streaming

Purpose and Scope

This page explains the AI SDK Core workflow for plain text generation and streamed text delivery. The public documentation frames large language models as systems that generate text from prompts containing instructions and information, and it names two core entry points: generateText for receiving a completed result and streamText for consuming output as it arrives. That distinction matters when choosing between background jobs, summaries, agent steps, and interactive user interfaces. Non-interactive tasks usually prefer a completed response object, while chat and terminal experiences usually benefit from streaming partial text to the client as soon as the provider emits it.

Sources: content/docs/03-ai-sdk-core/05-generating-text.mdx, packages/ai/src/generate-text/stream-language-model-call.test.ts

The text-generation layer is also the foundation for more advanced AI SDK features. The docs explicitly describe tool calling and structured data generation as being built on top of text generation, so learning these primitives first makes the rest of AI SDK Core easier to reason about. A prompt may be a simple user request, or it may combine instructions with task content such as an article to summarize. The same model invocation concepts then extend into multi-step tool loops, schema-constrained output, and UI streams that need metadata, tool state, or final usage information.

Sources: content/docs/03-ai-sdk-core/05-generating-text.mdx

Relevant Source Files

  • content/docs/03-ai-sdk-core/05-generating-text.mdx — Defines the reader-facing purpose of generating and streaming text, shows generateText examples, and lists the result fields and performance metrics exposed by the public API.
  • packages/ai/src/generate-text/generate-text.test.ts — Provides regression coverage for the completed text generation path and the behavior expected from the public generateText result surface.
  • packages/ai/src/generate-text/stream-language-model-call.test.ts — Exercises the lower-level streaming model call pipeline, including callback ordering, model settings propagation, tools, usage parts, and stream part conversion.
  • packages/ai/src/text-stream/pipe-text-stream-to-response.test.ts — Verifies that text streams can be piped to Node ServerResponse objects with correct headers, status handling, and decoded text chunks.

Core Primitives

Use generateText when the application wants the final answer and metadata after the model call has completed. The documented examples import it from ai, pass a provider model, and provide either a direct prompt or a richer combination of instructions and prompt content. The returned object exposes text for the generated text from the final step, but it is not limited to plain text. It also carries content across steps, generated files, referenced sources when supported by the model, tool calls, tool results, finish reasons, warnings, usage, step details, final-step details, and structured output when an output specification is used.

Sources: content/docs/03-ai-sdk-core/05-generating-text.mdx, packages/ai/src/generate-text/generate-text.test.ts

Use streaming when latency and interactivity are part of the product experience. The stream pipeline receives model stream parts and turns them into higher-level text stream behavior. The stream-language-model-call test constructs a mock language model whose doStream method returns a readable stream of provider parts, then converts the resulting stream back into an array for assertions. This shows the contract at the boundary: the model emits structured stream parts such as finish information and usage, while the AI SDK layer is responsible for wrapping those parts with prompt, settings, tool, repair, and callback behavior.

Sources: packages/ai/src/generate-text/stream-language-model-call.test.ts

Execution Flow

A completed generation starts with a model and prompt, optionally enriched by instructions and model settings. The documentation examples show a recipe prompt and a summarization prompt with writer instructions, which illustrates the usual pattern: keep durable behavior in instructions and put request-specific content in the prompt. After the model call finishes, callers read result.text for the final answer and inspect the broader result object when they need observability, billing information, intermediate steps, generated assets, or tool activity. For agents, those step and tool fields are especially important because the final text may be only the last part of a multi-step exchange.

Sources: content/docs/03-ai-sdk-core/05-generating-text.mdx

A streaming generation has an additional runtime phase before provider execution: call-start instrumentation. The stream-language-model-call test verifies that onLanguageModelCallStart runs before doStream, and the captured event includes the call identifier, provider, model identifier, messages, settings, reasoning option, and JSON-schema description of available tools. This ordering is useful for telemetry and auditing because the application can record the intended request before the provider begins producing output. It also means settings such as max output tokens, temperature, penalties, stop sequences, seed, and reasoning are observable at the model-call boundary.

Sources: packages/ai/src/generate-text/stream-language-model-call.test.ts

Tool-aware streaming adds another layer of behavior without changing the basic model-call shape. The stream test supplies a tool set built with tool, an input schema from Zod, and an async execution function. It also accepts optional repairToolCall and refineToolInput hooks, showing that streamed model output may require validation or correction before a tool is executed. The test imports NoSuchToolError, tool repair types, and tool input refinement types, which signals that the stream pipeline must handle invalid or mismatched tool calls deliberately rather than treating every provider-emitted tool request as executable.

Sources: packages/ai/src/generate-text/stream-language-model-call.test.ts

Response Objects and Performance Fields

The public result object is designed to serve both simple and advanced callers. For a basic script, text, finishReason, and usage may be enough. For a production service, warnings, rawFinishReason, steps, and finalStep help explain why a provider behaved a certain way. The docs also describe per-step performance values such as effective output tokens per second, effective total tokens per second, total step time, response time, tool execution time keyed by tool call identifier, and streaming-only timing such as time to first output. These fields make generation results useful for debugging, dashboards, and provider comparisons.

Sources: content/docs/03-ai-sdk-core/05-generating-text.mdx

AreaImportant fields or behaviorWhen to inspect it
Final answertext, content, outputRendering a finished response or consuming structured output
Provider completionfinishReason, rawFinishReason, warningsDiagnosing truncation, unsupported settings, or provider-specific behavior
Cost and throughputusage, steps, finalStep.performanceMeasuring billing, latency, and tokens per second
Tool loopstoolCalls, toolResults, stepsUnderstanding intermediate agent actions and tool outputs
Model referencesfiles, sourcesHandling generated assets or model-provided citations when available

Text Stream Response Helpers

When the output should be written directly to an HTTP response, pipeTextStreamToResponse provides the Node response bridge. The test verifies that it sets the status code, status message, custom headers, and a default content-type of text/plain; charset=utf-8, then writes encoded stream chunks that decode back to the original text. This is the server-side counterpart to the streaming model call: once a readable text stream exists, the helper is responsible for adapting it to a response object without the application manually handling chunk encoding, stream completion, or header normalization.

Sources: packages/ai/src/text-stream/pipe-text-stream-to-response.test.ts

The same response helper can pipe a stream created from structured text stream parts. The test builds a stream containing start, two text-delta parts with the same text identifier, and a text-end part. Passing that through toTextStream produces the plain chunks Hello and , world!, which are then written to the mock response. This demonstrates an important boundary: internal stream parts may include lifecycle and identity information, but the plain text response only emits the user-visible text deltas. Applications that need richer UI message metadata should use UI stream helpers instead of flattening everything to text.

Sources: packages/ai/src/text-stream/pipe-text-stream-to-response.test.ts

Practical Usage Pattern

For a server route that returns one completed answer, call generateText, await the result, and send result.text plus any metadata your application needs. For a route that should progressively render output, use the streaming path, transform the model stream into a text stream, and pipe it to the response. Keep telemetry callbacks close to the model-call boundary so they capture settings and messages before execution begins. Keep tool validation and repair logic explicit, because streamed tool calls can arrive before the final answer and may need schema checks, input refinement, or human review depending on the application.

Sources: content/docs/03-ai-sdk-core/05-generating-text.mdx, packages/ai/src/generate-text/stream-language-model-call.test.ts, packages/ai/src/text-stream/pipe-text-stream-to-response.test.ts

import { generateText } from 'ai';
 
const result = await generateText({
  model,
  instructions: 'You are a professional writer. Write clearly and concisely.',
  prompt: `Summarize the following article in 3-5 sentences: ${article}`,
});
 
return result.text;

Testing Signals and Next Steps

The tests in this area are valuable examples because they focus on observable contracts rather than provider-specific implementation details. Mock language models and readable stream utilities make callback order, stream conversion, tool configuration, finish events, and response piping deterministic. When changing generation or streaming code, preserve those contracts: start callbacks should happen before model execution, settings should be visible in call events, text deltas should survive conversion in order, and HTTP response helpers should set predictable text headers. Next, read the pages on tool calling, structured data generation, streaming foundations, and UI stream protocols to decide whether your feature needs plain text, tool-aware steps, or richer UI message streams.

Sources: packages/ai/src/generate-text/generate-text.test.ts, packages/ai/src/generate-text/stream-language-model-call.test.ts, packages/ai/src/text-stream/pipe-text-stream-to-response.test.ts