Use with Vercel AI SDK
Trace Vercel AI SDK calls (generateText, streamText, generateObject, embeddings, agents) by wrapping the ai module with wrapVercelAI().
Use with Vercel AI SDK
The Vercel AI SDK (the ai package) is traced by wrapping the ai module with wrapVercelAI(). Pass the imported module through the wrapper once, then use the functions it returns in place of the originals — every generateText, streamText, and so on is captured as a trace.
The Vercel AI SDK integration is TypeScript / Node.js only.
Install
npm install @browserstack/ai-sdk ai @ai-sdk/openai@ai-sdk/openai is the model-provider package used in this example. Install the one that matches your model instead (@ai-sdk/anthropic, @ai-sdk/google, etc.) — @browserstack/ai-sdk and ai are always required.
Set your credentials as environment variables before running. The SDK reads AISDK_PUBLIC_KEY / AISDK_SECRET_KEY; the OpenAI provider reads OPENAI_API_KEY:
export AISDK_PUBLIC_KEY=pk-...
export AISDK_SECRET_KEY=sk-...
export OPENAI_API_KEY=sk-...
node app.jsPrefer keeping keys in a .env file? Install dotenv and add import 'dotenv/config'; as the first line — it loads the file into process.env. It's a convenience, not an SDK requirement.
Usage
Wrap the ai module with wrapVercelAI(), create your model provider as usual, then call the wrapped functions. This is a complete, runnable ES module (node app.js with "type": "module", or app.mjs).
import * as aiModule from 'ai';
import { createOpenAI } from '@ai-sdk/openai';
import { wrapVercelAI } from '@browserstack/ai-sdk';
// Wrap the module once; use the returned functions everywhere.
const ai = wrapVercelAI(aiModule);
// Wait for auto-instrumentation to finish initializing so the first call is
// traced. Short scripts only — a long-running server does not need this.
await new Promise((r) => setTimeout(r, 5000));
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
async function main() {
// generateText — captured as a trace
const { text } = await ai.generateText({
model: openai('gpt-4o-mini'),
prompt: 'In one sentence, what is the capital of France?',
});
console.log('generateText →', text);
// Short-lived scripts exit before spans are exported — wait briefly so the
// batch is flushed. A long-running server does not need this.
await new Promise((r) => setTimeout(r, 5000));
console.log('Done');
}
main().catch((err) => {
console.error(err);
process.exit(1);
});Any function you use is read off the wrapped module the same way — ai.generateObject, ai.streamObject, ai.embed, and so on.
About the two setTimeout waits
They exist only because this example is a short-lived script that starts calling the model immediately and then exits. They are not part of the tracing API.
- The wait before the calls gives the SDK's auto-instrumentation a moment to finish initializing after
wrapVercelAI(), so the firstgenerateTextcall is captured instead of slipping through before setup completes. - The wait before exit lets the batched spans finish exporting. Spans are sent in the background in batches; a script that exits the instant the call returns can terminate before that batch is flushed, dropping the trace.
Neither wait is needed in production. A long-running service (API server, background worker) initializes tracing once at startup — well before it serves any traffic — and never exits between requests, so spans export continuously on their own. Remove both waits there. Only in environments that start fresh and exit per invocation (a serverless function, a one-shot CLI) do you need to guarantee the final spans are sent — and there you should flush explicitly on graceful shutdown rather than relying on a fixed setTimeout.
What gets traced
wrapVercelAI instruments the module's core functions:
| Category | Functions |
|---|---|
| Text & objects | generateText, generateObject |
| Streaming | streamText, streamObject |
| Embeddings | embed, embedMany |
| Images | generateImage |
| Reranking | rerank |
| Agents | Agent / ToolLoopAgent (generate / stream), including tool calls |
Each call is captured with the model, prompt / messages, response, and token usage. Streaming calls also record time-to-first-token, and agent loops capture each step and tool call as nested spans.
See also
- Auto-Instrumentation — providers and other frameworks
- Manual Tracing — record any call yourself
- Supported Integrations — full support matrix