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 +1257 -757
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +1250 -751
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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 =
|
|
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
|
|
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] =
|
|
1388
|
+
result[key] = serializeValue2(value);
|
|
1389
1389
|
}
|
|
1390
1390
|
return result;
|
|
1391
1391
|
}
|
|
1392
1392
|
if (Array.isArray(obj)) {
|
|
1393
|
-
return obj.map((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] =
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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))
|
|
18196
|
-
|
|
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 =
|
|
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
|
-
|
|
18641
|
+
msg.role
|
|
18312
18642
|
);
|
|
18313
18643
|
span2.setAttribute(
|
|
18314
18644
|
`${SpanAttributes2.LLM_PROMPTS}.${i}.content`,
|
|
18315
|
-
|
|
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
|
-
|
|
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 (
|
|
18404
|
-
|
|
18405
|
-
|
|
18406
|
-
|
|
18407
|
-
|
|
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
|
|
18435
|
-
if (
|
|
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(
|
|
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/
|
|
18461
|
-
|
|
18462
|
-
|
|
18463
|
-
|
|
18464
|
-
|
|
18465
|
-
|
|
18466
|
-
|
|
18467
|
-
|
|
18468
|
-
|
|
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/
|
|
18480
|
-
|
|
18481
|
-
|
|
18482
|
-
|
|
18483
|
-
|
|
18484
|
-
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
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
|
-
|
|
18542
|
-
|
|
18543
|
-
|
|
18544
|
-
|
|
18545
|
-
|
|
18546
|
-
|
|
18547
|
-
|
|
18548
|
-
|
|
18549
|
-
|
|
18550
|
-
|
|
18551
|
-
|
|
18552
|
-
|
|
18553
|
-
|
|
18554
|
-
|
|
18555
|
-
|
|
18556
|
-
|
|
18557
|
-
|
|
18558
|
-
|
|
18559
|
-
|
|
18560
|
-
|
|
18561
|
-
|
|
18562
|
-
|
|
18563
|
-
|
|
18564
|
-
|
|
18565
|
-
|
|
18566
|
-
|
|
18567
|
-
|
|
18568
|
-
|
|
18569
|
-
|
|
18570
|
-
|
|
18571
|
-
|
|
18572
|
-
|
|
18573
|
-
|
|
18574
|
-
|
|
18575
|
-
|
|
18576
|
-
|
|
18577
|
-
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
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
|
-
|
|
18630
|
-
|
|
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
|
-
"
|
|
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([
|
|
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(
|
|
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
|
|
18683
|
-
|
|
18684
|
-
|
|
18685
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18695
|
-
|
|
18696
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
18706
|
-
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
|
|
18710
|
-
|
|
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
|
-
|
|
18713
|
-
} catch (error) {
|
|
18714
|
-
target.finalizeSpan(api.SpanStatusCode.ERROR);
|
|
18715
|
-
throw error;
|
|
19160
|
+
target.finalizeSpanOnce(api.SpanStatusCode.OK);
|
|
18716
19161
|
}
|
|
18717
|
-
|
|
18718
|
-
|
|
18719
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
|
|
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.
|
|
19267
|
+
this.finalizeSpanOnce(api.SpanStatusCode.OK);
|
|
18861
19268
|
}
|
|
18862
|
-
|
|
18863
|
-
|
|
18864
|
-
|
|
18865
|
-
|
|
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
|
-
|
|
18876
|
-
|
|
18877
|
-
|
|
18878
|
-
|
|
18879
|
-
|
|
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
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18978
|
-
|
|
18979
|
-
|
|
18980
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18993
|
-
|
|
18994
|
-
|
|
18995
|
-
|
|
18996
|
-
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
19070
|
-
this._instrumentMessages(AnthropicSDK
|
|
19071
|
-
this._instrumentBetaMessages(AnthropicSDK
|
|
19072
|
-
this._instrumentBatchMessages(AnthropicSDK
|
|
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
|
-
|
|
19083
|
-
|
|
19084
|
-
this.
|
|
19085
|
-
this.
|
|
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
|
|
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
|
|
19681
|
+
"Anthropic instrumentation: Could not find Messages class"
|
|
19105
19682
|
);
|
|
19106
19683
|
return;
|
|
19107
19684
|
}
|
|
19108
|
-
|
|
19109
|
-
|
|
19110
|
-
|
|
19111
|
-
|
|
19112
|
-
|
|
19113
|
-
|
|
19114
|
-
|
|
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
|
|
19143
|
-
|
|
19144
|
-
|
|
19145
|
-
|
|
19146
|
-
|
|
19147
|
-
|
|
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
|
|
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
|
|
19713
|
+
"Anthropic instrumentation: Could not find Beta Messages class"
|
|
19172
19714
|
);
|
|
19173
19715
|
return;
|
|
19174
19716
|
}
|
|
19175
|
-
|
|
19176
|
-
|
|
19177
|
-
|
|
19178
|
-
|
|
19179
|
-
|
|
19180
|
-
|
|
19181
|
-
|
|
19182
|
-
|
|
19183
|
-
|
|
19184
|
-
|
|
19185
|
-
|
|
19186
|
-
|
|
19187
|
-
|
|
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
|
|
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
|
|
19209
|
-
|
|
19210
|
-
|
|
19211
|
-
|
|
19212
|
-
|
|
19213
|
-
|
|
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
|
|
19765
|
+
_uninstrumentMessages(AnthropicSDK) {
|
|
19229
19766
|
try {
|
|
19230
|
-
const
|
|
19231
|
-
|
|
19232
|
-
if (
|
|
19233
|
-
|
|
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
|
|
19775
|
+
_uninstrumentBetaMessages(AnthropicSDK) {
|
|
19244
19776
|
try {
|
|
19245
|
-
const
|
|
19246
|
-
|
|
19247
|
-
if (
|
|
19248
|
-
|
|
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
|
|
19787
|
+
_uninstrumentBatchMessages(AnthropicSDK) {
|
|
19255
19788
|
try {
|
|
19256
|
-
const
|
|
19257
|
-
|
|
19258
|
-
if (
|
|
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
|
|
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,
|
|
20486
|
+
var chatWrapper2 = (tracer) => googleGenAIWrapper(tracer, CHAT_SPAN_NAME, "chat");
|
|
19956
20487
|
var embeddingsWrapper = (tracer) => googleGenAIWrapper(tracer, EMBEDDING_SPAN_NAME, "embedding");
|
|
19957
|
-
var
|
|
19958
|
-
var startChatWrapper = (tracer) => googleGenAIStartChatWrapper(tracer,
|
|
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
|
-
|
|
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
|
|
20147
|
-
var
|
|
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 &&
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
21583
|
-
|
|
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
|
-
|
|
21618
|
-
|
|
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 =
|
|
21639
|
-
const targetProto =
|
|
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 =
|
|
21651
|
-
const targetProto =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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,
|
|
21822
|
-
var
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22866
|
+
originalMethods3.set(`chat.stream-${index}`, originalStream);
|
|
22336
22867
|
const tracer = this.tracer;
|
|
22337
|
-
const wrapper =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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.
|
|
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",
|
|
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",
|
|
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
|
|
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
|
-
|
|
25701
|
-
|
|
25702
|
-
|
|
25703
|
-
|
|
25704
|
-
|
|
25705
|
-
|
|
25706
|
-
|
|
25707
|
-
|
|
25708
|
-
|
|
25709
|
-
|
|
25710
|
-
|
|
25711
|
-
|
|
25712
|
-
|
|
25713
|
-
|
|
25714
|
-
|
|
25715
|
-
|
|
25716
|
-
|
|
25717
|
-
|
|
25718
|
-
|
|
25719
|
-
|
|
25720
|
-
|
|
25721
|
-
|
|
25722
|
-
|
|
25723
|
-
|
|
25724
|
-
|
|
25725
|
-
|
|
25726
|
-
|
|
25727
|
-
|
|
25728
|
-
|
|
25729
|
-
|
|
25730
|
-
|
|
25731
|
-
|
|
25732
|
-
|
|
25733
|
-
|
|
25734
|
-
|
|
25735
|
-
|
|
25736
|
-
|
|
25737
|
-
|
|
25738
|
-
|
|
25739
|
-
|
|
25740
|
-
|
|
25741
|
-
|
|
25742
|
-
|
|
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
|
-
|
|
26136
|
-
|
|
26137
|
-
|
|
26138
|
-
|
|
26139
|
-
|
|
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;
|