Skip to content
Development
Skill

/output-dev-llm-streaming

Implement LLM text streaming in Output workflow steps with generateTextWithStreaming, Agent.generateWithStreaming, streamText, or Agent.stream. Use when adding token progress, onChunk callbacks, or handling streamText onEnd/onError with Temporal retries.

From plugin
output
43753 skills11 agents1 command
Install
$ npx -y skills add growthxai/output --skill output-dev-llm-streaming --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/output-dev-llm-streaming

Context preview

The summary Claude sees to decide when to auto-load this skill.

Implement LLM text streaming in Output workflow steps with generateTextWithStreaming, Agent.generateWithStreaming, streamText, or Agent.stream. Use when adding token progress, onChunk callbacks, or handling streamText onEnd/onError with Temporal retries.

SKILL.md

output-dev-llm-streaming.SKILL.md
name: output-dev-llm-streaming
description: Implement LLM text streaming in Output workflow steps with generateTextWithStreaming, Agent.generateWithStreaming, streamText, or Agent.stream. Use when adding token progress, onChunk callbacks, or handling streamText onEnd/onError with Temporal retries.
allowed-tools: [Read, Write, Edit]

LLM Text Streaming

When to Use This Skill

  • Adding token or chunk progress to an LLM-powered step
  • Choosing between completed generation and direct stream access
  • Using `onChunk`, or `onEnd` / `onError` on `streamText()` / `Agent.stream()`
  • Making stream failures trigger Temporal activity retries
  • Streaming Agent responses or persisting streamed conversations

Choose the API

| Need | Use | |------|-----| | Complete single-shot result | `generateText()` | | Complete result plus `onChunk` progress | `generateTextWithStreaming()` | | Direct access to `textStream` or `stream` | `streamText()` | | Complete Agent result plus `onChunk` progress | `Agent.generateWithStreaming()` | | Direct access to the Agent stream | `Agent.stream()` |

In workflow steps, prefer `generateTextWithStreaming()` or `Agent.generateWithStreaming()` when `onChunk` progress is sufficient. They consume the stream internally, return complete results like `generateText()` or `Agent.generate()`, and reject on provider, transport, or abort errors. Rejection allows Temporal to record the failed activity attempt and apply the step retry policy.

`streamText()` and `Agent.stream()` remain supported for code that needs direct control over stream consumption.

generateTextWithStreaming()

import { generateTextWithStreaming } from '@outputai/llm';

const result = await generateTextWithStreaming( {
  prompt: 'draft@v1',
  variables: { topic },
  onChunk( { chunk } ) {
    if ( chunk.type === 'text-delta' ) {
      process.stdout.write( chunk.text );
    }
  }
} );

return result.result;

The result has the same complete response fields as `generateText()`, including `result`, `text`, `output`, `usage`, `finishReason`, and `cost`. Structured output passed with `aiSdk.Output.*` is available through `result.output`.

Agent.generateWithStreaming()

const result = await agent.generateWithStreaming( {
  onChunk( { chunk } ) {
    if ( chunk.type === 'text-delta' ) {
      process.stdout.write( chunk.text );
    }
  }
} );

`generateWithStreaming()` returns a complete Agent response and automatically stores messages when the Agent has a `messageStore`.

Direct stream error handling

AI SDK streaming delivers provider and transport failures through `onError`. Iterating `textStream` does not reliably throw the original error. When using `streamText()` in a workflow step, capture the error and throw it after consumption:

import { streamText } from '@outputai/llm';

const captured: { error: unknown } = { error: null };
const result = streamText( {
  prompt: 'draft@v1',
  variables: { topic },
  onError( { error } ) {
    captured.error = error;
  }
} );

const chunks: string[] = [];
for await ( const chunk of result.textStream ) {
  chunks.push( chunk );
}

if ( captured.error ) {
  throw captured.error;
}

return chunks.join( '' );

Registering `onError` without throwing the captured error can let the step return an empty successful result, preventing Temporal from retrying it. Awaiting a completion property may also produce a generic no-output error instead of the original provider error.

`Agent.stream()` stores conversation messages in its wrapped `onEnd` when `finishReason` is not `'error'`. Use `Agent.generateWithStreaming()` when a complete stored response meets the requirement.

Streaming call arguments: `prompt`, `promptDir`, `variables`, `tools`, `output`, `toolChoice`, `stopWhen`, `abortSignal`, plus `onChunk` (`generateTextWithStreaming`) or `onChunk` / `onEnd` / `onError` (`streamText`). Agent methods: `messages`, `abortSignal`, `toolChoice`, plus those same stream callbacks.

Rules

  • Prefer the completed streaming APIs in Temporal steps unless direct stream access is required.
  • Do not rely on `onError` alone to fail a step using `streamText()`.
  • Throw the captured error only after stream consumption finishes.
  • Keep `onChunk` side effects bounded. A Temporal signal per token creates a history event per signal, so batch high-frequency updates.
  • Do not describe `streamText()` or `Agent.stream()` as deprecated.

Related Skills

  • `output-dev-step-function` - Put LLM calls inside Temporal activity steps
  • `output-dev-agent-class` - Construct and use reusable Agents
  • `output-dev-prompt-file` - Create prompt files for generation
  • `output-error-try-catch` - Handle step and workflow failures
Read more
Ships withoutput

The open-source TypeScript framework for building AI workflows and agents. Designed for Claude Code — describe what you want, Claude builds it, with all the best practices already in place. One framework.

Get the whole plugin

Other skills on output.