Skip to main content

Vercel AI SDK Integration

Automatically track all Vercel AI SDK calls with full input/output logging, token usage, and tool executions. Enable OpenTelemetry and experimental_telemetry—no wrapper or extra instrumentation needed.

What Gets Tracked Automatically

CategoryCaptured
LLM callsModel, provider, prompt, messages, system prompt
ResponsesGenerated text, finish reason
Token usageInput tokens, output tokens, total tokens
Tool callsAll tool executions with input/output
LatencyDuration in milliseconds

Installation

npm install ai @ai-sdk/openai @opentelemetry/api @vercel/otel @runcascade/cascade-sdk
# or with other providers
npm install @ai-sdk/anthropic @ai-sdk/google

Configuration

Add CASCADE_API_KEY to .env (or Vercel dashboard) and call configureVercelAiTelemetry at app startup. Traces export to Cascade Cloud automatically.
# .env
CASCADE_API_KEY=csk_live_your_key_here
import { configureVercelAiTelemetry } from '@runcascade/cascade-sdk';

await configureVercelAiTelemetry({
  serviceName: 'my-ai-app',
  apiKey: process.env.CASCADE_API_KEY,
  registerOtel: true,
});

Basic Usage

  1. Call configureVercelAiTelemetry at startup (with registerOtel: true).
  2. Enable experimental_telemetry on your AI calls.
  3. Traces export to Cascade Cloud automatically.
import { configureVercelAiTelemetry } from '@runcascade/cascade-sdk';
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';

await configureVercelAiTelemetry({
  serviceName: 'my-ai-app',
  apiKey: process.env.CASCADE_API_KEY,
  registerOtel: true,
});

const { text } = await generateText({
  model: openai('gpt-4'),
  prompt: 'What is the capital of France?',
  experimental_telemetry: { isEnabled: true },
});

With Tools

Tool calls are automatically traced as child spans:
import { generateText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

const { text } = await generateText({
  model: openai('gpt-4'),
  prompt: "What's the weather in San Francisco?",
  tools: {
    getWeather: tool({
      description: 'Get weather for a location',
      inputSchema: z.object({ location: z.string() }),
      execute: async ({ location }) => {
        return { temperature: 72, conditions: 'sunny' };
      },
    }),
  },
  experimental_telemetry: { isEnabled: true },
});
Each tool execution appears in Cascade with tool.name, tool.input, and tool.output.

Streaming

streamText is fully supported. Spans are emitted as chunks complete.
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = streamText({
  model: openai('gpt-4'),
  prompt: 'Tell me a story',
  experimental_telemetry: { isEnabled: true },
});

for await (const chunk of result.textStream) {
  process.stdout.write(chunk);
}

Next.js

Create instrumentation.ts at the project root (or in src/):
// instrumentation.ts
import { configureVercelAiTelemetry } from '@runcascade/cascade-sdk';

export async function register() {
  await configureVercelAiTelemetry({
    serviceName: 'my-nextjs-ai-app',
    apiKey: process.env.CASCADE_API_KEY,
    registerOtel: true,
  });
}
Then use generateText or streamText in your API routes with experimental_telemetry: { isEnabled: true }:
// app/api/chat/route.ts
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';

export async function POST(request: Request) {
  const { message } = await request.json();

  const { text } = await generateText({
    model: openai('gpt-4o'),
    messages: [
      { role: 'system', content: 'You are helpful.' },
      { role: 'user', content: message },
    ],
    experimental_telemetry: { isEnabled: true },
  });

  return Response.json({ response: text });
}