@sentry/node 10.52.0 → 10.53.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/integrations/tracing/anthropic-ai/instrumentation.js +8 -8
- package/build/cjs/integrations/tracing/anthropic-ai/instrumentation.js.map +1 -1
- package/build/cjs/integrations/tracing/google-genai/instrumentation.js +9 -9
- package/build/cjs/integrations/tracing/google-genai/instrumentation.js.map +1 -1
- package/build/cjs/integrations/tracing/langchain/instrumentation.js +12 -12
- package/build/cjs/integrations/tracing/langchain/instrumentation.js.map +1 -1
- package/build/cjs/integrations/tracing/langgraph/instrumentation.js +12 -12
- package/build/cjs/integrations/tracing/langgraph/instrumentation.js.map +1 -1
- package/build/cjs/integrations/tracing/openai/instrumentation.js +11 -11
- package/build/cjs/integrations/tracing/openai/instrumentation.js.map +1 -1
- package/build/cjs/integrations/tracing/postgresjs.js +10 -10
- package/build/cjs/integrations/tracing/postgresjs.js.map +1 -1
- package/build/esm/integrations/tracing/anthropic-ai/instrumentation.js +8 -8
- package/build/esm/integrations/tracing/anthropic-ai/instrumentation.js.map +1 -1
- package/build/esm/integrations/tracing/google-genai/instrumentation.js +9 -9
- package/build/esm/integrations/tracing/google-genai/instrumentation.js.map +1 -1
- package/build/esm/integrations/tracing/langchain/instrumentation.js +12 -12
- package/build/esm/integrations/tracing/langchain/instrumentation.js.map +1 -1
- package/build/esm/integrations/tracing/langgraph/instrumentation.js +12 -12
- package/build/esm/integrations/tracing/langgraph/instrumentation.js.map +1 -1
- package/build/esm/integrations/tracing/openai/instrumentation.js +11 -11
- package/build/esm/integrations/tracing/openai/instrumentation.js.map +1 -1
- package/build/esm/integrations/tracing/postgresjs.js +10 -10
- package/build/esm/integrations/tracing/postgresjs.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/package.json +4 -4
|
@@ -28,8 +28,8 @@ class SentryAnthropicAiInstrumentation extends instrumentation.InstrumentationBa
|
|
|
28
28
|
/**
|
|
29
29
|
* Core patch logic applying instrumentation to the Anthropic AI client constructor.
|
|
30
30
|
*/
|
|
31
|
-
_patch(exports
|
|
32
|
-
const Original = exports
|
|
31
|
+
_patch(exports) {
|
|
32
|
+
const Original = exports.Anthropic;
|
|
33
33
|
|
|
34
34
|
const config = this.getConfig();
|
|
35
35
|
|
|
@@ -60,10 +60,10 @@ class SentryAnthropicAiInstrumentation extends instrumentation.InstrumentationBa
|
|
|
60
60
|
// Constructor replacement - handle read-only properties
|
|
61
61
|
// The Anthropic property might have only a getter, so use defineProperty
|
|
62
62
|
try {
|
|
63
|
-
exports
|
|
63
|
+
exports.Anthropic = WrappedAnthropic;
|
|
64
64
|
} catch {
|
|
65
65
|
// If direct assignment fails, override the property descriptor
|
|
66
|
-
Object.defineProperty(exports
|
|
66
|
+
Object.defineProperty(exports, 'Anthropic', {
|
|
67
67
|
value: WrappedAnthropic,
|
|
68
68
|
writable: true,
|
|
69
69
|
configurable: true,
|
|
@@ -74,12 +74,12 @@ class SentryAnthropicAiInstrumentation extends instrumentation.InstrumentationBa
|
|
|
74
74
|
// Wrap the default export if it points to the original constructor
|
|
75
75
|
// Constructor replacement - handle read-only properties
|
|
76
76
|
// The Anthropic property might have only a getter, so use defineProperty
|
|
77
|
-
if (exports
|
|
77
|
+
if (exports.default === Original) {
|
|
78
78
|
try {
|
|
79
|
-
exports
|
|
79
|
+
exports.default = WrappedAnthropic;
|
|
80
80
|
} catch {
|
|
81
81
|
// If direct assignment fails, override the property descriptor
|
|
82
|
-
Object.defineProperty(exports
|
|
82
|
+
Object.defineProperty(exports, 'default', {
|
|
83
83
|
value: WrappedAnthropic,
|
|
84
84
|
writable: true,
|
|
85
85
|
configurable: true,
|
|
@@ -87,7 +87,7 @@ class SentryAnthropicAiInstrumentation extends instrumentation.InstrumentationBa
|
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
return exports
|
|
90
|
+
return exports;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/anthropic-ai/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n} from '@opentelemetry/instrumentation';\nimport type { AnthropicAiClient, AnthropicAiOptions } from '@sentry/core';\nimport {\n _INTERNAL_shouldSkipAiProviderWrapping,\n ANTHROPIC_AI_INTEGRATION_NAME,\n instrumentAnthropicAiClient,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=0.19.2 <1.0.0'];\n\ntype AnthropicAiInstrumentationOptions = InstrumentationConfig & AnthropicAiOptions;\n\n/**\n * Represents the patched shape of the Anthropic AI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n Anthropic: abstract new (...args: unknown[]) => AnthropicAiClient;\n}\n\n/**\n * Sentry Anthropic AI instrumentation using OpenTelemetry.\n */\nexport class SentryAnthropicAiInstrumentation extends InstrumentationBase<AnthropicAiInstrumentationOptions> {\n public constructor(config: AnthropicAiInstrumentationOptions = {}) {\n super('@sentry/instrumentation-anthropic-ai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n '@anthropic-ai/sdk',\n supportedVersions,\n this._patch.bind(this),\n );\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the Anthropic AI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.Anthropic;\n\n const config = this.getConfig();\n\n const WrappedAnthropic = function (this: unknown, ...args: unknown[]) {\n // Check if wrapping should be skipped (e.g., when LangChain is handling instrumentation)\n if (_INTERNAL_shouldSkipAiProviderWrapping(ANTHROPIC_AI_INTEGRATION_NAME)) {\n return Reflect.construct(Original, args) as AnthropicAiClient;\n }\n\n const instance = Reflect.construct(Original, args);\n\n return instrumentAnthropicAiClient(instance as AnthropicAiClient, config);\n } as unknown as abstract new (...args: unknown[]) => AnthropicAiClient;\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedAnthropic, Original);\n Object.setPrototypeOf(WrappedAnthropic.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedAnthropic, key, descriptor);\n }\n }\n }\n\n // Constructor replacement - handle read-only properties\n // The Anthropic property might have only a getter, so use defineProperty\n try {\n exports.Anthropic = WrappedAnthropic;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'Anthropic', {\n value: WrappedAnthropic,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Wrap the default export if it points to the original constructor\n // Constructor replacement - handle read-only properties\n // The Anthropic property might have only a getter, so use defineProperty\n if (exports.default === Original) {\n try {\n exports.default = WrappedAnthropic;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'default', {\n value: WrappedAnthropic,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n return exports;\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/anthropic-ai/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n} from '@opentelemetry/instrumentation';\nimport type { AnthropicAiClient, AnthropicAiOptions } from '@sentry/core';\nimport {\n _INTERNAL_shouldSkipAiProviderWrapping,\n ANTHROPIC_AI_INTEGRATION_NAME,\n instrumentAnthropicAiClient,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=0.19.2 <1.0.0'];\n\ntype AnthropicAiInstrumentationOptions = InstrumentationConfig & AnthropicAiOptions;\n\n/**\n * Represents the patched shape of the Anthropic AI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n Anthropic: abstract new (...args: unknown[]) => AnthropicAiClient;\n}\n\n/**\n * Sentry Anthropic AI instrumentation using OpenTelemetry.\n */\nexport class SentryAnthropicAiInstrumentation extends InstrumentationBase<AnthropicAiInstrumentationOptions> {\n public constructor(config: AnthropicAiInstrumentationOptions = {}) {\n super('@sentry/instrumentation-anthropic-ai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n '@anthropic-ai/sdk',\n supportedVersions,\n this._patch.bind(this),\n );\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the Anthropic AI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.Anthropic;\n\n const config = this.getConfig();\n\n const WrappedAnthropic = function (this: unknown, ...args: unknown[]) {\n // Check if wrapping should be skipped (e.g., when LangChain is handling instrumentation)\n if (_INTERNAL_shouldSkipAiProviderWrapping(ANTHROPIC_AI_INTEGRATION_NAME)) {\n return Reflect.construct(Original, args) as AnthropicAiClient;\n }\n\n const instance = Reflect.construct(Original, args);\n\n return instrumentAnthropicAiClient(instance as AnthropicAiClient, config);\n } as unknown as abstract new (...args: unknown[]) => AnthropicAiClient;\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedAnthropic, Original);\n Object.setPrototypeOf(WrappedAnthropic.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedAnthropic, key, descriptor);\n }\n }\n }\n\n // Constructor replacement - handle read-only properties\n // The Anthropic property might have only a getter, so use defineProperty\n try {\n exports.Anthropic = WrappedAnthropic;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'Anthropic', {\n value: WrappedAnthropic,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Wrap the default export if it points to the original constructor\n // Constructor replacement - handle read-only properties\n // The Anthropic property might have only a getter, so use defineProperty\n if (exports.default === Original) {\n try {\n exports.default = WrappedAnthropic;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'default', {\n value: WrappedAnthropic,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n return exports;\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","_INTERNAL_shouldSkipAiProviderWrapping","ANTHROPIC_AI_INTEGRATION_NAME","instrumentAnthropicAiClient"],"mappings":";;;;;AAcA,MAAM,iBAAA,GAAoB,CAAC,iBAAiB,CAAC;;AAY7C;AACA;AACA;AACO,MAAM,gCAAA,SAAyCA,mCAAmB,CAAoC;AAC7G,GAAS,WAAW,CAAC,MAAM,GAAsC,EAAE,EAAE;AACrE,IAAI,KAAK,CAAC,sCAAsC,EAAEC,gBAAW,EAAE,MAAM,CAAC;AACtE,EAAE;;AAEF;AACA;AACA;AACA,GAAS,IAAI,GAAoC;AACjD,IAAI,MAAM,MAAA,GAAS,IAAIC,mDAAmC;AAC1D,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAC5B,KAAK;AACL,IAAI,OAAO,MAAM;AACjB,EAAE;;AAEF;AACA;AACA;AACA,GAAU,MAAM,CAAC,OAAO,EAAqD;AAC7E,IAAI,MAAM,QAAA,GAAW,OAAO,CAAC,SAAS;;AAEtC,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,SAAS,EAAE;;AAEnC,IAAI,MAAM,mBAAmB,WAAyB,GAAG,IAAI,EAAa;AAC1E;AACA,MAAM,IAAIC,2CAAsC,CAACC,kCAA6B,CAAC,EAAE;AACjF,QAAQ,OAAO,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAA;AAC/C,MAAM;;AAEN,MAAM,MAAM,QAAA,GAAW,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;;AAExD,MAAM,OAAOC,gCAA2B,CAAC,QAAA,GAA+B,MAAM,CAAC;AAC/E,IAAI,CAAA;;AAEJ;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,gBAAgB,EAAE,QAAQ,CAAC;AACrD,IAAI,MAAM,CAAC,cAAc,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;;AAEzE,IAAI,KAAK,MAAM,GAAA,IAAO,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE;AAC5D,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1D,QAAQ,MAAM,UAAA,GAAa,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,CAAC;AACzE,QAAQ,IAAI,UAAU,EAAE;AACxB,UAAU,MAAM,CAAC,cAAc,CAAC,gBAAgB,EAAE,GAAG,EAAE,UAAU,CAAC;AAClE,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ;AACA;AACA,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,SAAA,GAAY,gBAAgB;AAC1C,IAAI,EAAE,MAAM;AACZ;AACA,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE;AAClD,QAAQ,KAAK,EAAE,gBAAgB;AAC/B,QAAQ,QAAQ,EAAE,IAAI;AACtB,QAAQ,YAAY,EAAE,IAAI;AAC1B,QAAQ,UAAU,EAAE,IAAI;AACxB,OAAO,CAAC;AACR,IAAI;;AAEJ;AACA;AACA;AACA,IAAI,IAAI,OAAO,CAAC,OAAA,KAAY,QAAQ,EAAE;AACtC,MAAM,IAAI;AACV,QAAQ,OAAO,CAAC,OAAA,GAAU,gBAAgB;AAC1C,MAAM,EAAE,MAAM;AACd;AACA,QAAQ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE;AAClD,UAAU,KAAK,EAAE,gBAAgB;AACjC,UAAU,QAAQ,EAAE,IAAI;AACxB,UAAU,YAAY,EAAE,IAAI;AAC5B,UAAU,UAAU,EAAE,IAAI;AAC1B,SAAS,CAAC;AACV,MAAM;AACN,IAAI;AACJ,IAAI,OAAO,OAAO;AAClB,EAAE;AACF;;;;"}
|
|
@@ -24,8 +24,8 @@ class SentryGoogleGenAiInstrumentation extends instrumentation.InstrumentationBa
|
|
|
24
24
|
const module = new instrumentation.InstrumentationNodeModuleDefinition(
|
|
25
25
|
'@google/genai',
|
|
26
26
|
supportedVersions,
|
|
27
|
-
exports
|
|
28
|
-
exports
|
|
27
|
+
exports => this._patch(exports),
|
|
28
|
+
exports => exports,
|
|
29
29
|
// In CJS, @google/genai re-exports from (dist/node/index.cjs) file.
|
|
30
30
|
// Patching only the root module sometimes misses the real implementation or
|
|
31
31
|
// gets overwritten when that file is loaded. We add a file-level patch so that
|
|
@@ -34,8 +34,8 @@ class SentryGoogleGenAiInstrumentation extends instrumentation.InstrumentationBa
|
|
|
34
34
|
new instrumentation.InstrumentationNodeModuleFile(
|
|
35
35
|
'@google/genai/dist/node/index.cjs',
|
|
36
36
|
supportedVersions,
|
|
37
|
-
exports
|
|
38
|
-
exports
|
|
37
|
+
exports => this._patch(exports),
|
|
38
|
+
exports => exports,
|
|
39
39
|
),
|
|
40
40
|
],
|
|
41
41
|
);
|
|
@@ -45,12 +45,12 @@ class SentryGoogleGenAiInstrumentation extends instrumentation.InstrumentationBa
|
|
|
45
45
|
/**
|
|
46
46
|
* Core patch logic applying instrumentation to the Google GenAI client constructor.
|
|
47
47
|
*/
|
|
48
|
-
_patch(exports
|
|
49
|
-
const Original = exports
|
|
48
|
+
_patch(exports) {
|
|
49
|
+
const Original = exports.GoogleGenAI;
|
|
50
50
|
const config = this.getConfig();
|
|
51
51
|
|
|
52
52
|
if (typeof Original !== 'function') {
|
|
53
|
-
return exports
|
|
53
|
+
return exports;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
const WrappedGoogleGenAI = function ( ...args) {
|
|
@@ -78,9 +78,9 @@ class SentryGoogleGenAiInstrumentation extends instrumentation.InstrumentationBa
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// Replace google genai exports with the wrapped constructor
|
|
81
|
-
core.replaceExports(exports
|
|
81
|
+
core.replaceExports(exports, 'GoogleGenAI', WrappedGoogleGenAI);
|
|
82
82
|
|
|
83
|
-
return exports
|
|
83
|
+
return exports;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/google-genai/instrumentation.ts"],"sourcesContent":["import type { InstrumentationConfig, InstrumentationModuleDefinition } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { GoogleGenAIClient, GoogleGenAIOptions } from '@sentry/core';\nimport {\n _INTERNAL_shouldSkipAiProviderWrapping,\n GOOGLE_GENAI_INTEGRATION_NAME,\n instrumentGoogleGenAIClient,\n replaceExports,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=0.10.0 <2'];\n\n/**\n * Represents the patched shape of the Google GenAI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n GoogleGenAI?: unknown;\n}\n\ntype GoogleGenAIInstrumentationOptions = GoogleGenAIOptions & InstrumentationConfig;\n\n/**\n * Sentry Google GenAI instrumentation using OpenTelemetry.\n */\nexport class SentryGoogleGenAiInstrumentation extends InstrumentationBase<GoogleGenAIInstrumentationOptions> {\n public constructor(config: GoogleGenAIInstrumentationOptions = {}) {\n super('@sentry/instrumentation-google-genai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n '@google/genai',\n supportedVersions,\n exports => this._patch(exports),\n exports => exports,\n // In CJS, @google/genai re-exports from (dist/node/index.cjs) file.\n // Patching only the root module sometimes misses the real implementation or\n // gets overwritten when that file is loaded. We add a file-level patch so that\n // _patch runs again on the concrete implementation\n [\n new InstrumentationNodeModuleFile(\n '@google/genai/dist/node/index.cjs',\n supportedVersions,\n exports => this._patch(exports),\n exports => exports,\n ),\n ],\n );\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the Google GenAI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.GoogleGenAI;\n const config = this.getConfig();\n\n if (typeof Original !== 'function') {\n return exports;\n }\n\n const WrappedGoogleGenAI = function (this: unknown, ...args: unknown[]): GoogleGenAIClient {\n // Check if wrapping should be skipped (e.g., when LangChain is handling instrumentation)\n if (_INTERNAL_shouldSkipAiProviderWrapping(GOOGLE_GENAI_INTEGRATION_NAME)) {\n return Reflect.construct(Original, args) as GoogleGenAIClient;\n }\n\n const instance = Reflect.construct(Original, args);\n\n return instrumentGoogleGenAIClient(instance, config);\n };\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedGoogleGenAI, Original);\n Object.setPrototypeOf(WrappedGoogleGenAI.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedGoogleGenAI, key, descriptor);\n }\n }\n }\n\n // Replace google genai exports with the wrapped constructor\n replaceExports(exports, 'GoogleGenAI', WrappedGoogleGenAI);\n\n return exports;\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/google-genai/instrumentation.ts"],"sourcesContent":["import type { InstrumentationConfig, InstrumentationModuleDefinition } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { GoogleGenAIClient, GoogleGenAIOptions } from '@sentry/core';\nimport {\n _INTERNAL_shouldSkipAiProviderWrapping,\n GOOGLE_GENAI_INTEGRATION_NAME,\n instrumentGoogleGenAIClient,\n replaceExports,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=0.10.0 <2'];\n\n/**\n * Represents the patched shape of the Google GenAI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n GoogleGenAI?: unknown;\n}\n\ntype GoogleGenAIInstrumentationOptions = GoogleGenAIOptions & InstrumentationConfig;\n\n/**\n * Sentry Google GenAI instrumentation using OpenTelemetry.\n */\nexport class SentryGoogleGenAiInstrumentation extends InstrumentationBase<GoogleGenAIInstrumentationOptions> {\n public constructor(config: GoogleGenAIInstrumentationOptions = {}) {\n super('@sentry/instrumentation-google-genai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n '@google/genai',\n supportedVersions,\n exports => this._patch(exports),\n exports => exports,\n // In CJS, @google/genai re-exports from (dist/node/index.cjs) file.\n // Patching only the root module sometimes misses the real implementation or\n // gets overwritten when that file is loaded. We add a file-level patch so that\n // _patch runs again on the concrete implementation\n [\n new InstrumentationNodeModuleFile(\n '@google/genai/dist/node/index.cjs',\n supportedVersions,\n exports => this._patch(exports),\n exports => exports,\n ),\n ],\n );\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the Google GenAI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.GoogleGenAI;\n const config = this.getConfig();\n\n if (typeof Original !== 'function') {\n return exports;\n }\n\n const WrappedGoogleGenAI = function (this: unknown, ...args: unknown[]): GoogleGenAIClient {\n // Check if wrapping should be skipped (e.g., when LangChain is handling instrumentation)\n if (_INTERNAL_shouldSkipAiProviderWrapping(GOOGLE_GENAI_INTEGRATION_NAME)) {\n return Reflect.construct(Original, args) as GoogleGenAIClient;\n }\n\n const instance = Reflect.construct(Original, args);\n\n return instrumentGoogleGenAIClient(instance, config);\n };\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedGoogleGenAI, Original);\n Object.setPrototypeOf(WrappedGoogleGenAI.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedGoogleGenAI, key, descriptor);\n }\n }\n }\n\n // Replace google genai exports with the wrapped constructor\n replaceExports(exports, 'GoogleGenAI', WrappedGoogleGenAI);\n\n return exports;\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","InstrumentationNodeModuleFile","_INTERNAL_shouldSkipAiProviderWrapping","GOOGLE_GENAI_INTEGRATION_NAME","instrumentGoogleGenAIClient","replaceExports"],"mappings":";;;;;AAeA,MAAM,iBAAA,GAAoB,CAAC,aAAa,CAAC;;AAEzC;AACA;AACA;;AAQA;AACA;AACA;AACO,MAAM,gCAAA,SAAyCA,mCAAmB,CAAoC;AAC7G,GAAS,WAAW,CAAC,MAAM,GAAsC,EAAE,EAAE;AACrE,IAAI,KAAK,CAAC,sCAAsC,EAAEC,gBAAW,EAAE,MAAM,CAAC;AACtE,EAAE;;AAEF;AACA;AACA;AACA,GAAS,IAAI,GAAoC;AACjD,IAAI,MAAM,MAAA,GAAS,IAAIC,mDAAmC;AAC1D,MAAM,eAAe;AACrB,MAAM,iBAAiB;AACvB,MAAM,WAAW,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACrC,MAAM,OAAA,IAAW,OAAO;AACxB;AACA;AACA;AACA;AACA,MAAM;AACN,QAAQ,IAAIC,6CAA6B;AACzC,UAAU,mCAAmC;AAC7C,UAAU,iBAAiB;AAC3B,UAAU,WAAW,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACzC,UAAU,OAAA,IAAW,OAAO;AAC5B,SAAS;AACT,OAAO;AACP,KAAK;AACL,IAAI,OAAO,MAAM;AACjB,EAAE;;AAEF;AACA;AACA;AACA,GAAU,MAAM,CAAC,OAAO,EAAqD;AAC7E,IAAI,MAAM,QAAA,GAAW,OAAO,CAAC,WAAW;AACxC,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,SAAS,EAAE;;AAEnC,IAAI,IAAI,OAAO,QAAA,KAAa,UAAU,EAAE;AACxC,MAAM,OAAO,OAAO;AACpB,IAAI;;AAEJ,IAAI,MAAM,qBAAqB,WAAyB,GAAG,IAAI,EAAgC;AAC/F;AACA,MAAM,IAAIC,2CAAsC,CAACC,kCAA6B,CAAC,EAAE;AACjF,QAAQ,OAAO,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAA;AAC/C,MAAM;;AAEN,MAAM,MAAM,QAAA,GAAW,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;;AAExD,MAAM,OAAOC,gCAA2B,CAAC,QAAQ,EAAE,MAAM,CAAC;AAC1D,IAAI,CAAC;;AAEL;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,QAAQ,CAAC;AACvD,IAAI,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;;AAE3E,IAAI,KAAK,MAAM,GAAA,IAAO,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE;AAC5D,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1D,QAAQ,MAAM,UAAA,GAAa,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,CAAC;AACzE,QAAQ,IAAI,UAAU,EAAE;AACxB,UAAU,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,GAAG,EAAE,UAAU,CAAC;AACpE,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ;AACA,IAAIC,mBAAc,CAAC,OAAO,EAAE,aAAa,EAAE,kBAAkB,CAAC;;AAE9D,IAAI,OAAO,OAAO;AAClB,EAAE;AACF;;;;"}
|
|
@@ -108,13 +108,13 @@ class SentryLangChainInstrumentation extends instrumentation.InstrumentationBase
|
|
|
108
108
|
packageName,
|
|
109
109
|
supportedVersions,
|
|
110
110
|
this._patch.bind(this),
|
|
111
|
-
exports
|
|
111
|
+
exports => exports,
|
|
112
112
|
[
|
|
113
113
|
new instrumentation.InstrumentationNodeModuleFile(
|
|
114
114
|
`${packageName}/dist/index.cjs`,
|
|
115
115
|
supportedVersions,
|
|
116
116
|
this._patch.bind(this),
|
|
117
|
-
exports
|
|
117
|
+
exports => exports,
|
|
118
118
|
),
|
|
119
119
|
],
|
|
120
120
|
),
|
|
@@ -127,14 +127,14 @@ class SentryLangChainInstrumentation extends instrumentation.InstrumentationBase
|
|
|
127
127
|
'langchain',
|
|
128
128
|
supportedVersions,
|
|
129
129
|
this._patch.bind(this),
|
|
130
|
-
exports
|
|
130
|
+
exports => exports,
|
|
131
131
|
[
|
|
132
132
|
// To catch the CJS build that contains ConfigurableModel / initChatModel for v1
|
|
133
133
|
new instrumentation.InstrumentationNodeModuleFile(
|
|
134
134
|
'langchain/dist/chat_models/universal.cjs',
|
|
135
135
|
supportedVersions,
|
|
136
136
|
this._patch.bind(this),
|
|
137
|
-
exports
|
|
137
|
+
exports => exports,
|
|
138
138
|
),
|
|
139
139
|
],
|
|
140
140
|
),
|
|
@@ -147,7 +147,7 @@ class SentryLangChainInstrumentation extends instrumentation.InstrumentationBase
|
|
|
147
147
|
* Core patch logic - patches chat model and embedding methods
|
|
148
148
|
* This is called when a LangChain provider package is loaded
|
|
149
149
|
*/
|
|
150
|
-
_patch(exports
|
|
150
|
+
_patch(exports) {
|
|
151
151
|
// Skip AI provider wrapping now that LangChain is actually being used
|
|
152
152
|
// This prevents duplicate spans from Anthropic/OpenAI/GoogleGenAI standalone integrations
|
|
153
153
|
core._INTERNAL_skipAiProviderWrapping([
|
|
@@ -163,20 +163,20 @@ class SentryLangChainInstrumentation extends instrumentation.InstrumentationBase
|
|
|
163
163
|
|
|
164
164
|
// Patch Runnable methods to inject callbacks at request time
|
|
165
165
|
// This directly manipulates options.callbacks that LangChain uses
|
|
166
|
-
this._patchRunnableMethods(exports
|
|
166
|
+
this._patchRunnableMethods(exports, sentryHandler);
|
|
167
167
|
|
|
168
168
|
// Patch embedding methods to create spans directly
|
|
169
169
|
// Embeddings don't use the callback system, so we wrap the methods themselves
|
|
170
|
-
this._patchEmbeddingsMethods(exports
|
|
170
|
+
this._patchEmbeddingsMethods(exports, config);
|
|
171
171
|
|
|
172
|
-
return exports
|
|
172
|
+
return exports;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
/**
|
|
176
176
|
* Patches chat model methods (invoke, stream, batch) to inject Sentry callbacks
|
|
177
177
|
* Finds a chat model class from the provider package exports and patches its prototype methods
|
|
178
178
|
*/
|
|
179
|
-
_patchRunnableMethods(exports
|
|
179
|
+
_patchRunnableMethods(exports, sentryHandler) {
|
|
180
180
|
// Known chat model class names for each provider
|
|
181
181
|
const knownChatModelNames = [
|
|
182
182
|
'ChatAnthropic',
|
|
@@ -188,7 +188,7 @@ class SentryLangChainInstrumentation extends instrumentation.InstrumentationBase
|
|
|
188
188
|
'ConfigurableModel',
|
|
189
189
|
];
|
|
190
190
|
|
|
191
|
-
const exportsToPatch = (exports
|
|
191
|
+
const exportsToPatch = (exports.universal_exports ?? exports) ;
|
|
192
192
|
|
|
193
193
|
const chatModelClass = Object.values(exportsToPatch).find(exp => {
|
|
194
194
|
return typeof exp === 'function' && knownChatModelNames.includes(exp.name);
|
|
@@ -229,8 +229,8 @@ class SentryLangChainInstrumentation extends instrumentation.InstrumentationBase
|
|
|
229
229
|
*
|
|
230
230
|
* Instruments any exported class whose prototype has both embedQuery and embedDocuments as functions.
|
|
231
231
|
*/
|
|
232
|
-
_patchEmbeddingsMethods(exports
|
|
233
|
-
const exportsToPatch = (exports
|
|
232
|
+
_patchEmbeddingsMethods(exports, options) {
|
|
233
|
+
const exportsToPatch = (exports.universal_exports ?? exports) ;
|
|
234
234
|
|
|
235
235
|
for (const exp of Object.values(exportsToPatch)) {
|
|
236
236
|
if (typeof exp !== 'function' || !exp.prototype) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/langchain/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { LangChainOptions } from '@sentry/core';\nimport {\n _INTERNAL_skipAiProviderWrapping,\n ANTHROPIC_AI_INTEGRATION_NAME,\n createLangChainCallbackHandler,\n GOOGLE_GENAI_INTEGRATION_NAME,\n instrumentLangChainEmbeddings,\n OPENAI_INTEGRATION_NAME,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=0.1.0 <2.0.0'];\n\ntype LangChainInstrumentationOptions = InstrumentationConfig & LangChainOptions;\n\n/**\n * Represents the patched shape of LangChain provider package exports\n */\ninterface PatchedLangChainExports {\n [key: string]: unknown;\n}\n\n/**\n * Augments a callback handler list with Sentry's handler if not already present\n */\nfunction augmentCallbackHandlers(handlers: unknown, sentryHandler: unknown): unknown {\n // Handle null/undefined - return array with just our handler\n if (!handlers) {\n return [sentryHandler];\n }\n\n // If handlers is already an array\n if (Array.isArray(handlers)) {\n // Check if our handler is already in the list\n if (handlers.includes(sentryHandler)) {\n return handlers;\n }\n // Add our handler to the list\n return [...handlers, sentryHandler];\n }\n\n // If it's a single handler object, convert to array\n if (typeof handlers === 'object') {\n return [handlers, sentryHandler];\n }\n\n // Unknown type - return original\n return handlers;\n}\n\n/**\n * Wraps Runnable methods (invoke, stream, batch) to inject Sentry callbacks at request time\n * Uses a Proxy to intercept method calls and augment the options.callbacks\n */\nfunction wrapRunnableMethod(\n originalMethod: (...args: unknown[]) => unknown,\n sentryHandler: unknown,\n _methodName: string,\n): (...args: unknown[]) => unknown {\n return new Proxy(originalMethod, {\n apply(target, thisArg, args: unknown[]): unknown {\n // LangChain Runnable method signatures:\n // invoke(input, options?) - options contains callbacks\n // stream(input, options?) - options contains callbacks\n // batch(inputs, options?) - options contains callbacks\n\n // Options is typically the second argument\n const optionsIndex = 1;\n let options = args[optionsIndex] as Record<string, unknown> | undefined;\n\n // If options don't exist or aren't an object, create them\n if (!options || typeof options !== 'object' || Array.isArray(options)) {\n options = {};\n args[optionsIndex] = options;\n }\n\n // Inject our callback handler into options.callbacks (request time callbacks)\n const existingCallbacks = options.callbacks;\n const augmentedCallbacks = augmentCallbackHandlers(existingCallbacks, sentryHandler);\n options.callbacks = augmentedCallbacks;\n\n // Call original method with augmented options\n return Reflect.apply(target, thisArg, args);\n },\n }) as (...args: unknown[]) => unknown;\n}\n\n/**\n * Sentry LangChain instrumentation using OpenTelemetry.\n */\nexport class SentryLangChainInstrumentation extends InstrumentationBase<LangChainInstrumentationOptions> {\n public constructor(config: LangChainInstrumentationOptions = {}) {\n super('@sentry/instrumentation-langchain', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n * We patch the BaseChatModel class methods to inject callbacks\n *\n * We hook into provider packages (@langchain/anthropic, @langchain/openai, etc.)\n * because @langchain/core is often bundled and not loaded as a separate module\n */\n public init(): InstrumentationModuleDefinition | InstrumentationModuleDefinition[] {\n const modules: InstrumentationModuleDefinition[] = [];\n\n // Hook into common LangChain provider packages\n const providerPackages = [\n '@langchain/anthropic',\n '@langchain/openai',\n '@langchain/google-genai',\n '@langchain/mistralai',\n '@langchain/google-vertexai',\n '@langchain/groq',\n ];\n\n for (const packageName of providerPackages) {\n // In CJS, LangChain packages re-export from dist/index.cjs files.\n // Patching only the root module sometimes misses the real implementation or\n // gets overwritten when that file is loaded. We add a file-level patch so that\n // _patch runs again on the concrete implementation\n modules.push(\n new InstrumentationNodeModuleDefinition(\n packageName,\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n new InstrumentationNodeModuleFile(\n `${packageName}/dist/index.cjs`,\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n );\n }\n\n // Hook into main 'langchain' package to catch initChatModel (v1+)\n modules.push(\n new InstrumentationNodeModuleDefinition(\n 'langchain',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n // To catch the CJS build that contains ConfigurableModel / initChatModel for v1\n new InstrumentationNodeModuleFile(\n 'langchain/dist/chat_models/universal.cjs',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n );\n\n return modules;\n }\n\n /**\n * Core patch logic - patches chat model and embedding methods\n * This is called when a LangChain provider package is loaded\n */\n private _patch(exports: PatchedLangChainExports): PatchedLangChainExports | void {\n // Skip AI provider wrapping now that LangChain is actually being used\n // This prevents duplicate spans from Anthropic/OpenAI/GoogleGenAI standalone integrations\n _INTERNAL_skipAiProviderWrapping([\n OPENAI_INTEGRATION_NAME,\n ANTHROPIC_AI_INTEGRATION_NAME,\n GOOGLE_GENAI_INTEGRATION_NAME,\n ]);\n\n const config = this.getConfig();\n\n // Create a shared handler instance for chat model callbacks\n const sentryHandler = createLangChainCallbackHandler(config);\n\n // Patch Runnable methods to inject callbacks at request time\n // This directly manipulates options.callbacks that LangChain uses\n this._patchRunnableMethods(exports, sentryHandler);\n\n // Patch embedding methods to create spans directly\n // Embeddings don't use the callback system, so we wrap the methods themselves\n this._patchEmbeddingsMethods(exports, config);\n\n return exports;\n }\n\n /**\n * Patches chat model methods (invoke, stream, batch) to inject Sentry callbacks\n * Finds a chat model class from the provider package exports and patches its prototype methods\n */\n private _patchRunnableMethods(exports: PatchedLangChainExports, sentryHandler: unknown): void {\n // Known chat model class names for each provider\n const knownChatModelNames = [\n 'ChatAnthropic',\n 'ChatOpenAI',\n 'ChatGoogleGenerativeAI',\n 'ChatMistralAI',\n 'ChatVertexAI',\n 'ChatGroq',\n 'ConfigurableModel',\n ];\n\n const exportsToPatch = (exports.universal_exports ?? exports) as Record<string, unknown>;\n\n const chatModelClass = Object.values(exportsToPatch).find(exp => {\n return typeof exp === 'function' && knownChatModelNames.includes(exp.name);\n }) as { prototype: unknown; name: string } | undefined;\n\n if (!chatModelClass) {\n return;\n }\n\n // Patch directly on chatModelClass.prototype\n const targetProto = chatModelClass.prototype as Record<string, unknown>;\n\n // Skip if already patched (both file-level and module-level hooks resolve to the same prototype)\n if (targetProto.__sentry_patched__) {\n return;\n }\n targetProto.__sentry_patched__ = true;\n\n // Patch the methods (invoke, stream, batch)\n // All chat model instances will inherit these patched methods\n const methodsToPatch = ['invoke', 'stream', 'batch'] as const;\n\n for (const methodName of methodsToPatch) {\n const method = targetProto[methodName];\n if (typeof method === 'function') {\n targetProto[methodName] = wrapRunnableMethod(\n method as (...args: unknown[]) => unknown,\n sentryHandler,\n methodName,\n );\n }\n }\n }\n\n /**\n * Patches embedding class methods (embedQuery, embedDocuments) to create Sentry spans.\n *\n * Unlike chat models which use LangChain's callback system, the Embeddings base class\n * has no callback support. We wrap the methods directly on the prototype.\n *\n * Instruments any exported class whose prototype has both embedQuery and embedDocuments as functions.\n */\n private _patchEmbeddingsMethods(exports: PatchedLangChainExports, options: LangChainOptions): void {\n const exportsToPatch = (exports.universal_exports ?? exports) as Record<string, unknown>;\n\n for (const exp of Object.values(exportsToPatch)) {\n if (typeof exp !== 'function' || !exp.prototype) {\n continue;\n }\n const proto = exp.prototype as Record<string, unknown>;\n if (typeof proto.embedQuery !== 'function' || typeof proto.embedDocuments !== 'function') {\n continue;\n }\n if (proto.__sentry_patched__) {\n continue;\n }\n proto.__sentry_patched__ = true;\n\n instrumentLangChainEmbeddings(proto, options);\n }\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","exports","InstrumentationNodeModuleFile","_INTERNAL_skipAiProviderWrapping","OPENAI_INTEGRATION_NAME","ANTHROPIC_AI_INTEGRATION_NAME","GOOGLE_GENAI_INTEGRATION_NAME","createLangChainCallbackHandler","instrumentLangChainEmbeddings"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/langchain/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { LangChainOptions } from '@sentry/core';\nimport {\n _INTERNAL_skipAiProviderWrapping,\n ANTHROPIC_AI_INTEGRATION_NAME,\n createLangChainCallbackHandler,\n GOOGLE_GENAI_INTEGRATION_NAME,\n instrumentLangChainEmbeddings,\n OPENAI_INTEGRATION_NAME,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=0.1.0 <2.0.0'];\n\ntype LangChainInstrumentationOptions = InstrumentationConfig & LangChainOptions;\n\n/**\n * Represents the patched shape of LangChain provider package exports\n */\ninterface PatchedLangChainExports {\n [key: string]: unknown;\n}\n\n/**\n * Augments a callback handler list with Sentry's handler if not already present\n */\nfunction augmentCallbackHandlers(handlers: unknown, sentryHandler: unknown): unknown {\n // Handle null/undefined - return array with just our handler\n if (!handlers) {\n return [sentryHandler];\n }\n\n // If handlers is already an array\n if (Array.isArray(handlers)) {\n // Check if our handler is already in the list\n if (handlers.includes(sentryHandler)) {\n return handlers;\n }\n // Add our handler to the list\n return [...handlers, sentryHandler];\n }\n\n // If it's a single handler object, convert to array\n if (typeof handlers === 'object') {\n return [handlers, sentryHandler];\n }\n\n // Unknown type - return original\n return handlers;\n}\n\n/**\n * Wraps Runnable methods (invoke, stream, batch) to inject Sentry callbacks at request time\n * Uses a Proxy to intercept method calls and augment the options.callbacks\n */\nfunction wrapRunnableMethod(\n originalMethod: (...args: unknown[]) => unknown,\n sentryHandler: unknown,\n _methodName: string,\n): (...args: unknown[]) => unknown {\n return new Proxy(originalMethod, {\n apply(target, thisArg, args: unknown[]): unknown {\n // LangChain Runnable method signatures:\n // invoke(input, options?) - options contains callbacks\n // stream(input, options?) - options contains callbacks\n // batch(inputs, options?) - options contains callbacks\n\n // Options is typically the second argument\n const optionsIndex = 1;\n let options = args[optionsIndex] as Record<string, unknown> | undefined;\n\n // If options don't exist or aren't an object, create them\n if (!options || typeof options !== 'object' || Array.isArray(options)) {\n options = {};\n args[optionsIndex] = options;\n }\n\n // Inject our callback handler into options.callbacks (request time callbacks)\n const existingCallbacks = options.callbacks;\n const augmentedCallbacks = augmentCallbackHandlers(existingCallbacks, sentryHandler);\n options.callbacks = augmentedCallbacks;\n\n // Call original method with augmented options\n return Reflect.apply(target, thisArg, args);\n },\n }) as (...args: unknown[]) => unknown;\n}\n\n/**\n * Sentry LangChain instrumentation using OpenTelemetry.\n */\nexport class SentryLangChainInstrumentation extends InstrumentationBase<LangChainInstrumentationOptions> {\n public constructor(config: LangChainInstrumentationOptions = {}) {\n super('@sentry/instrumentation-langchain', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n * We patch the BaseChatModel class methods to inject callbacks\n *\n * We hook into provider packages (@langchain/anthropic, @langchain/openai, etc.)\n * because @langchain/core is often bundled and not loaded as a separate module\n */\n public init(): InstrumentationModuleDefinition | InstrumentationModuleDefinition[] {\n const modules: InstrumentationModuleDefinition[] = [];\n\n // Hook into common LangChain provider packages\n const providerPackages = [\n '@langchain/anthropic',\n '@langchain/openai',\n '@langchain/google-genai',\n '@langchain/mistralai',\n '@langchain/google-vertexai',\n '@langchain/groq',\n ];\n\n for (const packageName of providerPackages) {\n // In CJS, LangChain packages re-export from dist/index.cjs files.\n // Patching only the root module sometimes misses the real implementation or\n // gets overwritten when that file is loaded. We add a file-level patch so that\n // _patch runs again on the concrete implementation\n modules.push(\n new InstrumentationNodeModuleDefinition(\n packageName,\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n new InstrumentationNodeModuleFile(\n `${packageName}/dist/index.cjs`,\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n );\n }\n\n // Hook into main 'langchain' package to catch initChatModel (v1+)\n modules.push(\n new InstrumentationNodeModuleDefinition(\n 'langchain',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n // To catch the CJS build that contains ConfigurableModel / initChatModel for v1\n new InstrumentationNodeModuleFile(\n 'langchain/dist/chat_models/universal.cjs',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n );\n\n return modules;\n }\n\n /**\n * Core patch logic - patches chat model and embedding methods\n * This is called when a LangChain provider package is loaded\n */\n private _patch(exports: PatchedLangChainExports): PatchedLangChainExports | void {\n // Skip AI provider wrapping now that LangChain is actually being used\n // This prevents duplicate spans from Anthropic/OpenAI/GoogleGenAI standalone integrations\n _INTERNAL_skipAiProviderWrapping([\n OPENAI_INTEGRATION_NAME,\n ANTHROPIC_AI_INTEGRATION_NAME,\n GOOGLE_GENAI_INTEGRATION_NAME,\n ]);\n\n const config = this.getConfig();\n\n // Create a shared handler instance for chat model callbacks\n const sentryHandler = createLangChainCallbackHandler(config);\n\n // Patch Runnable methods to inject callbacks at request time\n // This directly manipulates options.callbacks that LangChain uses\n this._patchRunnableMethods(exports, sentryHandler);\n\n // Patch embedding methods to create spans directly\n // Embeddings don't use the callback system, so we wrap the methods themselves\n this._patchEmbeddingsMethods(exports, config);\n\n return exports;\n }\n\n /**\n * Patches chat model methods (invoke, stream, batch) to inject Sentry callbacks\n * Finds a chat model class from the provider package exports and patches its prototype methods\n */\n private _patchRunnableMethods(exports: PatchedLangChainExports, sentryHandler: unknown): void {\n // Known chat model class names for each provider\n const knownChatModelNames = [\n 'ChatAnthropic',\n 'ChatOpenAI',\n 'ChatGoogleGenerativeAI',\n 'ChatMistralAI',\n 'ChatVertexAI',\n 'ChatGroq',\n 'ConfigurableModel',\n ];\n\n const exportsToPatch = (exports.universal_exports ?? exports) as Record<string, unknown>;\n\n const chatModelClass = Object.values(exportsToPatch).find(exp => {\n return typeof exp === 'function' && knownChatModelNames.includes(exp.name);\n }) as { prototype: unknown; name: string } | undefined;\n\n if (!chatModelClass) {\n return;\n }\n\n // Patch directly on chatModelClass.prototype\n const targetProto = chatModelClass.prototype as Record<string, unknown>;\n\n // Skip if already patched (both file-level and module-level hooks resolve to the same prototype)\n if (targetProto.__sentry_patched__) {\n return;\n }\n targetProto.__sentry_patched__ = true;\n\n // Patch the methods (invoke, stream, batch)\n // All chat model instances will inherit these patched methods\n const methodsToPatch = ['invoke', 'stream', 'batch'] as const;\n\n for (const methodName of methodsToPatch) {\n const method = targetProto[methodName];\n if (typeof method === 'function') {\n targetProto[methodName] = wrapRunnableMethod(\n method as (...args: unknown[]) => unknown,\n sentryHandler,\n methodName,\n );\n }\n }\n }\n\n /**\n * Patches embedding class methods (embedQuery, embedDocuments) to create Sentry spans.\n *\n * Unlike chat models which use LangChain's callback system, the Embeddings base class\n * has no callback support. We wrap the methods directly on the prototype.\n *\n * Instruments any exported class whose prototype has both embedQuery and embedDocuments as functions.\n */\n private _patchEmbeddingsMethods(exports: PatchedLangChainExports, options: LangChainOptions): void {\n const exportsToPatch = (exports.universal_exports ?? exports) as Record<string, unknown>;\n\n for (const exp of Object.values(exportsToPatch)) {\n if (typeof exp !== 'function' || !exp.prototype) {\n continue;\n }\n const proto = exp.prototype as Record<string, unknown>;\n if (typeof proto.embedQuery !== 'function' || typeof proto.embedDocuments !== 'function') {\n continue;\n }\n if (proto.__sentry_patched__) {\n continue;\n }\n proto.__sentry_patched__ = true;\n\n instrumentLangChainEmbeddings(proto, options);\n }\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","InstrumentationNodeModuleFile","_INTERNAL_skipAiProviderWrapping","OPENAI_INTEGRATION_NAME","ANTHROPIC_AI_INTEGRATION_NAME","GOOGLE_GENAI_INTEGRATION_NAME","createLangChainCallbackHandler","instrumentLangChainEmbeddings"],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ class SentryLangGraphInstrumentation extends instrumentation.InstrumentationBase
|
|
|
22
22
|
'@langchain/langgraph',
|
|
23
23
|
supportedVersions,
|
|
24
24
|
this._patch.bind(this),
|
|
25
|
-
exports
|
|
25
|
+
exports => exports,
|
|
26
26
|
[
|
|
27
27
|
new instrumentation.InstrumentationNodeModuleFile(
|
|
28
28
|
/**
|
|
@@ -34,7 +34,7 @@ class SentryLangGraphInstrumentation extends instrumentation.InstrumentationBase
|
|
|
34
34
|
'@langchain/langgraph/dist/index.cjs',
|
|
35
35
|
supportedVersions,
|
|
36
36
|
this._patch.bind(this),
|
|
37
|
-
exports
|
|
37
|
+
exports => exports,
|
|
38
38
|
),
|
|
39
39
|
new instrumentation.InstrumentationNodeModuleFile(
|
|
40
40
|
/**
|
|
@@ -45,7 +45,7 @@ class SentryLangGraphInstrumentation extends instrumentation.InstrumentationBase
|
|
|
45
45
|
'@langchain/langgraph/dist/prebuilt/index.cjs',
|
|
46
46
|
supportedVersions,
|
|
47
47
|
this._patch.bind(this),
|
|
48
|
-
exports
|
|
48
|
+
exports => exports,
|
|
49
49
|
),
|
|
50
50
|
],
|
|
51
51
|
),
|
|
@@ -53,7 +53,7 @@ class SentryLangGraphInstrumentation extends instrumentation.InstrumentationBase
|
|
|
53
53
|
'@langchain/langgraph/prebuilt',
|
|
54
54
|
supportedVersions,
|
|
55
55
|
this._patch.bind(this),
|
|
56
|
-
exports
|
|
56
|
+
exports => exports,
|
|
57
57
|
[
|
|
58
58
|
new instrumentation.InstrumentationNodeModuleFile(
|
|
59
59
|
/**
|
|
@@ -63,7 +63,7 @@ class SentryLangGraphInstrumentation extends instrumentation.InstrumentationBase
|
|
|
63
63
|
'@langchain/langgraph/dist/prebuilt/index.cjs',
|
|
64
64
|
supportedVersions,
|
|
65
65
|
this._patch.bind(this),
|
|
66
|
-
exports
|
|
66
|
+
exports => exports,
|
|
67
67
|
),
|
|
68
68
|
],
|
|
69
69
|
),
|
|
@@ -73,7 +73,7 @@ class SentryLangGraphInstrumentation extends instrumentation.InstrumentationBase
|
|
|
73
73
|
/**
|
|
74
74
|
* Core patch logic applying instrumentation to the LangGraph module.
|
|
75
75
|
*/
|
|
76
|
-
_patch(exports
|
|
76
|
+
_patch(exports) {
|
|
77
77
|
const client = core.getClient();
|
|
78
78
|
const options = {
|
|
79
79
|
...this.getConfig(),
|
|
@@ -82,14 +82,14 @@ class SentryLangGraphInstrumentation extends instrumentation.InstrumentationBase
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
// Patch StateGraph.compile to instrument both compile() and invoke()
|
|
85
|
-
if (exports
|
|
86
|
-
core.instrumentLangGraph(exports
|
|
85
|
+
if (exports.StateGraph && typeof exports.StateGraph === 'function') {
|
|
86
|
+
core.instrumentLangGraph(exports.StateGraph.prototype , options);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// Patch createReactAgent to instrument agent creation and invocation
|
|
90
|
-
if (exports
|
|
91
|
-
const originalCreateReactAgent = exports
|
|
92
|
-
Object.defineProperty(exports
|
|
90
|
+
if (exports.createReactAgent && typeof exports.createReactAgent === 'function') {
|
|
91
|
+
const originalCreateReactAgent = exports.createReactAgent;
|
|
92
|
+
Object.defineProperty(exports, 'createReactAgent', {
|
|
93
93
|
value: core.instrumentCreateReactAgent(originalCreateReactAgent , options),
|
|
94
94
|
writable: true,
|
|
95
95
|
enumerable: true,
|
|
@@ -97,7 +97,7 @@ class SentryLangGraphInstrumentation extends instrumentation.InstrumentationBase
|
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
return exports
|
|
100
|
+
return exports;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/langgraph/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { CompiledGraph, LangGraphOptions } from '@sentry/core';\nimport { getClient, instrumentCreateReactAgent, instrumentLangGraph, SDK_VERSION } from '@sentry/core';\n\nconst supportedVersions = ['>=0.0.0 <2.0.0'];\n\ntype LangGraphInstrumentationOptions = InstrumentationConfig & LangGraphOptions;\n\n/**\n * Represents the patched shape of the LangGraph module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n StateGraph?: abstract new (...args: unknown[]) => unknown;\n createReactAgent?: (...args: unknown[]) => CompiledGraph;\n}\n\n/**\n * Sentry LangGraph instrumentation using OpenTelemetry.\n */\nexport class SentryLangGraphInstrumentation extends InstrumentationBase<LangGraphInstrumentationOptions> {\n public constructor(config: LangGraphInstrumentationOptions = {}) {\n super('@sentry/instrumentation-langgraph', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition[] {\n return [\n new InstrumentationNodeModuleDefinition(\n '@langchain/langgraph',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n new InstrumentationNodeModuleFile(\n /**\n * In CJS, LangGraph packages re-export from dist/index.cjs files.\n * Patching only the root module sometimes misses the real implementation or\n * gets overwritten when that file is loaded. We add a file-level patch so that\n * _patch runs again on the concrete implementation\n */\n '@langchain/langgraph/dist/index.cjs',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n new InstrumentationNodeModuleFile(\n /**\n * In CJS, the prebuilt submodule re-exports from dist/prebuilt/index.cjs.\n * We add a file-level patch under the main module so that CJS require()\n * of @langchain/langgraph/prebuilt gets patched.\n */\n '@langchain/langgraph/dist/prebuilt/index.cjs',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n new InstrumentationNodeModuleDefinition(\n '@langchain/langgraph/prebuilt',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n new InstrumentationNodeModuleFile(\n /**\n * In CJS, the prebuilt submodule re-exports from dist/prebuilt/index.cjs.\n * We add file-level patches so _patch runs on the concrete implementation.\n */\n '@langchain/langgraph/dist/prebuilt/index.cjs',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n ];\n }\n\n /**\n * Core patch logic applying instrumentation to the LangGraph module.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const client = getClient();\n const options = {\n ...this.getConfig(),\n recordInputs: this.getConfig().recordInputs ?? client?.getOptions().sendDefaultPii,\n recordOutputs: this.getConfig().recordOutputs ?? client?.getOptions().sendDefaultPii,\n };\n\n // Patch StateGraph.compile to instrument both compile() and invoke()\n if (exports.StateGraph && typeof exports.StateGraph === 'function') {\n instrumentLangGraph(exports.StateGraph.prototype as { compile: (...args: unknown[]) => unknown }, options);\n }\n\n // Patch createReactAgent to instrument agent creation and invocation\n if (exports.createReactAgent && typeof exports.createReactAgent === 'function') {\n const originalCreateReactAgent = exports.createReactAgent;\n Object.defineProperty(exports, 'createReactAgent', {\n value: instrumentCreateReactAgent(originalCreateReactAgent as (...args: unknown[]) => CompiledGraph, options),\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n\n return exports;\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/langgraph/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { CompiledGraph, LangGraphOptions } from '@sentry/core';\nimport { getClient, instrumentCreateReactAgent, instrumentLangGraph, SDK_VERSION } from '@sentry/core';\n\nconst supportedVersions = ['>=0.0.0 <2.0.0'];\n\ntype LangGraphInstrumentationOptions = InstrumentationConfig & LangGraphOptions;\n\n/**\n * Represents the patched shape of the LangGraph module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n StateGraph?: abstract new (...args: unknown[]) => unknown;\n createReactAgent?: (...args: unknown[]) => CompiledGraph;\n}\n\n/**\n * Sentry LangGraph instrumentation using OpenTelemetry.\n */\nexport class SentryLangGraphInstrumentation extends InstrumentationBase<LangGraphInstrumentationOptions> {\n public constructor(config: LangGraphInstrumentationOptions = {}) {\n super('@sentry/instrumentation-langgraph', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition[] {\n return [\n new InstrumentationNodeModuleDefinition(\n '@langchain/langgraph',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n new InstrumentationNodeModuleFile(\n /**\n * In CJS, LangGraph packages re-export from dist/index.cjs files.\n * Patching only the root module sometimes misses the real implementation or\n * gets overwritten when that file is loaded. We add a file-level patch so that\n * _patch runs again on the concrete implementation\n */\n '@langchain/langgraph/dist/index.cjs',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n new InstrumentationNodeModuleFile(\n /**\n * In CJS, the prebuilt submodule re-exports from dist/prebuilt/index.cjs.\n * We add a file-level patch under the main module so that CJS require()\n * of @langchain/langgraph/prebuilt gets patched.\n */\n '@langchain/langgraph/dist/prebuilt/index.cjs',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n new InstrumentationNodeModuleDefinition(\n '@langchain/langgraph/prebuilt',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n new InstrumentationNodeModuleFile(\n /**\n * In CJS, the prebuilt submodule re-exports from dist/prebuilt/index.cjs.\n * We add file-level patches so _patch runs on the concrete implementation.\n */\n '@langchain/langgraph/dist/prebuilt/index.cjs',\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n ];\n }\n\n /**\n * Core patch logic applying instrumentation to the LangGraph module.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const client = getClient();\n const options = {\n ...this.getConfig(),\n recordInputs: this.getConfig().recordInputs ?? client?.getOptions().sendDefaultPii,\n recordOutputs: this.getConfig().recordOutputs ?? client?.getOptions().sendDefaultPii,\n };\n\n // Patch StateGraph.compile to instrument both compile() and invoke()\n if (exports.StateGraph && typeof exports.StateGraph === 'function') {\n instrumentLangGraph(exports.StateGraph.prototype as { compile: (...args: unknown[]) => unknown }, options);\n }\n\n // Patch createReactAgent to instrument agent creation and invocation\n if (exports.createReactAgent && typeof exports.createReactAgent === 'function') {\n const originalCreateReactAgent = exports.createReactAgent;\n Object.defineProperty(exports, 'createReactAgent', {\n value: instrumentCreateReactAgent(originalCreateReactAgent as (...args: unknown[]) => CompiledGraph, options),\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n\n return exports;\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","InstrumentationNodeModuleFile","getClient","instrumentLangGraph","instrumentCreateReactAgent"],"mappings":";;;;;AAUA,MAAM,iBAAA,GAAoB,CAAC,gBAAgB,CAAC;;AAa5C;AACA;AACA;AACO,MAAM,8BAAA,SAAuCA,mCAAmB,CAAkC;AACzG,GAAS,WAAW,CAAC,MAAM,GAAoC,EAAE,EAAE;AACnE,IAAI,KAAK,CAAC,mCAAmC,EAAEC,gBAAW,EAAE,MAAM,CAAC;AACnE,EAAE;;AAEF;AACA;AACA;AACA,GAAS,IAAI,GAAsC;AACnD,IAAI,OAAO;AACX,MAAM,IAAIC,mDAAmC;AAC7C,QAAQ,sBAAsB;AAC9B,QAAQ,iBAAiB;AACzB,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAC9B,QAAQ,OAAA,IAAW,OAAO;AAC1B,QAAQ;AACR,UAAU,IAAIC,6CAA6B;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,iBAAiB;AAC7B,YAAY,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClC,YAAY,OAAA,IAAW,OAAO;AAC9B,WAAW;AACX,UAAU,IAAIA,6CAA6B;AAC3C;AACA;AACA;AACA;AACA;AACA,YAAY,8CAA8C;AAC1D,YAAY,iBAAiB;AAC7B,YAAY,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClC,YAAY,OAAA,IAAW,OAAO;AAC9B,WAAW;AACX,SAAS;AACT,OAAO;AACP,MAAM,IAAID,mDAAmC;AAC7C,QAAQ,+BAA+B;AACvC,QAAQ,iBAAiB;AACzB,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAC9B,QAAQ,OAAA,IAAW,OAAO;AAC1B,QAAQ;AACR,UAAU,IAAIC,6CAA6B;AAC3C;AACA;AACA;AACA;AACA,YAAY,8CAA8C;AAC1D,YAAY,iBAAiB;AAC7B,YAAY,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClC,YAAY,OAAA,IAAW,OAAO;AAC9B,WAAW;AACX,SAAS;AACT,OAAO;AACP,KAAK;AACL,EAAE;;AAEF;AACA;AACA;AACA,GAAU,MAAM,CAAC,OAAO,EAAqD;AAC7E,IAAI,MAAM,MAAA,GAASC,cAAS,EAAE;AAC9B,IAAI,MAAM,UAAU;AACpB,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE;AACzB,MAAM,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,YAAA,IAAgB,MAAM,EAAE,UAAU,EAAE,CAAC,cAAc;AACxF,MAAM,aAAa,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,aAAA,IAAiB,MAAM,EAAE,UAAU,EAAE,CAAC,cAAc;AAC1F,KAAK;;AAEL;AACA,IAAI,IAAI,OAAO,CAAC,UAAA,IAAc,OAAO,OAAO,CAAC,UAAA,KAAe,UAAU,EAAE;AACxE,MAAMC,wBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,SAAA,GAA2D,OAAO,CAAC;AAChH,IAAI;;AAEJ;AACA,IAAI,IAAI,OAAO,CAAC,gBAAA,IAAoB,OAAO,OAAO,CAAC,gBAAA,KAAqB,UAAU,EAAE;AACpF,MAAM,MAAM,wBAAA,GAA2B,OAAO,CAAC,gBAAgB;AAC/D,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE;AACzD,QAAQ,KAAK,EAAEC,+BAA0B,CAAC,wBAAA,GAAmE,OAAO,CAAC;AACrH,QAAQ,QAAQ,EAAE,IAAI;AACtB,QAAQ,UAAU,EAAE,IAAI;AACxB,QAAQ,YAAY,EAAE,IAAI;AAC1B,OAAO,CAAC;AACR,IAAI;;AAEJ,IAAI,OAAO,OAAO;AAClB,EAAE;AACF;;;;"}
|
|
@@ -24,8 +24,8 @@ class SentryOpenAiInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
24
24
|
/**
|
|
25
25
|
* Core patch logic applying instrumentation to the OpenAI and AzureOpenAI client constructors.
|
|
26
26
|
*/
|
|
27
|
-
_patch(exports
|
|
28
|
-
let result = exports
|
|
27
|
+
_patch(exports) {
|
|
28
|
+
let result = exports;
|
|
29
29
|
result = this._patchClient(result, 'OpenAI');
|
|
30
30
|
result = this._patchClient(result, 'AzureOpenAI');
|
|
31
31
|
return result;
|
|
@@ -34,10 +34,10 @@ class SentryOpenAiInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
34
34
|
/**
|
|
35
35
|
* Patch logic applying instrumentation to the specified client constructor.
|
|
36
36
|
*/
|
|
37
|
-
_patchClient(exports
|
|
38
|
-
const Original = exports
|
|
37
|
+
_patchClient(exports, exportKey) {
|
|
38
|
+
const Original = exports[exportKey];
|
|
39
39
|
if (!Original) {
|
|
40
|
-
return exports
|
|
40
|
+
return exports;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const config = this.getConfig();
|
|
@@ -69,10 +69,10 @@ class SentryOpenAiInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
69
69
|
// Constructor replacement - handle read-only properties
|
|
70
70
|
// The OpenAI property might have only a getter, so use defineProperty
|
|
71
71
|
try {
|
|
72
|
-
exports
|
|
72
|
+
exports[exportKey] = WrappedOpenAI;
|
|
73
73
|
} catch {
|
|
74
74
|
// If direct assignment fails, override the property descriptor
|
|
75
|
-
Object.defineProperty(exports
|
|
75
|
+
Object.defineProperty(exports, exportKey, {
|
|
76
76
|
value: WrappedOpenAI,
|
|
77
77
|
writable: true,
|
|
78
78
|
configurable: true,
|
|
@@ -83,12 +83,12 @@ class SentryOpenAiInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
83
83
|
// Wrap the default export if it points to the original constructor
|
|
84
84
|
// Constructor replacement - handle read-only properties
|
|
85
85
|
// The OpenAI property might have only a getter, so use defineProperty
|
|
86
|
-
if (exports
|
|
86
|
+
if (exports.default === Original) {
|
|
87
87
|
try {
|
|
88
|
-
exports
|
|
88
|
+
exports.default = WrappedOpenAI;
|
|
89
89
|
} catch {
|
|
90
90
|
// If direct assignment fails, override the property descriptor
|
|
91
|
-
Object.defineProperty(exports
|
|
91
|
+
Object.defineProperty(exports, 'default', {
|
|
92
92
|
value: WrappedOpenAI,
|
|
93
93
|
writable: true,
|
|
94
94
|
configurable: true,
|
|
@@ -96,7 +96,7 @@ class SentryOpenAiInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
-
return exports
|
|
99
|
+
return exports;
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/openai/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n} from '@opentelemetry/instrumentation';\nimport type { Integration, OpenAiClient, OpenAiOptions } from '@sentry/core';\nimport {\n _INTERNAL_shouldSkipAiProviderWrapping,\n instrumentOpenAiClient,\n OPENAI_INTEGRATION_NAME,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=4.0.0 <7'];\n\nexport interface OpenAiIntegration extends Integration {\n options: OpenAiOptions;\n}\n\ntype OpenAiInstrumentationOptions = InstrumentationConfig & OpenAiOptions;\n\n/**\n * Represents the patched shape of the OpenAI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n OpenAI: abstract new (...args: unknown[]) => OpenAiClient;\n AzureOpenAI?: abstract new (...args: unknown[]) => OpenAiClient;\n}\n\n/**\n * Sentry OpenAI instrumentation using OpenTelemetry.\n */\nexport class SentryOpenAiInstrumentation extends InstrumentationBase<OpenAiInstrumentationOptions> {\n public constructor(config: OpenAiInstrumentationOptions = {}) {\n super('@sentry/instrumentation-openai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition('openai', supportedVersions, this._patch.bind(this));\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the OpenAI and AzureOpenAI client constructors.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n let result = exports;\n result = this._patchClient(result, 'OpenAI');\n result = this._patchClient(result, 'AzureOpenAI');\n return result;\n }\n\n /**\n * Patch logic applying instrumentation to the specified client constructor.\n */\n private _patchClient(exports: PatchedModuleExports, exportKey: 'OpenAI' | 'AzureOpenAI'): PatchedModuleExports {\n const Original = exports[exportKey];\n if (!Original) {\n return exports;\n }\n\n const config = this.getConfig();\n\n const WrappedOpenAI = function (this: unknown, ...args: unknown[]) {\n // Check if wrapping should be skipped (e.g., when LangChain is handling instrumentation)\n if (_INTERNAL_shouldSkipAiProviderWrapping(OPENAI_INTEGRATION_NAME)) {\n return Reflect.construct(Original, args) as OpenAiClient;\n }\n\n const instance = Reflect.construct(Original, args);\n\n return instrumentOpenAiClient(instance as OpenAiClient, config);\n } as unknown as abstract new (...args: unknown[]) => OpenAiClient;\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedOpenAI, Original);\n Object.setPrototypeOf(WrappedOpenAI.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedOpenAI, key, descriptor);\n }\n }\n }\n\n // Constructor replacement - handle read-only properties\n // The OpenAI property might have only a getter, so use defineProperty\n try {\n exports[exportKey] = WrappedOpenAI;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, exportKey, {\n value: WrappedOpenAI,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Wrap the default export if it points to the original constructor\n // Constructor replacement - handle read-only properties\n // The OpenAI property might have only a getter, so use defineProperty\n if (exports.default === Original) {\n try {\n exports.default = WrappedOpenAI;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'default', {\n value: WrappedOpenAI,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n return exports;\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/openai/instrumentation.ts"],"sourcesContent":["import {\n InstrumentationBase,\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationNodeModuleDefinition,\n} from '@opentelemetry/instrumentation';\nimport type { Integration, OpenAiClient, OpenAiOptions } from '@sentry/core';\nimport {\n _INTERNAL_shouldSkipAiProviderWrapping,\n instrumentOpenAiClient,\n OPENAI_INTEGRATION_NAME,\n SDK_VERSION,\n} from '@sentry/core';\n\nconst supportedVersions = ['>=4.0.0 <7'];\n\nexport interface OpenAiIntegration extends Integration {\n options: OpenAiOptions;\n}\n\ntype OpenAiInstrumentationOptions = InstrumentationConfig & OpenAiOptions;\n\n/**\n * Represents the patched shape of the OpenAI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n OpenAI: abstract new (...args: unknown[]) => OpenAiClient;\n AzureOpenAI?: abstract new (...args: unknown[]) => OpenAiClient;\n}\n\n/**\n * Sentry OpenAI instrumentation using OpenTelemetry.\n */\nexport class SentryOpenAiInstrumentation extends InstrumentationBase<OpenAiInstrumentationOptions> {\n public constructor(config: OpenAiInstrumentationOptions = {}) {\n super('@sentry/instrumentation-openai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition('openai', supportedVersions, this._patch.bind(this));\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the OpenAI and AzureOpenAI client constructors.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n let result = exports;\n result = this._patchClient(result, 'OpenAI');\n result = this._patchClient(result, 'AzureOpenAI');\n return result;\n }\n\n /**\n * Patch logic applying instrumentation to the specified client constructor.\n */\n private _patchClient(exports: PatchedModuleExports, exportKey: 'OpenAI' | 'AzureOpenAI'): PatchedModuleExports {\n const Original = exports[exportKey];\n if (!Original) {\n return exports;\n }\n\n const config = this.getConfig();\n\n const WrappedOpenAI = function (this: unknown, ...args: unknown[]) {\n // Check if wrapping should be skipped (e.g., when LangChain is handling instrumentation)\n if (_INTERNAL_shouldSkipAiProviderWrapping(OPENAI_INTEGRATION_NAME)) {\n return Reflect.construct(Original, args) as OpenAiClient;\n }\n\n const instance = Reflect.construct(Original, args);\n\n return instrumentOpenAiClient(instance as OpenAiClient, config);\n } as unknown as abstract new (...args: unknown[]) => OpenAiClient;\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedOpenAI, Original);\n Object.setPrototypeOf(WrappedOpenAI.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedOpenAI, key, descriptor);\n }\n }\n }\n\n // Constructor replacement - handle read-only properties\n // The OpenAI property might have only a getter, so use defineProperty\n try {\n exports[exportKey] = WrappedOpenAI;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, exportKey, {\n value: WrappedOpenAI,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Wrap the default export if it points to the original constructor\n // Constructor replacement - handle read-only properties\n // The OpenAI property might have only a getter, so use defineProperty\n if (exports.default === Original) {\n try {\n exports.default = WrappedOpenAI;\n } catch {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'default', {\n value: WrappedOpenAI,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n return exports;\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","_INTERNAL_shouldSkipAiProviderWrapping","OPENAI_INTEGRATION_NAME","instrumentOpenAiClient"],"mappings":"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"}
|
|
@@ -48,15 +48,15 @@ class PostgresJsInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
48
48
|
const module = new instrumentation.InstrumentationNodeModuleDefinition(
|
|
49
49
|
'postgres',
|
|
50
50
|
SUPPORTED_VERSIONS,
|
|
51
|
-
exports
|
|
51
|
+
exports => {
|
|
52
52
|
try {
|
|
53
|
-
return this._patchPostgres(exports
|
|
53
|
+
return this._patchPostgres(exports);
|
|
54
54
|
} catch (e) {
|
|
55
55
|
debugBuild.DEBUG_BUILD && core.debug.error('Failed to patch postgres module:', e);
|
|
56
|
-
return exports
|
|
56
|
+
return exports;
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
|
-
exports
|
|
59
|
+
exports => exports,
|
|
60
60
|
);
|
|
61
61
|
|
|
62
62
|
// Add fallback Query.prototype patching for pre-existing sql instances (CJS only)
|
|
@@ -79,15 +79,15 @@ class PostgresJsInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
79
79
|
* Patches the postgres module by wrapping the main export function.
|
|
80
80
|
* This intercepts the creation of sql instances and instruments them.
|
|
81
81
|
*/
|
|
82
|
-
_patchPostgres(exports
|
|
82
|
+
_patchPostgres(exports) {
|
|
83
83
|
// In CJS: exports is the function itself
|
|
84
84
|
// In ESM: exports.default is the function
|
|
85
|
-
const isFunction = typeof exports
|
|
86
|
-
const Original = isFunction ? exports
|
|
85
|
+
const isFunction = typeof exports === 'function';
|
|
86
|
+
const Original = isFunction ? exports : exports.default;
|
|
87
87
|
|
|
88
88
|
if (typeof Original !== 'function') {
|
|
89
89
|
debugBuild.DEBUG_BUILD && core.debug.warn('postgres module does not export a function. Skipping instrumentation.');
|
|
90
|
-
return exports
|
|
90
|
+
return exports;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
@@ -127,8 +127,8 @@ class PostgresJsInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
127
127
|
if (isFunction) {
|
|
128
128
|
return WrappedPostgres ;
|
|
129
129
|
} else {
|
|
130
|
-
core.replaceExports(exports
|
|
131
|
-
return exports
|
|
130
|
+
core.replaceExports(exports, 'default', WrappedPostgres);
|
|
131
|
+
return exports;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|