Vercel AI: reasoning tokens never reach `invoke_agent` parents, and streamed parents report candidate-only output
@RulaKhaled 已经在做这个了。
开始于 2026年9月11日。
评估
这个 Issue 还没有评估数据。
描述
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.
- 主要语言
- TypeScript
- 星标
- 8.7k
- 派生
- 1.9k
- 平均合并
- 1 天 16 小时
- 30 天内合并 PR
- 576
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
getsentry/sentry-javascript 的其他 Issue
-
Browser Bug Next.js Traces Waiting for: Product Owner
难度 2/5 1-3 小时 新手友好度 75/100
getsentry/sentry-javascript#24672 · 1 条评论 ·
-
javascript
难度 2/5 1-3 小时 新手友好度 75/100
getsentry/sentry-javascript#24200 · 2 条评论 ·
-
javascript Task
难度 2/5 1-3 小时 新手友好度 82/100
getsentry/sentry-javascript#24134 · 1 条评论 ·
-
Cloudflare Workers javascript Tests
难度 2/5 1-3 小时 新手友好度 78/100
getsentry/sentry-javascript#24051 · 1 条评论 ·
-
Bug Bun javascript
难度 2/5 1-3 小时 新手友好度 92/100
getsentry/sentry-javascript#24045 · 1 条评论 ·
查看 getsentry/sentry-javascript 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 84/100
bcgov/bc-wallet-mobile#4761 · 1 条评论 ·
-
external-issue to-triage
难度 2/5 1-3 小时 新手友好度 88/100
-
area-deployment area-integrations triage:bot-seen
难度 2/5 半天 新手友好度 86/100
-
难度 2/5 1-3 小时 新手友好度 82/100
-
refactor
难度 2/5 1-3 小时 新手友好度 84/100