Closes the duplicate-event footgun when users wire both @voightxyz/openai / @voightxyz/anthropic (otel: true) AND VoightExporter into the same OTel runtime.
What changed
VoightExporter.export() now recognises the voight.source: 'wrapper' attribute that the OpenAI + Anthropic wrappers stamp on their OTel spans (when run with otel: true), and skips those spans cleanly — no POST, no error, callback still SUCCESS.
Spans without that attribute — the canonical streamText / generateText / streamObject / generateObject spans the Vercel AI SDK emits — are unaffected and continue to flow. Other OTel exporters in the same process (Langfuse, Datadog, Phoenix, Sentry) aren't filtered; the dedup is scoped to the Voight-to-Voight loop.
Companion releases
Ships alongside:
Both gain the otel: true opt-in that emits the dedup-marked spans.
Validation
End-to-end smoke from the npm registry (after beta cycle): wrapped OpenAI + Anthropic calls with otel: true and VoightExporter in the same OTel runtime → exactly 1 POST to /v1/events per call. Pre-existing Vercel AI SDK spans → forwarded normally.
Tests: 105 → 109 green (4 new dedup cases). B.8.4: removing the filter triggers exactly 2 failures.
Install
npm install @voightxyz/vercel-ai