diff --git a/static/app/gettingStartedDocs/javascript-astro/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript-astro/agentMonitoring.tsx
deleted file mode 100644
index 9d844c93f66c96..00000000000000
--- a/static/app/gettingStartedDocs/javascript-astro/agentMonitoring.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-
-export const agentMonitoring = getNodeAgentMonitoringOnboarding({
- packageName: '@sentry/astro',
- configFileName: 'sentry.server.config.js',
-});
diff --git a/static/app/gettingStartedDocs/javascript-astro/index.tsx b/static/app/gettingStartedDocs/javascript-astro/index.tsx
index a3044121d43c41..37acc842772cb1 100644
--- a/static/app/gettingStartedDocs/javascript-astro/index.tsx
+++ b/static/app/gettingStartedDocs/javascript-astro/index.tsx
@@ -3,8 +3,8 @@ import {featureFlag} from 'sentry/gettingStartedDocs/javascript/featureFlag';
import {logsFullStack} from 'sentry/gettingStartedDocs/javascript/logs';
import {metricsFullStack} from 'sentry/gettingStartedDocs/javascript/metrics';
import {profilingFullStack} from 'sentry/gettingStartedDocs/javascript/profiling';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-import {agentMonitoring} from './agentMonitoring';
import {crashReport} from './crashReport';
import {feedback} from './feedback';
import {mcp} from './mcp';
@@ -32,7 +32,10 @@ const docs: Docs = {
docsPlatform: 'astro',
packageName: '@sentry/astro',
}),
- agentMonitoringOnboarding: agentMonitoring,
+ agentMonitoringOnboarding: getNodeAgentMonitoringOnboarding({
+ packageName: '@sentry/astro',
+ configFileName: 'sentry.server.config.js',
+ }),
mcpOnboarding: mcp,
};
diff --git a/static/app/gettingStartedDocs/javascript-nextjs/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript-nextjs/agentMonitoring.tsx
deleted file mode 100644
index 0915f42b47f03c..00000000000000
--- a/static/app/gettingStartedDocs/javascript-nextjs/agentMonitoring.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-
-export const agentMonitoring = getNodeAgentMonitoringOnboarding({
- packageName: '@sentry/nextjs',
- configFileName: 'sentry.server.config.ts',
-});
diff --git a/static/app/gettingStartedDocs/javascript-nextjs/index.tsx b/static/app/gettingStartedDocs/javascript-nextjs/index.tsx
index 228f8b58582e18..37bd7200dd7bdd 100644
--- a/static/app/gettingStartedDocs/javascript-nextjs/index.tsx
+++ b/static/app/gettingStartedDocs/javascript-nextjs/index.tsx
@@ -3,9 +3,9 @@ import {featureFlag} from 'sentry/gettingStartedDocs/javascript/featureFlag';
import {logsFullStack} from 'sentry/gettingStartedDocs/javascript/logs';
import {metricsFullStack} from 'sentry/gettingStartedDocs/javascript/metrics';
import {profilingFullStack} from 'sentry/gettingStartedDocs/javascript/profiling';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
import {tct} from 'sentry/locale';
-import {agentMonitoring} from './agentMonitoring';
import {crashReport} from './crashReport';
import {feedback} from './feedback';
import {mcp} from './mcp';
@@ -87,7 +87,10 @@ const docs: Docs = {
docsPlatform: 'nextjs',
packageName: '@sentry/nextjs',
}),
- agentMonitoringOnboarding: agentMonitoring,
+ agentMonitoringOnboarding: getNodeAgentMonitoringOnboarding({
+ packageName: '@sentry/nextjs',
+ configFileName: 'sentry.server.config.ts',
+ }),
mcpOnboarding: mcp,
};
diff --git a/static/app/gettingStartedDocs/javascript-nuxt/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript-nuxt/agentMonitoring.tsx
deleted file mode 100644
index f6c3ce07407a85..00000000000000
--- a/static/app/gettingStartedDocs/javascript-nuxt/agentMonitoring.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-
-export const agentMonitoring = getNodeAgentMonitoringOnboarding({
- packageName: '@sentry/nuxt',
- configFileName: 'sentry.server.config.ts',
-});
diff --git a/static/app/gettingStartedDocs/javascript-nuxt/index.tsx b/static/app/gettingStartedDocs/javascript-nuxt/index.tsx
index 890e049eadad82..3f97db92c920d8 100644
--- a/static/app/gettingStartedDocs/javascript-nuxt/index.tsx
+++ b/static/app/gettingStartedDocs/javascript-nuxt/index.tsx
@@ -3,8 +3,8 @@ import {featureFlag} from 'sentry/gettingStartedDocs/javascript/featureFlag';
import {logsFullStack} from 'sentry/gettingStartedDocs/javascript/logs';
import {metricsFullStack} from 'sentry/gettingStartedDocs/javascript/metrics';
import {profiling} from 'sentry/gettingStartedDocs/javascript/profiling';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-import {agentMonitoring} from './agentMonitoring';
import {crashReport} from './crashReport';
import {feedback} from './feedback';
import {mcp} from './mcp';
@@ -31,7 +31,10 @@ const docs: Docs = {
docsPlatform: 'nuxt',
packageName: '@sentry/nuxt',
}),
- agentMonitoringOnboarding: agentMonitoring,
+ agentMonitoringOnboarding: getNodeAgentMonitoringOnboarding({
+ packageName: '@sentry/nuxt',
+ configFileName: 'sentry.server.config.ts',
+ }),
mcpOnboarding: mcp,
};
diff --git a/static/app/gettingStartedDocs/javascript-react-router/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript-react-router/agentMonitoring.tsx
deleted file mode 100644
index 86bf4847850222..00000000000000
--- a/static/app/gettingStartedDocs/javascript-react-router/agentMonitoring.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-
-export const agentMonitoring = getNodeAgentMonitoringOnboarding({
- packageName: '@sentry/react-router',
- configFileName: 'instrument.server.mjs',
-});
diff --git a/static/app/gettingStartedDocs/javascript-react-router/index.tsx b/static/app/gettingStartedDocs/javascript-react-router/index.tsx
index 731f4ed878a102..961dcbc2169d6e 100644
--- a/static/app/gettingStartedDocs/javascript-react-router/index.tsx
+++ b/static/app/gettingStartedDocs/javascript-react-router/index.tsx
@@ -2,8 +2,8 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types';
import {logsFullStack} from 'sentry/gettingStartedDocs/javascript/logs';
import {metricsFullStack} from 'sentry/gettingStartedDocs/javascript/metrics';
import {profilingFullStack} from 'sentry/gettingStartedDocs/javascript/profiling';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-import {agentMonitoring} from './agentMonitoring';
import {crashReport} from './crashReport';
import {feedback} from './feedback';
import {mcp} from './mcp';
@@ -24,7 +24,10 @@ const docs: Docs = {
nodeProfilingLink:
'https://docs.sentry.io/platforms/javascript/guides/react-router/profiling/node-profiling/',
}),
- agentMonitoringOnboarding: agentMonitoring,
+ agentMonitoringOnboarding: getNodeAgentMonitoringOnboarding({
+ packageName: '@sentry/react-router',
+ configFileName: 'instrument.server.mjs',
+ }),
logsOnboarding: logsFullStack({
docsPlatform: 'react-router',
packageName: '@sentry/react-router',
diff --git a/static/app/gettingStartedDocs/javascript-remix/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript-remix/agentMonitoring.tsx
deleted file mode 100644
index 175d0968066703..00000000000000
--- a/static/app/gettingStartedDocs/javascript-remix/agentMonitoring.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-
-export const agentMonitoring = getNodeAgentMonitoringOnboarding({
- packageName: '@sentry/remix',
- configFileName: 'instrument.server.mjs',
-});
diff --git a/static/app/gettingStartedDocs/javascript-remix/index.tsx b/static/app/gettingStartedDocs/javascript-remix/index.tsx
index f3d2ea8c929b6a..28c45323c69038 100644
--- a/static/app/gettingStartedDocs/javascript-remix/index.tsx
+++ b/static/app/gettingStartedDocs/javascript-remix/index.tsx
@@ -3,8 +3,8 @@ import {featureFlag} from 'sentry/gettingStartedDocs/javascript/featureFlag';
import {logsFullStack} from 'sentry/gettingStartedDocs/javascript/logs';
import {metricsFullStack} from 'sentry/gettingStartedDocs/javascript/metrics';
import {profilingFullStack} from 'sentry/gettingStartedDocs/javascript/profiling';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-import {agentMonitoring} from './agentMonitoring';
import {crashReport} from './crashReport';
import {feedback} from './feedback';
import {mcp} from './mcp';
@@ -28,7 +28,10 @@ const docs: Docs = {
docsPlatform: 'remix',
packageName: '@sentry/remix',
}),
- agentMonitoringOnboarding: agentMonitoring,
+ agentMonitoringOnboarding: getNodeAgentMonitoringOnboarding({
+ packageName: '@sentry/remix',
+ configFileName: 'instrument.server.mjs',
+ }),
logsOnboarding: logsFullStack({
docsPlatform: 'remix',
packageName: '@sentry/remix',
diff --git a/static/app/gettingStartedDocs/javascript-solidstart/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript-solidstart/agentMonitoring.tsx
deleted file mode 100644
index 073fca29ac73d8..00000000000000
--- a/static/app/gettingStartedDocs/javascript-solidstart/agentMonitoring.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-
-export const agentMonitoring = getNodeAgentMonitoringOnboarding({
- packageName: '@sentry/solidstart',
- configFileName: 'instrument.server.mjs',
-});
diff --git a/static/app/gettingStartedDocs/javascript-solidstart/index.tsx b/static/app/gettingStartedDocs/javascript-solidstart/index.tsx
index c67539a889375f..4c9b5e0181019b 100644
--- a/static/app/gettingStartedDocs/javascript-solidstart/index.tsx
+++ b/static/app/gettingStartedDocs/javascript-solidstart/index.tsx
@@ -3,8 +3,8 @@ import {featureFlag} from 'sentry/gettingStartedDocs/javascript/featureFlag';
import {logsFullStack} from 'sentry/gettingStartedDocs/javascript/logs';
import {metricsFullStack} from 'sentry/gettingStartedDocs/javascript/metrics';
import {profiling} from 'sentry/gettingStartedDocs/javascript/profiling';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-import {agentMonitoring} from './agentMonitoring';
import {crashReport} from './crashReport';
import {feedback} from './feedback';
import {mcp} from './mcp';
@@ -23,7 +23,10 @@ const docs: Docs = {
docsLink:
'https://docs.sentry.io/platforms/javascript/guides/solidstart/profiling/browser-profiling/',
}),
- agentMonitoringOnboarding: agentMonitoring,
+ agentMonitoringOnboarding: getNodeAgentMonitoringOnboarding({
+ packageName: '@sentry/solidstart',
+ configFileName: 'instrument.server.mjs',
+ }),
logsOnboarding: logsFullStack({
docsPlatform: 'solidstart',
packageName: '@sentry/solidstart',
diff --git a/static/app/gettingStartedDocs/javascript-sveltekit/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript-sveltekit/agentMonitoring.tsx
deleted file mode 100644
index 763bcc3e2642c9..00000000000000
--- a/static/app/gettingStartedDocs/javascript-sveltekit/agentMonitoring.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-
-export const agentMonitoring = getNodeAgentMonitoringOnboarding({
- packageName: '@sentry/sveltekit',
- configFileName: 'instrumentation.server.js',
-});
diff --git a/static/app/gettingStartedDocs/javascript-sveltekit/index.tsx b/static/app/gettingStartedDocs/javascript-sveltekit/index.tsx
index 25f323597d0b8d..45d893e667a3ba 100644
--- a/static/app/gettingStartedDocs/javascript-sveltekit/index.tsx
+++ b/static/app/gettingStartedDocs/javascript-sveltekit/index.tsx
@@ -3,8 +3,8 @@ import {featureFlag} from 'sentry/gettingStartedDocs/javascript/featureFlag';
import {logsFullStack} from 'sentry/gettingStartedDocs/javascript/logs';
import {metricsFullStack} from 'sentry/gettingStartedDocs/javascript/metrics';
import {profilingFullStack} from 'sentry/gettingStartedDocs/javascript/profiling';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-import {agentMonitoring} from './agentMonitoring';
import {crashReport} from './crashReport';
import {feedback} from './feedback';
import {mcp} from './mcp';
@@ -24,7 +24,10 @@ const docs: Docs = {
nodeProfilingLink:
'https://docs.sentry.io/platforms/javascript/guides/sveltekit/profiling/node-profiling/',
}),
- agentMonitoringOnboarding: agentMonitoring,
+ agentMonitoringOnboarding: getNodeAgentMonitoringOnboarding({
+ packageName: '@sentry/sveltekit',
+ configFileName: 'instrumentation.server.js',
+ }),
logsOnboarding: logsFullStack({
docsPlatform: 'sveltekit',
packageName: '@sentry/sveltekit',
diff --git a/static/app/gettingStartedDocs/javascript-tanstackstart-react/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript-tanstackstart-react/agentMonitoring.tsx
deleted file mode 100644
index 8b7fb840c1aeb0..00000000000000
--- a/static/app/gettingStartedDocs/javascript-tanstackstart-react/agentMonitoring.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-
-export const agentMonitoring = getNodeAgentMonitoringOnboarding({
- packageName: '@sentry/tanstackstart-react',
- configFileName: 'app/ssr.tsx',
-});
diff --git a/static/app/gettingStartedDocs/javascript-tanstackstart-react/index.tsx b/static/app/gettingStartedDocs/javascript-tanstackstart-react/index.tsx
index 72d70d5035ca06..fab5cf0a8e7a72 100644
--- a/static/app/gettingStartedDocs/javascript-tanstackstart-react/index.tsx
+++ b/static/app/gettingStartedDocs/javascript-tanstackstart-react/index.tsx
@@ -2,8 +2,8 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types';
import {logsFullStack} from 'sentry/gettingStartedDocs/javascript/logs';
import {metricsFullStack} from 'sentry/gettingStartedDocs/javascript/metrics';
import {profilingFullStack} from 'sentry/gettingStartedDocs/javascript/profiling';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/utils';
-import {agentMonitoring} from './agentMonitoring';
import {mcp} from './mcp';
import {onboarding} from './onboarding';
@@ -16,7 +16,10 @@ const docs: Docs = {
nodeProfilingLink:
'https://docs.sentry.io/platforms/javascript/guides/tanstackstart-react/profiling/node-profiling/',
}),
- agentMonitoringOnboarding: agentMonitoring,
+ agentMonitoringOnboarding: getNodeAgentMonitoringOnboarding({
+ packageName: '@sentry/tanstackstart-react',
+ configFileName: 'app/ssr.tsx',
+ }),
logsOnboarding: logsFullStack({
docsPlatform: 'tanstackstart-react',
packageName: '@sentry/tanstackstart-react',
diff --git a/static/app/gettingStartedDocs/javascript/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript/agentMonitoring.tsx
index 274c9114bfe641..e2a7d7a6518d9a 100644
--- a/static/app/gettingStartedDocs/javascript/agentMonitoring.tsx
+++ b/static/app/gettingStartedDocs/javascript/agentMonitoring.tsx
@@ -14,7 +14,7 @@ import {
import {t, tct} from 'sentry/locale';
import {AgentIntegration} from 'sentry/views/insights/pages/agents/utils/agentIntegrations';
-function getClientSideAgentMonitoringOnboardingConfig({
+function getClientSideConfig({
integration,
params,
sentryImport,
@@ -321,7 +321,7 @@ export function agentMonitoring({
return [
{
title: t('Configure'),
- content: getClientSideAgentMonitoringOnboardingConfig({
+ content: getClientSideConfig({
integration: selected,
sentryImport: getImport(packageName, importMode).join('\n'),
params,
diff --git a/static/app/gettingStartedDocs/node/utils.tsx b/static/app/gettingStartedDocs/node/utils.tsx
index 9995b55b1d99fb..47b3643001417b 100644
--- a/static/app/gettingStartedDocs/node/utils.tsx
+++ b/static/app/gettingStartedDocs/node/utils.tsx
@@ -103,6 +103,48 @@ export function getAgentMonitoringInstallStep(
packageName?: `@sentry/${string}`;
} = {}
): OnboardingStep[] {
+ const selected =
+ (params.platformOptions as any)?.integration ?? AgentIntegration.VERCEL_AI;
+
+ if (selected === AgentIntegration.MASTRA) {
+ return [
+ {
+ type: StepType.INSTALL,
+ content: [
+ {
+ type: 'text',
+ text: tct(
+ 'Install the [code:@mastra/sentry] package to enable Sentry integration with Mastra.',
+ {
+ code: ,
+ }
+ ),
+ },
+ {
+ type: 'code',
+ tabs: [
+ {
+ label: 'npm',
+ language: 'bash',
+ code: 'npm install @mastra/sentry',
+ },
+ {
+ label: 'yarn',
+ language: 'bash',
+ code: 'yarn add @mastra/sentry',
+ },
+ {
+ label: 'pnpm',
+ language: 'bash',
+ code: 'pnpm add @mastra/sentry',
+ },
+ ],
+ },
+ ],
+ },
+ ];
+ }
+
return [
{
type: StepType.INSTALL,
@@ -409,341 +451,105 @@ Sentry.profiler.stopProfiler();
],
});
-const getBrowserAgentMonitoringOnboardingConfiguration = ({
+function getAgentMonitoringConfigStep({
+ params,
integration,
packageName,
importMode,
+ configFileName,
}: {
integration: AgentIntegration;
packageName: `@sentry/${string}`;
- importMode?: 'esm' | 'cjs' | 'esm-only';
-}): ContentBlock[] => {
- if (integration === AgentIntegration.LANGGRAPH) {
- return [
- {
- type: 'text',
- text: tct(
- 'Then follow the [manualSpanCreationDoc:manual custom spans] to instrument your AI calls, or use the [code:instrumentLangGraph] helper:',
- {
- manualSpanCreationDoc: (
-
- ),
- code: ,
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName, importMode).join('\n')}
-import { ChatOpenAI } from "@langchain/openai";
-import { createReactAgent } from "@langchain/langgraph/prebuilt";
-import { HumanMessage, SystemMessage } from "@langchain/core/messages";
-
-const llm = new ChatOpenAI({
- modelName: "gpt-4o",
- // WARNING: Never expose API keys in browser code
- apiKey: "YOUR_OPENAI_API_KEY",
-});
-
-const agent = createReactAgent({ llm, tools: [] });
-
-Sentry.instrumentLangGraph(agent, {
- recordInputs: true,
- recordOutputs: true,
-});
-
-const result = await agent.invoke({
- messages: [
- new SystemMessage("You are a helpful assistant."),
- new HumanMessage("Tell me a joke")
- ],
-});
-
-const messages = result.messages;
-const lastMessage = messages[messages.length - 1];
-const text = lastMessage.content;
- `,
- },
- ],
- },
- ];
- }
-
- if (integration === AgentIntegration.LANGCHAIN) {
- return [
- {
- type: 'text',
- text: tct(
- 'Then follow the [manualSpanCreationDoc:manual custom spans] to instrument your AI calls, or use the [code:createLangChainCallbackHandler] helper:',
- {
- manualSpanCreationDoc: (
-
- ),
- code: ,
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName, importMode).join('\n')}
-import { ChatOpenAI } from "@langchain/openai";
-import { HumanMessage, SystemMessage } from "@langchain/core/messages";
-
-
-// Create a LangChain callback handler
-const callbackHandler = Sentry.createLangChainCallbackHandler({
- recordInputs: true, // Optional: record input prompts/messages
- recordOutputs: true, // Optional: record output responses
-});
-
-const chatModel = new ChatOpenAI({
- modelName: "gpt-4o",
- // WARNING: Never expose API keys in browser code
- apiKey: "YOUR_OPENAI_API_KEY",
-});
-
-const messages = [
- new SystemMessage("You are a helpful assistant."),
- new HumanMessage("Tell me a joke"),
-];
-
-const response = await chatModel.invoke(messages, {
- callbacks: [callbackHandler],
-});
-const text = response.content;
- `,
- },
- ],
- },
- ];
- }
-
- if (integration === AgentIntegration.GOOGLE_GENAI) {
- return [
- {
- type: 'text',
- text: tct(
- 'Then follow the [manualSpanCreationDoc:manual custom spans] to instrument your AI calls, or use the [code:instrumentGoogleGenAIClient] helper:',
- {
- manualSpanCreationDoc: (
-
- ),
- code: ,
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName, importMode).join('\n')}
-import { GoogleGenAI } from "@google/genai";
-
-// WARNING: Never expose API keys in browser code
-const genAI = new GoogleGenAI("YOUR_GOOGLE_API_KEY");
-
-const client = Sentry.instrumentGoogleGenAIClient(genAI, {
- recordInputs: true,
- recordOutputs: true,
-});
-
-const response = await client.models.generateContent({
- model: 'gemini-2.5-flash-lite',
- contents: 'Why is the sky blue?',
-});
- `,
- },
- ],
- },
- ];
- }
-
- if (integration === AgentIntegration.ANTHROPIC) {
- return [
- {
- type: 'text',
- text: tct(
- 'Then follow the [manualSpanCreationDoc:manual custom spans] to instrument your AI calls, or use the [code:instrumentAnthropicAiClient] helper:',
- {
- manualSpanCreationDoc: (
-
- ),
- code: ,
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName, importMode).join('\n')}
-import Anthropic from "@anthropic-ai/sdk";
-
-const anthropic = new Anthropic();
-
-const client = Sentry.instrumentAnthropicAiClient(anthropic, {
- recordInputs: true,
- recordOutputs: true,
-});
-
-const msg = await client.messages.create({
- model: "claude-3-5-sonnet",
- messages: [{role: "user", content: "Tell me a joke"}],
-});
- `,
- },
- ],
- },
- ];
- }
-
- if (integration === AgentIntegration.OPENAI) {
- return [
- {
- type: 'text',
- text: tct(
- 'Then follow the [manualSpanCreationDoc:manual custom spans] to instrument your AI calls, or use the [code:instrumentOpenAiClient] helper:',
- {
- manualSpanCreationDoc: (
-
- ),
- code: ,
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName, importMode).join('\n')}
-import OpenAI from "openai";
-
-const openai = new OpenAI();
-
-const client = Sentry.instrumentOpenAiClient(openai, {
- recordInputs: true,
- recordOutputs: true,
-});
-
-const response = await client.responses.create({
- model: "gpt-4o-mini",
- input: "Tell me a joke",
-});
- `,
- },
- ],
- },
- ];
- }
-
- return [];
-};
-
-export const getNodeAgentMonitoringOnboarding = ({
- packageName = '@sentry/node',
- configFileName,
- importMode,
-}: {
+ params: DocsParams;
configFileName?: string;
importMode?: 'esm' | 'cjs' | 'esm-only';
- packageName?: `@sentry/${string}`;
-} = {}): OnboardingConfig => ({
- install: params => {
- const selected =
- (params.platformOptions as any)?.integration ?? AgentIntegration.VERCEL_AI;
+}): OnboardingStep[] {
+ // Meta-frameworks can run on multiple runtimes (Node.js server-side, Browser client-side, etc.).
+ // We only show Node.js instructions here to keep onboarding simple.
+ // For other runtimes, we show an alert linking to the docs.
+ const isMetaFramework = javascriptMetaFrameworks.includes(params.platformKey);
- if (selected === AgentIntegration.MASTRA) {
- return [
+ const manualInstrumentationAlert: ContentBlock[] = isMetaFramework
+ ? [
{
- type: StepType.INSTALL,
- content: [
+ type: 'alert',
+ alertType: 'info',
+ text: tct(
+ "Below you'll find setup instructions for server-side on Node.js. For other runtimes, like the Browser, the instrumentation needs to be manually enabled. [link:See the docs] for more information.",
{
- type: 'text',
- text: tct(
- 'Install the [code:@mastra/sentry] package to enable Sentry integration with Mastra.',
- {
- code: ,
- }
+ link: (
+
),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'npm',
- language: 'bash',
- code: 'npm install @mastra/sentry',
- },
- {
- label: 'yarn',
- language: 'bash',
- code: 'yarn add @mastra/sentry',
- },
- {
- label: 'pnpm',
- language: 'bash',
- code: 'pnpm add @mastra/sentry',
- },
- ],
- },
- ],
+ }
+ ),
},
- ];
- }
+ ]
+ : [];
- return getAgentMonitoringInstallStep(params, {
- packageName,
- });
- },
- configure: params => {
- const selected =
- (params.platformOptions as any)?.integration ?? AgentIntegration.VERCEL_AI;
+ const vercelAiExtraInstrumentation: ContentBlock[] =
+ integration === AgentIntegration.VERCEL_AI
+ ? [
+ {
+ type: 'text',
+ text: tct(
+ 'To correctly capture spans, pass the [code:experimental_telemetry] object to every [code:generateText], [code:generateObject], and [code:streamText] function call. For more details, see the [link:AI SDK Telemetry Metadata docs].',
+ {
+ code: ,
+ link: (
+
+ ),
+ }
+ ),
+ },
+ {
+ type: 'code',
+ tabs: [
+ {
+ label: 'JavaScript',
+ language: 'javascript',
+ code: `const { generateText } = require('ai');
+const { openai } = require('@ai-sdk/openai');
- if (selected === AgentIntegration.MANUAL) {
- return getAgentMonitoringManualConfigStep(params, {
- packageName,
- importMode,
- });
- }
+const result = await generateText({
+ model: openai("gpt-4o"),
+ prompt: "Tell me a joke",
+ experimental_telemetry: {
+ isEnabled: true,
+ recordInputs: true,
+ recordOutputs: true,
+ },
+});`,
+ },
+ ],
+ },
+ ]
+ : [];
- if (selected === AgentIntegration.MASTRA) {
- return [
- {
- title: t('Configure'),
- content: [
- {
- type: 'text',
- text: tct(
- 'Configure Mastra to use Sentry by adding the [code:SentryExporter] to your Mastra observability config. For more details, see the [link:@mastra/sentry package].',
- {
- code: ,
- link: (
-
- ),
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `import { Mastra } from '@mastra/core';
+ return [
+ {
+ title: t('Configure'),
+ content:
+ integration === AgentIntegration.MASTRA
+ ? [
+ {
+ type: 'text',
+ text: tct(
+ 'Configure Mastra to use Sentry by adding the [code:SentryExporter] to your Mastra observability config. For more details, see the [link:@mastra/sentry package].',
+ {
+ code: ,
+ link: (
+
+ ),
+ }
+ ),
+ },
+ {
+ type: 'code',
+ tabs: [
+ {
+ label: 'JavaScript',
+ language: 'javascript',
+ code: `import { Mastra } from '@mastra/core';
import { SentryExporter } from '@mastra/sentry';
const mastra = new Mastra({
@@ -755,6 +561,7 @@ const mastra = new Mastra({
exporters: [
new SentryExporter({
dsn: '${params.dsn.public}',
+ // Tracing must be enabled for agent monitoring to work
tracesSampleRate: 1.0,
}),
],
@@ -762,74 +569,28 @@ const mastra = new Mastra({
},
},
});`,
- },
- ],
- },
- ],
- },
- ];
- }
-
- const isNodeOrMetaPlatform =
- params.platformKey.startsWith('node') ||
- javascriptMetaFrameworks.includes(params.platformKey);
-
- const vercelAiExtraInstrumentation: ContentBlock[] = [
- {
- type: 'text',
- text: tct(
- 'To correctly capture spans, pass the [code:experimental_telemetry] object to every [code:generateText], [code:generateObject], and [code:streamText] function call. For more details, see the [link:AI SDK Telemetry Metadata docs].',
- {
- code: ,
- link: (
-
- ),
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `const { generateText } = require('ai');
-const { openai } = require('@ai-sdk/openai');
-
-const result = await generateText({
- model: openai("gpt-4o"),
- prompt: "Tell me a joke",
- experimental_telemetry: {
- isEnabled: true,
- recordInputs: true,
- recordOutputs: true,
- },
-});`,
- },
- ],
- },
- ];
-
- const nonManualContent: ContentBlock[] = [
- {
- type: 'text',
- text: isNodeOrMetaPlatform
- ? tct(
- 'Import and initialize the Sentry SDK - the [integration] will be enabled automatically:',
+ },
+ ],
+ },
+ ]
+ : [
+ ...manualInstrumentationAlert,
{
- integration:
- AGENT_INTEGRATION_LABELS[selected as AgentIntegration] ?? selected,
- }
- )
- : t('Import and initialize the Sentry SDK:'),
- },
- {
- type: 'code',
- tabs: [
- {
- label: configFileName ? configFileName : 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName, importMode).join('\n')}
+ type: 'text',
+ text: tct(
+ 'Import and initialize the Sentry SDK - the [integration] will be enabled automatically:',
+ {
+ integration: AGENT_INTEGRATION_LABELS[integration] ?? integration,
+ }
+ ),
+ },
+ {
+ type: 'code',
+ tabs: [
+ {
+ label: configFileName ?? 'JavaScript',
+ language: 'javascript',
+ code: `${getImport(packageName, importMode).join('\n')}
Sentry.init({
dsn: "${params.dsn.public}",
@@ -839,120 +600,92 @@ Sentry.init({
// see https://docs.sentry.io/platforms/javascript/data-management/data-collected/ for more info
sendDefaultPii: true,
});`,
- },
- ],
- },
- ...(selected === AgentIntegration.VERCEL_AI ? vercelAiExtraInstrumentation : []),
- ];
-
- return [
- {
- title: t('Configure'),
- content: isNodeOrMetaPlatform
- ? nonManualContent
- : [
- ...nonManualContent,
- ...getBrowserAgentMonitoringOnboardingConfiguration({
- integration: selected,
- packageName,
- importMode,
- }),
+ },
+ ],
+ },
+ ...vercelAiExtraInstrumentation,
],
- },
- ];
- },
- verify: params => {
- const isNodePlatform =
- params.platformKey.startsWith('node') ||
- javascriptMetaFrameworks.includes(params.platformKey as any);
-
- const content: ContentBlock[] = [
- {
- type: 'text',
- text: t('Verify that your instrumentation works by simply calling your LLM.'),
- },
- ];
+ },
+ ];
+}
- if (!isNodePlatform) {
- return [
- {
- type: StepType.VERIFY,
- content,
- },
- ];
- }
+function getAgentMonitoringVerifyStep(params: DocsParams): OnboardingStep[] {
+ const content: ContentBlock[] = [
+ {
+ type: 'text',
+ text: t('Verify that your instrumentation works by simply calling your LLM.'),
+ },
+ ];
- const selected =
- (params.platformOptions as any)?.integration ?? AgentIntegration.VERCEL_AI;
+ const selected =
+ (params.platformOptions as any)?.integration ?? AgentIntegration.VERCEL_AI;
- if (selected === AgentIntegration.ANTHROPIC) {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `
-const Anthropic = require("@anthropic-ai/sdk");
+ if (selected === AgentIntegration.ANTHROPIC) {
+ content.push({
+ type: 'code',
+ tabs: [
+ {
+ label: 'JavaScript',
+ language: 'javascript',
+ code: `const Anthropic = require("@anthropic-ai/sdk");
const client = new Anthropic();
const msg = await client.messages.create({
- messages: [{role: "user", content: "Tell me a joke"}],
+ messages: [{ role: "user", content: "Tell me a joke" }],
model: "claude-sonnet-4-5-20250929",
-});
-`,
- },
- ],
- });
- }
- if (selected === AgentIntegration.OPENAI) {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `
-const OpenAI = require("openai");
+});`,
+ },
+ ],
+ });
+ }
+
+ if (selected === AgentIntegration.OPENAI) {
+ content.push({
+ type: 'code',
+ tabs: [
+ {
+ label: 'JavaScript',
+ language: 'javascript',
+ code: `const OpenAI = require("openai");
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-4o-mini",
input: "Tell me a joke",
});`,
- },
- ],
- });
- }
- if (selected === AgentIntegration.GOOGLE_GENAI) {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `
-const GoogleGenAI = require("@google/genai").GoogleGenAI;
+ },
+ ],
+ });
+ }
+
+ if (selected === AgentIntegration.GOOGLE_GENAI) {
+ content.push({
+ type: 'code',
+ tabs: [
+ {
+ label: 'JavaScript',
+ language: 'javascript',
+ code: `const GoogleGenAI = require("@google/genai").GoogleGenAI;
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
-const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
+const ai = new GoogleGenAI({ apiKey: GEMINI_API_KEY });
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: 'Why is the sky blue?',
});`,
- },
- ],
- });
- }
- if (selected === AgentIntegration.LANGCHAIN) {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `
-const { ChatOpenAI } = require("@langchain/openai");
+ },
+ ],
+ });
+ }
+
+ if (selected === AgentIntegration.LANGCHAIN) {
+ content.push({
+ type: 'code',
+ tabs: [
+ {
+ label: 'JavaScript',
+ language: 'javascript',
+ code: `const { ChatOpenAI } = require("@langchain/openai");
const { HumanMessage, SystemMessage } = require("@langchain/core/messages");
const chatModel = new ChatOpenAI({
@@ -967,19 +700,19 @@ const messages = [
const response = await chatModel.invoke(messages);
const text = response.content;`,
- },
- ],
- });
- }
- if (selected === AgentIntegration.LANGGRAPH) {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `
-const { ChatOpenAI } = require("@langchain/openai");
+ },
+ ],
+ });
+ }
+
+ if (selected === AgentIntegration.LANGGRAPH) {
+ content.push({
+ type: 'code',
+ tabs: [
+ {
+ label: 'JavaScript',
+ language: 'javascript',
+ code: `const { ChatOpenAI } = require("@langchain/openai");
const { createReactAgent } = require("@langchain/langgraph/prebuilt");
const { HumanMessage, SystemMessage } = require("@langchain/core/messages");
@@ -1000,18 +733,19 @@ const result = await agent.invoke({
const messages = result.messages;
const lastMessage = messages[messages.length - 1];
const text = lastMessage.content;`,
- },
- ],
- });
- }
- if (selected === AgentIntegration.MASTRA) {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `import { Agent } from '@mastra/core/agent';
+ },
+ ],
+ });
+ }
+
+ if (selected === AgentIntegration.MASTRA) {
+ content.push({
+ type: 'code',
+ tabs: [
+ {
+ label: 'JavaScript',
+ language: 'javascript',
+ code: `import { Agent } from '@mastra/core/agent';
// This agent needs to be registered in your Mastra config
const agent = new Agent({
@@ -1022,18 +756,52 @@ const agent = new Agent({
});
const result = await agent.generate([{ role: "user", content: "Hello!" }]);`,
- },
- ],
+ },
+ ],
+ });
+ }
+
+ return [
+ {
+ type: StepType.VERIFY,
+ content,
+ },
+ ];
+}
+
+export const getNodeAgentMonitoringOnboarding = ({
+ packageName = '@sentry/node',
+ configFileName,
+ importMode,
+}: {
+ configFileName?: string;
+ importMode?: 'esm' | 'cjs' | 'esm-only';
+ packageName?: `@sentry/${string}`;
+} = {}): OnboardingConfig => ({
+ install: params =>
+ getAgentMonitoringInstallStep(params, {
+ packageName,
+ }),
+ configure: params => {
+ const selected =
+ (params.platformOptions as any)?.integration ?? AgentIntegration.VERCEL_AI;
+
+ if (selected === AgentIntegration.MANUAL) {
+ return getAgentMonitoringManualConfigStep(params, {
+ packageName,
+ importMode,
});
}
- return [
- {
- type: StepType.VERIFY,
- content,
- },
- ];
+ return getAgentMonitoringConfigStep({
+ params,
+ integration: selected,
+ packageName,
+ importMode,
+ configFileName,
+ });
},
+ verify: getAgentMonitoringVerifyStep,
});
export const getNodeMcpOnboarding = ({
diff --git a/static/app/views/insights/pages/agents/onboarding.tsx b/static/app/views/insights/pages/agents/onboarding.tsx
index 9ae4150680fe65..44b6725862fa0b 100644
--- a/static/app/views/insights/pages/agents/onboarding.tsx
+++ b/static/app/views/insights/pages/agents/onboarding.tsx
@@ -23,7 +23,10 @@ import {useUrlPlatformOptions} from 'sentry/components/onboarding/platformOption
import Panel from 'sentry/components/panels/panel';
import PanelBody from 'sentry/components/panels/panelBody';
import {SetupTitle} from 'sentry/components/updatedEmptyState';
-import {agentMonitoringPlatforms} from 'sentry/data/platformCategories';
+import {
+ agentMonitoringPlatforms,
+ javascriptMetaFrameworks,
+} from 'sentry/data/platformCategories';
import platforms, {otherPlatform} from 'sentry/data/platforms';
import {t, tct} from 'sentry/locale';
import ConfigStore from 'sentry/stores/configStore';
@@ -32,7 +35,10 @@ import pulsingIndicatorStyles from 'sentry/styles/pulsingIndicator';
import {space} from 'sentry/styles/space';
import type {PlatformKey, Project} from 'sentry/types/project';
import {getSelectedProjectList} from 'sentry/utils/project/useSelectedProjectsHaveField';
+import {decodeInteger} from 'sentry/utils/queryString';
import useApi from 'sentry/utils/useApi';
+import {useLocation} from 'sentry/utils/useLocation';
+import {useNavigate} from 'sentry/utils/useNavigate';
import useOrganization from 'sentry/utils/useOrganization';
import usePageFilters from 'sentry/utils/usePageFilters';
import useProjects from 'sentry/utils/useProjects';
@@ -48,18 +54,6 @@ import {
PYTHON_AGENT_INTEGRATIONS,
} from './utils/agentIntegrations';
-// Full-stack JS frameworks that support server-side agent SDKs.
-const fullStackJsPlatforms = [
- 'javascript-astro',
- 'javascript-nextjs',
- 'javascript-nuxt',
- 'javascript-react-router',
- 'javascript-remix',
- 'javascript-solidstart',
- 'javascript-sveltekit',
- 'javascript-tanstackstart-react',
-];
-
const serverSideNodeIntegrations = new Set([
AgentIntegration.VERCEL_AI,
AgentIntegration.MASTRA,
@@ -222,6 +216,8 @@ export function Onboarding() {
const {isSelfHosted, urlPrefix} = useLegacyStore(ConfigStore);
const project = useOnboardingProject();
const organization = useOrganization();
+ const location = useLocation();
+ const navigate = useNavigate();
const currentPlatform = project?.platform
? platforms.find(p => p.id === project.platform)
@@ -236,7 +232,9 @@ export function Onboarding() {
// Local integration options for Agent Monitoring only
const isPythonPlatform = (project?.platform ?? '').startsWith('python');
const isNodePlatform = (project?.platform ?? '').startsWith('node');
- const isFullStackJsPlatform = fullStackJsPlatforms.includes(project?.platform ?? '');
+ const isFullStackJsPlatform = javascriptMetaFrameworks.includes(
+ project?.platform ?? 'other'
+ );
const hasServerSideNode = isNodePlatform || isFullStackJsPlatform;
const integrationOptions = {
@@ -258,6 +256,7 @@ export function Onboarding() {
})),
},
};
+
const selectedPlatformOptions = useUrlPlatformOptions(integrationOptions);
const {isPending: isLoadingRegistry, data: registryData} =
@@ -325,13 +324,24 @@ export function Onboarding() {
{introduction && {introduction}}
-
+ {
+ navigate({
+ pathname: location.pathname,
+ query: {
+ ...location.query,
+ guidedStep: step,
+ },
+ });
+ }}
+ >
{steps
- // Only show non-optional steps
+ // Only show non-collapsible steps
.filter(step => !step.collapsible)
.map((step, index) => (