Skip to content

fix(server-utils): Record AI SDK tool spans for tools run outside its tool loop - #25820

Merged
mydea merged 2 commits into
fix/eve-model-started-conversation-idfrom
fix/eve-tool-spans
Oct 28, 2026
Merged

mydea merged 2 commits into
fix/eve-model-started-conversation-idfrom
fix/eve-tool-spans

Conversation

@mydea

@mydea mydea commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Why: eve 0.84+ runs tools in its own loop instead of the AI SDK's, so ai:telemetry never publishes executeTool for them. eve apps lose their gen_ai.execute_tool spans, and tool errors aren't captured (this is why node-eve (latest) fails). eve still calls the AI SDK's globally registered telemetry integrations around each tool call, so the Vercel AI integration now registers one that publishes those executions to the channel. The existing subscriber then builds the span, keeps it active while the tool runs (manual spans nest under it) and captures errors. The span ends in onToolExecutionEnd, because that is the only place eve passes the tool output.

This isn't eve-specific, but it only changes anything for code that runs tools outside the AI SDK's loop. The AI SDK's own loop also calls the integration, but always inside its own tool span. The integration detects that by tool call id and just runs the tool, which the existing "captures error in tool" tests (exactly 3 spans, ai v6 and v7) cover.

How to review: vercel-ai-tool-telemetry.ts is the whole change. The fact that node-eve (latest) E2E now passes is what shows that this works as intended.

Unsure about: We write to globalThis.AI_SDK_TELEMETRY_INTEGRATIONS directly, which is what ai's registerTelemetry does, because the SDK can't import ai. eve's own call.requested/call.settled events would avoid that, but the span wouldn't be active during the tool.

Stacked on #25809.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

size-limit report 📦

Compared: 2fca194 (PR test merge using develop at 445c2f5)

Against: 1ffbccd (develop) · base run #63950

⚠️ Baseline mismatch: 2 develop commit(s) in the PR build are missing from the baseline. Their size changes also affect this comparison. Compare commits. Re-run once develop's baseline build for 445c2f5 finishes.

Path Size % Change Change
@sentry/browser 30.33 kB - -
@sentry/browser - with treeshaking flags 28.45 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 28.34 kB - -
@sentry/browser (incl. Tracing) 52.6 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 52.6 kB - -
@sentry/browser (incl. Tracing, Profiling) 55.53 kB - -
@sentry/browser (incl. Tracing, Replay) 92.8 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 81.42 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 97.53 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 110.51 kB - -
@sentry/browser (incl. Feedback) 47.89 kB - -
@sentry/browser (incl. sendFeedback) 35.4 kB - -
@sentry/browser (incl. FeedbackAsync) 40.51 kB - -
@sentry/browser (incl. Metrics) 31.34 kB - -
@sentry/browser (incl. Logs) 31.62 kB - -
@sentry/browser (incl. Metrics & Logs) 32.3 kB - -
@sentry/react 32.14 kB - -
@sentry/react (incl. Tracing) 54.88 kB - -
@sentry/vue 38.6 kB - -
@sentry/vue (incl. Tracing) 55.49 kB - -
@sentry/svelte 30.36 kB - -
@sentry/remix (Remix 3 client bundle) 57.64 kB - -
CDN Bundle 32.06 kB - -
CDN Bundle (incl. Tracing) 53.09 kB - -
CDN Bundle (incl. Logs, Metrics) 34.26 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 55.04 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 75.68 kB - -
CDN Bundle (incl. Tracing, Replay) 91.22 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 93.16 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 97.35 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 99.33 kB - -
CDN Bundle - uncompressed 94.29 kB - -
CDN Bundle (incl. Tracing) - uncompressed 157.28 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 100.84 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 163.25 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 232.34 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 278.91 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 284.87 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 292.62 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 298.56 kB - -
@sentry/nextjs (client) 57.74 kB - -
@sentry/sveltekit (client) 53.05 kB - -
@sentry/core/server 43.84 kB - -
@sentry/core/browser 13.95 kB - -
@sentry/node 154.79 kB +0.16% +233 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 81.62 kB - -
@sentry/node - without tracing 95.69 kB +0.01% +9 B 🔺
@sentry/node - without channel injection 135.43 kB +0.17% +229 B 🔺
@sentry/aws-serverless 103.86 kB +0.01% +9 B 🔺
@sentry/cloudflare (withSentry) - minified 197.77 kB - -
@sentry/cloudflare (withSentry) 491.5 kB - -
@sentry/nextjs/cloudflare (withSentry) - minified 218.35 kB - -

View base workflow run

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Optional E2E tests

Some optional checks were not successful. They do not block the merge. 2 not successful, 60 successful. See the run.

