Vercel AI: reasoning tokens never reach `invoke_agent` parents, and streamed parents report candidate-only output
@RulaKhaled ya está trabajando en esto.
Desde el 11/9/2026.
Evaluación
Este issue todavía no se ha evaluado.
Descripción
Follow-up to #23433, which fixes Gemini reasoning tokens on model-call (gen_ai.generate_content) spans. Two gaps are deliberately out of scope there and need a decision.
Background
Per the conventions, gen_ai.usage.output_tokens is reasoning-inclusive and gen_ai.usage.reasoning.output_tokens is a subset of it. On ai v4/v5 with @ai-sdk/google, the SDK's outputTokens is candidate-only — reasoning ("thoughts") is exposed only through providerMetadata.google.usageMetadata. #23433 recomputes output on model-call spans from candidatesTokenCount + thoughtsTokenCount.
It cannot do the same on gen_ai.invoke_agent parents: their ai.usage.* is totalUsage summed across every step, while ai.response.providerMetadata describes the last step only. So #23433 gates output_tokens, total_tokens and reasoning.output_tokens off parents entirely.
Gap 1 — streamed parents report candidate-only output
With spanStreamingIntegration enabled, each span is emitted independently, so there is no pass that can re-derive a parent from its children. Measured on v10 with #23433 applied:
| parent | static (event processor) | streamed |
|---|---|---|
| single-step | output 101, total 115 ✅ |
output 1, total 15 ⚠️ |
| multi-step | output 201, total 1101 ✅ |
output 21, total 921 ⚠️ |
The static path is correct because applyAccumulatedTokens overwrites the parent by summing its (already corrected) children. The streamed path has no equivalent.
Gap 2 — reasoning.output_tokens never reaches parents
accumulateTokensForParent / applyAccumulatedTokens sum input and output but never reasoning, so unlike output/total there is no fallback once it is gated. A parent therefore carries no reasoning count on either path. Writing the ungated value would be wrong rather than merely absent: on a two-step call it reports the last step's reasoning as the whole call's (e.g. 100 where the true aggregate is 80 + 100 = 180).
Options to investigate
-
Sum reasoning in
accumulateTokensForParent/applyAccumulatedTokens. Gives parents a true aggregate reasoning count and closes Gap 2 on the static path. Does not help the streamed path, which has no accumulation. Touches shared token plumbing that every provider flows through, so it needs its own testing. -
Read the SDK's own reasoning tokens instead of deriving them from
providerMetadata.aiv6+ exposesai.usage.outputTokenDetails.reasoningTokens(and the deprecatedai.usage.reasoningTokens) directly on the span, sourced fromusage.outputTokens.reasoning, and v6outputTokensis alreadytotal= text + reasoning. Nothing in the SDK reads either today. This is provider-agnostic, works on both paths, and would cover Gemini, OpenAI and Anthropic at once — but only for SDK versions that emit it.
Also worth folding in
- On
v10, the OpenAI branch ofgetProviderMetadataAttributeswritesgen_ai.usage.output_tokens.reasoning, which@sentry/conventionsmarks deprecated in favour ofgen_ai.usage.reasoning.output_tokens. It has the same last-step-only issue on parents. - On
develop, the Vercel AI OTel path was removed in #23384.enrichSpanOnEndinvercel-ai-dc-subscriber.tsreads input/output/total but neveroutputTokenDetails.reasoningTokens, sogen_ai.usage.reasoning.output_tokensis currently only ever populated for OpenAI. Option 2 likely applies there more cleanly than onv10.
- Lenguaje dominante
- TypeScript
- Estrellas
- 8.7k
- Forks
- 1.9k
- Merge medio
- 1 d 16 h
- PR fusionados (30 d)
- 576
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de getsentry/sentry-javascript
-
Browser Bug Next.js Traces Waiting for: Product Owner
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
getsentry/sentry-javascript#24672 · 1 comentario ·
-
javascript
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
getsentry/sentry-javascript#24200 · 2 comentarios ·
-
javascript Task
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
getsentry/sentry-javascript#24134 · 1 comentario ·
-
Cloudflare Workers javascript Tests
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
getsentry/sentry-javascript#24051 · 1 comentario ·
-
Bug Bun javascript
Dificultad 2/5 1-3 horas Aptitud para principiantes 92/100
getsentry/sentry-javascript#24045 · 1 comentario ·
Todos los issues de getsentry/sentry-javascript
Issues similares
-
bug(cli): hapi doctor inline-media prints a fabricated B:\ helper-script path in packaged installs Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
-
Crush Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
catppuccin/catppuccin#3125 ·
-
Add a SECURITY.md Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
ElementsProject/cln-application#167 · 1 comentario · 1 reacción ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Quantco/pnpm-licenses#17 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100