How do I see every tool call for calls to the Vercel AI SDK?
Rius records each tool execution in a Vercel AI SDK call as its own execute_tool span, with the tool’s arguments and result, inside the agent span for that call. On ai 7, install @ai-sdk/otel and call init(). On ai 5 and 6, turn on telemetry for each call. You then read the tool calls in the trace waterfall or list them on the Spans tab.
How it works
The integration is TypeScript only. It uses the AI SDK’s own OpenTelemetry telemetry, and Rius stores what it emits. For each generateText, streamText, generateObject or streamObject call, you get:
- An agent span (
invoke_agent) that wraps the steps of a tool-calling loop, with a span for each step. - A
chatspan for each model call. It carries the messages, the request’s tool definitions, the resolved model, the finish reason and token usage, including cache reads and reasoning tokens. Streamed calls also carry time to first token. - An
execute_toolspan for each tool execution. It holds the tool’s arguments and result asgen_ai.tool.call.argumentsandgen_ai.tool.call.result. - Embedding spans for embedding calls.
Cost is computed by Rius from the model and the token counts, so you never send it. Each model call is counted once in tokens and cost, and the agent span still shows the run’s total.
The tool spans come from the AI SDK, so you add no tracing code inside your tools to see them. Your own span is for the call as a whole. Without one, each AI SDK call shows up as a standalone trace. Wrapping the call in observe places it inside your agent’s run, next to the rest of your work.
Tool arguments and results count as content. If you set captureContent: false or a mask, they are stripped or masked the same way prompts and responses are, and the rest of the span stays.
Set it up
-
Turn on the AI SDK’s telemetry. Which way depends on your
aiversion.On
ai7, install the telemetry package. It needs Node 22 or newer.init()registers it for you.npm install @ai-sdk/otelOn
ai5 and 6, install nothing and opt in on each call. A call without this setting is not traced.const { text } = await generateText({ model: openai('gpt-4o-mini'), prompt: 'Summarize this ticket', experimental_telemetry: { isEnabled: true }, }) -
Initialize Rius once at startup, then make your call. The full install and
init()options are on the Integrations page, and the version details are in the Vercel AI SDK recipe.import { init } from '@glassflow-ai/rius' import { openai } from '@ai-sdk/openai' import { generateText } from 'ai' const rius = init({ apiKey: 'ri_...', serviceName: 'my-agent' }) await rius.ready // the integration is attached before the first call const { text } = await generateText({ model: openai('gpt-4o-mini'), prompt: 'Summarize this ticket', }) await rius.shutdown() // export queued spans before the process exits -
To see the tool calls inside your agent’s run, wrap the call in
observeand give the function a name. An anonymous function traces as anonymous.import { init, observe } from '@glassflow-ai/rius' import { openai } from '@ai-sdk/openai' import { generateText } from 'ai' const rius = init({ apiKey: 'ri_...', serviceName: 'my-agent' }) await rius.ready // the integration is attached before the first call const handle = observe(async function handle(prompt: string) { const { text } = await generateText({ model: openai('gpt-4o-mini'), prompt, }) return text }) await handle('Summarize this ticket') await rius.shutdown() -
Check that the integration attached. On
ai7,await rius.readylistsvercel-ai. Onai5 and 6 it does not list it even when tracing works, so look for the trace instead. Rius also warns atinit()when it findsai7 without@ai-sdk/otel, because that combination produces no spans.
What you get
Open the trace in the console, as described in Exploring traces, and the tool calls are in three places:
- The waterfall. The trace appears as a tree on a timeline, with spans badged by kind (chain, llm, tool). Each tool call sits under the agent span for the call that made it, beside the model calls. If a tool fails, the failed spans are highlighted along the path from the root.
- The Spans tab. It lists spans instead of whole traces. Pick Tool in the All kinds menu to see every tool call across all traces, and sort by duration to find the slow ones.
- The span detail. Select an
execute_toolspan and read the arguments and result in the Input / Output tab. Raw shows the span exactly as ingested.
When the same tool is called several times in a row, the trace collapses the calls into one row, such as fetch_article · 3 attempts · recovered. Expand it for each attempt. Each chat span also shows tokens and cost, so you can see what each step of the tool loop spent. For the wider picture, see Monitor AI agents in production.
On ai 5 and 6, image, speech and transcription calls are not traced at all, because they take no telemetry settings. On ai 7 they are.
When something else fits
If a tool does work worth timing on its own, such as several database queries, add your own observe span inside that function to break it down. For libraries without an integration, trace calls with manual generations as described on the Integrations page. Python code cannot use this integration, since the AI SDK is JavaScript only.