Skip to Content

How do I trace streaming responses from the Vercel AI SDK?

Rius traces streamed Vercel AI SDK calls with the same setup as any other call, and each streamed call carries time to first token. On ai 7, install @ai-sdk/otel and call init(). On ai 5 and 6, turn telemetry on for each call. Each model call is recorded with its messages, model, token usage and cost, and the Vercel AI SDK integration is TypeScript only.

How it works

The integration reads the OpenTelemetry telemetry that the Vercel AI SDK produces, so you do not write tracing code around the stream. A streamed call is recorded like any other call:

  • An agent span for the streamText or streamObject call.
  • A chat span for each model call, with its messages, model, finish reason and token usage, including cache reads and reasoning tokens.
  • An execute_tool span for each tool execution, with the tool’s arguments and result.
  • Time to first token on the streamed call. Rius computes it from the spans, and you never send a latency value. It is available from @glassflow-ai/rius 1.1.0 on ai 7 and from 1.2.0 on ai 5 and 6.

Time to first token is the number a user feels when a stream starts, and total duration mostly tracks how long the answer is. Rius uses it for time to first token percentiles (p50 and p95) in your usage view.

There is no span for you to end. The spans come from the AI SDK’s telemetry, and the integration does not ask you to call end() or to mark the first chunk. Marking the first chunk yourself with record_first_token() or recordFirstToken() applies only to manual generations. If you write your own generation around a stream, you own its lifetime and call end() when the stream finishes. The tracing page shows that pattern.

Cost is computed by Rius from the model and the token counts. Each model call is counted once in token and cost totals, and the agent span still shows the run’s total.

Set it up

  1. On ai 7, install the telemetry package. It needs Node 22 or newer, the same floor as ai 7.
npm install @ai-sdk/otel
  1. Initialize Rius once at startup. With @glassflow-ai/rius 0.6.0 or newer, init() registers @ai-sdk/otel for you, so every AI SDK call is traced with no telemetry code in your application. The example below streams with streamText. The Vercel AI SDK page covers the full setup.
import { init } from '@glassflow-ai/rius' import { openai } from '@ai-sdk/openai' import { streamText } from 'ai' const rius = init({ apiKey: 'ri_...', serviceName: 'my-agent' }) await rius.ready // the AI SDK integration is registered before the first call const result = streamText({ model: openai('gpt-4o-mini'), prompt: 'Summarize this ticket', }) for await (const chunk of result.textStream) process.stdout.write(chunk) await rius.shutdown() // export queued spans before the process exits
  1. On ai 5 and 6, nothing is installed, but each call must opt in, including each streamed call. Add the setting to the call’s options:
const result = streamText({ model: openai('gpt-4o-mini'), prompt: 'Summarize this ticket', experimental_telemetry: { isEnabled: true }, })
  1. Keep await rius.shutdown() at the end of a short script. The TypeScript SDK does not flush queued spans when the process exits, so a stream that finishes just before exit can otherwise be lost.

  2. Run one streamed call and open the trace in the console. You see the agent span, the chat span with its model, tokens and cost, and the time to first token. If nothing appears on ai 7, check the process log: Rius warns at init() when it finds ai 7 without @ai-sdk/otel. On ai 5 and 6, the usual cause is a call without isEnabled: true.

What you get

  • Streamed calls that read like non-streamed ones: the same agent, chat and execute_tool spans, with messages, models, tool definitions and token usage.
  • Time to first token for every streamed call, so you can compare models and spot slow starts instead of reading long durations as slowness.
  • Cost for each call, computed by Rius as a list-price estimate in US dollars, with each call counted once.
  • Your privacy controls apply to the streamed content as they do to any other span. captureContent: false and a mask cover prompts, responses, tool definitions and tool arguments and results.
  • Your calls inside your agent’s run, if you wrap them in observe. Without it, each call arrives as its own trace. The integrations overview lists every supported library and framework.

When something else fits

  • If your stream goes through a library the integration does not cover, such as a TypeScript OpenAI or Anthropic stream, time to first token is not recorded automatically. Trace that call as a manual generation: call recordFirstToken() in the loop and setUsage() with the counts from the final chunk, and leave that integration out with init({ instruments: [...] }) (1.8.0 or later) so the call is not counted twice.
  • If you use Python, there is no Vercel AI SDK integration, because the library is JavaScript only. Use the integration for the client library or framework you call from Python.

Still stuck? Get help

Last updated on