Skip to content

feat(vercel-ai-sdk): add AI SDK v7 integration#794

Merged
hassiebp merged 39 commits into
mainfrom
codex/add-vercel-ai-sdk-integration
Jun 26, 2026
Merged

feat(vercel-ai-sdk): add AI SDK v7 integration#794
hassiebp merged 39 commits into
mainfrom
codex/add-vercel-ai-sdk-integration

Conversation

@hassiebp

@hassiebp hassiebp commented Apr 22, 2026

Copy link
Copy Markdown
Collaborator

Problem

AI SDK v7 moved telemetry to the callback-based Telemetry API and removed the old integration path used by the previous Langfuse/Vercel AI SDK integration. Langfuse needs a maintained package that works with v7, keeps the AI SDK OpenTelemetry span shape aligned with Vercel's reference implementation, and still lets users attach Langfuse prompt and observation metadata.

Changes

  • Adds a new @langfuse/vercel-ai-sdk workspace package for AI SDK v7.
  • Implements LangfuseVercelAiSdkIntegration as a thin Telemetry wrapper around Vercel's @ai-sdk/otel OpenTelemetry integration.
  • Uses the upstream enrichSpan hook to add only Langfuse observation attributes, instead of recreating AI SDK span lifecycle behavior ourselves.
  • Maps every AI SDK-included runtimeContext key to Langfuse observation metadata, except langfusePrompt, which links Langfuse prompt name/version and is not added as metadata.
  • Keeps trace-level context out of the integration; users should set user/session/tags/trace metadata via propagateAttributes from @langfuse/tracing.
  • Extends @langfuse/otel media parsing to handle AI SDK v7 OpenTelemetry message parts, including file/image attachments and empty blob-content guards.
  • Adds package unit tests, integration coverage for propagateAttributes and span processing, and e2e coverage for AI SDK v7 server-side ingestion.
  • Aligns the e2e OpenAI provider dependency with AI SDK v7 canary packages so file/image inputs serialize correctly.
  • Wires the new package into the workspace, build, typedoc, Vitest workspace, root package table, and lockfile.

Verification

  • pnpm run build
  • pnpm run check:lint
  • pnpm run check:type
  • pnpm run check:format
  • pnpm --filter @langfuse/vercel-ai-sdk test
  • pnpm exec vitest run --project=integration tests/integration/vercel-ai-sdk.integration.test.ts
  • GitHub Actions lint, test-integration, test-e2e, and all-tests-passed are green on 148389c.

Release info

Bump level

  • Major
  • Minor
  • Patch

Libraries affected

  • All of them
  • @langfuse/core
  • @langfuse/client
  • @langfuse/tracing
  • @langfuse/otel
  • @langfuse/openai
  • @langfuse/langchain
  • @langfuse/vercel-ai-sdk

Changelog notes

  • Added @langfuse/vercel-ai-sdk with AI SDK v7 telemetry support.
  • Added AI SDK v7 media attachment parsing for OpenTelemetry spans exported through Langfuse.

@vercel

vercel Bot commented Apr 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
langfuse-js Ready Ready Preview Jun 26, 2026 2:37pm

Request Review

@github-actions

Copy link
Copy Markdown

@claude review

Comment thread tests/e2e/vercel-ai-sdk-v7.e2e.test.ts Outdated
Comment thread packages/vercel-ai-sdk/src/tests/testUtils.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 53f0072fe4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread vitest.workspace.ts Outdated
Comment thread tests/e2e/vercel-ai-sdk-v7.e2e.test.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 83394e9706

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/vercel-ai-sdk/src/testUtils.ts Outdated
Comment thread tests/integration/vercel-ai-sdk.integration.test.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 22c6d54403

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/vercel-ai-sdk/src/LangfuseVercelAiSdkIntegration.ts
Comment thread packages/vercel-ai-sdk/README.md Outdated
Comment thread packages/otel/src/MediaService.ts Outdated
Comment thread tests/e2e/vercel-ai-sdk-v7.e2e.test.ts Outdated
Comment thread packages/otel/src/MediaService.ts
Comment thread packages/vercel-ai-sdk/src/tests/testUtils.ts Outdated
Comment thread packages/vercel-ai-sdk/package.json

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b51f773f96

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/vercel-ai-sdk/package.json
Comment thread packages/vercel-ai-sdk/package.json Outdated
Comment thread packages/vercel-ai-sdk/package.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f88c8c15d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/vercel-ai-sdk/src/LangfuseVercelAiSdkIntegration.ts
@hassiebp hassiebp had a problem deploying to protected branches June 18, 2026 12:18 — with GitHub Actions Failure

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 81bfa1f0aa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/otel/src/MediaService.ts
Comment thread packages/vercel-ai-sdk/README.md Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: beb0ff7c01

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/vercel-ai-sdk/package.json
Comment thread packages/otel/src/MediaService.ts
@hassiebp hassiebp merged commit 7368af4 into main Jun 26, 2026
11 of 13 checks passed
@hassiebp hassiebp deleted the codex/add-vercel-ai-sdk-integration branch June 26, 2026 14:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f4d6a9d4a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

This integration targets AI SDK v7 GA. Install it together with `ai@^7`; the package depends on the matching `@ai-sdk/otel` integration internally.

