Install the peer
pnpm add @mv37/rollout aiWrap the AI SDK
Wrap the AI SDK module explicitly. This does not monkeypatch globals — only calls made through the returned object are instrumented. Pass stable identity through experimental_telemetry.metadata with eventMetadata:
import * as ai from "ai";import { Rollout } from "@mv37/rollout";import { wrapAISDK, eventMetadata } from "@mv37/rollout/ai-sdk";const rollout = new Rollout({ apiKey: process.env.ROLLOUT_API_KEY });const wrappedAI = wrapAISDK(ai, { client: rollout, context: { agentName: "support_agent", userId: "user_123", conversationId: "chat_123", },});const result = await wrappedAI.generateText({ model, prompt: "Help the user", experimental_telemetry: { metadata: eventMetadata({ userId: "user_123", conversationId: "chat_123", externalTraceId: "message_123", agentName: "support_agent", }), },});What it instruments
wrapAISDK currently instruments generateText, streamText, generateObject, and streamObject. It creates an implicit trace when there is no active Rollout trace, or attaches the LLM span to the active trace when one exists.
Stream calls preserve the AI SDK result object and record stream start/end, bounded previews, usage, finish reason, and any tool callbacks the AI SDK exposes.
useChat route handlers
For useChat route handlers, derive stable metadata from the request body with eventMetadataFromChatRequest:
import * as ai from "ai";import { convertToModelMessages } from "ai";import { eventMetadataFromChatRequest, wrapAISDK } from "@mv37/rollout/ai-sdk";export async function POST(req: Request) { const body = await req.json(); const wrappedAI = wrapAISDK(ai, { client: rollout }); const result = wrappedAI.streamText({ model, messages: convertToModelMessages(body.messages), experimental_telemetry: { metadata: eventMetadataFromChatRequest({ request: body, userId: "user_123", agentName: "support_agent", }), }, }); return result.toUIMessageStreamResponse();}Server only
Heads up
Use this integration only on the server. Do not expose Rollout workspace API keys in browser bundles.