Vercel AI: reasoning tokens never reach `invoke_agent` parents, and streamed parents report candidate-only output
@RulaKhaled đang làm issue này rồi.
Từ ngày 11/9/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
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.
- Ngôn ngữ chính
- TypeScript
- Star
- 8.7k
- Fork
- 1.9k
- Merge trung bình
- 1 ngày 16 giờ
- Pull request đã merge (30 ngày)
- 576
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của getsentry/sentry-javascript
-
Browser Bug Next.js Traces Waiting for: Product Owner
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
getsentry/sentry-javascript#24672 · 1 bình luận ·
-
javascript
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
getsentry/sentry-javascript#24200 · 2 bình luận ·
-
javascript Task
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
getsentry/sentry-javascript#24134 · 1 bình luận ·
-
Cloudflare Workers javascript Tests
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
getsentry/sentry-javascript#24051 · 1 bình luận ·
-
Bug Bun javascript
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 92/100
getsentry/sentry-javascript#24045 · 1 bình luận ·
Tất cả issue của getsentry/sentry-javascript
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
bcgov/bc-wallet-mobile#4761 · 1 bình luận ·
-
external-issue to-triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
-
area-deployment area-integrations triage:bot-seen
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 86/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
-
refactor
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100