netra-sdk 1.3.0 → 1.4.0

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/dist/index.cjs CHANGED
@@ -9,8 +9,8 @@ var module$1 = require('module');
9
9
  var async_hooks = require('async_hooks');
10
10
  var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
11
11
  var nodeServerSdk = require('@traceloop/node-server-sdk');
12
- var dotenv = require('dotenv');
13
12
  var shimmer = require('shimmer');
13
+ var dotenv = require('dotenv');
14
14
  var core = require('@opentelemetry/core');
15
15
  var http = require('http');
16
16
  var https = require('https');
@@ -40,8 +40,8 @@ function _interopNamespace(e) {
40
40
  }
41
41
 
42
42
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
43
- var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
44
43
  var shimmer__default = /*#__PURE__*/_interopDefault(shimmer);
44
+ var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
45
45
  var http__namespace = /*#__PURE__*/_interopNamespace(http);
46
46
  var https__namespace = /*#__PURE__*/_interopNamespace(https);
47
47
  var pLimit__default = /*#__PURE__*/_interopDefault(pLimit);
@@ -1340,7 +1340,7 @@ var require_validation = __commonJS({
1340
1340
  exports$1.needsEscaping = needsEscaping3;
1341
1341
  exports$1.escapeObject = escapeObject3;
1342
1342
  exports$1.isEscapedObject = isEscapedObject;
1343
- exports$1.serializeValue = serializeValue3;
1343
+ exports$1.serializeValue = serializeValue2;
1344
1344
  exports$1.serializeLcObject = serializeLcObject;
1345
1345
  exports$1.escapeIfNeeded = escapeIfNeeded3;
1346
1346
  exports$1.unescapeValue = unescapeValue;
@@ -1374,7 +1374,7 @@ var require_validation = __commonJS({
1374
1374
  id
1375
1375
  };
1376
1376
  }
1377
- function serializeValue3(obj) {
1377
+ function serializeValue2(obj) {
1378
1378
  if (isSerializableLike3(obj)) {
1379
1379
  return serializeLcObject(obj);
1380
1380
  }
@@ -1385,12 +1385,12 @@ var require_validation = __commonJS({
1385
1385
  }
1386
1386
  const result = {};
1387
1387
  for (const [key, value] of Object.entries(record)) {
1388
- result[key] = serializeValue3(value);
1388
+ result[key] = serializeValue2(value);
1389
1389
  }
1390
1390
  return result;
1391
1391
  }
1392
1392
  if (Array.isArray(obj)) {
1393
- return obj.map((item) => serializeValue3(item));
1393
+ return obj.map((item) => serializeValue2(item));
1394
1394
  }
1395
1395
  if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean" || obj === null) {
1396
1396
  return obj;
@@ -1406,7 +1406,7 @@ var require_validation = __commonJS({
1406
1406
  if (secretFields.has(key)) {
1407
1407
  newKwargs[key] = value;
1408
1408
  } else {
1409
- newKwargs[key] = serializeValue3(value);
1409
+ newKwargs[key] = serializeValue2(value);
1410
1410
  }
1411
1411
  }
1412
1412
  serialized.kwargs = newKwargs;
@@ -14493,6 +14493,9 @@ var Logger = class {
14493
14493
  static get isDebug() {
14494
14494
  return this._debugMode || ["1", "true"].includes((process.env.NETRA_DEBUG ?? "").toLowerCase());
14495
14495
  }
14496
+ static isDebugMode() {
14497
+ return this.isDebug;
14498
+ }
14496
14499
  static debug(...args) {
14497
14500
  if (this.isDebug) console.debug(PREFIX, ...args);
14498
14501
  }
@@ -15046,6 +15049,9 @@ var Usage = class {
15046
15049
  }
15047
15050
  };
15048
15051
 
15052
+ // src/version.ts
15053
+ var SDK_VERSION = "1.4.0";
15054
+
15049
15055
  // src/config.ts
15050
15056
  var NetraInstruments = /* @__PURE__ */ ((NetraInstruments2) => {
15051
15057
  NetraInstruments2["ALL"] = "__all__";
@@ -15244,11 +15250,34 @@ var Config = class {
15244
15250
  const headerStr = Object.entries(this.headers).map(([k, v]) => `${k}=${v}`).join(",");
15245
15251
  process.env.TRACELOOP_HEADERS = headerStr;
15246
15252
  }
15253
+ this._setResourceAttributesEnv();
15254
+ }
15255
+ _setResourceAttributesEnv() {
15256
+ const attrs = {
15257
+ "deployment.environment": this.environment,
15258
+ "service.name": this.appName
15259
+ };
15260
+ for (const [k, v] of Object.entries(this.resourceAttributes)) {
15261
+ attrs[k] = String(v);
15262
+ }
15263
+ const existing = process.env.OTEL_RESOURCE_ATTRIBUTES;
15264
+ if (existing) {
15265
+ for (const pair of existing.split(",")) {
15266
+ const eqIdx = pair.indexOf("=");
15267
+ if (eqIdx <= 0) continue;
15268
+ const key = decodeURIComponent(pair.slice(0, eqIdx).trim());
15269
+ if (key) {
15270
+ attrs[key] = decodeURIComponent(pair.slice(eqIdx + 1).trim());
15271
+ }
15272
+ }
15273
+ }
15274
+ const encodeAttrValue = (s) => encodeURIComponent(s);
15275
+ process.env.OTEL_RESOURCE_ATTRIBUTES = Object.entries(attrs).map(([k, v]) => `${encodeAttrValue(k)}=${encodeAttrValue(v)}`).join(",");
15247
15276
  }
15248
15277
  };
15249
15278
  Config.SDK_NAME = "netra";
15250
15279
  Config.LIBRARY_NAME = "netra";
15251
- Config.LIBRARY_VERSION = "1.0.0";
15280
+ Config.LIBRARY_VERSION = SDK_VERSION;
15252
15281
  Config.TRIAL_BLOCK_DURATION_SECONDS = 900;
15253
15282
  // 15 minutes
15254
15283
  Config.ATTRIBUTE_MAX_LEN = parseInt(
@@ -15257,6 +15286,9 @@ Config.ATTRIBUTE_MAX_LEN = parseInt(
15257
15286
  Config.CONVERSATION_MAX_LEN = parseInt(
15258
15287
  process.env.NETRA_CONVERSATION_CONTENT_MAX_LEN || "50000"
15259
15288
  );
15289
+ Config.SPAN_ATTRIBUTE_MAX_SIZE = parseInt(
15290
+ process.env.NETRA_SPAN_ATTRIBUTE_MAX_SIZE || "30000"
15291
+ );
15260
15292
 
15261
15293
  // src/utils/pattern-matching.ts
15262
15294
  function compilePatterns(patterns) {
@@ -15518,6 +15550,57 @@ var ConversationType = /* @__PURE__ */ ((ConversationType3) => {
15518
15550
  return ConversationType3;
15519
15551
  })(ConversationType || {});
15520
15552
 
15553
+ // src/utils/serialization.ts
15554
+ var ELLIPSIS = "...";
15555
+ function truncate(s, maxLength) {
15556
+ if (s.length <= maxLength) return s;
15557
+ if (maxLength <= ELLIPSIS.length) return s.slice(0, maxLength);
15558
+ return s.slice(0, maxLength - ELLIPSIS.length) + ELLIPSIS;
15559
+ }
15560
+ function safeStringify(value, maxLength) {
15561
+ if (typeof value === "string") {
15562
+ if (maxLength && value.length > maxLength) {
15563
+ return truncate(value, maxLength);
15564
+ }
15565
+ return value;
15566
+ }
15567
+ const seen = /* @__PURE__ */ new WeakSet();
15568
+ let result;
15569
+ try {
15570
+ result = JSON.stringify(value, (_key, val) => {
15571
+ if (typeof val === "function")
15572
+ return `[Function: ${val.name || "anonymous"}]`;
15573
+ if (typeof val === "symbol") return val.toString();
15574
+ if (typeof val === "bigint") return val.toString();
15575
+ if (val !== null && typeof val === "object") {
15576
+ if (seen.has(val)) return "[Circular]";
15577
+ seen.add(val);
15578
+ const name = val.constructor?.name;
15579
+ if (name && name !== "Object" && name !== "Array" && Object.keys(val).length > 20) {
15580
+ return `[${name}]`;
15581
+ }
15582
+ }
15583
+ return val;
15584
+ }) ?? String(value);
15585
+ } catch {
15586
+ result = value?.constructor?.name ? `[${value.constructor.name}]` : String(value);
15587
+ }
15588
+ if (maxLength && result.length > maxLength) {
15589
+ return truncate(result, maxLength);
15590
+ }
15591
+ return result;
15592
+ }
15593
+ function serializeValue(value, maxLength) {
15594
+ if (value === null || value === void 0) return String(value);
15595
+ const t = typeof value;
15596
+ if (t === "string" || t === "number" || t === "boolean") {
15597
+ const s = String(value);
15598
+ if (maxLength && s.length > maxLength) return truncate(s, maxLength);
15599
+ return s;
15600
+ }
15601
+ return safeStringify(value, maxLength);
15602
+ }
15603
+
15521
15604
  // src/session-manager.ts
15522
15605
  var MODULE_NAME = "netra.session-manager";
15523
15606
  var entityStorage = new async_hooks.AsyncLocalStorage();
@@ -15531,12 +15614,6 @@ var globalFallbackContext = {
15531
15614
  function getEntityContext() {
15532
15615
  return entityStorage.getStore() ?? globalFallbackContext;
15533
15616
  }
15534
- function serializeValue(value) {
15535
- if (typeof value === "string") {
15536
- return value.substring(0, Config.ATTRIBUTE_MAX_LEN);
15537
- }
15538
- return JSON.stringify(value).substring(0, Config.ATTRIBUTE_MAX_LEN);
15539
- }
15540
15617
  var SessionManager = class _SessionManager {
15541
15618
  // Span registry (name → stack)
15542
15619
  static registerSpan(name, span2) {
@@ -15651,7 +15728,10 @@ var SessionManager = class _SessionManager {
15651
15728
  */
15652
15729
  static setInput(value) {
15653
15730
  try {
15654
- _SessionManager.setAttributeOnActiveSpan("netra.user.input", serializeValue(value));
15731
+ _SessionManager.setAttributeOnActiveSpan(
15732
+ "netra.user.input",
15733
+ serializeValue(value, Config.ATTRIBUTE_MAX_LEN)
15734
+ );
15655
15735
  } catch (e) {
15656
15736
  Logger.error("setInput failed:", e);
15657
15737
  }
@@ -15663,7 +15743,10 @@ var SessionManager = class _SessionManager {
15663
15743
  */
15664
15744
  static setOutput(value) {
15665
15745
  try {
15666
- _SessionManager.setAttributeOnActiveSpan("netra.user.output", serializeValue(value));
15746
+ _SessionManager.setAttributeOnActiveSpan(
15747
+ "netra.user.output",
15748
+ serializeValue(value, Config.ATTRIBUTE_MAX_LEN)
15749
+ );
15667
15750
  } catch (e) {
15668
15751
  Logger.error("setOutput failed:", e);
15669
15752
  }
@@ -15675,7 +15758,10 @@ var SessionManager = class _SessionManager {
15675
15758
  */
15676
15759
  static setRootInput(value) {
15677
15760
  try {
15678
- RootSpanProcessor.setAttributeOnRootSpan("netra.user.input", serializeValue(value));
15761
+ RootSpanProcessor.setAttributeOnRootSpan(
15762
+ "netra.user.input",
15763
+ serializeValue(value, Config.ATTRIBUTE_MAX_LEN)
15764
+ );
15679
15765
  } catch (e) {
15680
15766
  Logger.error("setRootInput failed:", e);
15681
15767
  }
@@ -15687,7 +15773,10 @@ var SessionManager = class _SessionManager {
15687
15773
  */
15688
15774
  static setRootOutput(value) {
15689
15775
  try {
15690
- RootSpanProcessor.setAttributeOnRootSpan("netra.user.output", serializeValue(value));
15776
+ RootSpanProcessor.setAttributeOnRootSpan(
15777
+ "netra.user.output",
15778
+ serializeValue(value, Config.ATTRIBUTE_MAX_LEN)
15779
+ );
15691
15780
  } catch (e) {
15692
15781
  Logger.error("setRootOutput failed:", e);
15693
15782
  }
@@ -17254,6 +17343,58 @@ var Prompts = class {
17254
17343
  }
17255
17344
  };
17256
17345
 
17346
+ // src/processors/attribute-size-limit-processor.ts
17347
+ var DEFAULT_MAX_ATTRIBUTE_SIZE = 32e3;
17348
+ var AttributeSizeLimitProcessor = class {
17349
+ constructor(maxAttributeSize) {
17350
+ this.maxAttributeSize = maxAttributeSize ?? DEFAULT_MAX_ATTRIBUTE_SIZE;
17351
+ }
17352
+ onStart(span2, _parentContext) {
17353
+ try {
17354
+ this._wrapSetAttribute(span2);
17355
+ } catch (e) {
17356
+ Logger.debug("AttributeSizeLimitProcessor.onStart error:", e);
17357
+ }
17358
+ }
17359
+ onEnd(_span) {
17360
+ }
17361
+ shutdown() {
17362
+ return Promise.resolve();
17363
+ }
17364
+ forceFlush() {
17365
+ return Promise.resolve();
17366
+ }
17367
+ _wrapSetAttribute(span2) {
17368
+ const original = span2.setAttribute.bind(span2);
17369
+ const maxLen = this.maxAttributeSize;
17370
+ const patched = (key, value) => {
17371
+ try {
17372
+ return original(key, truncateValue(value, maxLen));
17373
+ } catch {
17374
+ try {
17375
+ return original(key, value);
17376
+ } catch {
17377
+ return span2;
17378
+ }
17379
+ }
17380
+ };
17381
+ span2.setAttribute = patched;
17382
+ }
17383
+ };
17384
+ function truncateValue(value, maxLen) {
17385
+ if (typeof value === "string") {
17386
+ return value.length > maxLen ? value.substring(0, maxLen) : value;
17387
+ }
17388
+ if (Array.isArray(value)) {
17389
+ const serialized = JSON.stringify(value);
17390
+ if (serialized.length > maxLen) {
17391
+ return serialized.substring(0, maxLen);
17392
+ }
17393
+ return value;
17394
+ }
17395
+ return value;
17396
+ }
17397
+
17257
17398
  // src/processors/instrumentation-span-processor.ts
17258
17399
  var ALLOWED_INSTRUMENTATION_NAMES = /* @__PURE__ */ new Set([
17259
17400
  "openai",
@@ -17659,6 +17800,9 @@ function setSessionBaggage(key, value) {
17659
17800
  }
17660
17801
  }
17661
17802
  var SessionSpanProcessor = class {
17803
+ constructor(environment = "local") {
17804
+ this.environment = environment;
17805
+ }
17662
17806
  /**
17663
17807
  * Called when a span starts. Adds session and entity context attributes.
17664
17808
  */
@@ -17667,6 +17811,7 @@ var SessionSpanProcessor = class {
17667
17811
  span2.setAttribute("library.name", Config.LIBRARY_NAME);
17668
17812
  span2.setAttribute("library.version", Config.LIBRARY_VERSION);
17669
17813
  span2.setAttribute("sdk.name", Config.SDK_NAME);
17814
+ span2.setAttribute("deployment.environment", this.environment);
17670
17815
  const ctxToUse = parentContext || api.context.active();
17671
17816
  const baggage = api.propagation.getBaggage(ctxToUse);
17672
17817
  const sessionId = baggage?.getEntry("session_id")?.value ?? sessionValues.get("session_id");
@@ -18073,6 +18218,184 @@ var SpanIOProcessor = class {
18073
18218
  }
18074
18219
  };
18075
18220
 
18221
+ // src/instrumentation/anthropic/version.ts
18222
+ var __version__ = "1.0.0";
18223
+
18224
+ // src/utils/response-handler.ts
18225
+ function isAsyncIterable(value) {
18226
+ return value != null && typeof value[Symbol.asyncIterator] === "function";
18227
+ }
18228
+ function isPromise(value) {
18229
+ return value != null && typeof value.then === "function";
18230
+ }
18231
+ var ITERATOR_METHODS = /* @__PURE__ */ new Set(["next", "return", "throw"]);
18232
+ function wrapAsyncIterable(source, callbacks) {
18233
+ function createWrappedIterator() {
18234
+ const iterator = source[Symbol.asyncIterator]();
18235
+ let done = false;
18236
+ const safeFinalize = (status) => {
18237
+ if (done) return;
18238
+ done = true;
18239
+ try {
18240
+ callbacks.finalize(status);
18241
+ } catch (e) {
18242
+ Logger.error("netra: finalize callback error", e);
18243
+ }
18244
+ };
18245
+ return {
18246
+ async next(value) {
18247
+ try {
18248
+ const result = await callbacks.withContext(() => iterator.next(value));
18249
+ if (!result.done) {
18250
+ try {
18251
+ callbacks.onChunk?.(result.value);
18252
+ } catch (e) {
18253
+ Logger.error("netra: onChunk callback error", e);
18254
+ }
18255
+ } else {
18256
+ safeFinalize("ok");
18257
+ }
18258
+ return result;
18259
+ } catch (e) {
18260
+ try {
18261
+ callbacks.onError(e);
18262
+ } catch {
18263
+ Logger.error("netra: onError callback error", e);
18264
+ }
18265
+ safeFinalize("error");
18266
+ throw e;
18267
+ }
18268
+ },
18269
+ async return(value) {
18270
+ try {
18271
+ const result = await callbacks.withContext(
18272
+ () => iterator.return?.(value) ?? { done: true, value }
18273
+ );
18274
+ safeFinalize("ok");
18275
+ return result;
18276
+ } catch (e) {
18277
+ try {
18278
+ callbacks.onError(e);
18279
+ } catch {
18280
+ Logger.error("netra: onError callback error", e);
18281
+ }
18282
+ safeFinalize("error");
18283
+ throw e;
18284
+ }
18285
+ },
18286
+ async throw(e) {
18287
+ try {
18288
+ const result = await callbacks.withContext(() => {
18289
+ if (iterator.throw) return iterator.throw(e);
18290
+ throw e;
18291
+ });
18292
+ if (result.done) safeFinalize("ok");
18293
+ return result;
18294
+ } catch (err) {
18295
+ try {
18296
+ callbacks.onError(err);
18297
+ } catch {
18298
+ Logger.error("netra: onError callback error", err);
18299
+ }
18300
+ safeFinalize("error");
18301
+ throw err;
18302
+ }
18303
+ }
18304
+ };
18305
+ }
18306
+ let directIterator = null;
18307
+ return new Proxy(source, {
18308
+ get(target, prop) {
18309
+ if (prop === Symbol.asyncIterator) {
18310
+ return () => createWrappedIterator();
18311
+ }
18312
+ if (typeof prop === "string" && ITERATOR_METHODS.has(prop)) {
18313
+ if (!directIterator) directIterator = createWrappedIterator();
18314
+ return directIterator[prop].bind(directIterator);
18315
+ }
18316
+ const value = target[prop];
18317
+ if (typeof value === "function") return value.bind(target);
18318
+ return value;
18319
+ }
18320
+ });
18321
+ }
18322
+ function wrapPromise(promise, callbacks, options) {
18323
+ let finalized = false;
18324
+ function safeFinalize(status) {
18325
+ if (finalized) return;
18326
+ finalized = true;
18327
+ try {
18328
+ callbacks.finalize(status);
18329
+ } catch (e) {
18330
+ Logger.error("netra: finalize callback error", e);
18331
+ }
18332
+ }
18333
+ const instrumentedPromise = (async () => {
18334
+ try {
18335
+ const value = await promise;
18336
+ if (isAsyncIterable(value)) {
18337
+ return wrapAsyncIterable(value, callbacks);
18338
+ }
18339
+ try {
18340
+ callbacks.onSuccess?.(value);
18341
+ } catch (e) {
18342
+ Logger.error("netra: onSuccess callback error", e);
18343
+ }
18344
+ safeFinalize("ok");
18345
+ return value;
18346
+ } catch (error) {
18347
+ try {
18348
+ callbacks.onError(error);
18349
+ } catch {
18350
+ Logger.error("netra: onError callback error", error);
18351
+ }
18352
+ safeFinalize("error");
18353
+ throw error;
18354
+ }
18355
+ })();
18356
+ if (!options?.preserveOriginal) {
18357
+ return instrumentedPromise;
18358
+ }
18359
+ const original = options.preserveOriginal;
18360
+ return new Proxy(instrumentedPromise, {
18361
+ get(target, prop, receiver) {
18362
+ if (prop === "then" || prop === "catch" || prop === "finally") {
18363
+ const value2 = Reflect.get(target, prop, receiver);
18364
+ if (typeof value2 === "function") return value2.bind(target);
18365
+ return value2;
18366
+ }
18367
+ const originalValue = original[prop];
18368
+ if (originalValue !== void 0) {
18369
+ if (typeof originalValue === "function")
18370
+ return originalValue.bind(original);
18371
+ return originalValue;
18372
+ }
18373
+ const value = Reflect.get(target, prop, receiver);
18374
+ if (typeof value === "function") return value.bind(target);
18375
+ return value;
18376
+ }
18377
+ });
18378
+ }
18379
+ function wrapResponse(response, callbacks, options) {
18380
+ if (isAsyncIterable(response)) {
18381
+ return wrapAsyncIterable(response, callbacks);
18382
+ }
18383
+ if (isPromise(response)) {
18384
+ return wrapPromise(response, callbacks, options);
18385
+ }
18386
+ try {
18387
+ callbacks.onSuccess?.(response);
18388
+ } catch (e) {
18389
+ Logger.error("netra: onSuccess callback error", e);
18390
+ }
18391
+ try {
18392
+ callbacks.finalize("ok");
18393
+ } catch (e) {
18394
+ Logger.error("netra: finalize callback error", e);
18395
+ }
18396
+ return response;
18397
+ }
18398
+
18076
18399
  // src/instrumentation/span-attributes.ts
18077
18400
  var SpanAttributes2 = {
18078
18401
  LLM_SYSTEM: "gen_ai.system",
@@ -18083,10 +18406,14 @@ var SpanAttributes2 = {
18083
18406
  LLM_REQUEST_TOP_P: "gen_ai.request.top_p",
18084
18407
  LLM_REQUEST_REASONING: "gen_ai.request.reasoning",
18085
18408
  LLM_REQUEST_REASONING_EFFORT: "gen_ai.request.reasoning_effort",
18409
+ LLM_REQUEST_TOOL_NAME: "gen_ai.request.tool.name",
18410
+ LLM_REQUEST_TOOL_ID: "gen_ai.request.tool.id",
18086
18411
  LLM_RESPONSE_MODEL: "gen_ai.response.model",
18412
+ LLM_RESPONSE_FINISH_REASON: "llm.response.finish_reason",
18087
18413
  LLM_USAGE_PROMPT_TOKENS: "gen_ai.usage.prompt_tokens",
18088
18414
  LLM_USAGE_COMPLETION_TOKENS: "gen_ai.usage.completion_tokens",
18089
18415
  LLM_USAGE_CACHE_READ_INPUT_TOKENS: "gen_ai.usage.cache_read_input_tokens",
18416
+ LLM_USAGE_CACHE_CREATION_INPUT_TOKENS: "gen_ai.usage.cache_creation_input_tokens",
18090
18417
  LLM_USAGE_REASONING_TOKENS: "gen_ai.usage.reasoning_tokens",
18091
18418
  LLM_USAGE_TOTAL_TOKENS: "llm.usage.total_tokens",
18092
18419
  LLM_FREQUENCY_PENALTY: "llm.frequency_penalty",
@@ -18096,8 +18423,6 @@ var SpanAttributes2 = {
18096
18423
  LLM_COMPLETIONS: "gen_ai.completion",
18097
18424
  LLM_PROMPTS: "gen_ai.prompt"
18098
18425
  };
18099
-
18100
- // src/instrumentation/utils.ts
18101
18426
  var VALID_NATIVE_TRACING_MODES = /* @__PURE__ */ new Set(["both", "netra", "netra-strict"]);
18102
18427
  function parseNativeTracingEnv(name) {
18103
18428
  const val = process.env[name];
@@ -18110,9 +18435,6 @@ function shouldSuppressInstrumentation() {
18110
18435
  const ctx = api.context.active();
18111
18436
  return ctx.getValue(SUPPRESS_INSTRUMENTATION_KEY) === true;
18112
18437
  }
18113
- function isPromise(value) {
18114
- return value instanceof Promise;
18115
- }
18116
18438
  function defineHidden(target, key, value) {
18117
18439
  Object.defineProperty(target, key, {
18118
18440
  value,
@@ -18142,18 +18464,6 @@ function isTraceContentEnabled() {
18142
18464
  const raw = process.env.TRACELOOP_TRACE_CONTENT ?? process.env.NETRA_TRACE_CONTENT ?? "";
18143
18465
  return ["1", "true"].includes(String(raw).toLowerCase());
18144
18466
  }
18145
- function safeStringify(value) {
18146
- if (typeof value === "string") return value;
18147
- try {
18148
- return JSON.stringify(value);
18149
- } catch {
18150
- return String(value);
18151
- }
18152
- }
18153
- function truncate(value, maxLen) {
18154
- if (!value || value.length <= maxLen) return value;
18155
- return value.slice(0, maxLen) + "...(truncated)";
18156
- }
18157
18467
  function hasContent(value) {
18158
18468
  if (value === void 0 || value === null) return false;
18159
18469
  if (typeof value === "string") return value.length > 0;
@@ -18184,7 +18494,7 @@ function setModelParams(span2, kwargs) {
18184
18494
  }
18185
18495
  function buildInputMessages(kwargs, requestType) {
18186
18496
  const messages = [];
18187
- if (requestType === "chat") {
18497
+ if (requestType === "chat" || requestType === "beta") {
18188
18498
  if (hasContent(kwargs.system)) {
18189
18499
  const systemContent = typeof kwargs.system === "string" ? kwargs.system : safeStringify(kwargs.system);
18190
18500
  messages.push({ role: "system", content: systemContent });
@@ -18192,12 +18502,34 @@ function buildInputMessages(kwargs, requestType) {
18192
18502
  const rawMessages = kwargs.messages;
18193
18503
  if (!Array.isArray(rawMessages)) return messages;
18194
18504
  for (const msg of rawMessages) {
18195
- if (!isDict(msg)) continue;
18196
- if (hasContent(msg.role) && hasContent(msg.content)) {
18505
+ if (!isDict(msg) || !hasContent(msg.role) || !hasContent(msg.content)) {
18506
+ continue;
18507
+ }
18508
+ if (msg.role !== "user" || !Array.isArray(msg.content)) {
18197
18509
  messages.push({
18198
18510
  role: msg.role,
18199
18511
  content: safeStringify(msg.content)
18200
18512
  });
18513
+ continue;
18514
+ }
18515
+ const isToolResult = (b) => isDict(b) && b.type === "tool_result";
18516
+ const userBlocks = msg.content.filter((b) => !isToolResult(b));
18517
+ if (userBlocks.length) {
18518
+ messages.push({
18519
+ role: "user",
18520
+ content: safeStringify(userBlocks)
18521
+ });
18522
+ }
18523
+ for (const block of msg.content) {
18524
+ if (!isToolResult(block)) continue;
18525
+ messages.push({
18526
+ role: "tool",
18527
+ content: safeStringify({
18528
+ tool_use_id: block.tool_use_id,
18529
+ content: block.content,
18530
+ is_error: block.is_error ?? false
18531
+ }, Config.CONVERSATION_MAX_LEN)
18532
+ });
18201
18533
  }
18202
18534
  }
18203
18535
  } else if (requestType === "response") {
@@ -18226,10 +18558,7 @@ function buildInputMessages(kwargs, requestType) {
18226
18558
  } else {
18227
18559
  const input = kwargs.input ?? kwargs.inputs;
18228
18560
  if (hasContent(input)) {
18229
- const content = truncate(
18230
- safeStringify(input),
18231
- Config.CONVERSATION_MAX_LEN
18232
- );
18561
+ const content = safeStringify(input, Config.CONVERSATION_MAX_LEN);
18233
18562
  messages.push({ role: "user", content });
18234
18563
  }
18235
18564
  }
@@ -18296,7 +18625,7 @@ function buildOutputMessages(response) {
18296
18625
  } else if (block.type === "tool_use" && block.name) {
18297
18626
  messages.push({
18298
18627
  role: "tool",
18299
- content: JSON.stringify({ name: block.name, input: block.input })
18628
+ content: JSON.stringify({ id: block.id, name: block.name, input: block.input })
18300
18629
  });
18301
18630
  }
18302
18631
  }
@@ -18306,13 +18635,14 @@ function buildOutputMessages(response) {
18306
18635
  function writePromptAttributes(span2, messages) {
18307
18636
  if (messages.length === 0) return;
18308
18637
  for (let i = 0; i < messages.length; i++) {
18638
+ const msg = messages[i];
18309
18639
  span2.setAttribute(
18310
18640
  `${SpanAttributes2.LLM_PROMPTS}.${i}.role`,
18311
- messages[i].role
18641
+ msg.role
18312
18642
  );
18313
18643
  span2.setAttribute(
18314
18644
  `${SpanAttributes2.LLM_PROMPTS}.${i}.content`,
18315
- messages[i].content
18645
+ msg.content
18316
18646
  );
18317
18647
  }
18318
18648
  span2.setAttribute("input", JSON.stringify(messages));
@@ -18364,6 +18694,9 @@ function setRequestAttributes(span2, kwargs, requestType, system) {
18364
18694
  span2.setAttribute(SpanAttributes2.LLM_REQUEST_MODEL, String(kwargs.model));
18365
18695
  }
18366
18696
  setModelParams(span2, kwargs);
18697
+ if (Array.isArray(kwargs.tools)) {
18698
+ span2.setAttribute("tools", safeStringify(kwargs.tools, Config.ATTRIBUTE_MAX_LEN));
18699
+ }
18367
18700
  if (kwargs.reasoning !== void 0) {
18368
18701
  span2.setAttribute(
18369
18702
  SpanAttributes2.LLM_REQUEST_REASONING,
@@ -18376,7 +18709,7 @@ function setRequestAttributes(span2, kwargs, requestType, system) {
18376
18709
  if (kwargs.suffix !== void 0) {
18377
18710
  span2.setAttribute(
18378
18711
  "llm.request.suffix",
18379
- truncate(safeStringify(kwargs.suffix), Config.CONVERSATION_MAX_LEN)
18712
+ safeStringify(kwargs.suffix, Config.CONVERSATION_MAX_LEN)
18380
18713
  );
18381
18714
  }
18382
18715
  }
@@ -18399,12 +18732,20 @@ function setResponseAttributes(span2, response) {
18399
18732
  }
18400
18733
  }
18401
18734
  function setFinishReason(span2, response) {
18735
+ if (response.stop_reason) {
18736
+ span2.setAttribute(
18737
+ SpanAttributes2.LLM_RESPONSE_FINISH_REASON,
18738
+ String(response.stop_reason)
18739
+ );
18740
+ span2.setAttribute("gen_ai.response.finish_reason", String(response.stop_reason));
18741
+ }
18402
18742
  const choices = response.choices;
18403
- if (!Array.isArray(choices) || choices.length === 0) return;
18404
- const reason = choices[0].finish_reason ?? choices[0].finishReason;
18405
- if (reason) {
18406
- span2.setAttribute("gen_ai.response.finish_reason", String(reason));
18407
- span2.setAttribute("llm.response.finish_reason", String(reason));
18743
+ if (Array.isArray(choices) && choices.length > 0) {
18744
+ const reason = choices[0].finish_reason ?? choices[0].finishReason;
18745
+ if (reason) {
18746
+ span2.setAttribute(SpanAttributes2.LLM_RESPONSE_FINISH_REASON, String(reason));
18747
+ span2.setAttribute("gen_ai.response.finish_reason", String(reason));
18748
+ }
18408
18749
  }
18409
18750
  }
18410
18751
  function setUsageAttributes(span2, response) {
@@ -18431,11 +18772,18 @@ function setUsageAttributes(span2, response) {
18431
18772
  Number(totalTokens)
18432
18773
  );
18433
18774
  }
18434
- const cacheTokens = (usage.prompt_tokens_details ?? usage.input_tokens_details)?.cached_tokens;
18435
- if (cacheTokens !== void 0) {
18775
+ const cacheReadTokens = usage.cache_read_input_tokens ?? (usage.prompt_tokens_details ?? usage.input_tokens_details)?.cached_tokens;
18776
+ if (cacheReadTokens !== void 0) {
18436
18777
  span2.setAttribute(
18437
18778
  SpanAttributes2.LLM_USAGE_CACHE_READ_INPUT_TOKENS,
18438
- Number(cacheTokens)
18779
+ Number(cacheReadTokens)
18780
+ );
18781
+ }
18782
+ const cacheCreationTokens = usage.cache_creation_input_tokens;
18783
+ if (cacheCreationTokens !== void 0) {
18784
+ span2.setAttribute(
18785
+ SpanAttributes2.LLM_USAGE_CACHE_CREATION_INPUT_TOKENS,
18786
+ Number(cacheCreationTokens)
18439
18787
  );
18440
18788
  }
18441
18789
  const reasoningTokens = (usage.completion_tokens_details ?? usage.output_tokens_details)?.reasoning_tokens;
@@ -18457,188 +18805,181 @@ function setEmbeddingResponseMeta(span2, response) {
18457
18805
  }
18458
18806
  }
18459
18807
 
18460
- // src/instrumentation/anthropic/utils.ts
18461
- function setRequestAttributes2(span2, kwargs, requestType) {
18462
- if (!span2.isRecording()) {
18463
- Logger.log("Span is not recording");
18464
- return;
18465
- }
18466
- setRequestAttributes(span2, kwargs, requestType, "anthropic");
18467
- }
18468
- function setResponseAttributes2(span2, response) {
18469
- if (!span2.isRecording()) {
18470
- Logger.log("Span is not recording");
18471
- return;
18472
- }
18473
- if (response?.type === "message_batch") {
18474
- span2.setAttribute("status", response?.processing_status);
18475
- }
18476
- setResponseAttributes(span2, response);
18477
- }
18808
+ // src/instrumentation/anthropic/types.ts
18809
+ var SPAN_NAMES = {
18810
+ CHAT: "anthropic.chat",
18811
+ STREAM: "anthropic.stream",
18812
+ BATCHES: "anthropic.batches",
18813
+ BETA: "anthropic.beta",
18814
+ BETA_STREAM: "anthropic.beta.stream",
18815
+ BETA_TOOL_RUNNER: "anthropic.beta.tool.runner"
18816
+ };
18478
18817
 
18479
- // src/instrumentation/anthropic/version.ts
18480
- var __version__ = "1.0.0";
18481
- var CHAT_SPAN_NAME = "anthropic.chat";
18482
- var BETA_SPAN_NAME = "anthropic.beta";
18483
- var BATCHES_SPAN_NAME = "anthropic.batches";
18484
- var STREAM_ENABLED_REQUESTS = ["chat", "beta"];
18485
- function anthropicWrapper(tracer, spanName, requestType) {
18486
- return function wrapper(wrapped, instance, args, kwargs) {
18487
- if (shouldSuppressInstrumentation()) {
18488
- const result = wrapped.call(instance, ...args);
18489
- return isPromise(result) ? result.then((value) => value) : result;
18490
- }
18491
- const currentContext = api.context.active();
18492
- const isStreaming = args[0]?.stream === true;
18493
- const activeSpan = api.trace.getSpan(api.context.active());
18494
- Logger.debug(`Anthropic invoke (${requestType}). Active TraceId: ${activeSpan?.spanContext().traceId}, SpanId: ${activeSpan?.spanContext().spanId}`);
18495
- if (isStreaming && STREAM_ENABLED_REQUESTS.includes(requestType)) {
18496
- const span2 = tracer.startSpan(
18497
- spanName + ".create",
18498
- {
18499
- kind: api.SpanKind.CLIENT,
18500
- attributes: {
18501
- "llm.request.type": requestType,
18502
- "llm.streaming": true
18503
- }
18504
- },
18505
- currentContext
18506
- );
18507
- try {
18508
- setRequestAttributes2(span2, kwargs, requestType);
18509
- const startTime = Date.now();
18510
- const spanContext = api.trace.setSpan(currentContext, span2);
18511
- const response = api.context.with(spanContext, () => wrapped.call(instance, ...args));
18512
- if (isPromise(response)) {
18513
- return (async () => {
18514
- try {
18515
- const stream = await response;
18516
- return new AsyncStreamingWrapper(span2, stream, startTime, kwargs, spanContext);
18517
- } catch (error) {
18518
- Logger.error("netra.instrumentation.anthropic:", error);
18519
- span2.setStatus({
18520
- code: api.SpanStatusCode.ERROR,
18521
- message: error instanceof Error ? error.message : String(error)
18522
- });
18523
- span2.recordException(error);
18524
- span2.end();
18525
- throw error;
18526
- }
18527
- })();
18528
- } else {
18529
- return new AsyncStreamingWrapper(span2, response, startTime, kwargs, spanContext);
18530
- }
18531
- } catch (error) {
18532
- Logger.error("netra.instrumentation.anthropic:", error);
18533
- span2.setStatus({
18534
- code: api.SpanStatusCode.ERROR,
18535
- message: error instanceof Error ? error.message : String(error)
18536
- });
18537
- span2.recordException(error);
18538
- span2.end();
18539
- throw error;
18818
+ // src/instrumentation/anthropic/utils.ts
18819
+ function processStreamChunk(completeResponse, chunk, span2) {
18820
+ try {
18821
+ switch (chunk.type) {
18822
+ case "message_start": {
18823
+ if (chunk.message?.model) {
18824
+ completeResponse.model = chunk.message.model;
18825
+ }
18826
+ if (chunk.message?.usage) {
18827
+ completeResponse.usage = chunk.message.usage;
18828
+ }
18829
+ break;
18540
18830
  }
18541
- } else {
18542
- return tracer.startActiveSpan(
18543
- spanName,
18544
- {
18545
- kind: api.SpanKind.CLIENT,
18546
- attributes: { "llm.request.type": requestType }
18547
- },
18548
- (span2) => {
18549
- try {
18550
- setRequestAttributes2(span2, kwargs, requestType);
18551
- const startTime = Date.now();
18552
- const spanContext = api.trace.setSpan(currentContext, span2);
18553
- const response = api.context.with(spanContext, () => wrapped.call(instance, ...args));
18554
- if (isPromise(response)) {
18555
- const instrumentedPromise = (async () => {
18556
- try {
18557
- const value = await response;
18558
- const endTime = Date.now();
18559
- const responseDict = modelAsDict(value);
18560
- setResponseAttributes2(span2, responseDict);
18561
- span2.setAttribute(
18562
- "llm.response.duration",
18563
- (endTime - startTime) / 1e3
18564
- );
18565
- span2.setStatus({ code: api.SpanStatusCode.OK });
18566
- span2.end();
18567
- return value;
18568
- } catch (error) {
18569
- Logger.error("netra.instrumentation.anthropic:", error);
18570
- span2.setStatus({
18571
- code: api.SpanStatusCode.ERROR,
18572
- message: error instanceof Error ? error.message : String(error)
18573
- });
18574
- span2.recordException(error);
18575
- span2.end();
18576
- throw error;
18577
- }
18578
- })();
18579
- return new Proxy(instrumentedPromise, {
18580
- get(target, prop, receiver) {
18581
- if (prop === "then" || prop === "catch" || prop === "finally") {
18582
- const value2 = Reflect.get(target, prop, receiver);
18583
- if (typeof value2 === "function") {
18584
- return value2.bind(target);
18585
- }
18586
- return value2;
18587
- }
18588
- const responseValue = response[prop];
18589
- if (responseValue !== void 0) {
18590
- if (typeof responseValue === "function") {
18591
- return responseValue.bind(response);
18592
- }
18593
- return responseValue;
18594
- }
18595
- const value = Reflect.get(target, prop, receiver);
18596
- if (typeof value === "function") {
18597
- return value.bind(target);
18598
- }
18599
- return value;
18600
- }
18601
- });
18602
- } else {
18603
- const endTime = Date.now();
18604
- const responseDict = modelAsDict(response);
18605
- setResponseAttributes2(span2, responseDict);
18606
- span2.setAttribute(
18607
- "llm.response.duration",
18608
- (endTime - startTime) / 1e3
18831
+ case "content_block_start": {
18832
+ if (!completeResponse.content) {
18833
+ completeResponse.content = [];
18834
+ }
18835
+ const block = chunk.content_block;
18836
+ if (!block) break;
18837
+ if (block.type === "tool_use") {
18838
+ completeResponse.content.push({
18839
+ type: "tool_use",
18840
+ id: block.id,
18841
+ name: block.name,
18842
+ input: ""
18843
+ });
18844
+ } else {
18845
+ completeResponse.content.push({
18846
+ type: block.type,
18847
+ text: ""
18848
+ });
18849
+ }
18850
+ break;
18851
+ }
18852
+ case "content_block_delta": {
18853
+ if (!completeResponse.content || completeResponse.content.length === 0) {
18854
+ completeResponse.content = [{ type: "text", text: "" }];
18855
+ }
18856
+ const targetIndex = chunk.index ?? completeResponse.content.length - 1;
18857
+ const targetBlock = completeResponse.content[targetIndex];
18858
+ if (!targetBlock) break;
18859
+ if (chunk.delta?.type === "input_json_delta" && targetBlock.type === "tool_use") {
18860
+ targetBlock.input += chunk.delta.partial_json ?? "";
18861
+ } else if (chunk.delta?.text) {
18862
+ targetBlock.text += chunk.delta.text;
18863
+ }
18864
+ break;
18865
+ }
18866
+ case "content_block_stop": {
18867
+ const blocks = completeResponse.content;
18868
+ if (blocks && blocks.length > 0) {
18869
+ const finishedBlock = blocks[blocks.length - 1];
18870
+ if (finishedBlock?.type === "tool_use" && typeof finishedBlock.input === "string") {
18871
+ try {
18872
+ finishedBlock.input = JSON.parse(finishedBlock.input);
18873
+ } catch {
18874
+ Logger.warn(
18875
+ "netra.instrumentation.anthropic: Failed to parse tool use input"
18609
18876
  );
18610
- span2.setStatus({ code: api.SpanStatusCode.OK });
18611
- span2.end();
18612
- return response;
18613
18877
  }
18614
- } catch (error) {
18615
- Logger.error("netra.instrumentation.anthropic:", error);
18616
- span2.setStatus({
18617
- code: api.SpanStatusCode.ERROR,
18618
- message: error instanceof Error ? error.message : String(error)
18619
- });
18620
- span2.recordException(error);
18621
- span2.end();
18622
- throw error;
18623
18878
  }
18624
18879
  }
18625
- );
18880
+ break;
18881
+ }
18882
+ case "message_delta": {
18883
+ if (chunk.delta?.stop_reason) {
18884
+ completeResponse.stop_reason = chunk.delta.stop_reason;
18885
+ }
18886
+ const usageData = chunk.usage ?? chunk.delta?.usage;
18887
+ if (usageData) {
18888
+ completeResponse.usage = {
18889
+ ...completeResponse.usage ?? {},
18890
+ ...usageData
18891
+ };
18892
+ }
18893
+ break;
18894
+ }
18895
+ case "message_stop": {
18896
+ if (chunk.usage) {
18897
+ completeResponse.usage = {
18898
+ ...completeResponse.usage ?? {},
18899
+ ...chunk.usage
18900
+ };
18901
+ }
18902
+ break;
18903
+ }
18626
18904
  }
18627
- };
18905
+ if (Logger.isDebugMode()) {
18906
+ span2.addEvent("llm.content.completion.chunk", {
18907
+ "chunk.type": chunk.type
18908
+ });
18909
+ }
18910
+ } catch (e) {
18911
+ Logger.error(
18912
+ "netra.instrumentation.anthropic: processStreamChunk error",
18913
+ e
18914
+ );
18915
+ }
18916
+ }
18917
+ function finalizeStreamSpan(span2, completeResponse, startTime, code) {
18918
+ try {
18919
+ const endTime = Date.now();
18920
+ setResponseAttributes2(span2, {
18921
+ model: completeResponse.model,
18922
+ content: completeResponse.content,
18923
+ usage: completeResponse.usage,
18924
+ stop_reason: completeResponse.stop_reason
18925
+ });
18926
+ span2.setAttribute("llm.response.duration", (endTime - startTime) / 1e3);
18927
+ span2.setStatus({ code });
18928
+ } catch (e) {
18929
+ Logger.error(
18930
+ "netra.instrumentation.anthropic: finalizeStreamSpan error",
18931
+ e
18932
+ );
18933
+ } finally {
18934
+ span2.end();
18935
+ }
18936
+ }
18937
+ function setRequestAttributes2(span2, kwargs, requestType) {
18938
+ try {
18939
+ if (!span2.isRecording()) {
18940
+ Logger.log("Span is not recording");
18941
+ return;
18942
+ }
18943
+ setRequestAttributes(span2, kwargs, requestType, "anthropic");
18944
+ } catch (e) {
18945
+ Logger.error(
18946
+ "netra.instrumentation.anthropic: setRequestAttributes error",
18947
+ e
18948
+ );
18949
+ }
18950
+ }
18951
+ function setResponseAttributes2(span2, response) {
18952
+ try {
18953
+ if (!span2.isRecording()) {
18954
+ Logger.log("Span is not recording");
18955
+ return;
18956
+ }
18957
+ if (response?.type === "message_batch") {
18958
+ span2.setAttribute("status", response?.processing_status);
18959
+ }
18960
+ setResponseAttributes(span2, response);
18961
+ } catch (e) {
18962
+ Logger.error(
18963
+ "netra.instrumentation.anthropic: setResponseAttributes error",
18964
+ e
18965
+ );
18966
+ }
18628
18967
  }
18629
- var chatWrapper = (tracer) => anthropicWrapper(tracer, CHAT_SPAN_NAME, "chat");
18630
- var betaWrapper = (tracer) => anthropicWrapper(tracer, BETA_SPAN_NAME, "beta");
18631
- var batchesWrapper = (tracer) => anthropicWrapper(tracer, BATCHES_SPAN_NAME, "batches");
18968
+
18969
+ // src/instrumentation/anthropic/wrappers.ts
18632
18970
  var WRAPPER_OWN_PROPS = /* @__PURE__ */ new Set([
18633
18971
  "span",
18634
18972
  "messageStream",
18635
18973
  "startTime",
18636
18974
  "requestKwargs",
18637
18975
  "completeResponse",
18638
- "processChunk",
18639
- "finalizeSpan",
18976
+ "finalizeSpanOnce",
18640
18977
  "processEventData",
18641
- "finalizeSpanFromMessage"
18978
+ "finalizeSpanFromMessage",
18979
+ "parentContext",
18980
+ "spanFinalized",
18981
+ "completionPending",
18982
+ "listenerMap"
18642
18983
  ]);
18643
18984
  var EVENT_EMITTER_METHODS = /* @__PURE__ */ new Set([
18644
18985
  "on",
@@ -18652,20 +18993,90 @@ var EVENT_EMITTER_METHODS = /* @__PURE__ */ new Set([
18652
18993
  "listenerCount"
18653
18994
  ]);
18654
18995
  var LISTENER_REGISTRATION_METHODS = /* @__PURE__ */ new Set(["on", "once", "addListener"]);
18996
+ var LISTENER_REMOVAL_METHODS = /* @__PURE__ */ new Set(["off", "removeListener"]);
18655
18997
  var COMPLETION_METHODS = /* @__PURE__ */ new Set(["finalMessage", "done", "finalText"]);
18656
- var TRACKED_STREAM_EVENTS = /* @__PURE__ */ new Set(["message", "contentBlock", "text", "finalMessage"]);
18998
+ var TRACKED_STREAM_EVENTS = /* @__PURE__ */ new Set([
18999
+ "message",
19000
+ "contentBlock",
19001
+ "text",
19002
+ "finalMessage"
19003
+ ]);
19004
+ var MAX_TOOL_ATTR_LENGTH = 4096;
19005
+ function wrapRunnableTools(tools, tracer, parentContext) {
19006
+ return tools.map((tool) => {
19007
+ if (typeof tool.run !== "function") return tool;
19008
+ const originalRun = tool.run;
19009
+ const toolName = tool.name ?? "unknown_tool";
19010
+ const wrappedRun = async function(input, runContext) {
19011
+ const toolUseId = runContext?.toolUse?.id ?? runContext?.toolUseBlock?.id;
19012
+ const traceContent = isTraceContentEnabled();
19013
+ const attrs = {
19014
+ "netra.span.type": "TOOL",
19015
+ [SpanAttributes2.LLM_REQUEST_TOOL_NAME]: toolName
19016
+ };
19017
+ if (toolUseId) attrs[SpanAttributes2.LLM_REQUEST_TOOL_ID] = toolUseId;
19018
+ if (traceContent) {
19019
+ attrs.input = safeStringify(input, MAX_TOOL_ATTR_LENGTH);
19020
+ }
19021
+ const span2 = tracer.startSpan(
19022
+ toolName,
19023
+ { kind: api.SpanKind.INTERNAL, attributes: attrs },
19024
+ parentContext
19025
+ );
19026
+ const spanCtx = api.trace.setSpan(parentContext, span2);
19027
+ try {
19028
+ const result = await api.context.with(
19029
+ spanCtx,
19030
+ () => originalRun.call(this, input, runContext)
19031
+ );
19032
+ if (traceContent) {
19033
+ span2.setAttribute(
19034
+ "output",
19035
+ safeStringify(result, MAX_TOOL_ATTR_LENGTH)
19036
+ );
19037
+ }
19038
+ span2.setStatus({ code: api.SpanStatusCode.OK });
19039
+ return result;
19040
+ } catch (error) {
19041
+ span2.setStatus({
19042
+ code: api.SpanStatusCode.ERROR,
19043
+ message: error instanceof Error ? error.message : String(error)
19044
+ });
19045
+ span2.recordException(error);
19046
+ throw error;
19047
+ } finally {
19048
+ span2.end();
19049
+ }
19050
+ };
19051
+ const wrapped = Object.create(
19052
+ Object.getPrototypeOf(tool),
19053
+ Object.getOwnPropertyDescriptors(tool)
19054
+ );
19055
+ wrapped.run = wrappedRun;
19056
+ return wrapped;
19057
+ });
19058
+ }
18657
19059
  var MessageStreamWrapper = class {
18658
- constructor(span2, messageStream, startTime, requestKwargs, spanContext) {
19060
+ constructor(span2, messageStream, startTime, requestKwargs, spanContext, parentContext) {
18659
19061
  this.completeResponse = {
18660
19062
  content: [],
18661
19063
  model: "",
18662
19064
  usage: {}
18663
19065
  };
19066
+ this.spanFinalized = false;
19067
+ this.completionPending = false;
19068
+ this.listenerMap = /* @__PURE__ */ new WeakMap();
18664
19069
  defineHidden(this, "span", span2);
18665
19070
  defineHidden(this, "messageStream", messageStream);
18666
19071
  defineHidden(this, "startTime", startTime);
18667
19072
  defineHidden(this, "requestKwargs", requestKwargs);
18668
- defineHidden(this, "spanContext", spanContext || api.trace.setSpan(api.context.active(), span2));
19073
+ defineHidden(
19074
+ this,
19075
+ "spanContext",
19076
+ spanContext || api.trace.setSpan(api.context.active(), span2)
19077
+ );
19078
+ defineHidden(this, "parentContext", parentContext || api.context.active());
19079
+ this.registerSafetyNetListeners();
18669
19080
  return new Proxy(this, {
18670
19081
  get(target, prop, receiver) {
18671
19082
  if (prop === "toJSON") {
@@ -18679,67 +19090,135 @@ var MessageStreamWrapper = class {
18679
19090
  }
18680
19091
  if (typeof prop === "string" && EVENT_EMITTER_METHODS.has(prop)) {
18681
19092
  const method = target.messageStream[prop];
18682
- if (typeof method === "function") {
18683
- if (LISTENER_REGISTRATION_METHODS.has(prop)) {
18684
- return function(event, listener) {
18685
- const wrappedListener = (...args) => {
19093
+ if (typeof method !== "function") return method;
19094
+ if (LISTENER_REGISTRATION_METHODS.has(prop)) {
19095
+ return function(event, listener) {
19096
+ const wrappedListener = (...args) => {
19097
+ try {
18686
19098
  target.span.addEvent(`messagestream.event.${event}`, {
18687
19099
  "event.type": event
18688
19100
  });
18689
- if (TRACKED_STREAM_EVENTS.has(event)) {
18690
- if (args[0]) {
18691
- target.processEventData(event, args[0]);
18692
- }
19101
+ if (TRACKED_STREAM_EVENTS.has(event) && args[0]) {
19102
+ target.processEventData(event, args[0]);
18693
19103
  }
18694
- return listener(...args);
18695
- };
18696
- return method.call(target.messageStream, event, wrappedListener);
19104
+ } catch (e) {
19105
+ Logger.error(
19106
+ "netra.instrumentation.anthropic: event tracking error",
19107
+ e
19108
+ );
19109
+ }
19110
+ return listener(...args);
18697
19111
  };
18698
- }
18699
- return method.bind(target.messageStream);
19112
+ let eventMap = target.listenerMap.get(listener);
19113
+ if (!eventMap) {
19114
+ eventMap = /* @__PURE__ */ new Map();
19115
+ target.listenerMap.set(listener, eventMap);
19116
+ }
19117
+ let wrappers = eventMap.get(event);
19118
+ if (!wrappers) {
19119
+ wrappers = [];
19120
+ eventMap.set(event, wrappers);
19121
+ }
19122
+ wrappers.push(wrappedListener);
19123
+ return method.call(target.messageStream, event, wrappedListener);
19124
+ };
18700
19125
  }
18701
- return method;
19126
+ if (LISTENER_REMOVAL_METHODS.has(prop)) {
19127
+ return function(event, listener) {
19128
+ const eventMap = target.listenerMap.get(listener);
19129
+ const wrappers = eventMap?.get(event);
19130
+ const wrapped = wrappers?.shift() ?? listener;
19131
+ if (wrappers && wrappers.length === 0) eventMap?.delete(event);
19132
+ return method.call(target.messageStream, event, wrapped);
19133
+ };
19134
+ }
19135
+ if (prop === "removeAllListeners") {
19136
+ return function(event) {
19137
+ target.listenerMap = /* @__PURE__ */ new WeakMap();
19138
+ return method.call(target.messageStream, event);
19139
+ };
19140
+ }
19141
+ return method.bind(target.messageStream);
18702
19142
  }
18703
19143
  if (typeof prop === "string" && COMPLETION_METHODS.has(prop)) {
18704
19144
  const method = target.messageStream[prop];
18705
- if (typeof method === "function") {
18706
- return async function(...args) {
18707
- try {
18708
- const result = await method.call(target.messageStream, ...args);
18709
- if (prop === "finalMessage" || prop === "done") {
18710
- target.finalizeSpanFromMessage(result);
19145
+ if (typeof method !== "function") return method;
19146
+ return async function(...args) {
19147
+ target.completionPending = true;
19148
+ try {
19149
+ const result = await method.call(target.messageStream, ...args);
19150
+ if (prop === "finalMessage" || prop === "done") {
19151
+ target.finalizeSpanFromMessage(result);
19152
+ } else if (prop === "finalText") {
19153
+ if (typeof result === "string" && result.length > 0) {
19154
+ target.completeResponse.content = [
19155
+ { type: "text", text: result }
19156
+ ];
19157
+ } else {
19158
+ target.flushCurrentText();
18711
19159
  }
18712
- return result;
18713
- } catch (error) {
18714
- target.finalizeSpan(api.SpanStatusCode.ERROR);
18715
- throw error;
19160
+ target.finalizeSpanOnce(api.SpanStatusCode.OK);
18716
19161
  }
18717
- };
18718
- }
18719
- return method;
19162
+ return result;
19163
+ } catch (error) {
19164
+ target.finalizeSpanOnce(api.SpanStatusCode.ERROR);
19165
+ throw error;
19166
+ }
19167
+ };
18720
19168
  }
18721
19169
  const value = target.messageStream[prop];
18722
- if (typeof value === "function") {
19170
+ if (typeof value === "function")
18723
19171
  return value.bind(target.messageStream);
18724
- }
18725
19172
  return value;
18726
19173
  }
18727
19174
  });
18728
19175
  }
19176
+ registerSafetyNetListeners() {
19177
+ try {
19178
+ if (typeof this.messageStream?.on !== "function") return;
19179
+ this.messageStream.on("end", () => {
19180
+ if (!this.completionPending) {
19181
+ this.finalizeSpanOnce(api.SpanStatusCode.OK);
19182
+ }
19183
+ });
19184
+ this.messageStream.on("error", (err) => {
19185
+ if (err && !this.spanFinalized) {
19186
+ this.span.setStatus({
19187
+ code: api.SpanStatusCode.ERROR,
19188
+ message: err instanceof Error ? err.message : String(err)
19189
+ });
19190
+ this.span.recordException(
19191
+ err instanceof Error ? err : new Error(String(err))
19192
+ );
19193
+ }
19194
+ this.finalizeSpanOnce(api.SpanStatusCode.ERROR);
19195
+ });
19196
+ } catch (e) {
19197
+ Logger.error(
19198
+ "netra.instrumentation.anthropic: safety net listener registration failed",
19199
+ e
19200
+ );
19201
+ }
19202
+ }
18729
19203
  toJSON() {
18730
19204
  return this.completeResponse;
18731
19205
  }
18732
19206
  async *[Symbol.asyncIterator]() {
19207
+ let errorOccurred = false;
18733
19208
  try {
18734
19209
  for await (const chunk of this.messageStream) {
18735
- this.processChunk(chunk);
19210
+ processStreamChunk(this.completeResponse, chunk, this.span);
18736
19211
  yield chunk;
18737
19212
  }
18738
- this.finalizeSpan(api.SpanStatusCode.OK);
18739
19213
  } catch (err) {
19214
+ errorOccurred = true;
18740
19215
  Logger.error("netra.instrumentation.anthropic: Stream error", err);
18741
- this.finalizeSpan(api.SpanStatusCode.ERROR);
19216
+ this.finalizeSpanOnce(api.SpanStatusCode.ERROR);
18742
19217
  throw err;
19218
+ } finally {
19219
+ if (!errorOccurred) {
19220
+ this.finalizeSpanOnce(api.SpanStatusCode.OK);
19221
+ }
18743
19222
  }
18744
19223
  }
18745
19224
  getSpanContext() {
@@ -18748,12 +19227,8 @@ var MessageStreamWrapper = class {
18748
19227
  processEventData(eventType, data) {
18749
19228
  switch (eventType) {
18750
19229
  case "message":
18751
- if (data.model) {
18752
- this.completeResponse.model = data.model;
18753
- }
18754
- if (data.usage) {
18755
- this.completeResponse.usage = data.usage;
18756
- }
19230
+ if (data.model) this.completeResponse.model = data.model;
19231
+ if (data.usage) this.completeResponse.usage = data.usage;
18757
19232
  break;
18758
19233
  case "text":
18759
19234
  if (!this.completeResponse.currentText) {
@@ -18774,250 +19249,359 @@ var MessageStreamWrapper = class {
18774
19249
  break;
18775
19250
  }
18776
19251
  }
18777
- processChunk(chunk) {
18778
- switch (chunk.type) {
18779
- case "message_start": {
18780
- if (chunk.message?.model) {
18781
- this.completeResponse.model = chunk.message.model;
18782
- }
18783
- if (chunk.message?.usage) {
18784
- this.completeResponse.usage = chunk.message.usage;
18785
- }
18786
- break;
18787
- }
18788
- case "content_block_start": {
18789
- if (!this.completeResponse.content) {
18790
- this.completeResponse.content = [];
18791
- }
18792
- const block = chunk.content_block;
18793
- if (block.type === "tool_use") {
18794
- this.completeResponse.content.push({
18795
- type: "tool_use",
18796
- id: block.id,
18797
- name: block.name,
18798
- input: ""
18799
- });
18800
- } else {
18801
- this.completeResponse.content.push({
18802
- type: block.type,
18803
- text: ""
18804
- });
18805
- }
18806
- break;
18807
- }
18808
- case "content_block_delta": {
18809
- if (!this.completeResponse.content || this.completeResponse.content.length === 0) {
18810
- this.completeResponse.content = [{ type: "text", text: "" }];
18811
- }
18812
- const lastBlock = this.completeResponse.content[this.completeResponse.content.length - 1];
18813
- if (chunk.delta?.type === "input_json_delta" && lastBlock?.type === "tool_use") {
18814
- lastBlock.input += chunk.delta.partial_json ?? "";
18815
- } else if (lastBlock && chunk.delta?.text) {
18816
- lastBlock.text += chunk.delta.text;
18817
- }
18818
- break;
18819
- }
18820
- case "content_block_stop": {
18821
- const blocks = this.completeResponse.content;
18822
- if (blocks && blocks.length > 0) {
18823
- const finishedBlock = blocks[blocks.length - 1];
18824
- if (finishedBlock?.type === "tool_use" && typeof finishedBlock.input === "string") {
18825
- try {
18826
- finishedBlock.input = JSON.parse(finishedBlock.input);
18827
- } catch {
18828
- Logger.warn("netra.instrumentation.anthropic: Failed to parse tool use input", finishedBlock.input);
18829
- }
18830
- }
18831
- }
18832
- break;
18833
- }
18834
- case "message_delta": {
18835
- if (chunk.delta?.usage) {
18836
- this.completeResponse.usage = {
18837
- ...this.completeResponse.usage,
18838
- ...chunk.delta.usage
18839
- };
18840
- }
18841
- break;
18842
- }
18843
- case "message_stop": {
18844
- if (chunk.usage) {
18845
- this.completeResponse.usage = chunk.usage;
18846
- }
18847
- break;
18848
- }
19252
+ flushCurrentText() {
19253
+ if (this.completeResponse.currentText && (!this.completeResponse.content || this.completeResponse.content.length === 0)) {
19254
+ this.completeResponse.content = [
19255
+ { type: "text", text: this.completeResponse.currentText }
19256
+ ];
18849
19257
  }
18850
- this.span.addEvent("llm.content.completion.chunk", {
18851
- "chunk.type": chunk.type
18852
- });
18853
19258
  }
18854
19259
  finalizeSpanFromMessage(message) {
18855
19260
  if (message) {
18856
19261
  if (message.model) this.completeResponse.model = message.model;
18857
19262
  if (message.content) this.completeResponse.content = message.content;
18858
19263
  if (message.usage) this.completeResponse.usage = message.usage;
19264
+ if (message.stop_reason)
19265
+ this.completeResponse.stop_reason = message.stop_reason;
18859
19266
  }
18860
- this.finalizeSpan(api.SpanStatusCode.OK);
19267
+ this.finalizeSpanOnce(api.SpanStatusCode.OK);
18861
19268
  }
18862
- finalizeSpan(code) {
18863
- const endTime = Date.now();
18864
- const duration = (endTime - this.startTime) / 1e3;
18865
- setResponseAttributes2(this.span, {
18866
- model: this.completeResponse.model,
18867
- content: this.completeResponse.content,
18868
- usage: this.completeResponse.usage
18869
- });
18870
- this.span.setAttribute("llm.response.duration", duration);
18871
- this.span.setStatus({ code });
18872
- this.span.end();
19269
+ finalizeSpanOnce(code) {
19270
+ if (this.spanFinalized) return;
19271
+ this.spanFinalized = true;
19272
+ finalizeStreamSpan(this.span, this.completeResponse, this.startTime, code);
18873
19273
  }
18874
19274
  };
18875
- var AsyncStreamingWrapper = class {
18876
- constructor(span2, response, startTime, requestKwargs, spanContext) {
18877
- this.iterator = null;
18878
- this.completeResponse = {
18879
- choices: [],
18880
- model: ""
18881
- };
18882
- defineHidden(this, "span", span2);
18883
- defineHidden(this, "response", response);
18884
- defineHidden(this, "startTime", startTime);
18885
- defineHidden(this, "requestKwargs", requestKwargs);
18886
- defineHidden(this, "spanContext", spanContext || api.trace.setSpan(api.context.active(), span2));
18887
- }
18888
- toJSON() {
18889
- return this.completeResponse;
18890
- }
18891
- [Symbol.asyncIterator]() {
18892
- return this;
18893
- }
18894
- async next() {
18895
- try {
18896
- if (!this.iterator) {
18897
- if (Symbol.asyncIterator in this.response) {
18898
- this.iterator = this.response[Symbol.asyncIterator]();
18899
- } else if (typeof this.response.next === "function") {
18900
- this.iterator = this.response;
18901
- } else {
18902
- throw new Error("Response is not iterable");
18903
- }
18904
- }
18905
- const result = await api.context.with(this.spanContext, () => this.iterator.next());
18906
- if (result.done) {
18907
- this.finalizeSpan(api.SpanStatusCode.OK);
18908
- return result;
18909
- }
18910
- this.processChunk(result.value);
18911
- return result;
18912
- } catch (error) {
18913
- this.finalizeSpan(api.SpanStatusCode.ERROR);
18914
- throw error;
18915
- }
18916
- }
18917
- processChunk(chunk) {
18918
- switch (chunk.type) {
18919
- case "message_start": {
18920
- if (chunk.message?.model) {
18921
- this.completeResponse.model = chunk.message.model;
18922
- }
18923
- if (chunk.message?.usage) {
18924
- this.completeResponse.usage = chunk.message.usage;
18925
- }
18926
- break;
18927
- }
18928
- case "content_block_start": {
18929
- const content = this.completeResponse.content || [];
18930
- this.completeResponse.content = content;
18931
- const block = chunk.content_block;
18932
- if (block.type === "tool_use") {
18933
- content.push({
18934
- type: "tool_use",
18935
- id: block.id,
18936
- name: block.name,
18937
- input: ""
18938
- });
18939
- } else {
18940
- content.push({
18941
- type: block.type,
18942
- text: ""
18943
- });
18944
- }
18945
- break;
18946
- }
18947
- case "content_block_delta": {
18948
- const content = this.completeResponse.content || [];
18949
- if (content.length === 0) {
18950
- content.push({ type: "text", text: "" });
18951
- this.completeResponse.content = content;
18952
- }
18953
- const lastBlock = content[content.length - 1];
18954
- if (chunk.delta?.type === "input_json_delta" && lastBlock?.type === "tool_use") {
18955
- lastBlock.input += chunk.delta.partial_json ?? "";
18956
- } else if (lastBlock && chunk.delta?.text) {
18957
- lastBlock.text += chunk.delta.text;
18958
- }
18959
- break;
19275
+ function anthropicWrapper(tracer, spanName, requestType) {
19276
+ return function wrapper(original) {
19277
+ return function(...args) {
19278
+ if (shouldSuppressInstrumentation()) {
19279
+ return original.apply(this, args);
18960
19280
  }
18961
- case "content_block_stop": {
18962
- const content = this.completeResponse.content || [];
18963
- if (content.length > 0) {
18964
- const finishedBlock = content[content.length - 1];
18965
- if (finishedBlock?.type === "tool_use" && typeof finishedBlock.input === "string") {
18966
- try {
18967
- finishedBlock.input = JSON.parse(finishedBlock.input);
18968
- } catch {
18969
- Logger.warn("netra.instrumentation.anthropic: Failed to parse tool use input", finishedBlock.input);
19281
+ const attributes = args[0] || {};
19282
+ const currentContext = api.context.active();
19283
+ const isStreaming = attributes.stream === true;
19284
+ const activeSpan = api.trace.getSpan(currentContext);
19285
+ Logger.debug(
19286
+ `Anthropic invoke (${requestType}). Active TraceId: ${activeSpan?.spanContext().traceId}, SpanId: ${activeSpan?.spanContext().spanId}`
19287
+ );
19288
+ return tracer.startActiveSpan(
19289
+ spanName,
19290
+ {
19291
+ kind: api.SpanKind.CLIENT,
19292
+ attributes: { "llm.request.type": requestType }
19293
+ },
19294
+ (span2) => {
19295
+ try {
19296
+ setRequestAttributes2(span2, attributes, requestType);
19297
+ if (isStreaming) {
19298
+ span2.setAttribute("llm.streaming", true);
18970
19299
  }
19300
+ const startTime = Date.now();
19301
+ const spanContext = api.trace.setSpan(currentContext, span2);
19302
+ const response = api.context.with(
19303
+ spanContext,
19304
+ () => original.apply(this, args)
19305
+ );
19306
+ const completeResponse = {
19307
+ content: [],
19308
+ model: "",
19309
+ usage: {}
19310
+ };
19311
+ return wrapResponse(
19312
+ response,
19313
+ {
19314
+ withContext: (fn) => api.context.with(spanContext, fn),
19315
+ onChunk: (chunk) => processStreamChunk(completeResponse, chunk, span2),
19316
+ onError: (error) => {
19317
+ Logger.error("netra.instrumentation.anthropic:", error);
19318
+ span2.setStatus({
19319
+ code: api.SpanStatusCode.ERROR,
19320
+ message: error instanceof Error ? error.message : String(error)
19321
+ });
19322
+ span2.recordException(error);
19323
+ },
19324
+ onSuccess: (value) => {
19325
+ const endTime = Date.now();
19326
+ const responseDict = modelAsDict(value);
19327
+ setResponseAttributes2(span2, responseDict);
19328
+ span2.setAttribute(
19329
+ "llm.response.duration",
19330
+ (endTime - startTime) / 1e3
19331
+ );
19332
+ },
19333
+ finalize: (status) => {
19334
+ const hasStreamData = completeResponse.content?.length || completeResponse.model || completeResponse.usage?.input_tokens !== void 0 || completeResponse.usage?.output_tokens !== void 0;
19335
+ if (status === "ok" && hasStreamData) {
19336
+ finalizeStreamSpan(
19337
+ span2,
19338
+ completeResponse,
19339
+ startTime,
19340
+ api.SpanStatusCode.OK
19341
+ );
19342
+ } else {
19343
+ if (status === "ok") {
19344
+ span2.setStatus({ code: api.SpanStatusCode.OK });
19345
+ }
19346
+ span2.end();
19347
+ }
19348
+ }
19349
+ },
19350
+ { preserveOriginal: response }
19351
+ );
19352
+ } catch (error) {
19353
+ Logger.error("netra.instrumentation.anthropic:", error);
19354
+ span2.setStatus({
19355
+ code: api.SpanStatusCode.ERROR,
19356
+ message: error instanceof Error ? error.message : String(error)
19357
+ });
19358
+ span2.recordException(error);
19359
+ span2.end();
19360
+ throw error;
18971
19361
  }
18972
19362
  }
18973
- break;
19363
+ );
19364
+ };
19365
+ };
19366
+ }
19367
+ function streamWrapper(tracer, spanName, requestType, originalCreate) {
19368
+ return function wrapper(original) {
19369
+ return function(...args) {
19370
+ if (shouldSuppressInstrumentation()) {
19371
+ return original.apply(this, args);
18974
19372
  }
18975
- case "message_delta": {
18976
- if (chunk.delta?.usage) {
18977
- const currentUsage = this.completeResponse.usage || {};
18978
- this.completeResponse.usage = {
18979
- ...currentUsage,
18980
- ...chunk.delta.usage
18981
- };
19373
+ const attributes = args[0] || {};
19374
+ const currentContext = api.context.active();
19375
+ const span2 = tracer.startSpan(
19376
+ spanName,
19377
+ {
19378
+ kind: api.SpanKind.CLIENT,
19379
+ attributes: {
19380
+ "llm.request.type": requestType,
19381
+ "llm.streaming": true,
19382
+ "llm.operation": "stream"
19383
+ }
19384
+ },
19385
+ currentContext
19386
+ );
19387
+ const spanContext = api.trace.setSpan(currentContext, span2);
19388
+ setRequestAttributes2(span2, attributes, requestType);
19389
+ const startTime = Date.now();
19390
+ const callTarget = originalCreate ? new Proxy(this, {
19391
+ get(target, prop) {
19392
+ if (prop === "create") return originalCreate.bind(target);
19393
+ const value = target[prop];
19394
+ if (typeof value === "function") return value.bind(target);
19395
+ return value;
18982
19396
  }
18983
- break;
19397
+ }) : this;
19398
+ try {
19399
+ const messageStream = api.context.with(
19400
+ spanContext,
19401
+ () => original.call(callTarget, ...args)
19402
+ );
19403
+ return new MessageStreamWrapper(
19404
+ span2,
19405
+ messageStream,
19406
+ startTime,
19407
+ attributes,
19408
+ spanContext,
19409
+ currentContext
19410
+ );
19411
+ } catch (error) {
19412
+ span2.setStatus({
19413
+ code: api.SpanStatusCode.ERROR,
19414
+ message: error instanceof Error ? error.message : String(error)
19415
+ });
19416
+ span2.recordException(error);
19417
+ span2.end();
19418
+ throw error;
18984
19419
  }
18985
- case "message_stop": {
18986
- if (chunk.usage) {
18987
- this.completeResponse.usage = chunk.usage;
19420
+ };
19421
+ };
19422
+ }
19423
+ function toolRunnerWrapper(tracer, spanName, requestType) {
19424
+ return function wrapper(original) {
19425
+ return function(...args) {
19426
+ if (shouldSuppressInstrumentation()) {
19427
+ return original.apply(this, args);
19428
+ }
19429
+ const attributes = args[0] || {};
19430
+ const currentContext = api.context.active();
19431
+ const span2 = tracer.startSpan(
19432
+ spanName,
19433
+ {
19434
+ kind: api.SpanKind.CLIENT,
19435
+ attributes: {
19436
+ "llm.request.type": requestType,
19437
+ "netra.span.type": "AGENT",
19438
+ "llm.operation": "tool.runner"
19439
+ }
19440
+ },
19441
+ currentContext
19442
+ );
19443
+ let spanEnded = false;
19444
+ const endSpanOnce = (code, error) => {
19445
+ if (spanEnded) return;
19446
+ spanEnded = true;
19447
+ if (error) {
19448
+ span2.setStatus({ code, message: error.message });
19449
+ span2.recordException(error);
19450
+ } else {
19451
+ span2.setStatus({ code });
18988
19452
  }
18989
- break;
19453
+ span2.end();
19454
+ };
19455
+ try {
19456
+ setRequestAttributes2(span2, attributes, "beta");
19457
+ const spanContext = api.trace.setSpan(currentContext, span2);
19458
+ const wrappedTools = Array.isArray(attributes.tools) ? wrapRunnableTools(attributes.tools, tracer, spanContext) : attributes.tools;
19459
+ const wrappedArgs = [
19460
+ { ...attributes, tools: wrappedTools },
19461
+ ...args.slice(1)
19462
+ ];
19463
+ const runner = api.context.with(
19464
+ spanContext,
19465
+ () => original.apply(this, wrappedArgs)
19466
+ );
19467
+ if (runner == null) {
19468
+ endSpanOnce(api.SpanStatusCode.OK);
19469
+ return runner;
19470
+ }
19471
+ return new Proxy(runner, {
19472
+ get(target, prop, receiver) {
19473
+ if (prop === Symbol.asyncIterator) {
19474
+ return function() {
19475
+ const originalIterator = target[Symbol.asyncIterator]();
19476
+ return {
19477
+ [Symbol.asyncIterator]() {
19478
+ return this;
19479
+ },
19480
+ async next() {
19481
+ try {
19482
+ const result = await api.context.with(
19483
+ spanContext,
19484
+ () => originalIterator.next()
19485
+ );
19486
+ if (result.done) endSpanOnce(api.SpanStatusCode.OK);
19487
+ return result;
19488
+ } catch (error) {
19489
+ endSpanOnce(api.SpanStatusCode.ERROR, error);
19490
+ throw error;
19491
+ }
19492
+ },
19493
+ async return(value2) {
19494
+ try {
19495
+ const result = await (originalIterator.return?.(
19496
+ value2
19497
+ ) ?? {
19498
+ done: true,
19499
+ value: value2
19500
+ });
19501
+ return result;
19502
+ } finally {
19503
+ endSpanOnce(api.SpanStatusCode.OK);
19504
+ }
19505
+ },
19506
+ async throw(error) {
19507
+ const err = error instanceof Error ? error : new Error(String(error));
19508
+ if (originalIterator.throw) {
19509
+ try {
19510
+ const result = await originalIterator.throw(error);
19511
+ if (result.done) {
19512
+ endSpanOnce(api.SpanStatusCode.ERROR, err);
19513
+ }
19514
+ return result;
19515
+ } catch (e) {
19516
+ endSpanOnce(
19517
+ api.SpanStatusCode.ERROR,
19518
+ e instanceof Error ? e : new Error(String(e))
19519
+ );
19520
+ throw e;
19521
+ }
19522
+ }
19523
+ endSpanOnce(api.SpanStatusCode.ERROR, err);
19524
+ throw error;
19525
+ }
19526
+ };
19527
+ };
19528
+ }
19529
+ if (prop === "then" || prop === "catch" || prop === "finally") {
19530
+ const originalMethod = target[prop];
19531
+ if (typeof originalMethod !== "function") return originalMethod;
19532
+ if (prop === "then") {
19533
+ return function(onFulfilled, onRejected) {
19534
+ return originalMethod.call(
19535
+ target,
19536
+ (v) => {
19537
+ endSpanOnce(api.SpanStatusCode.OK);
19538
+ return onFulfilled ? onFulfilled(v) : v;
19539
+ },
19540
+ (e) => {
19541
+ endSpanOnce(
19542
+ api.SpanStatusCode.ERROR,
19543
+ e instanceof Error ? e : new Error(String(e))
19544
+ );
19545
+ if (onRejected) return onRejected(e);
19546
+ throw e;
19547
+ }
19548
+ );
19549
+ };
19550
+ }
19551
+ if (prop === "catch") {
19552
+ return function(onRejected) {
19553
+ return receiver.then(void 0, onRejected);
19554
+ };
19555
+ }
19556
+ if (prop === "finally") {
19557
+ return function(onFinally) {
19558
+ return receiver.then(
19559
+ (v) => {
19560
+ onFinally?.();
19561
+ return v;
19562
+ },
19563
+ (e) => {
19564
+ onFinally?.();
19565
+ throw e;
19566
+ }
19567
+ );
19568
+ };
19569
+ }
19570
+ }
19571
+ const value = target[prop];
19572
+ if (typeof value === "function") return value.bind(target);
19573
+ return value;
19574
+ }
19575
+ });
19576
+ } catch (error) {
19577
+ endSpanOnce(
19578
+ api.SpanStatusCode.ERROR,
19579
+ error instanceof Error ? error : new Error(String(error))
19580
+ );
19581
+ throw error;
18990
19582
  }
18991
- }
18992
- this.span.addEvent("llm.content.completion.chunk", {
18993
- "chunk.type": chunk.type
18994
- });
18995
- }
18996
- finalizeSpan(code) {
18997
- const endTime = Date.now();
18998
- const duration = (endTime - this.startTime) / 1e3;
18999
- setResponseAttributes2(this.span, {
19000
- model: this.completeResponse.model,
19001
- content: this.completeResponse.content,
19002
- usage: this.completeResponse.usage
19003
- });
19004
- this.span.setAttribute("llm.response.duration", duration);
19005
- this.span.setStatus({ code });
19006
- this.span.end();
19007
- }
19008
- };
19583
+ };
19584
+ };
19585
+ }
19586
+ var chatWrapper = (tracer) => anthropicWrapper(tracer, SPAN_NAMES.CHAT, "chat");
19587
+ var betaWrapper = (tracer) => anthropicWrapper(tracer, SPAN_NAMES.BETA, "beta");
19588
+ var batchesWrapper = (tracer) => anthropicWrapper(tracer, SPAN_NAMES.BATCHES, "batches");
19589
+ var chatStreamWrapper = (tracer, originalCreate) => streamWrapper(tracer, SPAN_NAMES.STREAM, "chat", originalCreate);
19590
+ var betaStreamWrapper = (tracer, originalCreate) => streamWrapper(tracer, SPAN_NAMES.BETA_STREAM, "beta", originalCreate);
19591
+ var betaToolRunnerWrapper = (tracer) => toolRunnerWrapper(tracer, SPAN_NAMES.BETA_TOOL_RUNNER, "beta");
19009
19592
 
19010
19593
  // src/instrumentation/anthropic/index.ts
19011
19594
  var INSTRUMENTATION_NAME = "netra.instrumentation.anthropic";
19012
19595
  var INSTRUMENTS = ["anthropic >= 0.71.2"];
19013
- var originalMethods = /* @__PURE__ */ new Map();
19014
19596
  var isInstrumented = false;
19015
19597
  var anthropicClasses = [];
19016
- async function resolveAnthropicAsync() {
19598
+ async function resolveAnthropic() {
19017
19599
  if (anthropicClasses.length > 0) return anthropicClasses;
19018
19600
  try {
19019
19601
  const anthropicModule = await import('@anthropic-ai/sdk');
19020
- anthropicClasses.push(anthropicModule.Anthropic || anthropicModule.default || anthropicModule);
19602
+ anthropicClasses.push(
19603
+ anthropicModule.Anthropic || anthropicModule.default || anthropicModule
19604
+ );
19021
19605
  } catch {
19022
19606
  Logger.warn("Failed to resolve Anthropic ESM module");
19023
19607
  }
@@ -19033,9 +19617,6 @@ async function resolveAnthropicAsync() {
19033
19617
  }
19034
19618
  return anthropicClasses;
19035
19619
  }
19036
- function resolveAnthropic() {
19037
- return anthropicClasses;
19038
- }
19039
19620
  var NetraAnthropicInstrumentor = class {
19040
19621
  constructor() {
19041
19622
  this.tracer = null;
@@ -19043,15 +19624,13 @@ var NetraAnthropicInstrumentor = class {
19043
19624
  instrumentationDependencies() {
19044
19625
  return INSTRUMENTS;
19045
19626
  }
19046
- async instrumentAsync(options = {}) {
19627
+ async instrument(options = {}) {
19047
19628
  if (isInstrumented) {
19048
19629
  Logger.warn("Anthropic is already instrumented");
19049
19630
  return this;
19050
19631
  }
19051
- const classes = await resolveAnthropicAsync();
19052
- if (classes.length === 0) {
19053
- return this;
19054
- }
19632
+ const classes = await resolveAnthropic();
19633
+ if (classes.length === 0) return this;
19055
19634
  try {
19056
19635
  this.tracerProvider = options.tracerProvider;
19057
19636
  if (this.tracerProvider) {
@@ -19066,10 +19645,10 @@ var NetraAnthropicInstrumentor = class {
19066
19645
  Logger.error(`Failed to initialize tracer: ${error}`);
19067
19646
  return this;
19068
19647
  }
19069
- classes.forEach((AnthropicSDK, index) => {
19070
- this._instrumentMessages(AnthropicSDK, index);
19071
- this._instrumentBetaMessages(AnthropicSDK, index);
19072
- this._instrumentBatchMessages(AnthropicSDK, index);
19648
+ classes.forEach((AnthropicSDK) => {
19649
+ this._instrumentMessages(AnthropicSDK);
19650
+ this._instrumentBetaMessages(AnthropicSDK);
19651
+ this._instrumentBatchMessages(AnthropicSDK);
19073
19652
  });
19074
19653
  isInstrumented = true;
19075
19654
  return this;
@@ -19079,185 +19658,137 @@ var NetraAnthropicInstrumentor = class {
19079
19658
  Logger.warn("Anthropic is not instrumented");
19080
19659
  return;
19081
19660
  }
19082
- const classes = resolveAnthropic();
19083
- classes.forEach((AnthropicSDK, index) => {
19084
- this._uninstrumentMessages(AnthropicSDK, index);
19085
- this._uninstrumentBetaMessages(AnthropicSDK, index);
19086
- this._uninstrumentBatchMessages(AnthropicSDK, index);
19661
+ anthropicClasses.forEach((AnthropicSDK) => {
19662
+ this._uninstrumentMessages(AnthropicSDK);
19663
+ this._uninstrumentBetaMessages(AnthropicSDK);
19664
+ this._uninstrumentBatchMessages(AnthropicSDK);
19087
19665
  });
19088
- originalMethods.clear();
19089
19666
  anthropicClasses = [];
19090
19667
  isInstrumented = false;
19091
19668
  }
19092
19669
  isInstrumented() {
19093
19670
  return isInstrumented;
19094
19671
  }
19095
- _instrumentMessages(AnthropicSDK, index) {
19672
+ _instrumentMessages(AnthropicSDK) {
19096
19673
  if (!this.tracer) {
19097
19674
  Logger.warn("Anthropic instrumentation: No tracer available");
19098
19675
  return;
19099
19676
  }
19100
19677
  try {
19101
19678
  const MessagesClass = AnthropicSDK.Messages;
19102
- if (!MessagesClass) {
19679
+ if (!MessagesClass?.prototype) {
19103
19680
  Logger.error(
19104
- "Anthropic instrumentation: Could not find Anthropic Messages class to instrument"
19681
+ "Anthropic instrumentation: Could not find Messages class"
19105
19682
  );
19106
19683
  return;
19107
19684
  }
19108
- if (MessagesClass?.prototype?.stream) {
19109
- const originalStream = MessagesClass.prototype.stream;
19110
- originalMethods.set(`messages.stream-${index}`, originalStream);
19111
- const tracer = this.tracer;
19112
- MessagesClass.prototype.stream = function(...args) {
19113
- const original = originalStream.bind(this);
19114
- const kwargs = args[0] || {};
19115
- const currentContext = api.context.active();
19116
- const span2 = tracer.startSpan("anthropic.stream", {
19117
- kind: api.SpanKind.CLIENT,
19118
- attributes: {
19119
- "llm.request.type": "chat",
19120
- "llm.streaming": true,
19121
- "llm.operation": "stream"
19122
- }
19123
- }, currentContext);
19124
- const spanContext = api.trace.setSpan(currentContext, span2);
19125
- setRequestAttributes2(span2, kwargs, "chat");
19126
- const startTime = Date.now();
19127
- const instrumentedCreate = this.create;
19128
- const originalCreate = originalMethods.get(`messages.create-${index}`);
19129
- if (originalCreate) {
19130
- this.create = originalCreate;
19131
- }
19132
- try {
19133
- const messageStream = api.context.with(spanContext, () => original(...args));
19134
- return new MessageStreamWrapper(span2, messageStream, startTime, kwargs, spanContext);
19135
- } finally {
19136
- if (originalCreate) {
19137
- this.create = instrumentedCreate;
19138
- }
19139
- }
19140
- };
19685
+ const originalCreate = MessagesClass.prototype.create;
19686
+ if (typeof MessagesClass.prototype.create === "function") {
19687
+ shimmer__default.default.wrap(
19688
+ MessagesClass.prototype,
19689
+ "create",
19690
+ chatWrapper(this.tracer)
19691
+ );
19141
19692
  }
19142
- if (MessagesClass?.prototype?.create) {
19143
- const originalCreate = MessagesClass.prototype.create;
19144
- originalMethods.set(`messages.create-${index}`, originalCreate);
19145
- const tracer = this.tracer;
19146
- const wrapper = chatWrapper(tracer);
19147
- MessagesClass.prototype.create = function(...args) {
19148
- const original = originalCreate.bind(this);
19149
- const kwargs = args[0] || {};
19150
- return wrapper(
19151
- (...a) => original(...a),
19152
- this,
19153
- args,
19154
- kwargs
19155
- );
19156
- };
19693
+ if (typeof MessagesClass.prototype.stream === "function") {
19694
+ shimmer__default.default.wrap(
19695
+ MessagesClass.prototype,
19696
+ "stream",
19697
+ chatStreamWrapper(this.tracer, originalCreate)
19698
+ );
19157
19699
  }
19158
19700
  } catch (error) {
19159
19701
  Logger.error(`Failed to instrument messages: ${error}`);
19160
19702
  }
19161
19703
  }
19162
- _instrumentBetaMessages(AnthropicSDK, index) {
19704
+ _instrumentBetaMessages(AnthropicSDK) {
19163
19705
  if (!this.tracer) {
19164
19706
  Logger.warn("Anthropic instrumentation: No tracer available");
19165
19707
  return;
19166
19708
  }
19167
19709
  try {
19168
19710
  const BetaMessagesClass = AnthropicSDK.Beta?.Messages;
19169
- if (!BetaMessagesClass) {
19711
+ if (!BetaMessagesClass?.prototype) {
19170
19712
  Logger.error(
19171
- "Anthropic instrumentation: Could not find Anthropic Beta Messages class to instrument"
19713
+ "Anthropic instrumentation: Could not find Beta Messages class"
19172
19714
  );
19173
19715
  return;
19174
19716
  }
19175
- if (BetaMessagesClass?.prototype?.create) {
19176
- const originalCreate = BetaMessagesClass.prototype.create;
19177
- originalMethods.set(`beta.messages.create-${index}`, originalCreate);
19178
- const tracer = this.tracer;
19179
- const wrapper = betaWrapper(tracer);
19180
- BetaMessagesClass.prototype.create = function(...args) {
19181
- const original = originalCreate.bind(this);
19182
- const kwargs = args[0] || {};
19183
- return wrapper(
19184
- (...a) => original(...a),
19185
- this,
19186
- args,
19187
- kwargs
19188
- );
19189
- };
19717
+ const originalCreate = BetaMessagesClass.prototype.create;
19718
+ if (typeof BetaMessagesClass.prototype.create === "function") {
19719
+ shimmer__default.default.wrap(
19720
+ BetaMessagesClass.prototype,
19721
+ "create",
19722
+ betaWrapper(this.tracer)
19723
+ );
19724
+ }
19725
+ if (typeof BetaMessagesClass.prototype.stream === "function") {
19726
+ shimmer__default.default.wrap(
19727
+ BetaMessagesClass.prototype,
19728
+ "stream",
19729
+ betaStreamWrapper(this.tracer, originalCreate)
19730
+ );
19731
+ }
19732
+ if (typeof BetaMessagesClass.prototype.toolRunner === "function") {
19733
+ shimmer__default.default.wrap(
19734
+ BetaMessagesClass.prototype,
19735
+ "toolRunner",
19736
+ betaToolRunnerWrapper(this.tracer)
19737
+ );
19190
19738
  }
19191
19739
  } catch (error) {
19192
19740
  Logger.error(`Failed to instrument beta: ${error}`);
19193
19741
  }
19194
19742
  }
19195
- _instrumentBatchMessages(AnthropicSDK, index) {
19743
+ _instrumentBatchMessages(AnthropicSDK) {
19196
19744
  if (!this.tracer) {
19197
19745
  Logger.warn("Anthropic instrumentation: No tracer available");
19198
19746
  return;
19199
19747
  }
19200
19748
  try {
19201
19749
  const BatchMessageClass = AnthropicSDK.Messages?.Batches;
19202
- if (!BatchMessageClass) {
19203
- Logger.error(
19204
- "Anthropic instrumentation: Could not find Anthropic Batches class to instrument"
19205
- );
19750
+ if (!BatchMessageClass?.prototype) {
19751
+ Logger.error("Anthropic instrumentation: Could not find Batches class");
19206
19752
  return;
19207
19753
  }
19208
- if (BatchMessageClass?.prototype?.create) {
19209
- const originalCreate = BatchMessageClass.prototype.create;
19210
- originalMethods.set(`batch.messages.create-${index}`, originalCreate);
19211
- const tracer = this.tracer;
19212
- const wrapper = batchesWrapper(tracer);
19213
- BatchMessageClass.prototype.create = function(...args) {
19214
- const original = originalCreate.bind(this);
19215
- const kwargs = args[0] || {};
19216
- return wrapper(
19217
- (...a) => original(...a),
19218
- this,
19219
- args,
19220
- kwargs
19221
- );
19222
- };
19754
+ if (typeof BatchMessageClass.prototype.create === "function") {
19755
+ shimmer__default.default.wrap(
19756
+ BatchMessageClass.prototype,
19757
+ "create",
19758
+ batchesWrapper(this.tracer)
19759
+ );
19223
19760
  }
19224
19761
  } catch (error) {
19225
19762
  Logger.error(`Failed to instrument batches: ${error}`);
19226
19763
  }
19227
19764
  }
19228
- _uninstrumentMessages(AnthropicSDK, index) {
19765
+ _uninstrumentMessages(AnthropicSDK) {
19229
19766
  try {
19230
- const MessagesClass = AnthropicSDK.Messages;
19231
- const originalCreate = originalMethods.get(`messages.create-${index}`);
19232
- if (originalCreate && MessagesClass?.prototype) {
19233
- MessagesClass.prototype.create = originalCreate;
19234
- }
19235
- const originalStream = originalMethods.get(`messages.stream-${index}`);
19236
- if (originalStream && MessagesClass?.prototype) {
19237
- MessagesClass.prototype.stream = originalStream;
19238
- }
19767
+ const proto = AnthropicSDK.Messages?.prototype;
19768
+ if (!proto) return;
19769
+ if (typeof proto.create === "function") shimmer__default.default.unwrap(proto, "create");
19770
+ if (typeof proto.stream === "function") shimmer__default.default.unwrap(proto, "stream");
19239
19771
  } catch (error) {
19240
19772
  Logger.error(`Failed to uninstrument messages: ${error}`);
19241
19773
  }
19242
19774
  }
19243
- _uninstrumentBetaMessages(AnthropicSDK, index) {
19775
+ _uninstrumentBetaMessages(AnthropicSDK) {
19244
19776
  try {
19245
- const BetaMessagesClass = AnthropicSDK.Beta?.Messages;
19246
- const originalCreate = originalMethods.get(`beta.messages.create-${index}`);
19247
- if (originalCreate && BetaMessagesClass?.prototype) {
19248
- BetaMessagesClass.prototype.create = originalCreate;
19249
- }
19777
+ const proto = AnthropicSDK.Beta?.Messages?.prototype;
19778
+ if (!proto) return;
19779
+ if (typeof proto.create === "function") shimmer__default.default.unwrap(proto, "create");
19780
+ if (typeof proto.stream === "function") shimmer__default.default.unwrap(proto, "stream");
19781
+ if (typeof proto.toolRunner === "function")
19782
+ shimmer__default.default.unwrap(proto, "toolRunner");
19250
19783
  } catch (error) {
19251
19784
  Logger.error(`Failed to uninstrument beta: ${error}`);
19252
19785
  }
19253
19786
  }
19254
- _uninstrumentBatchMessages(AnthropicSDK, index) {
19787
+ _uninstrumentBatchMessages(AnthropicSDK) {
19255
19788
  try {
19256
- const BatchMessagesClass = AnthropicSDK.Messages?.Batches;
19257
- const originalCreate = originalMethods.get(`batch.messages.create-${index}`);
19258
- if (originalCreate && BatchMessagesClass?.prototype) {
19259
- BatchMessagesClass.prototype.create = originalCreate;
19260
- }
19789
+ const proto = AnthropicSDK.Messages?.Batches?.prototype;
19790
+ if (!proto) return;
19791
+ if (typeof proto.create === "function") shimmer__default.default.unwrap(proto, "create");
19261
19792
  } catch (error) {
19262
19793
  Logger.error(`Failed to uninstrument batches: ${error}`);
19263
19794
  }
@@ -19673,7 +20204,7 @@ function _setEmbeddingResponseAttributes(span2, response) {
19673
20204
  }
19674
20205
 
19675
20206
  // src/instrumentation/google-genai/wrappers.ts
19676
- var CHAT_SPAN_NAME2 = "google_genai.chat";
20207
+ var CHAT_SPAN_NAME = "google_genai.chat";
19677
20208
  var EMBEDDING_SPAN_NAME = "google_genai.embedding";
19678
20209
  function googleGenAIWrapper(tracer, spanName, requestType) {
19679
20210
  return function wrapper(original) {
@@ -19952,10 +20483,10 @@ function googleGenAIStartChatWrapper(tracer, spanName, requestType) {
19952
20483
  };
19953
20484
  };
19954
20485
  }
19955
- var chatWrapper2 = (tracer) => googleGenAIWrapper(tracer, CHAT_SPAN_NAME2, "chat");
20486
+ var chatWrapper2 = (tracer) => googleGenAIWrapper(tracer, CHAT_SPAN_NAME, "chat");
19956
20487
  var embeddingsWrapper = (tracer) => googleGenAIWrapper(tracer, EMBEDDING_SPAN_NAME, "embedding");
19957
- var chatStreamWrapper = (tracer) => googleGenAIStreamWrapper(tracer, CHAT_SPAN_NAME2, "chat");
19958
- var startChatWrapper = (tracer) => googleGenAIStartChatWrapper(tracer, CHAT_SPAN_NAME2, "chat");
20488
+ var chatStreamWrapper2 = (tracer) => googleGenAIStreamWrapper(tracer, CHAT_SPAN_NAME, "chat");
20489
+ var startChatWrapper = (tracer) => googleGenAIStartChatWrapper(tracer, CHAT_SPAN_NAME, "chat");
19959
20490
  var INSTRUMENTATION_NAME2 = "netra.instrumentation.google_genai";
19960
20491
  var INSTRUMENTS2 = ["@google/genai >= 0.24.1"];
19961
20492
  var isInstrumented2 = false;
@@ -20081,7 +20612,7 @@ var NetraGoogleGenerativeAIInstrumentor = class {
20081
20612
  shimmer__default.default.wrap(
20082
20613
  GenerativeModel.prototype,
20083
20614
  "generateContentStream",
20084
- chatStreamWrapper(tracer)
20615
+ chatStreamWrapper2(tracer)
20085
20616
  );
20086
20617
  shimmer__default.default.wrap(
20087
20618
  GenerativeModel.prototype,
@@ -20143,8 +20674,8 @@ function setResponseAttributes4(span2, response) {
20143
20674
  }
20144
20675
 
20145
20676
  // src/instrumentation/groq/wrappers.ts
20146
- var CHAT_SPAN_NAME3 = "groq.chat";
20147
- var STREAM_ENABLED_REQUESTS2 = ["chat"];
20677
+ var CHAT_SPAN_NAME2 = "groq.chat";
20678
+ var STREAM_ENABLED_REQUESTS = ["chat"];
20148
20679
  function groqWrapper(tracer, spanName, requestType) {
20149
20680
  return function wrapper(wrapped, instance, args, kwargs) {
20150
20681
  if (shouldSuppressInstrumentation()) {
@@ -20152,7 +20683,7 @@ function groqWrapper(tracer, spanName, requestType) {
20152
20683
  return isPromise(result) ? result.then((value) => value) : result;
20153
20684
  }
20154
20685
  const isStreaming = kwargs.stream === true;
20155
- if (isStreaming && STREAM_ENABLED_REQUESTS2.includes(requestType)) {
20686
+ if (isStreaming && STREAM_ENABLED_REQUESTS.includes(requestType)) {
20156
20687
  const currentContext = api.context.active();
20157
20688
  const span2 = tracer.startSpan(
20158
20689
  spanName,
@@ -20170,7 +20701,7 @@ function groqWrapper(tracer, spanName, requestType) {
20170
20701
  return (async () => {
20171
20702
  try {
20172
20703
  const stream = await response;
20173
- return new AsyncStreamingWrapper2(span2, stream, startTime, kwargs);
20704
+ return new AsyncStreamingWrapper(span2, stream, startTime, kwargs);
20174
20705
  } catch (error) {
20175
20706
  Logger.error("netra.instrumentation.groq:", error);
20176
20707
  span2.setStatus({
@@ -20259,7 +20790,7 @@ function groqWrapper(tracer, spanName, requestType) {
20259
20790
  }
20260
20791
  };
20261
20792
  }
20262
- var chatWrapper3 = (tracer) => groqWrapper(tracer, CHAT_SPAN_NAME3, "chat");
20793
+ var chatWrapper3 = (tracer) => groqWrapper(tracer, CHAT_SPAN_NAME2, "chat");
20263
20794
  var StreamingWrapper = class {
20264
20795
  constructor(span2, response, startTime, requestKwargs) {
20265
20796
  this.iterator = null;
@@ -20357,7 +20888,7 @@ var StreamingWrapper = class {
20357
20888
  this.span.end();
20358
20889
  }
20359
20890
  };
20360
- var AsyncStreamingWrapper2 = class {
20891
+ var AsyncStreamingWrapper = class {
20361
20892
  constructor(span2, response, startTime, requestKwargs) {
20362
20893
  this.iterator = null;
20363
20894
  this.completeResponse = {
@@ -20477,7 +21008,7 @@ var AsyncStreamingWrapper2 = class {
20477
21008
  // src/instrumentation/groq/index.ts
20478
21009
  var INSTRUMENTATION_NAME3 = "netra.instrumentation.groq";
20479
21010
  var INSTRUMENTS3 = ["groq-sdk >= 0.3.0"];
20480
- var originalMethods2 = /* @__PURE__ */ new Map();
21011
+ var originalMethods = /* @__PURE__ */ new Map();
20481
21012
  var isInstrumented3 = false;
20482
21013
  var groqClasses = [];
20483
21014
  async function resolveGroqAsync() {
@@ -20588,7 +21119,7 @@ var NetraGroqInstrumentor = class {
20588
21119
  classes.forEach((Groq, index) => {
20589
21120
  this._uninstrumentChatCompletions(Groq, index);
20590
21121
  });
20591
- originalMethods2.clear();
21122
+ originalMethods.clear();
20592
21123
  groqClasses = [];
20593
21124
  isInstrumented3 = false;
20594
21125
  }
@@ -20609,7 +21140,7 @@ var NetraGroqInstrumentor = class {
20609
21140
  return;
20610
21141
  }
20611
21142
  const originalCreate = CompletionsClass.prototype.create;
20612
- originalMethods2.set(`chat.completions.create-${index}`, originalCreate);
21143
+ originalMethods.set(`chat.completions.create-${index}`, originalCreate);
20613
21144
  const tracer = this.tracer;
20614
21145
  const wrapper = chatWrapper3(tracer);
20615
21146
  CompletionsClass.prototype.create = function(...args) {
@@ -20627,7 +21158,7 @@ var NetraGroqInstrumentor = class {
20627
21158
  _uninstrumentChatCompletions(Groq, index) {
20628
21159
  try {
20629
21160
  const CompletionsClass = Groq.Chat?.Completions;
20630
- const originalCreate = originalMethods2.get(`chat.completions.create-${index}`);
21161
+ const originalCreate = originalMethods.get(`chat.completions.create-${index}`);
20631
21162
  if (originalCreate && CompletionsClass?.prototype) {
20632
21163
  CompletionsClass.prototype.create = originalCreate;
20633
21164
  }
@@ -21466,7 +21997,7 @@ var INSTRUMENTATION_NAME4 = "netra.instrumentation.langgraph";
21466
21997
  var INSTRUMENTS4 = ["langgraph >= 1.1.1"];
21467
21998
  var isInstrumented4 = false;
21468
21999
  var LanggraphClass = null;
21469
- var originalMethods3 = /* @__PURE__ */ new Map();
22000
+ var originalMethods2 = /* @__PURE__ */ new Map();
21470
22001
  function findModuleInCache(moduleName) {
21471
22002
  if (typeof __require !== "undefined" && __require.cache) {
21472
22003
  const cache = __require.cache;
@@ -21562,7 +22093,7 @@ var NetraLanggraphInstrumentor = class {
21562
22093
  this._uninstrumentInvoke(Langgraph);
21563
22094
  this._uninstrumentStream(Langgraph);
21564
22095
  }
21565
- originalMethods3.clear();
22096
+ originalMethods2.clear();
21566
22097
  LanggraphClass = null;
21567
22098
  isInstrumented4 = false;
21568
22099
  }
@@ -21579,8 +22110,8 @@ var NetraLanggraphInstrumentor = class {
21579
22110
  }
21580
22111
  Logger.debug(`Found invoke on prototype: ${targetProto.constructor?.name}`);
21581
22112
  const originalInvoke = targetProto.invoke;
21582
- originalMethods3.set("langgraph.graph.invoke", originalInvoke);
21583
- originalMethods3.set("langgraph.graph.invoke.proto", targetProto);
22113
+ originalMethods2.set("langgraph.graph.invoke", originalInvoke);
22114
+ originalMethods2.set("langgraph.graph.invoke.proto", targetProto);
21584
22115
  const tracer = this.tracer;
21585
22116
  const wrapper = new LanggraphWrapper(tracer);
21586
22117
  const patchedInvoke = async function(input, config2, ...rest) {
@@ -21614,8 +22145,8 @@ var NetraLanggraphInstrumentor = class {
21614
22145
  }
21615
22146
  Logger.debug(`Found stream on prototype: ${targetProto.constructor?.name}`);
21616
22147
  const originalStream = targetProto.stream;
21617
- originalMethods3.set("langgraph.graph.stream", originalStream);
21618
- originalMethods3.set("langgraph.graph.stream.proto", targetProto);
22148
+ originalMethods2.set("langgraph.graph.stream", originalStream);
22149
+ originalMethods2.set("langgraph.graph.stream.proto", targetProto);
21619
22150
  const tracer = this.tracer;
21620
22151
  const wrapper = new LanggraphWrapper(tracer);
21621
22152
  targetProto.stream = async function(input, config2, ...rest) {
@@ -21635,8 +22166,8 @@ var NetraLanggraphInstrumentor = class {
21635
22166
  }
21636
22167
  _uninstrumentInvoke(Langgraph) {
21637
22168
  try {
21638
- const originalInvoke = originalMethods3.get("langgraph.graph.invoke");
21639
- const targetProto = originalMethods3.get("langgraph.graph.invoke.proto") || Langgraph?.prototype;
22169
+ const originalInvoke = originalMethods2.get("langgraph.graph.invoke");
22170
+ const targetProto = originalMethods2.get("langgraph.graph.invoke.proto") || Langgraph?.prototype;
21640
22171
  if (originalInvoke && targetProto?.invoke) {
21641
22172
  targetProto.invoke = originalInvoke;
21642
22173
  }
@@ -21647,8 +22178,8 @@ var NetraLanggraphInstrumentor = class {
21647
22178
  }
21648
22179
  _uninstrumentStream(Langgraph) {
21649
22180
  try {
21650
- const originalStream = originalMethods3.get("langgraph.graph.stream");
21651
- const targetProto = originalMethods3.get("langgraph.graph.stream.proto") || Langgraph?.prototype;
22181
+ const originalStream = originalMethods2.get("langgraph.graph.stream");
22182
+ const targetProto = originalMethods2.get("langgraph.graph.stream.proto") || Langgraph?.prototype;
21652
22183
  if (originalStream && targetProto?.stream) {
21653
22184
  targetProto.stream = originalStream;
21654
22185
  }
@@ -21688,11 +22219,11 @@ function setResponseAttributes5(span2, response) {
21688
22219
  }
21689
22220
 
21690
22221
  // src/instrumentation/mistralai/wrappers.ts
21691
- var CHAT_SPAN_NAME4 = "mistralai.chat";
22222
+ var CHAT_SPAN_NAME3 = "mistralai.chat";
21692
22223
  var EMBEDDING_SPAN_NAME2 = "mistralai.embedding";
21693
22224
  var FIM_SPAN_NAME = "mistralai.fim";
21694
22225
  var AGENTS_SPAN_NAME = "mistralai.agents";
21695
- var CHAT_STREAM_SPAN_NAME = CHAT_SPAN_NAME4;
22226
+ var CHAT_STREAM_SPAN_NAME = CHAT_SPAN_NAME3;
21696
22227
  var FIM_STREAM_SPAN_NAME = FIM_SPAN_NAME;
21697
22228
  var AGENTS_STREAM_SPAN_NAME = AGENTS_SPAN_NAME;
21698
22229
  function mistralWrapper(tracer, spanName, requestType) {
@@ -21787,7 +22318,7 @@ function mistralStreamWrapper(tracer, spanName, requestType) {
21787
22318
  try {
21788
22319
  const stream = await response;
21789
22320
  if (stream && typeof stream === "object" && Symbol.asyncIterator in stream) {
21790
- return new AsyncStreamingWrapper3(span2, stream, startTime, kwargs);
22321
+ return new AsyncStreamingWrapper2(span2, stream, startTime, kwargs);
21791
22322
  }
21792
22323
  return new StreamingWrapper2(span2, stream, startTime, kwargs);
21793
22324
  } catch (error) {
@@ -21803,7 +22334,7 @@ function mistralStreamWrapper(tracer, spanName, requestType) {
21803
22334
  })();
21804
22335
  }
21805
22336
  if (response && typeof response === "object" && Symbol.asyncIterator in response) {
21806
- return new AsyncStreamingWrapper3(span2, response, startTime, kwargs);
22337
+ return new AsyncStreamingWrapper2(span2, response, startTime, kwargs);
21807
22338
  }
21808
22339
  return new StreamingWrapper2(span2, response, startTime, kwargs);
21809
22340
  } catch (error) {
@@ -21818,8 +22349,8 @@ function mistralStreamWrapper(tracer, spanName, requestType) {
21818
22349
  }
21819
22350
  };
21820
22351
  }
21821
- var chatWrapper4 = (tracer) => mistralWrapper(tracer, CHAT_SPAN_NAME4, "chat");
21822
- var chatStreamWrapper2 = (tracer) => mistralStreamWrapper(tracer, CHAT_STREAM_SPAN_NAME, "chat");
22352
+ var chatWrapper4 = (tracer) => mistralWrapper(tracer, CHAT_SPAN_NAME3, "chat");
22353
+ var chatStreamWrapper3 = (tracer) => mistralStreamWrapper(tracer, CHAT_STREAM_SPAN_NAME, "chat");
21823
22354
  var embeddingsWrapper2 = (tracer) => mistralWrapper(tracer, EMBEDDING_SPAN_NAME2, "embedding");
21824
22355
  var fimWrapper = (tracer) => mistralWrapper(tracer, FIM_SPAN_NAME, "fim");
21825
22356
  var fimStreamWrapper = (tracer) => mistralStreamWrapper(tracer, FIM_STREAM_SPAN_NAME, "fim");
@@ -21970,7 +22501,7 @@ var StreamingWrapper2 = class {
21970
22501
  this.span.end();
21971
22502
  }
21972
22503
  };
21973
- var AsyncStreamingWrapper3 = class {
22504
+ var AsyncStreamingWrapper2 = class {
21974
22505
  constructor(span2, response, startTime, requestKwargs) {
21975
22506
  this.iterator = null;
21976
22507
  defineHidden(this, "span", span2);
@@ -22120,7 +22651,7 @@ var AsyncStreamingWrapper3 = class {
22120
22651
  // src/instrumentation/mistralai/index.ts
22121
22652
  var INSTRUMENTATION_NAME5 = "netra.instrumentation.mistral_ai";
22122
22653
  var INSTRUMENTS5 = ["@mistralai/mistralai >= 1.0.0"];
22123
- var originalMethods4 = /* @__PURE__ */ new Map();
22654
+ var originalMethods3 = /* @__PURE__ */ new Map();
22124
22655
  var isInstrumented5 = false;
22125
22656
  var mistralClasses = [];
22126
22657
  async function resolveMistralAsync() {
@@ -22269,7 +22800,7 @@ var NetraMistralAIInstrumentor = class {
22269
22800
  this._uninstrumentFIM(Mistral, index);
22270
22801
  this._uninstrumentAgents(Mistral, index);
22271
22802
  });
22272
- originalMethods4.clear();
22803
+ originalMethods3.clear();
22273
22804
  mistralClasses = [];
22274
22805
  isInstrumented5 = false;
22275
22806
  }
@@ -22315,7 +22846,7 @@ var NetraMistralAIInstrumentor = class {
22315
22846
  let didPatch = false;
22316
22847
  if (ChatClass?.prototype?.complete) {
22317
22848
  const originalComplete = ChatClass.prototype.complete;
22318
- originalMethods4.set(`chat.complete-${index}`, originalComplete);
22849
+ originalMethods3.set(`chat.complete-${index}`, originalComplete);
22319
22850
  const tracer = this.tracer;
22320
22851
  const wrapper = chatWrapper4(tracer);
22321
22852
  ChatClass.prototype.complete = function(...args) {
@@ -22332,9 +22863,9 @@ var NetraMistralAIInstrumentor = class {
22332
22863
  }
22333
22864
  if (ChatClass?.prototype?.stream) {
22334
22865
  const originalStream = ChatClass.prototype.stream;
22335
- originalMethods4.set(`chat.stream-${index}`, originalStream);
22866
+ originalMethods3.set(`chat.stream-${index}`, originalStream);
22336
22867
  const tracer = this.tracer;
22337
- const wrapper = chatStreamWrapper2(tracer);
22868
+ const wrapper = chatStreamWrapper3(tracer);
22338
22869
  ChatClass.prototype.stream = function(...args) {
22339
22870
  const original = originalStream.bind(this);
22340
22871
  const kwargs = args[0] || {};
@@ -22360,7 +22891,7 @@ var NetraMistralAIInstrumentor = class {
22360
22891
  let didPatch = false;
22361
22892
  if (EmbeddingsClass?.prototype?.create) {
22362
22893
  const originalCreate = EmbeddingsClass.prototype.create;
22363
- originalMethods4.set(`embeddings.create-${index}`, originalCreate);
22894
+ originalMethods3.set(`embeddings.create-${index}`, originalCreate);
22364
22895
  const tracer = this.tracer;
22365
22896
  const wrapper = embeddingsWrapper2(tracer);
22366
22897
  EmbeddingsClass.prototype.create = function(...args) {
@@ -22388,7 +22919,7 @@ var NetraMistralAIInstrumentor = class {
22388
22919
  let didPatch = false;
22389
22920
  if (FimClass?.prototype?.complete) {
22390
22921
  const originalComplete = FimClass.prototype.complete;
22391
- originalMethods4.set(`fim.complete-${index}`, originalComplete);
22922
+ originalMethods3.set(`fim.complete-${index}`, originalComplete);
22392
22923
  const tracer = this.tracer;
22393
22924
  const wrapper = fimWrapper(tracer);
22394
22925
  FimClass.prototype.complete = function(...args) {
@@ -22405,7 +22936,7 @@ var NetraMistralAIInstrumentor = class {
22405
22936
  }
22406
22937
  if (FimClass?.prototype?.stream) {
22407
22938
  const originalStream = FimClass.prototype.stream;
22408
- originalMethods4.set(`fim.stream-${index}`, originalStream);
22939
+ originalMethods3.set(`fim.stream-${index}`, originalStream);
22409
22940
  const tracer = this.tracer;
22410
22941
  const wrapper = fimStreamWrapper(tracer);
22411
22942
  FimClass.prototype.stream = function(...args) {
@@ -22433,7 +22964,7 @@ var NetraMistralAIInstrumentor = class {
22433
22964
  let didPatch = false;
22434
22965
  if (AgentsClass?.prototype?.complete) {
22435
22966
  const originalComplete = AgentsClass.prototype.complete;
22436
- originalMethods4.set(`agents.complete-${index}`, originalComplete);
22967
+ originalMethods3.set(`agents.complete-${index}`, originalComplete);
22437
22968
  const tracer = this.tracer;
22438
22969
  const wrapper = agentsWrapper(tracer);
22439
22970
  AgentsClass.prototype.complete = function(...args) {
@@ -22450,7 +22981,7 @@ var NetraMistralAIInstrumentor = class {
22450
22981
  }
22451
22982
  if (AgentsClass?.prototype?.stream) {
22452
22983
  const originalStream = AgentsClass.prototype.stream;
22453
- originalMethods4.set(`agents.stream-${index}`, originalStream);
22984
+ originalMethods3.set(`agents.stream-${index}`, originalStream);
22454
22985
  const tracer = this.tracer;
22455
22986
  const wrapper = agentsStreamWrapper(tracer);
22456
22987
  AgentsClass.prototype.stream = function(...args) {
@@ -22474,11 +23005,11 @@ var NetraMistralAIInstrumentor = class {
22474
23005
  _uninstrumentChat(Mistral, index) {
22475
23006
  try {
22476
23007
  const ChatClass = this._getCtor(Mistral, "chat");
22477
- const originalComplete = originalMethods4.get(`chat.complete-${index}`);
23008
+ const originalComplete = originalMethods3.get(`chat.complete-${index}`);
22478
23009
  if (originalComplete && ChatClass?.prototype) {
22479
23010
  ChatClass.prototype.complete = originalComplete;
22480
23011
  }
22481
- const originalStream = originalMethods4.get(`chat.stream-${index}`);
23012
+ const originalStream = originalMethods3.get(`chat.stream-${index}`);
22482
23013
  if (originalStream && ChatClass?.prototype) {
22483
23014
  ChatClass.prototype.stream = originalStream;
22484
23015
  }
@@ -22489,7 +23020,7 @@ var NetraMistralAIInstrumentor = class {
22489
23020
  _uninstrumentEmbeddings(Mistral, index) {
22490
23021
  try {
22491
23022
  const EmbeddingsClass = this._getCtor(Mistral, "embeddings");
22492
- const originalCreate = originalMethods4.get(`embeddings.create-${index}`);
23023
+ const originalCreate = originalMethods3.get(`embeddings.create-${index}`);
22493
23024
  if (originalCreate && EmbeddingsClass?.prototype) {
22494
23025
  EmbeddingsClass.prototype.create = originalCreate;
22495
23026
  }
@@ -22500,11 +23031,11 @@ var NetraMistralAIInstrumentor = class {
22500
23031
  _uninstrumentFIM(Mistral, index) {
22501
23032
  try {
22502
23033
  const FimClass = this._getCtor(Mistral, "fim");
22503
- const originalComplete = originalMethods4.get(`fim.complete-${index}`);
23034
+ const originalComplete = originalMethods3.get(`fim.complete-${index}`);
22504
23035
  if (originalComplete && FimClass?.prototype) {
22505
23036
  FimClass.prototype.complete = originalComplete;
22506
23037
  }
22507
- const originalStream = originalMethods4.get(`fim.stream-${index}`);
23038
+ const originalStream = originalMethods3.get(`fim.stream-${index}`);
22508
23039
  if (originalStream && FimClass?.prototype) {
22509
23040
  FimClass.prototype.stream = originalStream;
22510
23041
  }
@@ -22515,11 +23046,11 @@ var NetraMistralAIInstrumentor = class {
22515
23046
  _uninstrumentAgents(Mistral, index) {
22516
23047
  try {
22517
23048
  const AgentsClass = this._getCtor(Mistral, "agents");
22518
- const originalComplete = originalMethods4.get(`agents.complete-${index}`);
23049
+ const originalComplete = originalMethods3.get(`agents.complete-${index}`);
22519
23050
  if (originalComplete && AgentsClass?.prototype) {
22520
23051
  AgentsClass.prototype.complete = originalComplete;
22521
23052
  }
22522
- const originalStream = originalMethods4.get(`agents.stream-${index}`);
23053
+ const originalStream = originalMethods3.get(`agents.stream-${index}`);
22523
23054
  if (originalStream && AgentsClass?.prototype) {
22524
23055
  AgentsClass.prototype.stream = originalStream;
22525
23056
  }
@@ -22547,7 +23078,7 @@ function setResponseAttributes6(span2, response) {
22547
23078
  }
22548
23079
 
22549
23080
  // src/instrumentation/openai/wrappers.ts
22550
- var SPAN_NAMES = {
23081
+ var SPAN_NAMES2 = {
22551
23082
  chat: "openai.chat",
22552
23083
  embedding: "openai.embedding",
22553
23084
  response: "openai.response"
@@ -22688,7 +23219,7 @@ var StreamingWrapper3 = class extends BaseStreamHandler {
22688
23219
  throw new Error("Response is not iterable");
22689
23220
  }
22690
23221
  };
22691
- var AsyncStreamingWrapper4 = class extends BaseStreamHandler {
23222
+ var AsyncStreamingWrapper3 = class extends BaseStreamHandler {
22692
23223
  constructor(span2, response, startTime, requestKwargs) {
22693
23224
  super(span2, startTime, requestKwargs);
22694
23225
  this.iterator = null;
@@ -22744,7 +23275,7 @@ function executeStreaming(span2, ctx, kwargs, requestType, call) {
22744
23275
  return (async () => {
22745
23276
  try {
22746
23277
  const stream = await response;
22747
- return new AsyncStreamingWrapper4(span2, stream, startTime, kwargs);
23278
+ return new AsyncStreamingWrapper3(span2, stream, startTime, kwargs);
22748
23279
  } catch (error) {
22749
23280
  handleSpanError(span2, error);
22750
23281
  throw error;
@@ -22782,7 +23313,7 @@ function executeNonStreaming(span2, kwargs, requestType, call) {
22782
23313
  }
22783
23314
  }
22784
23315
  function openAIWrapper(tracer, requestType) {
22785
- const spanName = SPAN_NAMES[requestType];
23316
+ const spanName = SPAN_NAMES2[requestType];
22786
23317
  const spanOpts = { kind: api.SpanKind.CLIENT, attributes: { "llm.request.type": requestType } };
22787
23318
  return (wrapped, instance, args, kwargs) => {
22788
23319
  if (shouldSuppressInstrumentation()) {
@@ -24008,7 +24539,7 @@ function repositoryQueryWrapper(tracer) {
24008
24539
  var __version__8 = "1.0.0";
24009
24540
  var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
24010
24541
  var INSTRUMENTATION_NAME8 = "netra.instrumentation.typeorm";
24011
- var originalMethods5 = /* @__PURE__ */ new Map();
24542
+ var originalMethods4 = /* @__PURE__ */ new Map();
24012
24543
  var isInstrumented7 = false;
24013
24544
  var NetraTypeORMInstrumentor = class {
24014
24545
  constructor() {
@@ -24042,7 +24573,7 @@ var NetraTypeORMInstrumentor = class {
24042
24573
  });
24043
24574
  this._uninstrumentRepository().catch(() => {
24044
24575
  });
24045
- originalMethods5.clear();
24576
+ originalMethods4.clear();
24046
24577
  isInstrumented7 = false;
24047
24578
  }
24048
24579
  isInstrumented() {
@@ -24061,7 +24592,7 @@ var NetraTypeORMInstrumentor = class {
24061
24592
  }
24062
24593
  if (DataSource.prototype?.query) {
24063
24594
  const originalQuery = DataSource.prototype.query;
24064
- originalMethods5.set("DataSource.prototype.query", originalQuery);
24595
+ originalMethods4.set("DataSource.prototype.query", originalQuery);
24065
24596
  const tracer = this.tracer;
24066
24597
  const wrapper = queryWrapper(tracer);
24067
24598
  DataSource.prototype.query = function(...args) {
@@ -24086,7 +24617,7 @@ var NetraTypeORMInstrumentor = class {
24086
24617
  }
24087
24618
  if (EntityManager.prototype?.query) {
24088
24619
  const originalQuery = EntityManager.prototype.query;
24089
- originalMethods5.set("EntityManager.prototype.query", originalQuery);
24620
+ originalMethods4.set("EntityManager.prototype.query", originalQuery);
24090
24621
  const tracer = this.tracer;
24091
24622
  const wrapper = managerQueryWrapper(tracer);
24092
24623
  EntityManager.prototype.query = function(...args) {
@@ -24111,7 +24642,7 @@ var NetraTypeORMInstrumentor = class {
24111
24642
  }
24112
24643
  if (Repository.prototype?.query) {
24113
24644
  const originalQuery = Repository.prototype.query;
24114
- originalMethods5.set("Repository.prototype.query", originalQuery);
24645
+ originalMethods4.set("Repository.prototype.query", originalQuery);
24115
24646
  const tracer = this.tracer;
24116
24647
  const wrapper = repositoryQueryWrapper(tracer);
24117
24648
  Repository.prototype.query = function(...args) {
@@ -24127,7 +24658,7 @@ var NetraTypeORMInstrumentor = class {
24127
24658
  try {
24128
24659
  const typeorm = require2("typeorm");
24129
24660
  const DataSource = typeorm.DataSource || typeorm.default?.DataSource;
24130
- const originalQuery = originalMethods5.get("DataSource.prototype.query");
24661
+ const originalQuery = originalMethods4.get("DataSource.prototype.query");
24131
24662
  if (originalQuery && DataSource?.prototype) {
24132
24663
  DataSource.prototype.query = originalQuery;
24133
24664
  }
@@ -24139,7 +24670,7 @@ var NetraTypeORMInstrumentor = class {
24139
24670
  try {
24140
24671
  const typeorm = require2("typeorm");
24141
24672
  const EntityManager = typeorm.EntityManager || typeorm.default?.EntityManager;
24142
- const originalQuery = originalMethods5.get("EntityManager.prototype.query");
24673
+ const originalQuery = originalMethods4.get("EntityManager.prototype.query");
24143
24674
  if (originalQuery && EntityManager?.prototype) {
24144
24675
  EntityManager.prototype.query = originalQuery;
24145
24676
  }
@@ -24151,7 +24682,7 @@ var NetraTypeORMInstrumentor = class {
24151
24682
  try {
24152
24683
  const typeorm = require2("typeorm");
24153
24684
  const Repository = typeorm.Repository || typeorm.default?.Repository;
24154
- const originalQuery = originalMethods5.get("Repository.prototype.query");
24685
+ const originalQuery = originalMethods4.get("Repository.prototype.query");
24155
24686
  if (originalQuery && Repository?.prototype) {
24156
24687
  Repository.prototype.query = originalQuery;
24157
24688
  }
@@ -24804,7 +25335,7 @@ async function initCustomInstrumentationsAsync(config2, tracerProvider, customIn
24804
25335
  }
24805
25336
  if (customInstrumentModules.anthropic) {
24806
25337
  try {
24807
- await anthropicInstrumentor.instrumentAsync({ tracerProvider });
25338
+ await anthropicInstrumentor.instrument({ tracerProvider });
24808
25339
  Logger.debug("Custom Anthropic instrumentation enabled");
24809
25340
  } catch (e) {
24810
25341
  Logger.debug("Failed to initialize custom Anthropic instrumentation:", e);
@@ -24956,7 +25487,7 @@ function addCustomSpanProcessors(tracerProvider, config2, rootInstrumentNames) {
24956
25487
  }
24957
25488
  const instrumentationProcessor = new InstrumentationSpanProcessor();
24958
25489
  provider.addSpanProcessor(instrumentationProcessor);
24959
- const sessionProcessor = new SessionSpanProcessor();
25490
+ const sessionProcessor = new SessionSpanProcessor(config2.environment);
24960
25491
  provider.addSpanProcessor(sessionProcessor);
24961
25492
  const spanIOProcessor = new SpanIOProcessor();
24962
25493
  provider.addSpanProcessor(spanIOProcessor);
@@ -24968,6 +25499,10 @@ function addCustomSpanProcessors(tracerProvider, config2, rootInstrumentNames) {
24968
25499
  const scrubbingProcessor = new ScrubbingSpanProcessor();
24969
25500
  provider.addSpanProcessor(scrubbingProcessor);
24970
25501
  }
25502
+ const sizeLimitProcessor = new AttributeSizeLimitProcessor(
25503
+ Config.SPAN_ATTRIBUTE_MAX_SIZE
25504
+ );
25505
+ provider.addSpanProcessor(sizeLimitProcessor);
24971
25506
  Logger.debug("Custom span processors registered successfully");
24972
25507
  return provider;
24973
25508
  } catch (e) {
@@ -25616,33 +26151,6 @@ var Tracer17 = class {
25616
26151
  }
25617
26152
  }
25618
26153
  };
25619
- function safeStringify3(value, maxLen = 1e3) {
25620
- const seen = /* @__PURE__ */ new WeakSet();
25621
- try {
25622
- return JSON.stringify(value, (_key, val) => {
25623
- if (typeof val === "function") return `[Function: ${val.name || "anonymous"}]`;
25624
- if (typeof val === "symbol") return val.toString();
25625
- if (typeof val === "bigint") return val.toString();
25626
- if (val !== null && typeof val === "object") {
25627
- if (seen.has(val)) return "[Circular]";
25628
- seen.add(val);
25629
- const name = val.constructor?.name;
25630
- if (name && name !== "Object" && name !== "Array" && Object.keys(val).length > 20) {
25631
- return `[${name}]`;
25632
- }
25633
- }
25634
- return val;
25635
- }).substring(0, maxLen);
25636
- } catch {
25637
- return value?.constructor?.name ? `[${value.constructor.name}]` : String(typeof value);
25638
- }
25639
- }
25640
- function serializeValue2(value) {
25641
- if (value === null || value === void 0) return String(value);
25642
- const t = typeof value;
25643
- if (t === "string" || t === "number" || t === "boolean") return String(value);
25644
- return safeStringify3(value);
25645
- }
25646
26154
  function spanHasOutput(span2) {
25647
26155
  try {
25648
26156
  for (const field of ["attributes", "_attributes"]) {
@@ -25657,13 +26165,13 @@ function spanHasOutput(span2) {
25657
26165
  function addInputAttributes(span2, args, entityType) {
25658
26166
  span2.setAttribute(`${Config.LIBRARY_NAME}.entity.type`, entityType);
25659
26167
  if (args.length > 0) {
25660
- span2.setAttribute("input", safeStringify3(args));
26168
+ span2.setAttribute("input", safeStringify(args, Config.ATTRIBUTE_MAX_LEN));
25661
26169
  }
25662
26170
  }
25663
26171
  function addOutputAttributes(span2, result) {
25664
26172
  if (spanHasOutput(span2)) return;
25665
26173
  try {
25666
- span2.setAttribute("output", serializeValue2(result));
26174
+ span2.setAttribute("output", serializeValue(result, Config.ATTRIBUTE_MAX_LEN));
25667
26175
  } catch (e) {
25668
26176
  span2.setAttribute("output_error", String(e));
25669
26177
  }
@@ -25683,69 +26191,63 @@ function createFunctionWrapper(func, entityType, name, asType = "SPAN" /* SPAN *
25683
26191
  span2.setAttribute("netra.span.type", asType);
25684
26192
  SessionManager.registerSpan(spanName, span2);
25685
26193
  };
25686
- const handleError = (span2, e) => {
26194
+ const recordError = (span2, e) => {
25687
26195
  span2.setAttribute(`${Config.LIBRARY_NAME}.entity.error`, String(e));
25688
26196
  span2.setStatus({
25689
26197
  code: api.SpanStatusCode.ERROR,
25690
26198
  message: e instanceof Error ? e.message : String(e)
25691
26199
  });
25692
26200
  span2.recordException(e);
25693
- throw e;
25694
26201
  };
25695
26202
  const cleanup = (span2) => {
25696
26203
  span2.end();
25697
26204
  SessionManager.unregisterSpan(spanName, span2);
25698
26205
  SessionManager.popEntity(entityType);
25699
26206
  };
25700
- if (isAsync) {
25701
- const wrapper = async function(...args) {
25702
- SessionManager.pushEntity(entityType, spanName);
25703
- const tracer = api.trace.getTracer(moduleName);
25704
- return tracer.startActiveSpan(spanName, async (span2) => {
25705
- try {
25706
- initSpan(span2);
25707
- addInputAttributes(span2, args, entityType);
25708
- const result = await func.call(this, ...args);
25709
- addOutputAttributes(span2, result);
25710
- return result;
25711
- } catch (e) {
25712
- handleError(span2, e);
25713
- } finally {
25714
- cleanup(span2);
25715
- }
25716
- });
25717
- };
25718
- return wrapper;
25719
- } else {
25720
- const wrapper = function(...args) {
25721
- SessionManager.pushEntity(entityType, spanName);
25722
- const tracer = api.trace.getTracer(moduleName);
25723
- return tracer.startActiveSpan(spanName, (span2) => {
25724
- let returnedPromise = false;
25725
- try {
25726
- initSpan(span2);
25727
- addInputAttributes(span2, args, entityType);
25728
- const result = func.call(this, ...args);
25729
- if (result != null && typeof result.then === "function") {
25730
- returnedPromise = true;
25731
- return result.then((resolved) => {
25732
- addOutputAttributes(span2, resolved);
25733
- return resolved;
25734
- }).catch((e) => handleError(span2, e)).finally(() => cleanup(span2));
25735
- }
25736
- addOutputAttributes(span2, result);
25737
- return result;
25738
- } catch (e) {
25739
- handleError(span2, e);
25740
- } finally {
25741
- if (!returnedPromise) {
25742
- cleanup(span2);
25743
- }
25744
- }
25745
- });
25746
- };
25747
- return wrapper;
25748
- }
26207
+ const wrapperFn = isAsync ? async function(...args) {
26208
+ SessionManager.pushEntity(entityType, spanName);
26209
+ const tracer = api.trace.getTracer(moduleName);
26210
+ return tracer.startActiveSpan(spanName, async (span2) => {
26211
+ try {
26212
+ initSpan(span2);
26213
+ addInputAttributes(span2, args, entityType);
26214
+ const result = await func.call(this, ...args);
26215
+ const spanCtx = api.trace.setSpan(api.context.active(), span2);
26216
+ return wrapResponse(result, {
26217
+ withContext: (fn) => api.context.with(spanCtx, fn),
26218
+ onError: (e) => recordError(span2, e),
26219
+ onSuccess: (value) => addOutputAttributes(span2, value),
26220
+ finalize: () => cleanup(span2)
26221
+ });
26222
+ } catch (e) {
26223
+ recordError(span2, e);
26224
+ cleanup(span2);
26225
+ throw e;
26226
+ }
26227
+ });
26228
+ } : function(...args) {
26229
+ SessionManager.pushEntity(entityType, spanName);
26230
+ const tracer = api.trace.getTracer(moduleName);
26231
+ return tracer.startActiveSpan(spanName, (span2) => {
26232
+ try {
26233
+ initSpan(span2);
26234
+ addInputAttributes(span2, args, entityType);
26235
+ const result = func.call(this, ...args);
26236
+ const spanCtx = api.trace.setSpan(api.context.active(), span2);
26237
+ return wrapResponse(result, {
26238
+ withContext: (fn) => api.context.with(spanCtx, fn),
26239
+ onError: (e) => recordError(span2, e),
26240
+ onSuccess: (value) => addOutputAttributes(span2, value),
26241
+ finalize: () => cleanup(span2)
26242
+ });
26243
+ } catch (e) {
26244
+ recordError(span2, e);
26245
+ cleanup(span2);
26246
+ throw e;
26247
+ }
26248
+ });
26249
+ };
26250
+ return wrapperFn;
25749
26251
  }
25750
26252
  var SKIP_STATIC_PROPS = /* @__PURE__ */ new Set([
25751
26253
  "length",
@@ -26132,14 +26634,11 @@ Received ${signal}. Shutting down Netra SDK...`);
26132
26634
  spanWrapper.end();
26133
26635
  throw e;
26134
26636
  }
26135
- if (result instanceof Promise) {
26136
- return result.catch((e) => {
26137
- spanWrapper.setError(e instanceof Error ? e.message : String(e));
26138
- throw e;
26139
- }).finally(() => spanWrapper.end());
26140
- }
26141
- spanWrapper.end();
26142
- return result;
26637
+ return wrapResponse(result, {
26638
+ withContext: (fn2) => spanWrapper.withActive(fn2),
26639
+ onError: (e) => spanWrapper.setError(e instanceof Error ? e.message : String(e)),
26640
+ finalize: () => spanWrapper.end()
26641
+ });
26143
26642
  });
26144
26643
  }
26145
26644
  };
@@ -26150,6 +26649,7 @@ Netra.withBlockedSpansLocal = withBlockedSpansLocal;
26150
26649
  var index_default = Netra;
26151
26650
 
26152
26651
  exports.Aggregation = Aggregation;
26652
+ exports.AttributeSizeLimitProcessor = AttributeSizeLimitProcessor;
26153
26653
  exports.BaseTask = BaseTask;
26154
26654
  exports.ChartType = ChartType;
26155
26655
  exports.Config = Config;