---
title: "Vercel AI"
description: "Adds instrumentation for Vercel AI SDK."
url: https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai/
---

# Vercel AI | Sentry for Astro

*Import name: `Sentry.vercelAIIntegration`*

The `vercelAIIntegration` adds instrumentation for the [`ai`](https://www.npmjs.com/package/ai) SDK by Vercel to capture spans using the [AI SDK's built-in telemetry](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry).

Don't use the AI SDK's `registerTelemetry` API (AI SDK v7 and above) together with this integration. `vercelAIIntegration` already instruments the AI SDK, so registering telemetry separately produces duplicate spans.

## [Setup](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#setup)

The integration is enabled by default and captures spans for all `ai` function calls. No setup code is needed beyond enabling tracing:

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  tracesSampleRate: 1.0,
});
```

Prompts and completions are not captured until you opt in. See [Record inputs and outputs](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#record-inputs-and-outputs).

## [Record Inputs and Outputs](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#record-inputs-and-outputs)

Prompts and completions are not captured by default, because they usually contain user data. Turn recording on with `recordInputs` and `recordOutputs`.

Sentry resolves both settings in this order, and stops at the first one that is set:

1. The integration option — applies to every call.
2. The call's `experimental_telemetry` — applies to that call.
3. [`dataCollection.genAI`](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/options.md#dataCollection) — applies to every call.

The integration option wins over the call, not the other way around. If you set `recordInputs: false` on the integration, no call site can turn it back on.

Set the options on the integration to cover every call. Re-adding the integration replaces the default instance and configures it:

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  tracesSampleRate: 1.0,
  integrations: [
    Sentry.vercelAIIntegration({
      recordInputs: true,
      recordOutputs: true,
    }),
  ],
});
```

To record only some calls, leave the integration options unset and set them per call instead:

```javascript
const result = await generateText({
  model: openai("gpt-4o"),
  experimental_telemetry: {
    recordInputs: true,
    recordOutputs: true,
  },
});
```

`dataCollection: {}` also turns recording on, but it opts you into the SDK's permissive defaults for every other category too: user identity, cookies, headers, HTTP bodies, query parameters, and stack-frame locals. Prefer the integration and per-call options above unless you want all of it. See [`dataCollection`](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/options.md#dataCollection).

## [Configure individual calls](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#configure-individual-calls)

Every instrumented `ai` function takes an `experimental_telemetry` object. Use it to control one call instead of all of them. For the full list of fields, see the [AI SDK telemetry metadata docs](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry#telemetry-metadata).

### [Skip a Call](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#skip-a-call)

To capture no span for one call, set `isEnabled` to `false`:

```javascript
const result = await generateText({
  model: openai("gpt-4o"),
  experimental_telemetry: { isEnabled: false },
});
```

### [Identify Your Call Sites](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#identify-your-call-sites)

Spans carry the AI SDK function name, not yours, so a trace with several `generateText` calls is hard to read. Set `functionId` to label the call site. It appears on the span as `gen_ai.function_id`:

```javascript
const result = await generateText({
  model: openai("gpt-4o"),
  experimental_telemetry: {
    functionId: "summarize-ticket",
  },
});
```

### [ToolLoopAgent](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#toolloopagent)

The integration captures spans for the [`ToolLoopAgent`](https://ai-sdk.dev/docs/agents/overview#toolloopagent-class) class. Each call to `generate()` or `stream()` creates an agent span, with the individual LLM requests and tool executions as child spans.

`ToolLoopAgent` takes its telemetry settings on the constructor, not on `generate()` or `stream()`:

```javascript
const agent = new ToolLoopAgent({
  model: openai("gpt-4o"),
  tools: {
    /* ... */
  },
  experimental_telemetry: {
    functionId: "weather-agent",
  },
});

const result = await agent.generate({
  prompt: "What is the weather in San Francisco?",
});
```

Spans are captured without the `experimental_telemetry` block. Pass it only to set `functionId` or the recording options.

## [Options](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#options)

### [`enableTruncation`](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#enabletruncation)

*Type: `boolean`*

Truncates recorded input messages so large payloads stay within span size limits. Affects inputs only, not outputs.

Defaults to `true`.

```javascript
Sentry.init({
  integrations: [Sentry.vercelAIIntegration({ enableTruncation: false })],
});
```

### [`force`](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#force)

*Type: `boolean`*

Registers the integration's span processors even when the `ai` module can't be detected. Set this when your build bundles `ai`, which defeats module detection. See [Troubleshooting](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#troubleshooting).

Defaults to `false`.

```javascript
Sentry.init({
  integrations: [Sentry.vercelAIIntegration({ force: true })],
});
```

### [`recordInputs`](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#recordinputs)

*Type: `boolean`*

Records inputs to the `ai` function call. See [Record inputs and outputs](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#record-inputs-and-outputs) for the full resolution order and the per-call alternative.

### [`recordOutputs`](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#recordoutputs)

*Type: `boolean`*

Records outputs from the `ai` function call. See [Record inputs and outputs](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#record-inputs-and-outputs) for the full resolution order and the per-call alternative.

## [Supported Operations](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#supported-operations)

Spans are captured for these `ai` functions:

* `generateText()`
* `streamText()`
* `generateObject()`
* `streamObject()`
* `embed()`
* `embedMany()`
* `rerank()`

Plus `generate()` and `stream()` on [`ToolLoopAgent`](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#toolloopagent).

## [Supported Versions](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#supported-versions)

* `ai`: `>=3.0.0 <=7`

- Sentry SDK: `10.6.0`+

## [Troubleshooting](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#troubleshooting)

Why are my prompts and completions missing?

Recording is off unless you turn it on. Check, in order:

1. `recordInputs` and `recordOutputs` are set. See [Record inputs and outputs](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/vercelai.md#record-inputs-and-outputs).
2. You set them in a place the runtime reads. Some runtimes ignore the integration options and take them per call only.
3. No integration option is overriding your per-call value. The integration option wins.
