Frametail

AI SDK tracing

Wrap generateImage and experimental_generateVideo from the Vercel AI SDK for automatic tracing.

Why integrate

The Vercel AI SDK provides a unified interface for image and video generation across multiple providers (FAL, OpenAI, Google, xAI, and more). Frametail wrappers capture latency, prompts, model metadata, and output URLs while sanitizing binary data (base64, uint8Array).

Supports AI SDK v6 and v7 (canary).

Basic setup

pnpm add frametail ai @ai-sdk/fal
import { FrametailClient } from 'frametail'
import { experimental_generateVideo as generateVideo } from 'ai'
import { fal } from '@ai-sdk/fal'

const frametail = new FrametailClient({
  apiKey: process.env.FRAMETAIL_API_KEY!,
  projectKey: process.env.FRAMETAIL_PROJECT_KEY!,
  enableTracing: true,
})

// Wrap once
const tracedGenerateVideo = frametail.wrapGenerateVideo(generateVideo)

// Generate video with any AI SDK provider
const { video } = await tracedGenerateVideo({
  model: fal.video('luma-dream-machine/ray-2'),
  prompt: 'A serene mountain landscape at sunset',
  aspectRatio: '16:9',
})

Image generation

Wrap generateImage the same way. Spans use type compose with image.url and output.kind: image (aligned with Fal text-to-image traces):

import { generateImage } from 'ai'

const tracedGenerateImage = frametail.wrapGenerateImage(generateImage)

const { image } = await tracedGenerateImage({
  model: fal.image('fal-ai/flux/dev'),
  prompt: 'A cat wearing sunglasses, studio lighting',
  aspectRatio: '1:1',
})

Multiple images (n > 1) produce one span per call; binary fields in the response are stripped from exported span data.

Polling timeout

Video generation can take several minutes. Configure the polling timeout via providerOptions:

import { fal, type FalVideoModelOptions } from '@ai-sdk/fal'

const { video } = await tracedGenerateVideo({
  model: fal.video('luma-dream-machine/ray-2'),
  prompt: 'A cinematic timelapse of a city from dawn to dusk',
  duration: 10,
  providerOptions: {
    fal: {
      pollTimeoutMs: 600_000, // 10 minutes
    } satisfies FalVideoModelOptions,
  },
})

Image-to-video

When using image-to-video models, images are automatically masked in span data:

const { video } = await tracedGenerateVideo({
  model: fal.video('fal-ai/stable-video-diffusion'),
  prompt: {
    image: 'https://example.com/my-image.png',
    text: 'Animate with gentle motion',
  },
})

Standalone wrappers

Use wrapGenerateVideo or wrapGenerateImage directly without FrametailClient when you need a custom exporter:

import { wrapGenerateVideo, wrapGenerateImage, createConsoleExporter } from 'frametail'

const tracedVideo = wrapGenerateVideo(generateVideo, createConsoleExporter())
const tracedImage = wrapGenerateImage(generateImage, createConsoleExporter())

Traces dashboard

After generation completes, open Traces in the dashboard and filter by provider AI SDK. Each span shows:

  • Model and provider system (gen_ai.request.model, gen_ai.system)
  • Prompt text (video.prompt)
  • Video URL when available (video.url) or image URL (image.url)
  • Duration and any warnings