```sh
pnpm add @langfuse/vercel-ai-sdk ai

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add required Langfuse tracing packages to install step

pnpm add @langfuse/vercel-ai-sdk ai is not enough for the Usage example immediately below: it imports @langfuse/tracing, which this package does not depend on, and the spans also need a LangfuseSpanProcessor from @langfuse/otel to reach Langfuse. Users who follow these docs in a fresh project will hit a module-resolution error or end up with no exported spans, so include the required Langfuse/OpenTelemetry packages or make the sample not depend on them.

Useful? React with 👍 / 👎.

Comment on lines +100 to +101
// Handle media from Vercel AI SDK v6 and AI SDK v7.
if (["ai", "gen_ai"].includes(span.instrumentationScope.name)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 AI SDK v6/v7 media handling is skipped whenever a user passes a custom tracer to LangfuseVercelAiSdkIntegration, because MediaService.ts:101 gates the entire media block on ['ai','gen_ai'].includes(span.instrumentationScope.name) — but a user-supplied tracer (a publicly supported option in LangfuseVercelAiSdkIntegrationOptions) sets the scope name to whatever the user picked. The spans still get exported (the rest of the pipeline correctly classifies them by attribute presence via isGenAISpan), but base64 file/image payloads stay inline in gen_ai.input.messages / gen_ai.output.messages instead of being uploaded to Langfuse media storage. Fix: gate by attribute presence (e.g. reuse isGenAISpan from span-filter.ts, or check any gen_ai.*/ai.* key) so the classification matches the rest of the export pipeline.

Extended reasoning...

What the bug is

LangfuseVercelAiSdkIntegrationOptions (packages/vercel-ai-sdk/src/types.ts:9) exposes a public tracer?: Tracer option, which LangfuseVercelAiSdkIntegration.ts:37 forwards verbatim to the @ai-sdk/otel OpenTelemetry constructor. In the installed @ai-sdk/otel@1.0.0-beta.125, the constructor resolves this.tracer = options.tracer ?? trace.getTracer('gen_ai') — so every span produced by every this.tracer.startSpan(...) call inherits the user's chosen instrumentation scope name when a custom tracer is supplied.

The AI SDK semantic-convention attribute keys (gen_ai.input.messages, gen_ai.output.messages, gen_ai.operation.name, etc.) are hardcoded string literals on those span attributes, so they are emitted regardless of which tracer created the span. LangfuseSpanProcessor correctly exports those spans because span-filter.ts:32-36 isGenAISpan checks attribute presence (Object.keys(span.attributes).some(k => k.startsWith('gen_ai.'))), not the scope name.

But packages/otel/src/MediaService.ts:100-101 gates the entire v6 + v7 media-handling block on ["ai", "gen_ai"].includes(span.instrumentationScope.name). With a custom tracer like new LangfuseVercelAiSdkIntegration({ tracer: trace.getTracer("my-app") }), the scope is my-app, the check fails, and the whole v6 (ai.prompt.messages/ai.prompt) AND v7 (gen_ai.input.messages/gen_ai.output.messages) media replacement block is skipped. Base64 file/image payloads stay inline in the exported attributes — never uploaded to Langfuse media storage, never replaced with @@@langfuseMedia:...@@@ tags. The Langfuse UI then renders huge raw base64 strings instead of the inlined-media tag.

Step-by-step proof

  1. User writes new LangfuseVercelAiSdkIntegration({ tracer: trace.getTracer("my-app") }) (a documented option on LangfuseVercelAiSdkIntegrationOptions).
  2. That tracer reaches @ai-sdk/otel OpenTelemetry. Every span it creates carries instrumentationScope.name === "my-app".
  3. The user calls generateText({ messages: [{ role: "user", content: [{ type: "file", mediaType: "application/pdf", data: "<base64-pdf>" }, ...] }] }). @ai-sdk/otel serializes the messages into gen_ai.input.messages as JSON [{ role: "user", parts: [{ type: "blob", content: "<base64-pdf>", mime_type: "application/pdf" }, ...] }].
  4. LangfuseSpanProcessor calls isDefaultExportSpan(span)isGenAISpan(span) returns true (attributes start with gen_ai.), span is exported.
  5. MediaService.process(span) reaches line 100: ["ai", "gen_ai"].includes("my-app")false. The entire block at lines 100-232 is skipped.
  6. The exported attribute still contains the raw base64. No upload happens. Langfuse UI shows the base64 blob inline.

Replacing the check with isGenAISpan(span) (or any gen_ai.* attribute presence test) keeps the existing default behavior and fixes the custom-tracer case — and matches the asymmetry the verifiers flagged: the rest of the pipeline already classifies these spans by attribute presence; only this one site uses scope name.

Why it survived review

The tracer option is not exercised by the README examples, the package tests, the integration test, or the v7 e2e suite — every test path uses the default gen_ai scope. So the gate check works in the default flow and never triggers in CI. The codex bot raised the same issue in this PR's inline comment 3435755845 (2026-06-18T12:29:46Z), without maintainer response.

Suggested fix

In packages/otel/src/MediaService.ts, replace the scope-name check with attribute-presence detection. Either inline:

const isAiSdkSpan = Object.keys(span.attributes).some(
  (k) => k.startsWith("gen_ai.") || k.startsWith("ai."),
);
if (isAiSdkSpan) { ... }

or reuse the existing helper from span-filter.ts:

import { isGenAISpan } from "./span-filter.js";
// ...
if (isGenAISpan(span)) { ... }

The latter has the bonus of staying consistent with the rest of the export pipeline's classification.

🔬 also observed by chatgpt-codex-connector

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.

1 participant