11import type { IntegrationFn } from '@sentry/core' ;
22import { defineIntegration } from '@sentry/core' ;
3- import { patchClaudeCodeQuery } from './instrumentation' ;
3+ import { generateInstrumentOnce } from '@sentry/node-core' ;
4+ import { SentryClaudeCodeAgentSdkInstrumentation } from './otel-instrumentation' ;
5+ import type { ClaudeCodeOptions } from './types' ;
46
5- export interface ClaudeCodeOptions {
6- /**
7- * Whether to record prompt messages.
8- * Defaults to Sentry client's `sendDefaultPii` setting.
9- */
10- recordInputs ?: boolean ;
7+ export type { ClaudeCodeOptions } from './types' ;
118
12- /**
13- * Whether to record response text, tool calls, and tool outputs.
14- * Defaults to Sentry client's `sendDefaultPii` setting.
15- */
16- recordOutputs ?: boolean ;
9+ export const CLAUDE_CODE_AGENT_SDK_INTEGRATION_NAME = 'ClaudeCodeAgentSdk' ;
1710
18- /**
19- * Custom agent name to use for this integration.
20- * This allows you to differentiate between multiple Claude Code agents in your application.
21- * Defaults to 'claude-code'.
22- *
23- * @example
24- * ```typescript
25- * const query = createInstrumentedClaudeQuery({ name: 'app-builder' });
26- * ```
27- */
28- agentName ?: string ;
29- }
30-
31- const CLAUDE_CODE_INTEGRATION_NAME = 'ClaudeCode' ;
11+ /**
12+ * Instruments the Claude Code Agent SDK using OpenTelemetry.
13+ * This is called automatically when the integration is added to Sentry.
14+ */
15+ export const instrumentClaudeCodeAgentSdk = generateInstrumentOnce < ClaudeCodeOptions > (
16+ CLAUDE_CODE_AGENT_SDK_INTEGRATION_NAME ,
17+ options => new SentryClaudeCodeAgentSdkInstrumentation ( options ) ,
18+ ) ;
3219
33- const _claudeCodeIntegration = ( ( options : ClaudeCodeOptions = { } ) => {
20+ const _claudeCodeAgentSdkIntegration = ( ( options : ClaudeCodeOptions = { } ) => {
3421 return {
35- name : CLAUDE_CODE_INTEGRATION_NAME ,
22+ name : CLAUDE_CODE_AGENT_SDK_INTEGRATION_NAME ,
3623 options,
3724 setupOnce ( ) {
38- // Note: Automatic patching via require hooks doesn't work for ESM modules
39- // or webpack-bundled dependencies. Users must manually patch using patchClaudeCodeQuery()
40- // in their route files.
25+ instrumentClaudeCodeAgentSdk ( options ) ;
4126 } ,
4227 } ;
4328} ) satisfies IntegrationFn ;
4429
4530/**
46- * Adds Sentry tracing instrumentation for the Claude Code SDK.
31+ * Adds Sentry tracing instrumentation for the Claude Code Agent SDK.
4732 *
48- * **Important**: Due to ESM module and bundler limitations, this integration requires
49- * using the `createInstrumentedClaudeQuery()` helper function in your code.
50- * See the example below for proper usage .
33+ * This integration automatically instruments the `query` function from
34+ * `@anthropic-ai/claude-agent-sdk` to capture telemetry data following
35+ * OpenTelemetry Semantic Conventions for Generative AI .
5136 *
52- * This integration captures telemetry data following OpenTelemetry Semantic Conventions
53- * for Generative AI, including:
54- * - Agent invocation spans (`invoke_agent`)
55- * - LLM chat spans (`chat`)
56- * - Tool execution spans (`execute_tool`)
57- * - Token usage, model info, and session tracking
37+ * **Important**: Sentry must be initialized BEFORE importing `@anthropic-ai/claude-agent-sdk`.
5838 *
5939 * @example
6040 * ```typescript
61- * // Step 1: Configure the integration
41+ * // Initialize Sentry FIRST
6242 * import * as Sentry from '@sentry/node';
6343 *
6444 * Sentry.init({
6545 * dsn: 'your-dsn',
6646 * integrations: [
67- * Sentry.claudeCodeIntegration ({
47+ * Sentry.claudeCodeAgentSdkIntegration ({
6848 * recordInputs: true,
6949 * recordOutputs: true
7050 * })
7151 * ],
7252 * });
7353 *
74- * // Step 2: Use the helper in your routes
75- * import { createInstrumentedClaudeQuery } from '@sentry/node';
76- *
77- * const query = createInstrumentedClaudeQuery();
54+ * // THEN import the SDK - it will be automatically instrumented!
55+ * import { query } from '@anthropic-ai/claude-agent-sdk';
7856 *
79- * // Use query as normal - automatically instrumented!
57+ * // Use query as normal - spans are created automatically
8058 * for await (const message of query({
8159 * prompt: 'Hello',
82- * options: { model: 'claude-sonnet-4-5 ' }
60+ * options: { model: 'claude-sonnet-4-20250514 ' }
8361 * })) {
8462 * console.log(message);
8563 * }
8664 * ```
8765 *
66+ * ## Captured Telemetry
67+ *
68+ * This integration captures:
69+ * - Agent invocation spans (`gen_ai.invoke_agent`)
70+ * - LLM chat spans (`gen_ai.chat`)
71+ * - Tool execution spans (`gen_ai.execute_tool`)
72+ * - Token usage, model info, and session tracking
73+ *
8874 * ## Options
8975 *
9076 * - `recordInputs`: Whether to record prompt messages (default: respects `sendDefaultPii` client option)
9177 * - `recordOutputs`: Whether to record response text, tool calls, and outputs (default: respects `sendDefaultPii` client option)
78+ * - `agentName`: Custom agent name for differentiation (default: 'claude-code')
9279 *
9380 * ### Default Behavior
9481 *
@@ -101,7 +88,7 @@ const _claudeCodeIntegration = ((options: ClaudeCodeOptions = {}) => {
10188 * // Record inputs and outputs when sendDefaultPii is false
10289 * Sentry.init({
10390 * integrations: [
104- * Sentry.claudeCodeIntegration ({
91+ * Sentry.claudeCodeAgentSdkIntegration ({
10592 * recordInputs: true,
10693 * recordOutputs: true
10794 * })
@@ -112,31 +99,23 @@ const _claudeCodeIntegration = ((options: ClaudeCodeOptions = {}) => {
11299 * Sentry.init({
113100 * sendDefaultPii: true,
114101 * integrations: [
115- * Sentry.claudeCodeIntegration ({
102+ * Sentry.claudeCodeAgentSdkIntegration ({
116103 * recordInputs: false,
117104 * recordOutputs: false
118105 * })
119106 * ],
120107 * });
108+ *
109+ * // Custom agent name
110+ * Sentry.init({
111+ * integrations: [
112+ * Sentry.claudeCodeAgentSdkIntegration({
113+ * agentName: 'my-coding-assistant'
114+ * })
115+ * ],
116+ * });
121117 * ```
122118 *
123119 * @see https://docs.sentry.io/platforms/javascript/guides/node/ai-monitoring/
124120 */
125- export const claudeCodeIntegration = defineIntegration ( _claudeCodeIntegration ) ;
126-
127- /**
128- * Manually patch the Claude Code SDK query function with Sentry instrumentation.
129- *
130- * **Note**: Most users should use `createInstrumentedClaudeQuery()` instead,
131- * which is simpler and handles option retrieval automatically.
132- *
133- * This low-level function is exported for advanced use cases where you need
134- * explicit control over the patching process.
135- *
136- * @param queryFunction - The original query function from @anthropic-ai/claude-agent-sdk
137- * @param options - Instrumentation options (recordInputs, recordOutputs)
138- * @returns Instrumented query function
139- *
140- * @see createInstrumentedClaudeQuery for the recommended high-level helper
141- */
142- export { patchClaudeCodeQuery } ;
121+ export const claudeCodeAgentSdkIntegration = defineIntegration ( _claudeCodeAgentSdkIntegration ) ;
0 commit comments