Check Status
❌ CI: Optional E2E Tests / E2E node-anthropic-send-to-sentry (latest) Test (optional) Failing after 3m Details
❌ CI: Optional E2E Tests / E2E node-mastra Test (optional) Failing after 52s Details
Successful checks
Check Status
✅ CI: Optional E2E Tests / E2E gen-ai-libraries Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E nextjs-16 (deno) Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E nextjs-16 (vinext, bun) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E gen-ai-libraries (cloudflare) Test (optional) Successful in 57s Details
✅ CI: Optional E2E Tests / E2E nextjs-15 (turbo) Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E node-openai-send-to-sentry (latest) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E cloudflare-flue-send-to-sentry Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E node-express-send-to-sentry-static Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E nextjs-16 (canary, webpack) Test (optional) Successful in 5m Details
✅ CI: Optional E2E Tests / E2E nextjs-14 (latest) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E nuxt-4-static (canary) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E node-fastify-6 (tracer provider) Test (optional) Successful in 22s Details
✅ CI: Optional E2E Tests / E2E cloudflare-think Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E cloudflare-pi-durable Test (optional) Successful in 24s Details
✅ CI: Optional E2E Tests / E2E node-openai-decisions-send-to-sentry (latest) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E tanstackstart-react-sourcemaps Test (optional) Successful in 33s Details
✅ CI: Optional E2E Tests / E2E nextjs-16 (cloudflare, latest) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E deno (latest) Test (optional) Successful in 50s Details
✅ CI: Optional E2E Tests / E2E react-router-7-framework-instrumentation Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E cloudflare-agent Test (optional) Successful in 18s Details
✅ CI: Optional E2E Tests / E2E nextjs-orpc Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E nextjs-16-standalone (canary, turbopack) Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E node-flue (latest) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E cloudflare-think (ai v6) Test (optional) Successful in 55s Details
✅ CI: Optional E2E Tests / E2E cloudflare-mastra Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E debug-id-sourcemaps Test (optional) Successful in 35s Details
✅ CI: Optional E2E Tests / E2E node-express-mcp-v2 Test (optional) Successful in 17s Details
✅ CI: Optional E2E Tests / E2E node-express-mcp-v1 Test (optional) Successful in 14s Details
✅ CI: Optional E2E Tests / E2E nuxt-5-sourcemaps (static / nuxt generate) Test (optional) Successful in 20s Details
✅ CI: Optional E2E Tests / E2E nextjs-15 (latest) Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E cloudflare-workers-send-to-sentry Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E node-eve (latest) Test (optional) Successful in 57s Details
✅ CI: Optional E2E Tests / E2E node-openai-decisions-send-to-sentry Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E nextjs-16-tunnel (cloudflare) Test (optional) Successful in 44s Details
✅ CI: Optional E2E Tests / E2E astro-7-static Test (optional) Successful in 47s Details
✅ CI: Optional E2E Tests / E2E node-eve Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E nextjs-16 (vinext) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E node-anthropic-send-to-sentry Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E node-pi-durable Test (optional) Successful in 24s Details
✅ CI: Optional E2E Tests / E2E node-eve (orchestrion) Test (optional) Successful in 42s Details
✅ CI: Optional E2E Tests / E2E nuxt-5-sourcemaps (client source maps kept) Test (optional) Successful in 21s Details
✅ CI: Optional E2E Tests / E2E node-mastra (latest) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E solidstart-2 Test (optional) Successful in 39s Details
✅ CI: Optional E2E Tests / E2E tanstackstart-react-cloudflare Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E node-flue Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E nuxt-4 (canary) Test (optional) Successful in 2m Details
✅ CI: Optional E2E Tests / E2E node-openai-send-to-sentry Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E node-flue-send-to-sentry Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E astro-7 Test (optional) Successful in 57s Details
✅ CI: Optional E2E Tests / E2E nextjs-16 (canary, turbopack) Test (optional) Successful in 3m Details
✅ CI: Optional E2E Tests / E2E nextjs-14 (canary) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E node-express-send-to-sentry Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E nuxt-3 (canary) Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E nuxt-5-sourcemaps Test (optional) Successful in 22s Details
✅ CI: Optional E2E Tests / E2E nuxt-5 Test (optional) Successful in 7m Details
✅ CI: Optional E2E Tests / E2E supabase-nextjs Test (optional) Successful in 1m Details
✅ CI: Optional E2E Tests / E2E node-fastify-6 Test (optional) Successful in 20s Details
✅ CI: Optional E2E Tests / E2E node-pi-durable (latest) Test (optional) Successful in 23s Details
✅ CI: Optional E2E Tests / E2E cloudflare-pi-durable (latest) Test (optional) Successful in 41s Details
✅ CI: Optional E2E Tests / E2E node-flue-send-to-sentry (latest) Test (optional) Successful in 1m Details

mydea and others added 2 commits October 28, 2026 14:55
… tool loop

eve 0.84+ runs tools in its own loop instead of the AI SDK's, so the
`ai:telemetry` channel never published `executeTool` and no
`gen_ai.execute_tool` spans or tool errors were recorded. eve still calls
the AI SDK's registered telemetry integrations, so the Vercel AI integration
now registers one that publishes those tool executions to the channel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mydea
mydea force-pushed the fix/eve-tool-spans branch from bf1f2b5 to b12e123 Compare October 28, 2026 13:55
@mydea
mydea marked this pull request as ready for review October 28, 2026 14:12
@mydea
mydea requested a review from a team as a code owner October 28, 2026 14:12
@mydea
mydea requested review from andreiborza and isaacs and removed request for a team October 28, 2026 14:12
@mydea
mydea merged commit 90bd261 into develop Oct 28, 2026
321 of 323 checks passed
@mydea
mydea deleted the fix/eve-tool-spans branch October 28, 2026 14:25
mydea added a commit that referenced this pull request Oct 28, 2026
…#25809)

**Why:** eve 0.84 moved to its v27 event format, which replaced the
`step.attempt.*` instrumentation events with
`model.started`/`model.retried`/`model.settled`. `eveInstrumentation`
sets the conversation id from `turn.started` and `step.attempt.started`,
so on eve 0.84+ AI spans from resumed steps lost
`gen_ai.conversation.id`. It now also handles `model.started` (same
`scope.sessionId` shape) and keeps `step.attempt.started` for older eve.

The same release replaced the session stream's
`session.waiting`/`turn.failed` events with `delivery.settled`, so the
node-eve e2e helper never saw the turn end and aborted after 25s. That's
why `node-eve (latest)` has been failing on `develop`. The helper now
also stops on `delivery.settled`, keeping the old names for the pinned
`^0.63.0` variant.

**note**: With only this change, node-eve (latest) is still failing.
There is another thing that needs to be fixed for this, which should be
taken care of in
#25820 stacked on top
of this.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants