Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 74 additions & 60 deletions docs/platforms/javascript/common/agent-tracing/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ supported:
- javascript.nitro
---

With <Link to="/product/agents/dashboards/">Sentry Agent Tracing</Link>, you can monitor and debug your AI systems with full-stack context. You'll be able to track key insights like token usage, latency, tool usage, and error rates. Agent Tracing data will be fully connected to your other Sentry data like logs, errors, and traces.
With <Link to="/product/agents/dashboards/">Sentry Agent Tracing</Link>, you can monitor and debug your AI systems with full-stack context. Track token usage, latency, tool usage, and error rates — and group multi-turn chats in <Link to="/product/agents/conversations/">Conversations</Link>. Agent Tracing data is fully connected to your other Sentry data like logs, errors, and traces.

<AgentSetupCallout skill="sentry-setup-ai-monitoring" />

Expand All @@ -46,6 +46,10 @@ Before setting up Agent Tracing, ensure you have <PlatformLink to="/tracing/">tr

The JavaScript SDK supports automatic instrumentation for AI libraries. Add the integration for your AI library to your Sentry configuration:

<PlatformSection supported={["javascript.cloudflare"]}>
- <PlatformLink to="/features/workers-ai/">Cloudflare Workers AI</PlatformLink> — automatic instrumentation for `env.AI` (no integration to add)
</PlatformSection>

<PlatformSection notSupported={["javascript.deno"]}>
- <PlatformLink to="/configuration/integrations/vercelai/">Vercel AI SDK</PlatformLink>
- <PlatformLink to="/configuration/integrations/openai/">OpenAI</PlatformLink>
Expand Down Expand Up @@ -79,139 +83,149 @@ Sentry.init({
</SplitSection>
</SplitLayout>

## Options
## Tracking Conversations

<Alert>
Tracking Conversations has **beta** stability. Configuration options and behavior may change.
</Alert>

<SplitLayout>
<SplitSection>
<SplitSectionText>

### Privacy Controls
[Conversations](/product/agents/conversations/) groups multi-turn AI activity into a single replay of messages and tool calls. Use `setConversationId()` so every AI span in a chat session shares the same `gen_ai.conversation.id`.

All AI integrations support `recordInputs` and `recordOutputs` options to control whether prompts and responses are captured. Both default to `true`.
Some integrations infer a conversation ID automatically. For everything else (including Workers AI), set it yourself at the start of the session. The ID is applied to all AI-related spans in the current scope. Pass `null` to unset it.

Set these to `false` if your prompts or responses contain sensitive data you don't want sent to Sentry.
<PlatformSection supported={["javascript.cloudflare"]}>

Building with the [Cloudflare Agents SDK](https://developers.cloudflare.com/agents/)? Link chats with your session ID. See <PlatformLink to="/features/agents-sdk/">Cloudflare Agents SDK</PlatformLink>.

</PlatformSection>

</SplitSectionText>
<SplitSectionCode>

```javascript
import * as Sentry from "___SDK_PACKAGE___";
import { openAIIntegration } from "___SDK_PACKAGE___";

Sentry.init({
dsn: "___PUBLIC_DSN___",
tracesSampleRate: 1.0,
integrations: [
openAIIntegration({
recordInputs: false, // Don't capture prompts
recordOutputs: false, // Don't capture responses
}),
// Set conversation ID at the start of a conversation
Sentry.setConversationId('conv_abc123');

// All subsequent AI calls will be linked to this conversation
await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: "Hello" }],
});

// Later in the conversation
await openai.chat.completions.create({
model: "gpt-4",
messages: [
{ role: "user", content: "Hello" },
{ role: "assistant", content: "Hi there!" },
{ role: "user", content: "What's the weather?" },
],
});

// Both calls will have gen_ai.conversation.id: "conv_abc123"

// To unset it
Sentry.setConversationId(null);
```

</SplitSectionCode>
</SplitSection>
</SplitLayout>

### Identifying Users in Conversations

The [Conversations](/product/agents/conversations/) view includes a **User** column. To populate it, call `setUser` once per request or session, before any AI calls:

```javascript
import * as Sentry from "___SDK_PACKAGE___";

Sentry.setUser({ id: "user_123", email: "jane@example.com", username: "jane" });
```

Any of `id`, `email`, or `username` is sufficient — Conversations displays whichever fields are present. See the <PlatformLink to="/configuration/apis/#setUser">setUser API reference</PlatformLink> for the full list of supported fields.

## Options

<SplitLayout>
<SplitSection>
<SplitSectionText>

### Streaming Gen AI Spans
### Privacy Controls

`gen_ai` spans are sent as standalone envelope items instead of being bundled in the transaction by default (since SDK version `10.61.0`). This prevents AI spans with large inputs and outputs from hitting transaction payload size limits and being dropped, and is required for <Link to="/product/agents/conversations/">Conversations</Link> to work.
All AI integrations support `recordInputs` and `recordOutputs` options to control whether prompts and responses are captured. Both default to `true`.

To send `gen_ai` spans as part of the transaction instead, set `streamGenAiSpans` to `false`. Self-hosted Sentry users should set this to `false`, as standalone `gen_ai` spans may not be ingested by their Sentry instance.
Set these to `false` if your prompts or responses contain sensitive data you don't want sent to Sentry.

</SplitSectionText>
<SplitSectionCode>

```javascript
import * as Sentry from "___SDK_PACKAGE___";
import { openAIIntegration } from "___SDK_PACKAGE___";

Sentry.init({
dsn: "___PUBLIC_DSN___",
tracesSampleRate: 1.0,
streamGenAiSpans: false, // opt out of streaming gen_ai spans
integrations: [
openAIIntegration({
recordInputs: false, // Don't capture prompts
recordOutputs: false, // Don't capture responses
}),
],
});
```

</SplitSectionCode>
</SplitSection>
</SplitLayout>

## Tracking Conversations

<Alert>
Tracking Conversations has **beta** stability. Configuration options and behavior may change.
</Alert>

<SplitLayout>
<SplitSection>
<SplitSectionText>

When building AI applications with multi-turn conversations, you can use `setConversationId()` to link all AI spans from the same conversation together. This allows you to analyze entire conversation flows in Sentry.
### Streaming Gen AI Spans

`gen_ai` spans are sent as standalone envelope items instead of being bundled in the transaction by default (since SDK version `10.61.0`). This prevents AI spans with large inputs and outputs from hitting transaction payload size limits and being dropped, and is required for <Link to="/product/agents/conversations/">Conversations</Link> to work.

The conversation ID is automatically applied as the `gen_ai.conversation.id` attribute to all AI-related spans within the current scope. To unset the conversation ID, pass `null`.
To send `gen_ai` spans as part of the transaction instead, set `streamGenAiSpans` to `false`. Self-hosted Sentry users should set this to `false`, as standalone `gen_ai` spans may not be ingested by their Sentry instance.

</SplitSectionText>
<SplitSectionCode>

```javascript
import * as Sentry from "___SDK_PACKAGE___";

// Set conversation ID at the start of a conversation
Sentry.setConversationId('conv_abc123');

// All subsequent AI calls will be linked to this conversation
await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: "Hello" }],
});

// Later in the conversation
await openai.chat.completions.create({
model: "gpt-4",
messages: [
{ role: "user", content: "Hello" },
{ role: "assistant", content: "Hi there!" },
{ role: "user", content: "What's the weather?" },
],
Sentry.init({
dsn: "___PUBLIC_DSN___",
tracesSampleRate: 1.0,
streamGenAiSpans: false, // opt out of streaming gen_ai spans
});

// Both calls will have gen_ai.conversation.id: "conv_abc123"

// To unset it
Sentry.setConversationId(null);
```

</SplitSectionCode>
</SplitSection>
</SplitLayout>

## Identifying Users in Conversations

The [Conversations](/product/agents/conversations/) view includes a **User** column. To populate it, call `setUser` once per request or session, before any AI calls:

```javascript
import * as Sentry from "___SDK_PACKAGE___";

Sentry.setUser({ id: "user_123", email: "jane@example.com", username: "jane" });
```

Any of `id`, `email`, or `username` is sufficient — Conversations displays whichever fields are present. See the [setUser API reference](/platforms/javascript/configuration/apis/#setUser) for the full list of supported fields.

## Manual Instrumentation

You can also instrument agent spans yourself. See <PlatformLink to="/agent-tracing/manual-instrumentation/">manual instrumentation</PlatformLink>.

## Framework Exporters

<PlatformSection supported={["javascript.node", "javascript.aws-lambda", "javascript.azure-functions", "javascript.connect", "javascript.express", "javascript.fastify", "javascript.gcp-functions", "javascript.hapi", "javascript.hono", "javascript.koa", "javascript.nestjs", "javascript.bun", "javascript.nextjs", "javascript.nuxt", "javascript.astro", "javascript.solidstart", "javascript.sveltekit", "javascript.remix", "javascript.tanstackstart-react"]}>

If you're using an AI framework with a Sentry exporter, you can send traces to Sentry:

- <PlatformLink to="/agent-tracing/mastra/">Mastra Sentry Exporter</PlatformLink>

</PlatformSection>

## MCP Server Monitoring

If you're building MCP (Model Context Protocol) servers, Sentry can also track tool executions, prompt retrievals, and resource access. See <PlatformLink to="/tracing/instrumentation/mcp-module/">Instrument MCP Servers</PlatformLink> for setup instructions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: Cloudflare Agents SDK
description: "Link Cloudflare Agents SDK chats to Sentry Conversations with a chat session ID."
---

When you build agents with the [Cloudflare Agents SDK](https://developers.cloudflare.com/agents/), set a conversation ID so multi-turn AI activity groups correctly in <Link to="/product/agents/conversations/">Conversations</Link>.

Use **your chat session ID** (for example a UUID or `conv_…` value your app creates when the user starts a chat). Do not use a user ID, room name, or the Durable Object instance name unless that name is already one chat session.

Workers AI and other AI integrations do **not** set this for you.

## Prerequisites

- <PlatformLink to="/tracing/">Tracing enabled</PlatformLink>
- Durable Objects instrumented with `instrumentDurableObjectWithSentry` (see <PlatformLink to="/features/durableobject/">Durable Objects</PlatformLink>)

## Link conversations

Set the conversation ID before any AI calls in the request handler:

```typescript
import * as Sentry from "@sentry/cloudflare";
import { Agent } from "agents";

class MyAgentBase extends Agent<Env> {
async onRequest(request: Request): Promise<Response> {
// Your chat session ID for this conversation (not user id / "default")
const chatSessionId = new URL(request.url).searchParams.get("chatId");
if (chatSessionId) {
Sentry.setConversationId(chatSessionId);
}

const result = await this.env.AI.run("@cf/meta/llama-3.1-8b-instruct", {
messages: [{ role: "user", content: await request.text() }],
});

return new Response(JSON.stringify(result));
}
}

export const MyAgent = Sentry.instrumentDurableObjectWithSentry(
(env: Env) => ({
dsn: "___PUBLIC_DSN___",
tracesSampleRate: 1.0,
}),
MyAgentBase
);
```

If you already name each agent instance as one chat session (for example `useAgent({ name: chatSessionId })`), you can pass that value:

```typescript
Sentry.setConversationId(this.name);
```

Only do this when the instance name is **one conversation**, not per-user or a shared singleton like `"default"`.

To clear the ID: `Sentry.setConversationId(null)`.

## Users

Populate the Conversations **User** column with `Sentry.setUser` once per session, before AI calls. See <PlatformLink to="/agent-tracing/#identifying-users-in-conversations">Identifying Users in Conversations</PlatformLink>.

## Related

- <PlatformLink to="/features/workers-ai/">Workers AI</PlatformLink>
- <PlatformLink to="/features/durableobject/">Durable Objects</PlatformLink>
- <PlatformLink to="/agent-tracing/#tracking-conversations">Tracking Conversations</PlatformLink>
- <Link to="/product/agents/conversations/">Conversations</Link> product docs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "Learn how Sentry instruments Cloudflare Workers AI to capture gen_

<AvailableSince version="10.67.0" />

Sentry automatically instruments the [Cloudflare Workers AI binding](https://developers.cloudflare.com/workers-ai/get-started/workers-wrangler/) (`env.AI`). Calls to `env.AI.run(...)` create `gen_ai` spans that follow Sentry's <PlatformLink to="/ai-agent-monitoring/">AI Agent Monitoring</PlatformLink> conventions, capturing the model, request parameters, and token usage.
Sentry automatically instruments the [Cloudflare Workers AI binding](https://developers.cloudflare.com/workers-ai/get-started/workers-wrangler/) (`env.AI`). Calls to `env.AI.run(...)` create `gen_ai` spans that follow Sentry's <PlatformLink to="/agent-tracing/">Agent Tracing</PlatformLink> conventions, capturing the model, request parameters, and token usage.

No extra setup is required beyond initializing the SDK with `withSentry`. As long as your handler receives the instrumented `env`, the `AI` binding is wrapped for you:

Expand All @@ -32,86 +32,7 @@ export default Sentry.withSentry(

You can browse the full list of available models in the [Cloudflare Workers AI models directory](https://developers.cloudflare.com/ai/models/).

## Tracking Conversations
## Next Steps

<Alert>
Tracking Conversations has **beta** stability. Configuration options and
behavior may change.
</Alert>

The Workers AI instrumentation does **not** infer the conversation ID automatically. To group multi-turn AI calls into a single <Link to="/product/agents/conversations/">Conversation</Link>, set it manually with <PlatformLink to="/configuration/apis/#setConversationId">`Sentry.setConversationId()`</PlatformLink>. The ID is applied as the `gen_ai.conversation.id` attribute to all AI spans within the current scope. See <PlatformLink to="/ai-agent-monitoring/#tracking-conversations">Tracking Conversations</PlatformLink> for details.

When you use the [Cloudflare Agents SDK](https://developers.cloudflare.com/agents/), each agent instance already has a stable identifier, its Durable Object instance name (`this.name`), which is a natural conversation ID.

### Agent

Set the conversation ID at the start of the request handler, before any `env.AI.run(...)` calls:

```typescript
import * as Sentry from "@sentry/cloudflare";
import { Agent } from "agents";

class MyAgentBase extends Agent<Env> {
async onRequest(request: Request): Promise<Response> {
// Use the Agent's Durable Object instance name as the conversation ID
Sentry.setConversationId(this.name);

const result = await this.env.AI.run("@cf/meta/llama-3.1-8b-instruct", {
messages: [{ role: "user", content: await request.text() }],
});

return new Response(JSON.stringify(result));
}
}

export const MyAgent = Sentry.instrumentDurableObjectWithSentry(
(env: Env) => ({
dsn: "___PUBLIC_DSN___",
tracesSampleRate: 1.0,
}),
MyAgentBase
);
```

### ChatAgent

For chat agents, set the conversation ID at the top of `onChatMessage` so every AI call triggered while handling the message shares it:

```typescript
import * as Sentry from "@sentry/cloudflare";
import { AIChatAgent } from "@cloudflare/ai-chat";
import type { StreamTextOnFinishCallback } from "ai";

class MyChatAgentBase extends AIChatAgent<Env> {
async onChatMessage(
_onFinish: StreamTextOnFinishCallback
): Promise<Response | undefined> {
// Every message in this chat session shares the same conversation ID
Sentry.setConversationId(this.name);

const result = await this.env.AI.run("@cf/meta/llama-3.1-8b-instruct", {
messages: this.messages.map((m) => ({
role: m.role,
content: m.parts
.filter((p) => p.type === "text")
.map((p) => p.text)
.join(""),
})),
});

return new Response(JSON.stringify(result));
}
}

export const MyChatAgent = Sentry.instrumentDurableObjectWithSentry(
(env: Env) => ({
dsn: "___PUBLIC_DSN___",
tracesSampleRate: 1.0,
}),
MyChatAgentBase
);
```

To unset the conversation ID, pass `null` to `Sentry.setConversationId()`.

Grouped AI calls show up in the <Link to="/product/agents/conversations/">Conversations</Link> view, where you can inspect token usage, latency, and errors across an entire conversation.
- Group multi-turn chats in <Link to="/product/agents/conversations/">Conversations</Link> with <PlatformLink to="/agent-tracing/#tracking-conversations">`setConversationId()`</PlatformLink>
- Using the [Cloudflare Agents SDK](https://developers.cloudflare.com/agents/)? See <PlatformLink to="/features/agents-sdk/">Cloudflare Agents SDK</PlatformLink> for conversation linking
Loading