How does Rius count prompt cache tokens from the Vercel AI SDK?
Rius reads the cache read tokens each Vercel AI SDK model call reports and prices them at the cache read rate, separate from regular input tokens. The token usage on the span for each model call includes cache reads, and Rius computes the cost on its side from the model and those counts. You never send a price or a cost. The result shows as a cost on the call, the trace, the agent and the workspace, as described in Track LLM and agent cost.
How it works
The Vercel AI SDK integration is TypeScript only. It turns each AI SDK call into spans, and the span for each model call (a chat span) carries the resolved model and its token usage, including cache reads and reasoning tokens. Streamed calls also carry time to first token.
When a span reaches Rius, the model and counts are priced like this:
- Input tokens are the total prompt. They include cached tokens. The uncached share is that total minus the cache reads and writes.
- Each kind of token has its own rate. Uncached input, cache reads, cache writes and output tokens are each multiplied by their own price.
- Cache rates come from the provider’s entry in LiteLLM’s public model-price catalog, in US dollars. A model whose entry has no separate cache rates is charged its input rate for cache tokens.
- Cache write tokens are priced at the cache write rate whenever a span carries them. When the AI SDK reports cache write tokens (
inputTokenDetails.cacheWriteTokens), the Rius SDK stores them asgen_ai.usage.cache_write.input_tokens, so they are priced at the cache write rate. - The model must be known. Rius looks up
gen_ai.request.model. If the model is not in the catalog, or the call reported no usage, the cost is left empty, not zero.
Each model call is counted once. The wrapper span around the calls, such as the agent span or an embed or embedMany span, still shows the run’s total where the AI SDK reports one. The Rius SDK does this deduplication, so spans from @ai-sdk/otel sent without it can be counted twice.
Costs are list-price estimates. Rius applies standard rates, not batch, flex, priority or long-context pricing, and not discounts you negotiated, so your provider invoice can differ.
Set it up
- Install the Rius SDK, plus
@ai-sdk/otelif you useai7. It needs Node 22 or newer.
npm install @glassflow-ai/rius @opentelemetry/api
npm install @ai-sdk/otel- On
ai7, callinit()and make your calls. With@glassflow-ai/rius0.6.0 or newer,init()registers the telemetry integration for you, so no telemetry code is needed in your application. Shut down before the process exits so queued spans are exported.
import { init } from '@glassflow-ai/rius'
import { openai } from '@ai-sdk/openai'
import { generateText } from 'ai'
const rius = init({ apiKey: 'ri_...', serviceName: 'my-agent' })
const { text } = await generateText({
model: openai('gpt-4o-mini'),
prompt: 'Summarize this ticket',
})
await rius.shutdown() // export queued spans before the process exits- On
ai5 and 6, nothing else is installed, but each call must opt in, or no spans are emitted. Since@glassflow-ai/rius1.2.0, the cache read and reasoning counts are stored the same way whicheveraiversion made the call.
const { text } = await generateText({
model: openai('gpt-4o-mini'),
prompt: 'Summarize this ticket',
experimental_telemetry: { isEnabled: true },
})- Open the trace in the console. The model call span shows the resolved model, input and output token counts and a cost, nested under an agent span for the call. Wrap the call in
observeto see it inside your agent’s run instead of as a standalone trace.
If no spans appear on ai 7, check the process log. Rius warns at init() when it finds ai 7 without @ai-sdk/otel. Full setup for both versions is on the Vercel AI SDK integration page.
What you get
- Cache reads priced at their own rate. A call that reads a large cached prompt costs what the cache read rate implies, not the full input rate.
- One cost per call, rolled up. The cost sits on the span detail next to the model and the input and output token counts. It also rolls up to the cost per trace, the total and average cost per agent, the cost per end user, and the workspace total with cost by model on the Usage and cost page.
- Alerts on cost. Cost is a metric in custom alerts, measured per trace, so a prompt that grew or a loop that stopped hitting the cache can trigger an alert.
- Honest gaps. An unknown model shows an empty cost rather than $0, and totals add up only the calls that were priced.
- Tokens counted once. Each model call counts once in tokens and cost, even though wrapper spans show the run’s total.
When something else fits
- If your app is in Python, there is no Vercel AI SDK integration, because the library itself is JavaScript only. Use the Rius integration for the client library or framework you use instead.
- If you need an exact billed amount, use your provider’s invoice. Rius shows list-price estimates and does not apply negotiated, batch, flex or priority pricing.