netra-sdk 1.1.0-beta.1 → 1.2.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 +606 -267
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +113 -6
- package/dist/index.d.ts +113 -6
- package/dist/index.js +582 -245
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
package/dist/index.cjs
CHANGED
|
@@ -2462,14 +2462,14 @@ var require_otel = __commonJS({
|
|
|
2462
2462
|
getActiveSpan() {
|
|
2463
2463
|
return void 0;
|
|
2464
2464
|
}
|
|
2465
|
-
setSpan(
|
|
2466
|
-
return
|
|
2465
|
+
setSpan(context17, _span) {
|
|
2466
|
+
return context17;
|
|
2467
2467
|
}
|
|
2468
2468
|
getSpan(_context) {
|
|
2469
2469
|
return void 0;
|
|
2470
2470
|
}
|
|
2471
|
-
setSpanContext(
|
|
2472
|
-
return
|
|
2471
|
+
setSpanContext(context17, _spanContext) {
|
|
2472
|
+
return context17;
|
|
2473
2473
|
}
|
|
2474
2474
|
getTracerProvider() {
|
|
2475
2475
|
return void 0;
|
|
@@ -3036,17 +3036,17 @@ var require_p_retry = __commonJS({
|
|
|
3036
3036
|
}
|
|
3037
3037
|
const retriesLeft = Number.isFinite(options.retries) ? Math.max(0, options.retries - retriesConsumed) : options.retries;
|
|
3038
3038
|
const maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;
|
|
3039
|
-
const
|
|
3039
|
+
const context17 = Object.freeze({
|
|
3040
3040
|
error: normalizedError,
|
|
3041
3041
|
attemptNumber,
|
|
3042
3042
|
retriesLeft,
|
|
3043
3043
|
retriesConsumed
|
|
3044
3044
|
});
|
|
3045
|
-
await options.onFailedAttempt(
|
|
3045
|
+
await options.onFailedAttempt(context17);
|
|
3046
3046
|
if (calculateRemainingTime(startTime, maxRetryTime) <= 0) {
|
|
3047
3047
|
throw normalizedError;
|
|
3048
3048
|
}
|
|
3049
|
-
const consumeRetry = await options.shouldConsumeRetry(
|
|
3049
|
+
const consumeRetry = await options.shouldConsumeRetry(context17);
|
|
3050
3050
|
const remainingTime = calculateRemainingTime(startTime, maxRetryTime);
|
|
3051
3051
|
if (remainingTime <= 0 || retriesLeft <= 0) {
|
|
3052
3052
|
throw normalizedError;
|
|
@@ -3058,7 +3058,7 @@ var require_p_retry = __commonJS({
|
|
|
3058
3058
|
options.signal?.throwIfAborted();
|
|
3059
3059
|
return false;
|
|
3060
3060
|
}
|
|
3061
|
-
if (!await options.shouldRetry(
|
|
3061
|
+
if (!await options.shouldRetry(context17)) {
|
|
3062
3062
|
throw normalizedError;
|
|
3063
3063
|
}
|
|
3064
3064
|
if (!consumeRetry) {
|
|
@@ -3166,16 +3166,16 @@ var require_eventemitter3 = __commonJS({
|
|
|
3166
3166
|
Events.prototype = /* @__PURE__ */ Object.create(null);
|
|
3167
3167
|
if (!new Events().__proto__) prefix = false;
|
|
3168
3168
|
}
|
|
3169
|
-
function EE(fn,
|
|
3169
|
+
function EE(fn, context17, once) {
|
|
3170
3170
|
this.fn = fn;
|
|
3171
|
-
this.context =
|
|
3171
|
+
this.context = context17;
|
|
3172
3172
|
this.once = once || false;
|
|
3173
3173
|
}
|
|
3174
|
-
function addListener(emitter, event, fn,
|
|
3174
|
+
function addListener(emitter, event, fn, context17, once) {
|
|
3175
3175
|
if (typeof fn !== "function") {
|
|
3176
3176
|
throw new TypeError("The listener must be a function");
|
|
3177
3177
|
}
|
|
3178
|
-
var listener = new EE(fn,
|
|
3178
|
+
var listener = new EE(fn, context17 || emitter, once), evt = prefix ? prefix + event : event;
|
|
3179
3179
|
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
|
|
3180
3180
|
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
|
|
3181
3181
|
else emitter._events[evt] = [emitter._events[evt], listener];
|
|
@@ -3266,13 +3266,13 @@ var require_eventemitter3 = __commonJS({
|
|
|
3266
3266
|
}
|
|
3267
3267
|
return true;
|
|
3268
3268
|
};
|
|
3269
|
-
EventEmitter.prototype.on = function on(event, fn,
|
|
3270
|
-
return addListener(this, event, fn,
|
|
3269
|
+
EventEmitter.prototype.on = function on(event, fn, context17) {
|
|
3270
|
+
return addListener(this, event, fn, context17, false);
|
|
3271
3271
|
};
|
|
3272
|
-
EventEmitter.prototype.once = function once(event, fn,
|
|
3273
|
-
return addListener(this, event, fn,
|
|
3272
|
+
EventEmitter.prototype.once = function once(event, fn, context17) {
|
|
3273
|
+
return addListener(this, event, fn, context17, true);
|
|
3274
3274
|
};
|
|
3275
|
-
EventEmitter.prototype.removeListener = function removeListener(event, fn,
|
|
3275
|
+
EventEmitter.prototype.removeListener = function removeListener(event, fn, context17, once) {
|
|
3276
3276
|
var evt = prefix ? prefix + event : event;
|
|
3277
3277
|
if (!this._events[evt]) return this;
|
|
3278
3278
|
if (!fn) {
|
|
@@ -3281,12 +3281,12 @@ var require_eventemitter3 = __commonJS({
|
|
|
3281
3281
|
}
|
|
3282
3282
|
var listeners = this._events[evt];
|
|
3283
3283
|
if (listeners.fn) {
|
|
3284
|
-
if (listeners.fn === fn && (!once || listeners.once) && (!
|
|
3284
|
+
if (listeners.fn === fn && (!once || listeners.once) && (!context17 || listeners.context === context17)) {
|
|
3285
3285
|
clearEvent(this, evt);
|
|
3286
3286
|
}
|
|
3287
3287
|
} else {
|
|
3288
3288
|
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
|
|
3289
|
-
if (listeners[i].fn !== fn || once && !listeners[i].once ||
|
|
3289
|
+
if (listeners[i].fn !== fn || once && !listeners[i].once || context17 && listeners[i].context !== context17) {
|
|
3290
3290
|
events.push(listeners[i]);
|
|
3291
3291
|
}
|
|
3292
3292
|
}
|
|
@@ -5845,7 +5845,7 @@ var require_error = __commonJS({
|
|
|
5845
5845
|
}
|
|
5846
5846
|
};
|
|
5847
5847
|
exports$1.LangSmithConflictError = LangSmithConflictError;
|
|
5848
|
-
async function raiseForStatus(response,
|
|
5848
|
+
async function raiseForStatus(response, context17, consumeOnSuccess) {
|
|
5849
5849
|
let errorBody;
|
|
5850
5850
|
if (response.ok) {
|
|
5851
5851
|
if (consumeOnSuccess) {
|
|
@@ -5873,7 +5873,7 @@ var require_error = __commonJS({
|
|
|
5873
5873
|
errorBody = "";
|
|
5874
5874
|
}
|
|
5875
5875
|
}
|
|
5876
|
-
const fullMessage = `Failed to ${
|
|
5876
|
+
const fullMessage = `Failed to ${context17}. Received status [${response.status}]: ${response.statusText}. Message: ${errorBody}`;
|
|
5877
5877
|
if (response.status === 409) {
|
|
5878
5878
|
throw new LangSmithConflictError(fullMessage);
|
|
5879
5879
|
}
|
|
@@ -7226,7 +7226,7 @@ var require_client = __commonJS({
|
|
|
7226
7226
|
});
|
|
7227
7227
|
return stream;
|
|
7228
7228
|
}
|
|
7229
|
-
async _sendMultipartRequest(parts,
|
|
7229
|
+
async _sendMultipartRequest(parts, context17, options) {
|
|
7230
7230
|
const boundary = "----LangSmithFormBoundary" + Math.random().toString(36).slice(2);
|
|
7231
7231
|
const isNodeFetch = (0, fetch_js_1._globalFetchImplementationIsNodeFetch)();
|
|
7232
7232
|
const buildBuffered = () => this._createNodeFetchBody(parts, boundary);
|
|
@@ -7268,14 +7268,14 @@ var require_client = __commonJS({
|
|
|
7268
7268
|
res = await sendWithRetry(buildBuffered);
|
|
7269
7269
|
}
|
|
7270
7270
|
if ((!this.multipartStreamingDisabled || streamedAttempt) && res.status === 422 && (options?.apiUrl ?? this.apiUrl) !== DEFAULT_API_URL) {
|
|
7271
|
-
console.warn(`Streaming multipart upload to ${options?.apiUrl ?? this.apiUrl}/runs/multipart failed. This usually means the host does not support chunked uploads. Retrying with a buffered upload for operation "${
|
|
7271
|
+
console.warn(`Streaming multipart upload to ${options?.apiUrl ?? this.apiUrl}/runs/multipart failed. This usually means the host does not support chunked uploads. Retrying with a buffered upload for operation "${context17}".`);
|
|
7272
7272
|
this.multipartStreamingDisabled = true;
|
|
7273
7273
|
res = await sendWithRetry(buildBuffered);
|
|
7274
7274
|
}
|
|
7275
7275
|
} catch (e) {
|
|
7276
7276
|
console.warn(`${e.message.trim()}
|
|
7277
7277
|
|
|
7278
|
-
Context: ${
|
|
7278
|
+
Context: ${context17}`);
|
|
7279
7279
|
}
|
|
7280
7280
|
}
|
|
7281
7281
|
async updateRun(runId, run, options) {
|
|
@@ -14510,6 +14510,37 @@ var Logger = class {
|
|
|
14510
14510
|
}
|
|
14511
14511
|
};
|
|
14512
14512
|
Logger._debugMode = false;
|
|
14513
|
+
function injectTraceContextHeaders(headers) {
|
|
14514
|
+
const carrier = { ...headers };
|
|
14515
|
+
try {
|
|
14516
|
+
api.propagation.inject(api.context.active(), carrier);
|
|
14517
|
+
} catch {
|
|
14518
|
+
Logger.warn("netra: Failed to inject trace context headers");
|
|
14519
|
+
return headers;
|
|
14520
|
+
}
|
|
14521
|
+
return carrier;
|
|
14522
|
+
}
|
|
14523
|
+
function extractContextFromHeaders(headers) {
|
|
14524
|
+
const carrier = {};
|
|
14525
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
14526
|
+
if (typeof value === "string") {
|
|
14527
|
+
carrier[key.toLowerCase()] = value;
|
|
14528
|
+
} else if (Array.isArray(value) && value.length > 0) {
|
|
14529
|
+
carrier[key.toLowerCase()] = value[0];
|
|
14530
|
+
}
|
|
14531
|
+
}
|
|
14532
|
+
return api.propagation.extract(api.context.active(), carrier);
|
|
14533
|
+
}
|
|
14534
|
+
function runWithExtractedContext(headers, fn) {
|
|
14535
|
+
const extractedCtx = extractContextFromHeaders(headers);
|
|
14536
|
+
return api.context.with(extractedCtx, fn);
|
|
14537
|
+
}
|
|
14538
|
+
function netraExpressMiddleware() {
|
|
14539
|
+
return (req, _res, next) => {
|
|
14540
|
+
const extractedCtx = extractContextFromHeaders(req.headers);
|
|
14541
|
+
api.context.with(extractedCtx, next);
|
|
14542
|
+
};
|
|
14543
|
+
}
|
|
14513
14544
|
|
|
14514
14545
|
// src/api/http-client.ts
|
|
14515
14546
|
var NetraHttpClient = class {
|
|
@@ -14583,7 +14614,7 @@ var NetraHttpClient = class {
|
|
|
14583
14614
|
);
|
|
14584
14615
|
const response = await fetch(url.toString(), {
|
|
14585
14616
|
method: "GET",
|
|
14586
|
-
headers: this.headers,
|
|
14617
|
+
headers: injectTraceContextHeaders(this.headers),
|
|
14587
14618
|
signal: controller.signal
|
|
14588
14619
|
});
|
|
14589
14620
|
clearTimeout(timeoutId);
|
|
@@ -14612,7 +14643,7 @@ var NetraHttpClient = class {
|
|
|
14612
14643
|
);
|
|
14613
14644
|
const response = await fetch(url.toString(), {
|
|
14614
14645
|
method: "POST",
|
|
14615
|
-
headers: this.headers,
|
|
14646
|
+
headers: injectTraceContextHeaders(this.headers),
|
|
14616
14647
|
body: body ? JSON.stringify(body) : void 0,
|
|
14617
14648
|
signal: controller.signal
|
|
14618
14649
|
});
|
|
@@ -16165,13 +16196,13 @@ async function runSingleEvaluator(params) {
|
|
|
16165
16196
|
if (config2) {
|
|
16166
16197
|
expectedName = config2.name;
|
|
16167
16198
|
}
|
|
16168
|
-
const
|
|
16199
|
+
const context17 = {
|
|
16169
16200
|
input: itemInput,
|
|
16170
16201
|
taskOutput,
|
|
16171
16202
|
expectedOutput,
|
|
16172
16203
|
metadata
|
|
16173
16204
|
};
|
|
16174
|
-
let result = evaluator.evaluate(
|
|
16205
|
+
let result = evaluator.evaluate(context17);
|
|
16175
16206
|
if (result instanceof Promise) {
|
|
16176
16207
|
result = await result;
|
|
16177
16208
|
}
|
|
@@ -16525,10 +16556,14 @@ var Evaluation = class {
|
|
|
16525
16556
|
ctx.spanId = formatSpanId(spanContext.spanId);
|
|
16526
16557
|
}
|
|
16527
16558
|
ctx.sessionId = getSessionIdFromBaggage();
|
|
16528
|
-
const { output, status } = await
|
|
16559
|
+
const { output, status } = await span2.withActive(
|
|
16560
|
+
() => executeTask(task2, ctx.itemInput)
|
|
16561
|
+
);
|
|
16529
16562
|
ctx.taskOutput = output;
|
|
16530
16563
|
ctx.status = status;
|
|
16531
|
-
ctx.testRunItemId = await
|
|
16564
|
+
ctx.testRunItemId = await span2.withActive(
|
|
16565
|
+
() => this.postCompletedStatus(runId, ctx)
|
|
16566
|
+
);
|
|
16532
16567
|
if (evaluators && ctx.status === "completed") {
|
|
16533
16568
|
const evalTask = this.runEvaluatorsForItem(runId, ctx, evaluators);
|
|
16534
16569
|
bgEvalTasks.push(evalTask);
|
|
@@ -18142,6 +18177,10 @@ function setModelParams(span2, kwargs) {
|
|
|
18142
18177
|
function buildInputMessages(kwargs, requestType) {
|
|
18143
18178
|
const messages = [];
|
|
18144
18179
|
if (requestType === "chat") {
|
|
18180
|
+
if (hasContent(kwargs.system)) {
|
|
18181
|
+
const systemContent = typeof kwargs.system === "string" ? kwargs.system : safeStringify(kwargs.system);
|
|
18182
|
+
messages.push({ role: "system", content: systemContent });
|
|
18183
|
+
}
|
|
18145
18184
|
const rawMessages = kwargs.messages;
|
|
18146
18185
|
if (!Array.isArray(rawMessages)) return messages;
|
|
18147
18186
|
for (const msg of rawMessages) {
|
|
@@ -18466,7 +18505,7 @@ function anthropicWrapper(tracer, spanName, requestType) {
|
|
|
18466
18505
|
return (async () => {
|
|
18467
18506
|
try {
|
|
18468
18507
|
const stream = await response;
|
|
18469
|
-
return new AsyncStreamingWrapper(span2, stream, startTime, kwargs);
|
|
18508
|
+
return new AsyncStreamingWrapper(span2, stream, startTime, kwargs, spanContext);
|
|
18470
18509
|
} catch (error) {
|
|
18471
18510
|
Logger.error("netra.instrumentation.anthropic:", error);
|
|
18472
18511
|
span2.setStatus({
|
|
@@ -18479,7 +18518,7 @@ function anthropicWrapper(tracer, spanName, requestType) {
|
|
|
18479
18518
|
}
|
|
18480
18519
|
})();
|
|
18481
18520
|
} else {
|
|
18482
|
-
return new AsyncStreamingWrapper(span2, response, startTime, kwargs);
|
|
18521
|
+
return new AsyncStreamingWrapper(span2, response, startTime, kwargs, spanContext);
|
|
18483
18522
|
}
|
|
18484
18523
|
} catch (error) {
|
|
18485
18524
|
Logger.error("netra.instrumentation.anthropic:", error);
|
|
@@ -18608,7 +18647,7 @@ var LISTENER_REGISTRATION_METHODS = /* @__PURE__ */ new Set(["on", "once", "addL
|
|
|
18608
18647
|
var COMPLETION_METHODS = /* @__PURE__ */ new Set(["finalMessage", "done", "finalText"]);
|
|
18609
18648
|
var TRACKED_STREAM_EVENTS = /* @__PURE__ */ new Set(["message", "contentBlock", "text", "finalMessage"]);
|
|
18610
18649
|
var MessageStreamWrapper = class {
|
|
18611
|
-
constructor(span2, messageStream, startTime, requestKwargs) {
|
|
18650
|
+
constructor(span2, messageStream, startTime, requestKwargs, spanContext) {
|
|
18612
18651
|
this.completeResponse = {
|
|
18613
18652
|
content: [],
|
|
18614
18653
|
model: "",
|
|
@@ -18618,6 +18657,7 @@ var MessageStreamWrapper = class {
|
|
|
18618
18657
|
defineHidden(this, "messageStream", messageStream);
|
|
18619
18658
|
defineHidden(this, "startTime", startTime);
|
|
18620
18659
|
defineHidden(this, "requestKwargs", requestKwargs);
|
|
18660
|
+
defineHidden(this, "spanContext", spanContext || api.trace.setSpan(api.context.active(), span2));
|
|
18621
18661
|
return new Proxy(this, {
|
|
18622
18662
|
get(target, prop, receiver) {
|
|
18623
18663
|
if (prop === "toJSON") {
|
|
@@ -18694,6 +18734,9 @@ var MessageStreamWrapper = class {
|
|
|
18694
18734
|
throw err;
|
|
18695
18735
|
}
|
|
18696
18736
|
}
|
|
18737
|
+
getSpanContext() {
|
|
18738
|
+
return this.spanContext;
|
|
18739
|
+
}
|
|
18697
18740
|
processEventData(eventType, data) {
|
|
18698
18741
|
switch (eventType) {
|
|
18699
18742
|
case "message":
|
|
@@ -18738,10 +18781,20 @@ var MessageStreamWrapper = class {
|
|
|
18738
18781
|
if (!this.completeResponse.content) {
|
|
18739
18782
|
this.completeResponse.content = [];
|
|
18740
18783
|
}
|
|
18741
|
-
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18784
|
+
const block = chunk.content_block;
|
|
18785
|
+
if (block.type === "tool_use") {
|
|
18786
|
+
this.completeResponse.content.push({
|
|
18787
|
+
type: "tool_use",
|
|
18788
|
+
id: block.id,
|
|
18789
|
+
name: block.name,
|
|
18790
|
+
input: ""
|
|
18791
|
+
});
|
|
18792
|
+
} else {
|
|
18793
|
+
this.completeResponse.content.push({
|
|
18794
|
+
type: block.type,
|
|
18795
|
+
text: ""
|
|
18796
|
+
});
|
|
18797
|
+
}
|
|
18745
18798
|
break;
|
|
18746
18799
|
}
|
|
18747
18800
|
case "content_block_delta": {
|
|
@@ -18749,11 +18802,27 @@ var MessageStreamWrapper = class {
|
|
|
18749
18802
|
this.completeResponse.content = [{ type: "text", text: "" }];
|
|
18750
18803
|
}
|
|
18751
18804
|
const lastBlock = this.completeResponse.content[this.completeResponse.content.length - 1];
|
|
18752
|
-
if (
|
|
18805
|
+
if (chunk.delta?.type === "input_json_delta" && lastBlock?.type === "tool_use") {
|
|
18806
|
+
lastBlock.input += chunk.delta.partial_json ?? "";
|
|
18807
|
+
} else if (lastBlock && chunk.delta?.text) {
|
|
18753
18808
|
lastBlock.text += chunk.delta.text;
|
|
18754
18809
|
}
|
|
18755
18810
|
break;
|
|
18756
18811
|
}
|
|
18812
|
+
case "content_block_stop": {
|
|
18813
|
+
const blocks = this.completeResponse.content;
|
|
18814
|
+
if (blocks && blocks.length > 0) {
|
|
18815
|
+
const finishedBlock = blocks[blocks.length - 1];
|
|
18816
|
+
if (finishedBlock?.type === "tool_use" && typeof finishedBlock.input === "string") {
|
|
18817
|
+
try {
|
|
18818
|
+
finishedBlock.input = JSON.parse(finishedBlock.input);
|
|
18819
|
+
} catch {
|
|
18820
|
+
Logger.warn("netra.instrumentation.anthropic: Failed to parse tool use input", finishedBlock.input);
|
|
18821
|
+
}
|
|
18822
|
+
}
|
|
18823
|
+
}
|
|
18824
|
+
break;
|
|
18825
|
+
}
|
|
18757
18826
|
case "message_delta": {
|
|
18758
18827
|
if (chunk.delta?.usage) {
|
|
18759
18828
|
this.completeResponse.usage = {
|
|
@@ -18796,7 +18865,7 @@ var MessageStreamWrapper = class {
|
|
|
18796
18865
|
}
|
|
18797
18866
|
};
|
|
18798
18867
|
var AsyncStreamingWrapper = class {
|
|
18799
|
-
constructor(span2, response, startTime, requestKwargs) {
|
|
18868
|
+
constructor(span2, response, startTime, requestKwargs, spanContext) {
|
|
18800
18869
|
this.iterator = null;
|
|
18801
18870
|
this.completeResponse = {
|
|
18802
18871
|
choices: [],
|
|
@@ -18806,6 +18875,7 @@ var AsyncStreamingWrapper = class {
|
|
|
18806
18875
|
defineHidden(this, "response", response);
|
|
18807
18876
|
defineHidden(this, "startTime", startTime);
|
|
18808
18877
|
defineHidden(this, "requestKwargs", requestKwargs);
|
|
18878
|
+
defineHidden(this, "spanContext", spanContext || api.trace.setSpan(api.context.active(), span2));
|
|
18809
18879
|
}
|
|
18810
18880
|
toJSON() {
|
|
18811
18881
|
return this.completeResponse;
|
|
@@ -18824,7 +18894,7 @@ var AsyncStreamingWrapper = class {
|
|
|
18824
18894
|
throw new Error("Response is not iterable");
|
|
18825
18895
|
}
|
|
18826
18896
|
}
|
|
18827
|
-
const result = await this.iterator.next();
|
|
18897
|
+
const result = await api.context.with(this.spanContext, () => this.iterator.next());
|
|
18828
18898
|
if (result.done) {
|
|
18829
18899
|
this.finalizeSpan(api.SpanStatusCode.OK);
|
|
18830
18900
|
return result;
|
|
@@ -18850,10 +18920,20 @@ var AsyncStreamingWrapper = class {
|
|
|
18850
18920
|
case "content_block_start": {
|
|
18851
18921
|
const content = this.completeResponse.content || [];
|
|
18852
18922
|
this.completeResponse.content = content;
|
|
18853
|
-
|
|
18854
|
-
|
|
18855
|
-
|
|
18856
|
-
|
|
18923
|
+
const block = chunk.content_block;
|
|
18924
|
+
if (block.type === "tool_use") {
|
|
18925
|
+
content.push({
|
|
18926
|
+
type: "tool_use",
|
|
18927
|
+
id: block.id,
|
|
18928
|
+
name: block.name,
|
|
18929
|
+
input: ""
|
|
18930
|
+
});
|
|
18931
|
+
} else {
|
|
18932
|
+
content.push({
|
|
18933
|
+
type: block.type,
|
|
18934
|
+
text: ""
|
|
18935
|
+
});
|
|
18936
|
+
}
|
|
18857
18937
|
break;
|
|
18858
18938
|
}
|
|
18859
18939
|
case "content_block_delta": {
|
|
@@ -18863,11 +18943,27 @@ var AsyncStreamingWrapper = class {
|
|
|
18863
18943
|
this.completeResponse.content = content;
|
|
18864
18944
|
}
|
|
18865
18945
|
const lastBlock = content[content.length - 1];
|
|
18866
|
-
if (
|
|
18946
|
+
if (chunk.delta?.type === "input_json_delta" && lastBlock?.type === "tool_use") {
|
|
18947
|
+
lastBlock.input += chunk.delta.partial_json ?? "";
|
|
18948
|
+
} else if (lastBlock && chunk.delta?.text) {
|
|
18867
18949
|
lastBlock.text += chunk.delta.text;
|
|
18868
18950
|
}
|
|
18869
18951
|
break;
|
|
18870
18952
|
}
|
|
18953
|
+
case "content_block_stop": {
|
|
18954
|
+
const content = this.completeResponse.content || [];
|
|
18955
|
+
if (content.length > 0) {
|
|
18956
|
+
const finishedBlock = content[content.length - 1];
|
|
18957
|
+
if (finishedBlock?.type === "tool_use" && typeof finishedBlock.input === "string") {
|
|
18958
|
+
try {
|
|
18959
|
+
finishedBlock.input = JSON.parse(finishedBlock.input);
|
|
18960
|
+
} catch {
|
|
18961
|
+
Logger.warn("netra.instrumentation.anthropic: Failed to parse tool use input", finishedBlock.input);
|
|
18962
|
+
}
|
|
18963
|
+
}
|
|
18964
|
+
}
|
|
18965
|
+
break;
|
|
18966
|
+
}
|
|
18871
18967
|
case "message_delta": {
|
|
18872
18968
|
if (chunk.delta?.usage) {
|
|
18873
18969
|
const currentUsage = this.completeResponse.usage || {};
|
|
@@ -18908,19 +19004,29 @@ var INSTRUMENTATION_NAME = "netra.instrumentation.anthropic";
|
|
|
18908
19004
|
var INSTRUMENTS = ["anthropic >= 0.71.2"];
|
|
18909
19005
|
var originalMethods = /* @__PURE__ */ new Map();
|
|
18910
19006
|
var isInstrumented = false;
|
|
18911
|
-
var
|
|
19007
|
+
var anthropicClasses = [];
|
|
18912
19008
|
async function resolveAnthropicAsync() {
|
|
18913
|
-
if (
|
|
19009
|
+
if (anthropicClasses.length > 0) return anthropicClasses;
|
|
18914
19010
|
try {
|
|
18915
19011
|
const anthropicModule = await import('@anthropic-ai/sdk');
|
|
18916
|
-
|
|
18917
|
-
return AnthropicClass;
|
|
19012
|
+
anthropicClasses.push(anthropicModule.Anthropic || anthropicModule.default || anthropicModule);
|
|
18918
19013
|
} catch {
|
|
18919
|
-
|
|
19014
|
+
Logger.warn("Failed to resolve Anthropic ESM module");
|
|
18920
19015
|
}
|
|
19016
|
+
try {
|
|
19017
|
+
const req = 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)));
|
|
19018
|
+
const mod = req("@anthropic-ai/sdk");
|
|
19019
|
+
const cjsClass = mod.Anthropic || mod.default || mod;
|
|
19020
|
+
if (!anthropicClasses.includes(cjsClass)) {
|
|
19021
|
+
anthropicClasses.push(cjsClass);
|
|
19022
|
+
}
|
|
19023
|
+
} catch {
|
|
19024
|
+
Logger.warn("Failed to resolve Anthropic CJS module");
|
|
19025
|
+
}
|
|
19026
|
+
return anthropicClasses;
|
|
18921
19027
|
}
|
|
18922
19028
|
function resolveAnthropic() {
|
|
18923
|
-
return
|
|
19029
|
+
return anthropicClasses;
|
|
18924
19030
|
}
|
|
18925
19031
|
var NetraAnthropicInstrumentor = class {
|
|
18926
19032
|
constructor() {
|
|
@@ -18934,8 +19040,8 @@ var NetraAnthropicInstrumentor = class {
|
|
|
18934
19040
|
Logger.warn("Anthropic is already instrumented");
|
|
18935
19041
|
return this;
|
|
18936
19042
|
}
|
|
18937
|
-
const
|
|
18938
|
-
if (
|
|
19043
|
+
const classes = await resolveAnthropicAsync();
|
|
19044
|
+
if (classes.length === 0) {
|
|
18939
19045
|
return this;
|
|
18940
19046
|
}
|
|
18941
19047
|
try {
|
|
@@ -18952,9 +19058,11 @@ var NetraAnthropicInstrumentor = class {
|
|
|
18952
19058
|
Logger.error(`Failed to initialize tracer: ${error}`);
|
|
18953
19059
|
return this;
|
|
18954
19060
|
}
|
|
18955
|
-
|
|
18956
|
-
|
|
18957
|
-
|
|
19061
|
+
classes.forEach((AnthropicSDK, index) => {
|
|
19062
|
+
this._instrumentMessages(AnthropicSDK, index);
|
|
19063
|
+
this._instrumentBetaMessages(AnthropicSDK, index);
|
|
19064
|
+
this._instrumentBatchMessages(AnthropicSDK, index);
|
|
19065
|
+
});
|
|
18958
19066
|
isInstrumented = true;
|
|
18959
19067
|
return this;
|
|
18960
19068
|
}
|
|
@@ -18963,27 +19071,25 @@ var NetraAnthropicInstrumentor = class {
|
|
|
18963
19071
|
Logger.warn("Anthropic is not instrumented");
|
|
18964
19072
|
return;
|
|
18965
19073
|
}
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
19074
|
+
const classes = resolveAnthropic();
|
|
19075
|
+
classes.forEach((AnthropicSDK, index) => {
|
|
19076
|
+
this._uninstrumentMessages(AnthropicSDK, index);
|
|
19077
|
+
this._uninstrumentBetaMessages(AnthropicSDK, index);
|
|
19078
|
+
this._uninstrumentBatchMessages(AnthropicSDK, index);
|
|
19079
|
+
});
|
|
18969
19080
|
originalMethods.clear();
|
|
18970
|
-
|
|
19081
|
+
anthropicClasses = [];
|
|
18971
19082
|
isInstrumented = false;
|
|
18972
19083
|
}
|
|
18973
19084
|
isInstrumented() {
|
|
18974
19085
|
return isInstrumented;
|
|
18975
19086
|
}
|
|
18976
|
-
_instrumentMessages() {
|
|
19087
|
+
_instrumentMessages(AnthropicSDK, index) {
|
|
18977
19088
|
if (!this.tracer) {
|
|
18978
19089
|
Logger.warn("Anthropic instrumentation: No tracer available");
|
|
18979
19090
|
return;
|
|
18980
19091
|
}
|
|
18981
19092
|
try {
|
|
18982
|
-
const AnthropicSDK = resolveAnthropic();
|
|
18983
|
-
if (!AnthropicSDK) {
|
|
18984
|
-
Logger.warn("Anthropic instrumentation: Anthropic SDK not available");
|
|
18985
|
-
return;
|
|
18986
|
-
}
|
|
18987
19093
|
const MessagesClass = AnthropicSDK.Messages;
|
|
18988
19094
|
if (!MessagesClass) {
|
|
18989
19095
|
Logger.error(
|
|
@@ -18993,11 +19099,12 @@ var NetraAnthropicInstrumentor = class {
|
|
|
18993
19099
|
}
|
|
18994
19100
|
if (MessagesClass?.prototype?.stream) {
|
|
18995
19101
|
const originalStream = MessagesClass.prototype.stream;
|
|
18996
|
-
originalMethods.set(
|
|
19102
|
+
originalMethods.set(`messages.stream-${index}`, originalStream);
|
|
18997
19103
|
const tracer = this.tracer;
|
|
18998
19104
|
MessagesClass.prototype.stream = function(...args) {
|
|
18999
19105
|
const original = originalStream.bind(this);
|
|
19000
19106
|
const kwargs = args[0] || {};
|
|
19107
|
+
const currentContext = api.context.active();
|
|
19001
19108
|
const span2 = tracer.startSpan("anthropic.stream", {
|
|
19002
19109
|
kind: api.SpanKind.CLIENT,
|
|
19003
19110
|
attributes: {
|
|
@@ -19005,17 +19112,18 @@ var NetraAnthropicInstrumentor = class {
|
|
|
19005
19112
|
"llm.streaming": true,
|
|
19006
19113
|
"llm.operation": "stream"
|
|
19007
19114
|
}
|
|
19008
|
-
});
|
|
19115
|
+
}, currentContext);
|
|
19116
|
+
const spanContext = api.trace.setSpan(currentContext, span2);
|
|
19009
19117
|
setRequestAttributes2(span2, kwargs, "chat");
|
|
19010
19118
|
const startTime = Date.now();
|
|
19011
19119
|
const instrumentedCreate = this.create;
|
|
19012
|
-
const originalCreate = originalMethods.get(
|
|
19120
|
+
const originalCreate = originalMethods.get(`messages.create-${index}`);
|
|
19013
19121
|
if (originalCreate) {
|
|
19014
19122
|
this.create = originalCreate;
|
|
19015
19123
|
}
|
|
19016
19124
|
try {
|
|
19017
|
-
const messageStream = original(...args);
|
|
19018
|
-
return new MessageStreamWrapper(span2, messageStream, startTime, kwargs);
|
|
19125
|
+
const messageStream = api.context.with(spanContext, () => original(...args));
|
|
19126
|
+
return new MessageStreamWrapper(span2, messageStream, startTime, kwargs, spanContext);
|
|
19019
19127
|
} finally {
|
|
19020
19128
|
if (originalCreate) {
|
|
19021
19129
|
this.create = instrumentedCreate;
|
|
@@ -19025,7 +19133,7 @@ var NetraAnthropicInstrumentor = class {
|
|
|
19025
19133
|
}
|
|
19026
19134
|
if (MessagesClass?.prototype?.create) {
|
|
19027
19135
|
const originalCreate = MessagesClass.prototype.create;
|
|
19028
|
-
originalMethods.set(
|
|
19136
|
+
originalMethods.set(`messages.create-${index}`, originalCreate);
|
|
19029
19137
|
const tracer = this.tracer;
|
|
19030
19138
|
const wrapper = chatWrapper(tracer);
|
|
19031
19139
|
MessagesClass.prototype.create = function(...args) {
|
|
@@ -19043,17 +19151,12 @@ var NetraAnthropicInstrumentor = class {
|
|
|
19043
19151
|
Logger.error(`Failed to instrument messages: ${error}`);
|
|
19044
19152
|
}
|
|
19045
19153
|
}
|
|
19046
|
-
_instrumentBetaMessages() {
|
|
19154
|
+
_instrumentBetaMessages(AnthropicSDK, index) {
|
|
19047
19155
|
if (!this.tracer) {
|
|
19048
19156
|
Logger.warn("Anthropic instrumentation: No tracer available");
|
|
19049
19157
|
return;
|
|
19050
19158
|
}
|
|
19051
19159
|
try {
|
|
19052
|
-
const AnthropicSDK = resolveAnthropic();
|
|
19053
|
-
if (!AnthropicSDK) {
|
|
19054
|
-
Logger.warn("Anthropic instrumentation: Anthropic SDK not available");
|
|
19055
|
-
return;
|
|
19056
|
-
}
|
|
19057
19160
|
const BetaMessagesClass = AnthropicSDK.Beta?.Messages;
|
|
19058
19161
|
if (!BetaMessagesClass) {
|
|
19059
19162
|
Logger.error(
|
|
@@ -19063,7 +19166,7 @@ var NetraAnthropicInstrumentor = class {
|
|
|
19063
19166
|
}
|
|
19064
19167
|
if (BetaMessagesClass?.prototype?.create) {
|
|
19065
19168
|
const originalCreate = BetaMessagesClass.prototype.create;
|
|
19066
|
-
originalMethods.set(
|
|
19169
|
+
originalMethods.set(`beta.messages.create-${index}`, originalCreate);
|
|
19067
19170
|
const tracer = this.tracer;
|
|
19068
19171
|
const wrapper = betaWrapper(tracer);
|
|
19069
19172
|
BetaMessagesClass.prototype.create = function(...args) {
|
|
@@ -19081,17 +19184,12 @@ var NetraAnthropicInstrumentor = class {
|
|
|
19081
19184
|
Logger.error(`Failed to instrument beta: ${error}`);
|
|
19082
19185
|
}
|
|
19083
19186
|
}
|
|
19084
|
-
_instrumentBatchMessages() {
|
|
19187
|
+
_instrumentBatchMessages(AnthropicSDK, index) {
|
|
19085
19188
|
if (!this.tracer) {
|
|
19086
19189
|
Logger.warn("Anthropic instrumentation: No tracer available");
|
|
19087
19190
|
return;
|
|
19088
19191
|
}
|
|
19089
19192
|
try {
|
|
19090
|
-
const AnthropicSDK = resolveAnthropic();
|
|
19091
|
-
if (!AnthropicSDK) {
|
|
19092
|
-
Logger.warn("Anthropic instrumentation: Anthropic SDK not available");
|
|
19093
|
-
return;
|
|
19094
|
-
}
|
|
19095
19193
|
const BatchMessageClass = AnthropicSDK.Messages?.Batches;
|
|
19096
19194
|
if (!BatchMessageClass) {
|
|
19097
19195
|
Logger.error(
|
|
@@ -19101,7 +19199,7 @@ var NetraAnthropicInstrumentor = class {
|
|
|
19101
19199
|
}
|
|
19102
19200
|
if (BatchMessageClass?.prototype?.create) {
|
|
19103
19201
|
const originalCreate = BatchMessageClass.prototype.create;
|
|
19104
|
-
originalMethods.set(
|
|
19202
|
+
originalMethods.set(`batch.messages.create-${index}`, originalCreate);
|
|
19105
19203
|
const tracer = this.tracer;
|
|
19106
19204
|
const wrapper = batchesWrapper(tracer);
|
|
19107
19205
|
BatchMessageClass.prototype.create = function(...args) {
|
|
@@ -19119,25 +19217,25 @@ var NetraAnthropicInstrumentor = class {
|
|
|
19119
19217
|
Logger.error(`Failed to instrument batches: ${error}`);
|
|
19120
19218
|
}
|
|
19121
19219
|
}
|
|
19122
|
-
_uninstrumentMessages() {
|
|
19220
|
+
_uninstrumentMessages(AnthropicSDK, index) {
|
|
19123
19221
|
try {
|
|
19124
|
-
const AnthropicSDK = resolveAnthropic();
|
|
19125
|
-
if (!AnthropicSDK) return;
|
|
19126
19222
|
const MessagesClass = AnthropicSDK.Messages;
|
|
19127
|
-
const originalCreate = originalMethods.get(
|
|
19223
|
+
const originalCreate = originalMethods.get(`messages.create-${index}`);
|
|
19128
19224
|
if (originalCreate && MessagesClass?.prototype) {
|
|
19129
19225
|
MessagesClass.prototype.create = originalCreate;
|
|
19130
19226
|
}
|
|
19227
|
+
const originalStream = originalMethods.get(`messages.stream-${index}`);
|
|
19228
|
+
if (originalStream && MessagesClass?.prototype) {
|
|
19229
|
+
MessagesClass.prototype.stream = originalStream;
|
|
19230
|
+
}
|
|
19131
19231
|
} catch (error) {
|
|
19132
19232
|
Logger.error(`Failed to uninstrument messages: ${error}`);
|
|
19133
19233
|
}
|
|
19134
19234
|
}
|
|
19135
|
-
_uninstrumentBetaMessages() {
|
|
19235
|
+
_uninstrumentBetaMessages(AnthropicSDK, index) {
|
|
19136
19236
|
try {
|
|
19137
|
-
const AnthropicSDK = resolveAnthropic();
|
|
19138
|
-
if (!AnthropicSDK) return;
|
|
19139
19237
|
const BetaMessagesClass = AnthropicSDK.Beta?.Messages;
|
|
19140
|
-
const originalCreate = originalMethods.get(
|
|
19238
|
+
const originalCreate = originalMethods.get(`beta.messages.create-${index}`);
|
|
19141
19239
|
if (originalCreate && BetaMessagesClass?.prototype) {
|
|
19142
19240
|
BetaMessagesClass.prototype.create = originalCreate;
|
|
19143
19241
|
}
|
|
@@ -19145,12 +19243,10 @@ var NetraAnthropicInstrumentor = class {
|
|
|
19145
19243
|
Logger.error(`Failed to uninstrument beta: ${error}`);
|
|
19146
19244
|
}
|
|
19147
19245
|
}
|
|
19148
|
-
_uninstrumentBatchMessages() {
|
|
19246
|
+
_uninstrumentBatchMessages(AnthropicSDK, index) {
|
|
19149
19247
|
try {
|
|
19150
|
-
const AnthropicSDK = resolveAnthropic();
|
|
19151
|
-
if (!AnthropicSDK) return;
|
|
19152
19248
|
const BatchMessagesClass = AnthropicSDK.Messages?.Batches;
|
|
19153
|
-
const originalCreate = originalMethods.get(
|
|
19249
|
+
const originalCreate = originalMethods.get(`batch.messages.create-${index}`);
|
|
19154
19250
|
if (originalCreate && BatchMessagesClass?.prototype) {
|
|
19155
19251
|
BatchMessagesClass.prototype.create = originalCreate;
|
|
19156
19252
|
}
|
|
@@ -19172,6 +19268,16 @@ function safeStringify2(value) {
|
|
|
19172
19268
|
return String(value);
|
|
19173
19269
|
}
|
|
19174
19270
|
}
|
|
19271
|
+
function extractModelName(model) {
|
|
19272
|
+
if (model && model.startsWith("models/")) {
|
|
19273
|
+
return model.replace(/^models\//, "");
|
|
19274
|
+
}
|
|
19275
|
+
return model;
|
|
19276
|
+
}
|
|
19277
|
+
function normalizeGenAIRole(raw) {
|
|
19278
|
+
const rawLower = raw.toLowerCase();
|
|
19279
|
+
return rawLower === "model" ? "assistant" : rawLower;
|
|
19280
|
+
}
|
|
19175
19281
|
function setRequestAttributes3(span2, kwargs, requestType, args) {
|
|
19176
19282
|
span2._netra_kwargs = kwargs;
|
|
19177
19283
|
if (!span2.isRecording()) {
|
|
@@ -19289,6 +19395,26 @@ function _setPromptAttributes(span2, kwargs, args) {
|
|
|
19289
19395
|
promptIndex++;
|
|
19290
19396
|
}
|
|
19291
19397
|
}
|
|
19398
|
+
if (kwargs.history && Array.isArray(kwargs.history)) {
|
|
19399
|
+
for (const turn of kwargs.history) {
|
|
19400
|
+
const role = normalizeGenAIRole(String(turn.role ?? "user"));
|
|
19401
|
+
const parts = turn.parts;
|
|
19402
|
+
if (Array.isArray(parts)) {
|
|
19403
|
+
const textContent = parts.filter((p) => p.text !== void 0).map((p) => String(p.text)).join("");
|
|
19404
|
+
if (textContent) {
|
|
19405
|
+
span2.setAttribute(
|
|
19406
|
+
`${SpanAttributes2.LLM_PROMPTS}.${promptIndex}.role`,
|
|
19407
|
+
role
|
|
19408
|
+
);
|
|
19409
|
+
span2.setAttribute(
|
|
19410
|
+
`${SpanAttributes2.LLM_PROMPTS}.${promptIndex}.content`,
|
|
19411
|
+
textContent
|
|
19412
|
+
);
|
|
19413
|
+
promptIndex++;
|
|
19414
|
+
}
|
|
19415
|
+
}
|
|
19416
|
+
}
|
|
19417
|
+
}
|
|
19292
19418
|
if (!args) return;
|
|
19293
19419
|
if (typeof args === "string") {
|
|
19294
19420
|
span2.setAttribute(
|
|
@@ -19493,7 +19619,7 @@ function _setCompletionAttributes(span2, response) {
|
|
|
19493
19619
|
const candidate = candidates[i];
|
|
19494
19620
|
const content = candidate.content;
|
|
19495
19621
|
if (!content) continue;
|
|
19496
|
-
const role = String(content.role ?? "model");
|
|
19622
|
+
const role = normalizeGenAIRole(String(content.role ?? "model"));
|
|
19497
19623
|
const parts = content.parts;
|
|
19498
19624
|
if (!Array.isArray(parts)) continue;
|
|
19499
19625
|
const textContent = parts.filter((p) => p.text !== void 0).map((p) => String(p.text)).join("");
|
|
@@ -19551,12 +19677,16 @@ function googleGenAIWrapper(tracer, spanName, requestType) {
|
|
|
19551
19677
|
const modelInstance = this;
|
|
19552
19678
|
const modelName = modelInstance.model;
|
|
19553
19679
|
const systemInstruction = modelInstance.systemInstruction;
|
|
19680
|
+
const history = modelInstance.history;
|
|
19554
19681
|
if (modelName) {
|
|
19555
|
-
kwargs.model = modelName;
|
|
19682
|
+
kwargs.model = extractModelName(modelName);
|
|
19556
19683
|
}
|
|
19557
19684
|
if (systemInstruction) {
|
|
19558
19685
|
kwargs.systemInstruction = systemInstruction;
|
|
19559
19686
|
}
|
|
19687
|
+
if (history) {
|
|
19688
|
+
kwargs.history = history;
|
|
19689
|
+
}
|
|
19560
19690
|
const currentContext = api.context.active();
|
|
19561
19691
|
return tracer.startActiveSpan(
|
|
19562
19692
|
spanName,
|
|
@@ -19634,8 +19764,10 @@ function googleGenAIStreamWrapper(tracer, spanName, requestType) {
|
|
|
19634
19764
|
const modelInstance = this;
|
|
19635
19765
|
const modelName = modelInstance.model;
|
|
19636
19766
|
const systemInstruction = modelInstance.systemInstruction;
|
|
19637
|
-
|
|
19767
|
+
const history = modelInstance.history;
|
|
19768
|
+
if (modelName) kwargs.model = extractModelName(modelName);
|
|
19638
19769
|
if (systemInstruction) kwargs.systemInstruction = systemInstruction;
|
|
19770
|
+
if (history) kwargs.history = history;
|
|
19639
19771
|
const currentContext = api.context.active();
|
|
19640
19772
|
return tracer.startActiveSpan(
|
|
19641
19773
|
spanName,
|
|
@@ -19774,25 +19906,75 @@ function googleGenAIStreamWrapper(tracer, spanName, requestType) {
|
|
|
19774
19906
|
};
|
|
19775
19907
|
};
|
|
19776
19908
|
}
|
|
19909
|
+
function googleGenAIStartChatWrapper(tracer, spanName, requestType) {
|
|
19910
|
+
const sendMessageWrapperFn = googleGenAIWrapper(tracer, spanName, requestType);
|
|
19911
|
+
const sendMessageStreamWrapperFn = googleGenAIStreamWrapper(tracer, spanName, requestType);
|
|
19912
|
+
return function wrapper(original) {
|
|
19913
|
+
return function(...args) {
|
|
19914
|
+
const chatSession = original.apply(this, args);
|
|
19915
|
+
if (!chatSession) return chatSession;
|
|
19916
|
+
const modelInstance = this;
|
|
19917
|
+
const modelName = modelInstance.model;
|
|
19918
|
+
const systemInstruction = modelInstance.systemInstruction;
|
|
19919
|
+
const chatHistory = args[0]?.history;
|
|
19920
|
+
if (typeof chatSession.sendMessage === "function" && !chatSession.__netra_patched) {
|
|
19921
|
+
const originalSendMessage = chatSession.sendMessage.bind(chatSession);
|
|
19922
|
+
const wrappedSendMessage = sendMessageWrapperFn(originalSendMessage);
|
|
19923
|
+
chatSession.sendMessage = function(...sendArgs) {
|
|
19924
|
+
const ctx = this;
|
|
19925
|
+
if (modelName) ctx.model = modelName;
|
|
19926
|
+
if (systemInstruction) ctx.systemInstruction = systemInstruction;
|
|
19927
|
+
if (chatHistory) ctx.history = chatHistory;
|
|
19928
|
+
return wrappedSendMessage.apply(this, sendArgs);
|
|
19929
|
+
};
|
|
19930
|
+
if (typeof chatSession.sendMessageStream === "function") {
|
|
19931
|
+
const originalSendStream = chatSession.sendMessageStream.bind(chatSession);
|
|
19932
|
+
const wrappedSendStream = sendMessageStreamWrapperFn(originalSendStream);
|
|
19933
|
+
chatSession.sendMessageStream = function(...sendArgs) {
|
|
19934
|
+
const ctx = this;
|
|
19935
|
+
if (modelName) ctx.model = modelName;
|
|
19936
|
+
if (systemInstruction) ctx.systemInstruction = systemInstruction;
|
|
19937
|
+
if (chatHistory) ctx.history = chatHistory;
|
|
19938
|
+
return wrappedSendStream.apply(this, sendArgs);
|
|
19939
|
+
};
|
|
19940
|
+
}
|
|
19941
|
+
chatSession.__netra_patched = true;
|
|
19942
|
+
}
|
|
19943
|
+
return chatSession;
|
|
19944
|
+
};
|
|
19945
|
+
};
|
|
19946
|
+
}
|
|
19777
19947
|
var chatWrapper2 = (tracer) => googleGenAIWrapper(tracer, CHAT_SPAN_NAME2, "chat");
|
|
19778
19948
|
var embeddingsWrapper = (tracer) => googleGenAIWrapper(tracer, EMBEDDING_SPAN_NAME, "embedding");
|
|
19779
19949
|
var chatStreamWrapper = (tracer) => googleGenAIStreamWrapper(tracer, CHAT_SPAN_NAME2, "chat");
|
|
19780
|
-
var
|
|
19950
|
+
var startChatWrapper = (tracer) => googleGenAIStartChatWrapper(tracer, CHAT_SPAN_NAME2, "chat");
|
|
19781
19951
|
var INSTRUMENTATION_NAME2 = "netra.instrumentation.google_genai";
|
|
19782
19952
|
var INSTRUMENTS2 = ["@google/genai >= 0.24.1"];
|
|
19783
19953
|
var isInstrumented2 = false;
|
|
19954
|
+
var generativeModelClasses = [];
|
|
19784
19955
|
async function resolveGoogleGenerativeAIAsync() {
|
|
19785
|
-
if (
|
|
19956
|
+
if (generativeModelClasses.length > 0) return generativeModelClasses;
|
|
19786
19957
|
try {
|
|
19787
19958
|
const googleGenAIModule = await import('@google/generative-ai');
|
|
19788
|
-
|
|
19789
|
-
|
|
19959
|
+
const esmClass = googleGenAIModule.GenerativeModel || googleGenAIModule.default?.GenerativeModel || googleGenAIModule.default || googleGenAIModule;
|
|
19960
|
+
generativeModelClasses.push(esmClass);
|
|
19790
19961
|
} catch {
|
|
19791
|
-
|
|
19962
|
+
Logger.warn("Failed to resolve Google GenAI ESM module");
|
|
19963
|
+
}
|
|
19964
|
+
try {
|
|
19965
|
+
const req = 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)));
|
|
19966
|
+
const mod = req("@google/generative-ai");
|
|
19967
|
+
const cjsClass = mod.GenerativeModel || mod.default?.GenerativeModel || mod.default || mod;
|
|
19968
|
+
if (!generativeModelClasses.includes(cjsClass)) {
|
|
19969
|
+
generativeModelClasses.push(cjsClass);
|
|
19970
|
+
}
|
|
19971
|
+
} catch {
|
|
19972
|
+
Logger.warn("Failed to resolve Google GenAI CJS module");
|
|
19792
19973
|
}
|
|
19974
|
+
return generativeModelClasses;
|
|
19793
19975
|
}
|
|
19794
19976
|
function resolveGoogleGenerativeAI() {
|
|
19795
|
-
return
|
|
19977
|
+
return generativeModelClasses;
|
|
19796
19978
|
}
|
|
19797
19979
|
var NetraGoogleGenerativeAIInstrumentor = class {
|
|
19798
19980
|
constructor() {
|
|
@@ -19806,16 +19988,15 @@ var NetraGoogleGenerativeAIInstrumentor = class {
|
|
|
19806
19988
|
}
|
|
19807
19989
|
/**
|
|
19808
19990
|
* Instrument Google GenAI client methods (async version)
|
|
19809
|
-
*
|
|
19810
|
-
* that the application uses.
|
|
19991
|
+
* Tries both ESM and CJS resolution to cover dual-package setups.
|
|
19811
19992
|
*/
|
|
19812
19993
|
async instrumentAsync(options = {}) {
|
|
19813
19994
|
if (isInstrumented2) {
|
|
19814
19995
|
Logger.warn("Google GenAI is already instrumented");
|
|
19815
19996
|
return this;
|
|
19816
19997
|
}
|
|
19817
|
-
const
|
|
19818
|
-
if (
|
|
19998
|
+
const classes = await resolveGoogleGenerativeAIAsync();
|
|
19999
|
+
if (classes.length === 0) {
|
|
19819
20000
|
return this;
|
|
19820
20001
|
}
|
|
19821
20002
|
try {
|
|
@@ -19825,7 +20006,7 @@ var NetraGoogleGenerativeAIInstrumentor = class {
|
|
|
19825
20006
|
Logger.error(`Failed to initialize tracer: ${error}`);
|
|
19826
20007
|
return this;
|
|
19827
20008
|
}
|
|
19828
|
-
this._instrumentGenerativeModel();
|
|
20009
|
+
classes.forEach((model) => this._instrumentGenerativeModel(model));
|
|
19829
20010
|
isInstrumented2 = true;
|
|
19830
20011
|
return this;
|
|
19831
20012
|
}
|
|
@@ -19837,7 +20018,8 @@ var NetraGoogleGenerativeAIInstrumentor = class {
|
|
|
19837
20018
|
Logger.warn("Google GenAI is already instrumented");
|
|
19838
20019
|
return this;
|
|
19839
20020
|
}
|
|
19840
|
-
|
|
20021
|
+
const classes = resolveGoogleGenerativeAI();
|
|
20022
|
+
if (classes.length === 0) {
|
|
19841
20023
|
this.instrumentAsync(options).catch((e) => {
|
|
19842
20024
|
Logger.error("Failed to instrument Google GenAI:", e);
|
|
19843
20025
|
});
|
|
@@ -19850,7 +20032,7 @@ var NetraGoogleGenerativeAIInstrumentor = class {
|
|
|
19850
20032
|
Logger.error(`Failed to initialize tracer: ${error}`);
|
|
19851
20033
|
return this;
|
|
19852
20034
|
}
|
|
19853
|
-
this._instrumentGenerativeModel();
|
|
20035
|
+
classes.forEach((model) => this._instrumentGenerativeModel(model));
|
|
19854
20036
|
isInstrumented2 = true;
|
|
19855
20037
|
return this;
|
|
19856
20038
|
}
|
|
@@ -19862,8 +20044,9 @@ var NetraGoogleGenerativeAIInstrumentor = class {
|
|
|
19862
20044
|
Logger.warn("Google GenAI is not instrumented");
|
|
19863
20045
|
return;
|
|
19864
20046
|
}
|
|
19865
|
-
|
|
19866
|
-
|
|
20047
|
+
const classes = resolveGoogleGenerativeAI();
|
|
20048
|
+
classes.forEach((model) => this._uninstrumentGenerativeModel(model));
|
|
20049
|
+
generativeModelClasses = [];
|
|
19867
20050
|
isInstrumented2 = false;
|
|
19868
20051
|
}
|
|
19869
20052
|
/**
|
|
@@ -19872,10 +20055,10 @@ var NetraGoogleGenerativeAIInstrumentor = class {
|
|
|
19872
20055
|
isInstrumented() {
|
|
19873
20056
|
return isInstrumented2;
|
|
19874
20057
|
}
|
|
19875
|
-
_instrumentGenerativeModel() {
|
|
20058
|
+
_instrumentGenerativeModel(GenerativeModel) {
|
|
19876
20059
|
if (!this.tracer) return;
|
|
19877
20060
|
try {
|
|
19878
|
-
if (!GenerativeModel) {
|
|
20061
|
+
if (!GenerativeModel?.prototype) {
|
|
19879
20062
|
Logger.error(
|
|
19880
20063
|
"Failed to find Google GenAI GenerativeModel to instrument"
|
|
19881
20064
|
);
|
|
@@ -19897,14 +20080,22 @@ var NetraGoogleGenerativeAIInstrumentor = class {
|
|
|
19897
20080
|
"embedContent",
|
|
19898
20081
|
embeddingsWrapper(tracer)
|
|
19899
20082
|
);
|
|
20083
|
+
if (typeof GenerativeModel.prototype.startChat === "function") {
|
|
20084
|
+
shimmer__default.default.wrap(
|
|
20085
|
+
GenerativeModel.prototype,
|
|
20086
|
+
"startChat",
|
|
20087
|
+
startChatWrapper(tracer)
|
|
20088
|
+
);
|
|
20089
|
+
}
|
|
19900
20090
|
} catch (error) {
|
|
19901
20091
|
Logger.debug(
|
|
19902
20092
|
`Google GenAI instrumentation: failed to instrument: ${error}`
|
|
19903
20093
|
);
|
|
19904
20094
|
}
|
|
19905
20095
|
}
|
|
19906
|
-
_uninstrumentGenerativeModel() {
|
|
20096
|
+
_uninstrumentGenerativeModel(GenerativeModel) {
|
|
19907
20097
|
try {
|
|
20098
|
+
if (!GenerativeModel?.prototype) return;
|
|
19908
20099
|
if (typeof GenerativeModel.prototype.generateContent === "function") {
|
|
19909
20100
|
shimmer__default.default.unwrap(GenerativeModel.prototype, "generateContent");
|
|
19910
20101
|
}
|
|
@@ -19914,6 +20105,9 @@ var NetraGoogleGenerativeAIInstrumentor = class {
|
|
|
19914
20105
|
if (typeof GenerativeModel.prototype.embedContent === "function") {
|
|
19915
20106
|
shimmer__default.default.unwrap(GenerativeModel.prototype, "embedContent");
|
|
19916
20107
|
}
|
|
20108
|
+
if (typeof GenerativeModel.prototype.startChat === "function") {
|
|
20109
|
+
shimmer__default.default.unwrap(GenerativeModel.prototype, "startChat");
|
|
20110
|
+
}
|
|
19917
20111
|
} catch (error) {
|
|
19918
20112
|
Logger.debug(`Failed to uninstrument Google GenAI: ${error}`);
|
|
19919
20113
|
}
|
|
@@ -20277,19 +20471,29 @@ var INSTRUMENTATION_NAME3 = "netra.instrumentation.groq";
|
|
|
20277
20471
|
var INSTRUMENTS3 = ["groq-sdk >= 0.3.0"];
|
|
20278
20472
|
var originalMethods2 = /* @__PURE__ */ new Map();
|
|
20279
20473
|
var isInstrumented3 = false;
|
|
20280
|
-
var
|
|
20474
|
+
var groqClasses = [];
|
|
20281
20475
|
async function resolveGroqAsync() {
|
|
20282
|
-
if (
|
|
20476
|
+
if (groqClasses.length > 0) return groqClasses;
|
|
20283
20477
|
try {
|
|
20284
20478
|
const groqModule = await import('groq-sdk');
|
|
20285
|
-
|
|
20286
|
-
return GroqClass;
|
|
20479
|
+
groqClasses.push(groqModule.Groq || groqModule.default || groqModule);
|
|
20287
20480
|
} catch {
|
|
20288
|
-
|
|
20481
|
+
Logger.warn("Failed to resolve Groq ESM module");
|
|
20289
20482
|
}
|
|
20483
|
+
try {
|
|
20484
|
+
const req = 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)));
|
|
20485
|
+
const mod = req("groq-sdk");
|
|
20486
|
+
const cjsClass = mod.Groq || mod.default || mod;
|
|
20487
|
+
if (!groqClasses.includes(cjsClass)) {
|
|
20488
|
+
groqClasses.push(cjsClass);
|
|
20489
|
+
}
|
|
20490
|
+
} catch {
|
|
20491
|
+
Logger.warn("Failed to resolve Groq CJS module");
|
|
20492
|
+
}
|
|
20493
|
+
return groqClasses;
|
|
20290
20494
|
}
|
|
20291
20495
|
function resolveGroq() {
|
|
20292
|
-
return
|
|
20496
|
+
return groqClasses;
|
|
20293
20497
|
}
|
|
20294
20498
|
var NetraGroqInstrumentor = class {
|
|
20295
20499
|
constructor() {
|
|
@@ -20300,16 +20504,15 @@ var NetraGroqInstrumentor = class {
|
|
|
20300
20504
|
}
|
|
20301
20505
|
/**
|
|
20302
20506
|
* Instrument Groq client methods (async version)
|
|
20303
|
-
*
|
|
20304
|
-
* that the application uses.
|
|
20507
|
+
* Tries both ESM and CJS resolution to cover dual-package setups.
|
|
20305
20508
|
*/
|
|
20306
20509
|
async instrumentAsync(options = {}) {
|
|
20307
20510
|
if (isInstrumented3) {
|
|
20308
20511
|
Logger.warn("Groq is already instrumented");
|
|
20309
20512
|
return this;
|
|
20310
20513
|
}
|
|
20311
|
-
const
|
|
20312
|
-
if (
|
|
20514
|
+
const classes = await resolveGroqAsync();
|
|
20515
|
+
if (classes.length === 0) {
|
|
20313
20516
|
return this;
|
|
20314
20517
|
}
|
|
20315
20518
|
try {
|
|
@@ -20326,21 +20529,23 @@ var NetraGroqInstrumentor = class {
|
|
|
20326
20529
|
Logger.error(`Failed to initialize tracer: ${error}`);
|
|
20327
20530
|
return this;
|
|
20328
20531
|
}
|
|
20329
|
-
|
|
20532
|
+
classes.forEach((Groq, index) => {
|
|
20533
|
+
this._instrumentChatCompletions(Groq, index);
|
|
20534
|
+
});
|
|
20330
20535
|
isInstrumented3 = true;
|
|
20331
20536
|
return this;
|
|
20332
20537
|
}
|
|
20333
20538
|
/**
|
|
20334
20539
|
* Instrument Groq client methods (sync version - for backwards compatibility)
|
|
20335
|
-
* Note: This uses
|
|
20540
|
+
* Note: This uses cached Groq classes. Call instrumentAsync() for proper initialization.
|
|
20336
20541
|
*/
|
|
20337
20542
|
instrument(options = {}) {
|
|
20338
20543
|
if (isInstrumented3) {
|
|
20339
20544
|
Logger.warn("Groq is already instrumented");
|
|
20340
20545
|
return this;
|
|
20341
20546
|
}
|
|
20342
|
-
const
|
|
20343
|
-
if (
|
|
20547
|
+
const classes = resolveGroq();
|
|
20548
|
+
if (classes.length === 0) {
|
|
20344
20549
|
this.instrumentAsync(options).catch((e) => {
|
|
20345
20550
|
Logger.error("Failed to instrument Groq:", e);
|
|
20346
20551
|
});
|
|
@@ -20360,7 +20565,9 @@ var NetraGroqInstrumentor = class {
|
|
|
20360
20565
|
Logger.error(`Failed to initialize tracer: ${error}`);
|
|
20361
20566
|
return this;
|
|
20362
20567
|
}
|
|
20363
|
-
|
|
20568
|
+
classes.forEach((Groq, index) => {
|
|
20569
|
+
this._instrumentChatCompletions(Groq, index);
|
|
20570
|
+
});
|
|
20364
20571
|
isInstrumented3 = true;
|
|
20365
20572
|
return this;
|
|
20366
20573
|
}
|
|
@@ -20369,18 +20576,18 @@ var NetraGroqInstrumentor = class {
|
|
|
20369
20576
|
Logger.warn("Groq is not instrumented");
|
|
20370
20577
|
return;
|
|
20371
20578
|
}
|
|
20372
|
-
const
|
|
20373
|
-
|
|
20374
|
-
this._uninstrumentChatCompletions(Groq);
|
|
20375
|
-
}
|
|
20579
|
+
const classes = resolveGroq();
|
|
20580
|
+
classes.forEach((Groq, index) => {
|
|
20581
|
+
this._uninstrumentChatCompletions(Groq, index);
|
|
20582
|
+
});
|
|
20376
20583
|
originalMethods2.clear();
|
|
20377
|
-
|
|
20584
|
+
groqClasses = [];
|
|
20378
20585
|
isInstrumented3 = false;
|
|
20379
20586
|
}
|
|
20380
20587
|
isInstrumented() {
|
|
20381
20588
|
return isInstrumented3;
|
|
20382
20589
|
}
|
|
20383
|
-
_instrumentChatCompletions(Groq) {
|
|
20590
|
+
_instrumentChatCompletions(Groq, index) {
|
|
20384
20591
|
if (!this.tracer) {
|
|
20385
20592
|
Logger.warn("Groq instrumentation: No tracer available");
|
|
20386
20593
|
return;
|
|
@@ -20394,7 +20601,7 @@ var NetraGroqInstrumentor = class {
|
|
|
20394
20601
|
return;
|
|
20395
20602
|
}
|
|
20396
20603
|
const originalCreate = CompletionsClass.prototype.create;
|
|
20397
|
-
originalMethods2.set(
|
|
20604
|
+
originalMethods2.set(`chat.completions.create-${index}`, originalCreate);
|
|
20398
20605
|
const tracer = this.tracer;
|
|
20399
20606
|
const wrapper = chatWrapper3(tracer);
|
|
20400
20607
|
CompletionsClass.prototype.create = function(...args) {
|
|
@@ -20409,10 +20616,10 @@ var NetraGroqInstrumentor = class {
|
|
|
20409
20616
|
);
|
|
20410
20617
|
}
|
|
20411
20618
|
}
|
|
20412
|
-
_uninstrumentChatCompletions(Groq) {
|
|
20619
|
+
_uninstrumentChatCompletions(Groq, index) {
|
|
20413
20620
|
try {
|
|
20414
20621
|
const CompletionsClass = Groq.Chat?.Completions;
|
|
20415
|
-
const originalCreate = originalMethods2.get(
|
|
20622
|
+
const originalCreate = originalMethods2.get(`chat.completions.create-${index}`);
|
|
20416
20623
|
if (originalCreate && CompletionsClass?.prototype) {
|
|
20417
20624
|
CompletionsClass.prototype.create = originalCreate;
|
|
20418
20625
|
}
|
|
@@ -21907,19 +22114,31 @@ var INSTRUMENTATION_NAME5 = "netra.instrumentation.mistral_ai";
|
|
|
21907
22114
|
var INSTRUMENTS5 = ["@mistralai/mistralai >= 1.0.0"];
|
|
21908
22115
|
var originalMethods4 = /* @__PURE__ */ new Map();
|
|
21909
22116
|
var isInstrumented5 = false;
|
|
21910
|
-
var
|
|
22117
|
+
var mistralClasses = [];
|
|
21911
22118
|
async function resolveMistralAsync() {
|
|
21912
|
-
if (
|
|
22119
|
+
if (mistralClasses.length > 0) return mistralClasses;
|
|
21913
22120
|
try {
|
|
21914
22121
|
const mistralModule = await import('@mistralai/mistralai');
|
|
21915
|
-
|
|
21916
|
-
|
|
22122
|
+
mistralClasses.push(
|
|
22123
|
+
mistralModule.Mistral || mistralModule.default || mistralModule
|
|
22124
|
+
);
|
|
21917
22125
|
} catch {
|
|
21918
|
-
|
|
22126
|
+
Logger.warn("Failed to resolve MistralAI ESM module");
|
|
21919
22127
|
}
|
|
22128
|
+
try {
|
|
22129
|
+
const req = 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)));
|
|
22130
|
+
const mod = req("@mistralai/mistralai");
|
|
22131
|
+
const cjsClass = mod.Mistral || mod.default || mod;
|
|
22132
|
+
if (!mistralClasses.includes(cjsClass)) {
|
|
22133
|
+
mistralClasses.push(cjsClass);
|
|
22134
|
+
}
|
|
22135
|
+
} catch {
|
|
22136
|
+
Logger.warn("Failed to resolve MistralAI CJS module");
|
|
22137
|
+
}
|
|
22138
|
+
return mistralClasses;
|
|
21920
22139
|
}
|
|
21921
22140
|
function resolveMistral() {
|
|
21922
|
-
return
|
|
22141
|
+
return mistralClasses;
|
|
21923
22142
|
}
|
|
21924
22143
|
var NetraMistralAIInstrumentor = class {
|
|
21925
22144
|
constructor() {
|
|
@@ -21934,16 +22153,15 @@ var NetraMistralAIInstrumentor = class {
|
|
|
21934
22153
|
}
|
|
21935
22154
|
/**
|
|
21936
22155
|
* Instrument MistralAI client methods (async version)
|
|
21937
|
-
*
|
|
21938
|
-
* that the application uses.
|
|
22156
|
+
* Tries both ESM and CJS resolution to cover dual-package setups.
|
|
21939
22157
|
*/
|
|
21940
22158
|
async instrumentAsync(options = {}) {
|
|
21941
22159
|
if (isInstrumented5) {
|
|
21942
22160
|
Logger.warn("MistralAI is already instrumented");
|
|
21943
22161
|
return this;
|
|
21944
22162
|
}
|
|
21945
|
-
const
|
|
21946
|
-
if (
|
|
22163
|
+
const classes = await resolveMistralAsync();
|
|
22164
|
+
if (classes.length === 0) {
|
|
21947
22165
|
return this;
|
|
21948
22166
|
}
|
|
21949
22167
|
try {
|
|
@@ -21960,11 +22178,16 @@ var NetraMistralAIInstrumentor = class {
|
|
|
21960
22178
|
Logger.error(`Failed to initialize tracer: ${error}`);
|
|
21961
22179
|
return this;
|
|
21962
22180
|
}
|
|
21963
|
-
|
|
21964
|
-
|
|
21965
|
-
|
|
21966
|
-
|
|
21967
|
-
|
|
22181
|
+
let didPatch = false;
|
|
22182
|
+
classes.forEach((Mistral, index) => {
|
|
22183
|
+
const patchedChat = this._instrumentChat(Mistral, index);
|
|
22184
|
+
const patchedEmbeddings = this._instrumentEmbeddings(Mistral, index);
|
|
22185
|
+
const patchedFIM = this._instrumentFIM(Mistral, index);
|
|
22186
|
+
const patchedAgents = this._instrumentAgents(Mistral, index);
|
|
22187
|
+
if (patchedChat || patchedEmbeddings || patchedFIM || patchedAgents) {
|
|
22188
|
+
didPatch = true;
|
|
22189
|
+
}
|
|
22190
|
+
});
|
|
21968
22191
|
if (!didPatch) {
|
|
21969
22192
|
Logger.warn(
|
|
21970
22193
|
"MistralAI instrumentation initialized but no methods were patched. Is '@mistralai/mistralai' installed and compatible?"
|
|
@@ -21976,15 +22199,15 @@ var NetraMistralAIInstrumentor = class {
|
|
|
21976
22199
|
}
|
|
21977
22200
|
/**
|
|
21978
22201
|
* Instrument MistralAI client methods (sync version - for backwards compatibility)
|
|
21979
|
-
* Note: This uses
|
|
22202
|
+
* Note: This uses cached Mistral classes. Call instrumentAsync() for proper initialization.
|
|
21980
22203
|
*/
|
|
21981
22204
|
instrument(options = {}) {
|
|
21982
22205
|
if (isInstrumented5) {
|
|
21983
22206
|
Logger.warn("MistralAI is already instrumented");
|
|
21984
22207
|
return this;
|
|
21985
22208
|
}
|
|
21986
|
-
const
|
|
21987
|
-
if (
|
|
22209
|
+
const classes = resolveMistral();
|
|
22210
|
+
if (classes.length === 0) {
|
|
21988
22211
|
this.instrumentAsync(options).catch((e) => {
|
|
21989
22212
|
Logger.error("Failed to instrument MistralAI:", e);
|
|
21990
22213
|
});
|
|
@@ -22004,11 +22227,16 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22004
22227
|
Logger.error(`Failed to initialize tracer: ${error}`);
|
|
22005
22228
|
return this;
|
|
22006
22229
|
}
|
|
22007
|
-
|
|
22008
|
-
|
|
22009
|
-
|
|
22010
|
-
|
|
22011
|
-
|
|
22230
|
+
let didPatch = false;
|
|
22231
|
+
classes.forEach((Mistral, index) => {
|
|
22232
|
+
const patchedChat = this._instrumentChat(Mistral, index);
|
|
22233
|
+
const patchedEmbeddings = this._instrumentEmbeddings(Mistral, index);
|
|
22234
|
+
const patchedFIM = this._instrumentFIM(Mistral, index);
|
|
22235
|
+
const patchedAgents = this._instrumentAgents(Mistral, index);
|
|
22236
|
+
if (patchedChat || patchedEmbeddings || patchedFIM || patchedAgents) {
|
|
22237
|
+
didPatch = true;
|
|
22238
|
+
}
|
|
22239
|
+
});
|
|
22012
22240
|
if (!didPatch) {
|
|
22013
22241
|
Logger.warn(
|
|
22014
22242
|
"MistralAI instrumentation initialized but no methods were patched. Is '@mistralai/mistralai' installed and compatible?"
|
|
@@ -22026,15 +22254,15 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22026
22254
|
Logger.warn("MistralAI is not instrumented");
|
|
22027
22255
|
return;
|
|
22028
22256
|
}
|
|
22029
|
-
const
|
|
22030
|
-
|
|
22031
|
-
this._uninstrumentChat(Mistral);
|
|
22032
|
-
this._uninstrumentEmbeddings(Mistral);
|
|
22033
|
-
this._uninstrumentFIM(Mistral);
|
|
22034
|
-
this._uninstrumentAgents(Mistral);
|
|
22035
|
-
}
|
|
22257
|
+
const classes = resolveMistral();
|
|
22258
|
+
classes.forEach((Mistral, index) => {
|
|
22259
|
+
this._uninstrumentChat(Mistral, index);
|
|
22260
|
+
this._uninstrumentEmbeddings(Mistral, index);
|
|
22261
|
+
this._uninstrumentFIM(Mistral, index);
|
|
22262
|
+
this._uninstrumentAgents(Mistral, index);
|
|
22263
|
+
});
|
|
22036
22264
|
originalMethods4.clear();
|
|
22037
|
-
|
|
22265
|
+
mistralClasses = [];
|
|
22038
22266
|
isInstrumented5 = false;
|
|
22039
22267
|
}
|
|
22040
22268
|
/**
|
|
@@ -22072,14 +22300,14 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22072
22300
|
this._ensureResourceCtors(Mistral);
|
|
22073
22301
|
return this.resourceCtors[name] ?? null;
|
|
22074
22302
|
}
|
|
22075
|
-
_instrumentChat(Mistral) {
|
|
22303
|
+
_instrumentChat(Mistral, index) {
|
|
22076
22304
|
if (!this.tracer) return false;
|
|
22077
22305
|
try {
|
|
22078
22306
|
const ChatClass = this._getCtor(Mistral, "chat");
|
|
22079
22307
|
let didPatch = false;
|
|
22080
22308
|
if (ChatClass?.prototype?.complete) {
|
|
22081
22309
|
const originalComplete = ChatClass.prototype.complete;
|
|
22082
|
-
originalMethods4.set(
|
|
22310
|
+
originalMethods4.set(`chat.complete-${index}`, originalComplete);
|
|
22083
22311
|
const tracer = this.tracer;
|
|
22084
22312
|
const wrapper = chatWrapper4(tracer);
|
|
22085
22313
|
ChatClass.prototype.complete = function(...args) {
|
|
@@ -22096,7 +22324,7 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22096
22324
|
}
|
|
22097
22325
|
if (ChatClass?.prototype?.stream) {
|
|
22098
22326
|
const originalStream = ChatClass.prototype.stream;
|
|
22099
|
-
originalMethods4.set(
|
|
22327
|
+
originalMethods4.set(`chat.stream-${index}`, originalStream);
|
|
22100
22328
|
const tracer = this.tracer;
|
|
22101
22329
|
const wrapper = chatStreamWrapper2(tracer);
|
|
22102
22330
|
ChatClass.prototype.stream = function(...args) {
|
|
@@ -22117,14 +22345,14 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22117
22345
|
return false;
|
|
22118
22346
|
}
|
|
22119
22347
|
}
|
|
22120
|
-
_instrumentEmbeddings(Mistral) {
|
|
22348
|
+
_instrumentEmbeddings(Mistral, index) {
|
|
22121
22349
|
if (!this.tracer) return false;
|
|
22122
22350
|
try {
|
|
22123
22351
|
const EmbeddingsClass = this._getCtor(Mistral, "embeddings");
|
|
22124
22352
|
let didPatch = false;
|
|
22125
22353
|
if (EmbeddingsClass?.prototype?.create) {
|
|
22126
22354
|
const originalCreate = EmbeddingsClass.prototype.create;
|
|
22127
|
-
originalMethods4.set(
|
|
22355
|
+
originalMethods4.set(`embeddings.create-${index}`, originalCreate);
|
|
22128
22356
|
const tracer = this.tracer;
|
|
22129
22357
|
const wrapper = embeddingsWrapper2(tracer);
|
|
22130
22358
|
EmbeddingsClass.prototype.create = function(...args) {
|
|
@@ -22145,14 +22373,14 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22145
22373
|
return false;
|
|
22146
22374
|
}
|
|
22147
22375
|
}
|
|
22148
|
-
_instrumentFIM(Mistral) {
|
|
22376
|
+
_instrumentFIM(Mistral, index) {
|
|
22149
22377
|
if (!this.tracer) return false;
|
|
22150
22378
|
try {
|
|
22151
22379
|
const FimClass = this._getCtor(Mistral, "fim");
|
|
22152
22380
|
let didPatch = false;
|
|
22153
22381
|
if (FimClass?.prototype?.complete) {
|
|
22154
22382
|
const originalComplete = FimClass.prototype.complete;
|
|
22155
|
-
originalMethods4.set(
|
|
22383
|
+
originalMethods4.set(`fim.complete-${index}`, originalComplete);
|
|
22156
22384
|
const tracer = this.tracer;
|
|
22157
22385
|
const wrapper = fimWrapper(tracer);
|
|
22158
22386
|
FimClass.prototype.complete = function(...args) {
|
|
@@ -22169,7 +22397,7 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22169
22397
|
}
|
|
22170
22398
|
if (FimClass?.prototype?.stream) {
|
|
22171
22399
|
const originalStream = FimClass.prototype.stream;
|
|
22172
|
-
originalMethods4.set(
|
|
22400
|
+
originalMethods4.set(`fim.stream-${index}`, originalStream);
|
|
22173
22401
|
const tracer = this.tracer;
|
|
22174
22402
|
const wrapper = fimStreamWrapper(tracer);
|
|
22175
22403
|
FimClass.prototype.stream = function(...args) {
|
|
@@ -22190,14 +22418,14 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22190
22418
|
return false;
|
|
22191
22419
|
}
|
|
22192
22420
|
}
|
|
22193
|
-
_instrumentAgents(Mistral) {
|
|
22421
|
+
_instrumentAgents(Mistral, index) {
|
|
22194
22422
|
if (!this.tracer) return false;
|
|
22195
22423
|
try {
|
|
22196
22424
|
const AgentsClass = this._getCtor(Mistral, "agents");
|
|
22197
22425
|
let didPatch = false;
|
|
22198
22426
|
if (AgentsClass?.prototype?.complete) {
|
|
22199
22427
|
const originalComplete = AgentsClass.prototype.complete;
|
|
22200
|
-
originalMethods4.set(
|
|
22428
|
+
originalMethods4.set(`agents.complete-${index}`, originalComplete);
|
|
22201
22429
|
const tracer = this.tracer;
|
|
22202
22430
|
const wrapper = agentsWrapper(tracer);
|
|
22203
22431
|
AgentsClass.prototype.complete = function(...args) {
|
|
@@ -22214,7 +22442,7 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22214
22442
|
}
|
|
22215
22443
|
if (AgentsClass?.prototype?.stream) {
|
|
22216
22444
|
const originalStream = AgentsClass.prototype.stream;
|
|
22217
|
-
originalMethods4.set(
|
|
22445
|
+
originalMethods4.set(`agents.stream-${index}`, originalStream);
|
|
22218
22446
|
const tracer = this.tracer;
|
|
22219
22447
|
const wrapper = agentsStreamWrapper(tracer);
|
|
22220
22448
|
AgentsClass.prototype.stream = function(...args) {
|
|
@@ -22235,14 +22463,14 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22235
22463
|
return false;
|
|
22236
22464
|
}
|
|
22237
22465
|
}
|
|
22238
|
-
_uninstrumentChat(Mistral) {
|
|
22466
|
+
_uninstrumentChat(Mistral, index) {
|
|
22239
22467
|
try {
|
|
22240
22468
|
const ChatClass = this._getCtor(Mistral, "chat");
|
|
22241
|
-
const originalComplete = originalMethods4.get(
|
|
22469
|
+
const originalComplete = originalMethods4.get(`chat.complete-${index}`);
|
|
22242
22470
|
if (originalComplete && ChatClass?.prototype) {
|
|
22243
22471
|
ChatClass.prototype.complete = originalComplete;
|
|
22244
22472
|
}
|
|
22245
|
-
const originalStream = originalMethods4.get(
|
|
22473
|
+
const originalStream = originalMethods4.get(`chat.stream-${index}`);
|
|
22246
22474
|
if (originalStream && ChatClass?.prototype) {
|
|
22247
22475
|
ChatClass.prototype.stream = originalStream;
|
|
22248
22476
|
}
|
|
@@ -22250,10 +22478,10 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22250
22478
|
Logger.error(`Failed to uninstrument MistralAI chat: ${error}`);
|
|
22251
22479
|
}
|
|
22252
22480
|
}
|
|
22253
|
-
_uninstrumentEmbeddings(Mistral) {
|
|
22481
|
+
_uninstrumentEmbeddings(Mistral, index) {
|
|
22254
22482
|
try {
|
|
22255
22483
|
const EmbeddingsClass = this._getCtor(Mistral, "embeddings");
|
|
22256
|
-
const originalCreate = originalMethods4.get(
|
|
22484
|
+
const originalCreate = originalMethods4.get(`embeddings.create-${index}`);
|
|
22257
22485
|
if (originalCreate && EmbeddingsClass?.prototype) {
|
|
22258
22486
|
EmbeddingsClass.prototype.create = originalCreate;
|
|
22259
22487
|
}
|
|
@@ -22261,14 +22489,14 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22261
22489
|
Logger.error(`Failed to uninstrument MistralAI embeddings: ${error}`);
|
|
22262
22490
|
}
|
|
22263
22491
|
}
|
|
22264
|
-
_uninstrumentFIM(Mistral) {
|
|
22492
|
+
_uninstrumentFIM(Mistral, index) {
|
|
22265
22493
|
try {
|
|
22266
22494
|
const FimClass = this._getCtor(Mistral, "fim");
|
|
22267
|
-
const originalComplete = originalMethods4.get(
|
|
22495
|
+
const originalComplete = originalMethods4.get(`fim.complete-${index}`);
|
|
22268
22496
|
if (originalComplete && FimClass?.prototype) {
|
|
22269
22497
|
FimClass.prototype.complete = originalComplete;
|
|
22270
22498
|
}
|
|
22271
|
-
const originalStream = originalMethods4.get(
|
|
22499
|
+
const originalStream = originalMethods4.get(`fim.stream-${index}`);
|
|
22272
22500
|
if (originalStream && FimClass?.prototype) {
|
|
22273
22501
|
FimClass.prototype.stream = originalStream;
|
|
22274
22502
|
}
|
|
@@ -22276,14 +22504,14 @@ var NetraMistralAIInstrumentor = class {
|
|
|
22276
22504
|
Logger.error(`Failed to uninstrument MistralAI FIM: ${error}`);
|
|
22277
22505
|
}
|
|
22278
22506
|
}
|
|
22279
|
-
_uninstrumentAgents(Mistral) {
|
|
22507
|
+
_uninstrumentAgents(Mistral, index) {
|
|
22280
22508
|
try {
|
|
22281
22509
|
const AgentsClass = this._getCtor(Mistral, "agents");
|
|
22282
|
-
const originalComplete = originalMethods4.get(
|
|
22510
|
+
const originalComplete = originalMethods4.get(`agents.complete-${index}`);
|
|
22283
22511
|
if (originalComplete && AgentsClass?.prototype) {
|
|
22284
22512
|
AgentsClass.prototype.complete = originalComplete;
|
|
22285
22513
|
}
|
|
22286
|
-
const originalStream = originalMethods4.get(
|
|
22514
|
+
const originalStream = originalMethods4.get(`agents.stream-${index}`);
|
|
22287
22515
|
if (originalStream && AgentsClass?.prototype) {
|
|
22288
22516
|
AgentsClass.prototype.stream = originalStream;
|
|
22289
22517
|
}
|
|
@@ -24536,14 +24764,14 @@ function initOpenTelemetryInstrumentations(config2, resolved, blockInstruments)
|
|
|
24536
24764
|
netraHost = new URL(config2.otlpEndpoint).host;
|
|
24537
24765
|
}
|
|
24538
24766
|
} catch {
|
|
24539
|
-
|
|
24767
|
+
Logger.debug(`OTEL_NODE_EXCLUDED_URLS: malformed otlpEndpoint '${config2.otlpEndpoint}', skipping host-based exclusion`);
|
|
24540
24768
|
}
|
|
24541
24769
|
const excludeRegexes = (process.env.OTEL_NODE_EXCLUDED_URLS || "").split(",").map((s) => s.trim()).filter(Boolean).map((pattern) => {
|
|
24542
24770
|
try {
|
|
24543
24771
|
return new RegExp(pattern);
|
|
24544
24772
|
} catch {
|
|
24545
24773
|
if (config2.debugMode) {
|
|
24546
|
-
|
|
24774
|
+
Logger.debug(
|
|
24547
24775
|
`Invalid OTEL_NODE_EXCLUDED_URLS pattern skipped: ${pattern}`
|
|
24548
24776
|
);
|
|
24549
24777
|
}
|
|
@@ -24585,11 +24813,11 @@ function initOpenTelemetryInstrumentations(config2, resolved, blockInstruments)
|
|
|
24585
24813
|
});
|
|
24586
24814
|
registerInstrumentations({ instrumentations: [_undiciInstrumentation] });
|
|
24587
24815
|
if (config2.debugMode) {
|
|
24588
|
-
|
|
24816
|
+
Logger.debug("Undici/fetch instrumentation enabled");
|
|
24589
24817
|
}
|
|
24590
24818
|
} catch (e) {
|
|
24591
24819
|
if (config2.debugMode) {
|
|
24592
|
-
|
|
24820
|
+
Logger.debug("Undici/fetch instrumentation not available:", e);
|
|
24593
24821
|
}
|
|
24594
24822
|
}
|
|
24595
24823
|
}
|
|
@@ -24754,22 +24982,145 @@ async function uninstrumentAll() {
|
|
|
24754
24982
|
if (_httpInstrumentation) {
|
|
24755
24983
|
_httpInstrumentation.disable();
|
|
24756
24984
|
_httpInstrumentation = null;
|
|
24757
|
-
|
|
24985
|
+
Logger.debug("HTTP instrumentation disabled");
|
|
24758
24986
|
}
|
|
24759
24987
|
} catch (e) {
|
|
24760
|
-
|
|
24988
|
+
Logger.debug("Failed to uninstrument HTTP:", e);
|
|
24761
24989
|
}
|
|
24762
24990
|
try {
|
|
24763
24991
|
if (_undiciInstrumentation) {
|
|
24764
24992
|
_undiciInstrumentation.disable();
|
|
24765
24993
|
_undiciInstrumentation = null;
|
|
24766
|
-
|
|
24994
|
+
Logger.debug("Undici/fetch instrumentation disabled");
|
|
24767
24995
|
}
|
|
24768
24996
|
} catch (e) {
|
|
24769
|
-
|
|
24997
|
+
Logger.debug("Failed to uninstrument undici:", e);
|
|
24770
24998
|
}
|
|
24771
24999
|
}
|
|
25000
|
+
|
|
25001
|
+
// src/simulation/task.ts
|
|
25002
|
+
var BaseTask = class {
|
|
25003
|
+
};
|
|
25004
|
+
|
|
25005
|
+
// src/simulation/utils.ts
|
|
24772
25006
|
var LOG_PREFIX = "netra.simulation";
|
|
25007
|
+
var DEFAULT_FILE_DOWNLOAD_TIMEOUT_S = 30;
|
|
25008
|
+
var MAX_FILE_DOWNLOAD_WORKERS = 8;
|
|
25009
|
+
var _cachedFileDownloadTimeoutMs = null;
|
|
25010
|
+
function validateSimulationInputs(datasetId, task2) {
|
|
25011
|
+
if (!datasetId) {
|
|
25012
|
+
Logger.error(`${LOG_PREFIX}: dataset_id is required`);
|
|
25013
|
+
return false;
|
|
25014
|
+
}
|
|
25015
|
+
if (!(task2 instanceof BaseTask)) {
|
|
25016
|
+
Logger.error(`${LOG_PREFIX}: task must be a BaseTask instance`);
|
|
25017
|
+
return false;
|
|
25018
|
+
}
|
|
25019
|
+
return true;
|
|
25020
|
+
}
|
|
25021
|
+
function _getFileDownloadTimeout() {
|
|
25022
|
+
if (_cachedFileDownloadTimeoutMs !== null) {
|
|
25023
|
+
return _cachedFileDownloadTimeoutMs;
|
|
25024
|
+
}
|
|
25025
|
+
const envVal = process.env.NETRA_SIMULATION_FILE_DOWNLOAD_TIMEOUT;
|
|
25026
|
+
if (envVal) {
|
|
25027
|
+
const parsed = parseFloat(envVal);
|
|
25028
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
25029
|
+
_cachedFileDownloadTimeoutMs = parsed * 1e3;
|
|
25030
|
+
return _cachedFileDownloadTimeoutMs;
|
|
25031
|
+
}
|
|
25032
|
+
Logger.warn(
|
|
25033
|
+
`${LOG_PREFIX}: Invalid file download timeout '${envVal}', using default ${DEFAULT_FILE_DOWNLOAD_TIMEOUT_S}s`
|
|
25034
|
+
);
|
|
25035
|
+
}
|
|
25036
|
+
_cachedFileDownloadTimeoutMs = DEFAULT_FILE_DOWNLOAD_TIMEOUT_S * 1e3;
|
|
25037
|
+
return _cachedFileDownloadTimeoutMs;
|
|
25038
|
+
}
|
|
25039
|
+
async function _downloadSingleFile(fileData, timeoutMs, signal) {
|
|
25040
|
+
try {
|
|
25041
|
+
const response = await axios__default.default.get(fileData.downloadUrl, {
|
|
25042
|
+
responseType: "arraybuffer",
|
|
25043
|
+
timeout: timeoutMs,
|
|
25044
|
+
signal
|
|
25045
|
+
});
|
|
25046
|
+
const encoded = Buffer.from(response.data).toString("base64");
|
|
25047
|
+
return {
|
|
25048
|
+
fileName: fileData.fileName,
|
|
25049
|
+
contentType: fileData.contentType,
|
|
25050
|
+
description: fileData.description,
|
|
25051
|
+
data: encoded
|
|
25052
|
+
};
|
|
25053
|
+
} catch (error) {
|
|
25054
|
+
if (axios__default.default.isCancel(error)) {
|
|
25055
|
+
throw new Error(
|
|
25056
|
+
`Download of '${fileData.fileName}' was cancelled`
|
|
25057
|
+
);
|
|
25058
|
+
}
|
|
25059
|
+
const status = axios__default.default.isAxiosError(error) ? error.response?.status : void 0;
|
|
25060
|
+
const reason = status ? `HTTP ${status}` : error instanceof Error ? error.message : String(error);
|
|
25061
|
+
Logger.error(
|
|
25062
|
+
`${LOG_PREFIX}: Failed to download file '${fileData.fileName}': ${reason}`
|
|
25063
|
+
);
|
|
25064
|
+
throw new Error(
|
|
25065
|
+
`Failed to download file '${fileData.fileName}': ${reason}`
|
|
25066
|
+
);
|
|
25067
|
+
}
|
|
25068
|
+
}
|
|
25069
|
+
function parseFiles(rawFiles) {
|
|
25070
|
+
if (!rawFiles) {
|
|
25071
|
+
return [];
|
|
25072
|
+
}
|
|
25073
|
+
const parsed = [];
|
|
25074
|
+
for (const entry of rawFiles) {
|
|
25075
|
+
const fileName = entry.fileName || "";
|
|
25076
|
+
const downloadUrl = entry.downloadUrl || "";
|
|
25077
|
+
if (!fileName || !downloadUrl) {
|
|
25078
|
+
Logger.warn(
|
|
25079
|
+
`${LOG_PREFIX}: Skipping malformed file attachment (missing fileName or downloadUrl)`
|
|
25080
|
+
);
|
|
25081
|
+
continue;
|
|
25082
|
+
}
|
|
25083
|
+
parsed.push({
|
|
25084
|
+
fileName,
|
|
25085
|
+
contentType: entry.contentType || "",
|
|
25086
|
+
description: entry.description || void 0,
|
|
25087
|
+
downloadUrl
|
|
25088
|
+
});
|
|
25089
|
+
}
|
|
25090
|
+
return parsed;
|
|
25091
|
+
}
|
|
25092
|
+
async function processFiles(files) {
|
|
25093
|
+
if (!files || files.length === 0) {
|
|
25094
|
+
return null;
|
|
25095
|
+
}
|
|
25096
|
+
const timeoutMs = _getFileDownloadTimeout();
|
|
25097
|
+
const limit = pLimit__default.default(MAX_FILE_DOWNLOAD_WORKERS);
|
|
25098
|
+
const controller = new AbortController();
|
|
25099
|
+
const downloadPromises = files.map(
|
|
25100
|
+
(file) => limit(() => _downloadSingleFile(file, timeoutMs, controller.signal))
|
|
25101
|
+
);
|
|
25102
|
+
try {
|
|
25103
|
+
return await Promise.all(downloadPromises);
|
|
25104
|
+
} catch (error) {
|
|
25105
|
+
controller.abort();
|
|
25106
|
+
limit.clearQueue();
|
|
25107
|
+
throw error;
|
|
25108
|
+
}
|
|
25109
|
+
}
|
|
25110
|
+
async function executeTask2(task2, message, sessionId, rawFiles) {
|
|
25111
|
+
const processedFiles = rawFiles && rawFiles.length > 0 ? await processFiles(rawFiles) : null;
|
|
25112
|
+
const result = task2.run(message, sessionId, processedFiles);
|
|
25113
|
+
const resolvedResult = result instanceof Promise ? await result : result;
|
|
25114
|
+
if (typeof resolvedResult === "object" && resolvedResult !== null && "message" in resolvedResult && "sessionId" in resolvedResult) {
|
|
25115
|
+
return [resolvedResult.message, resolvedResult.sessionId];
|
|
25116
|
+
}
|
|
25117
|
+
throw new Error(
|
|
25118
|
+
`Task must return TaskResult, got ${typeof resolvedResult}`
|
|
25119
|
+
);
|
|
25120
|
+
}
|
|
25121
|
+
|
|
25122
|
+
// src/simulation/client.ts
|
|
25123
|
+
var LOG_PREFIX2 = "netra.simulation";
|
|
24773
25124
|
var DEFAULT_TIMEOUT = 1e4;
|
|
24774
25125
|
var SimulationHttpClient = class {
|
|
24775
25126
|
constructor(config2) {
|
|
@@ -24782,20 +25133,29 @@ var SimulationHttpClient = class {
|
|
|
24782
25133
|
_createClient(config2) {
|
|
24783
25134
|
const endpoint = (config2.otlpEndpoint || "").trim();
|
|
24784
25135
|
if (!endpoint) {
|
|
24785
|
-
Logger.error(`${
|
|
25136
|
+
Logger.error(`${LOG_PREFIX2}: NETRA_OTLP_ENDPOINT is required`);
|
|
24786
25137
|
return null;
|
|
24787
25138
|
}
|
|
24788
25139
|
const baseURL = this._resolveBaseUrl(endpoint);
|
|
24789
25140
|
const headers = this._buildHeaders(config2);
|
|
24790
25141
|
const timeout = this._getTimeout();
|
|
24791
25142
|
try {
|
|
24792
|
-
|
|
25143
|
+
const instance = axios__default.default.create({
|
|
24793
25144
|
baseURL,
|
|
24794
25145
|
headers,
|
|
24795
25146
|
timeout
|
|
24796
25147
|
});
|
|
25148
|
+
instance.interceptors.request.use(
|
|
25149
|
+
(config3) => {
|
|
25150
|
+
const traceHeaders = injectTraceContextHeaders({});
|
|
25151
|
+
Object.assign(config3.headers, traceHeaders);
|
|
25152
|
+
return config3;
|
|
25153
|
+
},
|
|
25154
|
+
(error) => Promise.reject(error)
|
|
25155
|
+
);
|
|
25156
|
+
return instance;
|
|
24797
25157
|
} catch (error) {
|
|
24798
|
-
Logger.error(`${
|
|
25158
|
+
Logger.error(`${LOG_PREFIX2}: Failed to create HTTP client:`, error);
|
|
24799
25159
|
return null;
|
|
24800
25160
|
}
|
|
24801
25161
|
}
|
|
@@ -24830,7 +25190,7 @@ var SimulationHttpClient = class {
|
|
|
24830
25190
|
const timeout = parseFloat(timeoutStr);
|
|
24831
25191
|
if (isNaN(timeout)) {
|
|
24832
25192
|
Logger.warn(
|
|
24833
|
-
`${
|
|
25193
|
+
`${LOG_PREFIX2}: Invalid timeout '${timeoutStr}', using default ${DEFAULT_TIMEOUT}ms`
|
|
24834
25194
|
);
|
|
24835
25195
|
return DEFAULT_TIMEOUT;
|
|
24836
25196
|
}
|
|
@@ -24839,9 +25199,9 @@ var SimulationHttpClient = class {
|
|
|
24839
25199
|
/**
|
|
24840
25200
|
* Create a new simulation run for the specified dataset.
|
|
24841
25201
|
*/
|
|
24842
|
-
async createRun(name, datasetId,
|
|
25202
|
+
async createRun(name, datasetId, context17) {
|
|
24843
25203
|
if (!this.client) {
|
|
24844
|
-
Logger.error(`${
|
|
25204
|
+
Logger.error(`${LOG_PREFIX2}: Client not initialized`);
|
|
24845
25205
|
return null;
|
|
24846
25206
|
}
|
|
24847
25207
|
try {
|
|
@@ -24849,14 +25209,14 @@ var SimulationHttpClient = class {
|
|
|
24849
25209
|
const payload = {
|
|
24850
25210
|
name,
|
|
24851
25211
|
datasetId,
|
|
24852
|
-
context:
|
|
25212
|
+
context: context17 || {}
|
|
24853
25213
|
};
|
|
24854
25214
|
const response = await this.client.post(url, payload);
|
|
24855
25215
|
const data = response.data;
|
|
24856
25216
|
const responseData = data.data || {};
|
|
24857
25217
|
const userMessages = responseData.userMessages || [];
|
|
24858
25218
|
if (userMessages.length === 0) {
|
|
24859
|
-
Logger.warn(`${
|
|
25219
|
+
Logger.warn(`${LOG_PREFIX2}: No user messages returned from create_run`);
|
|
24860
25220
|
return null;
|
|
24861
25221
|
}
|
|
24862
25222
|
const runId = responseData.id || "";
|
|
@@ -24864,7 +25224,8 @@ var SimulationHttpClient = class {
|
|
|
24864
25224
|
(msg) => ({
|
|
24865
25225
|
runItemId: msg.testRunItemId || "",
|
|
24866
25226
|
message: msg.userMessage || "",
|
|
24867
|
-
turnId: msg.turnId || ""
|
|
25227
|
+
turnId: msg.turnId || "",
|
|
25228
|
+
files: parseFiles(msg.attachments)
|
|
24868
25229
|
})
|
|
24869
25230
|
);
|
|
24870
25231
|
return {
|
|
@@ -24873,7 +25234,7 @@ var SimulationHttpClient = class {
|
|
|
24873
25234
|
};
|
|
24874
25235
|
} catch (error) {
|
|
24875
25236
|
const errorMsg = this._extractErrorMessage(error);
|
|
24876
|
-
Logger.error(`${
|
|
25237
|
+
Logger.error(`${LOG_PREFIX2}: Failed to create simulation run:`, errorMsg);
|
|
24877
25238
|
return null;
|
|
24878
25239
|
}
|
|
24879
25240
|
}
|
|
@@ -24882,7 +25243,7 @@ var SimulationHttpClient = class {
|
|
|
24882
25243
|
*/
|
|
24883
25244
|
async triggerConversation(message, turnId, sessionId, traceId) {
|
|
24884
25245
|
if (!this.client) {
|
|
24885
|
-
Logger.error(`${
|
|
25246
|
+
Logger.error(`${LOG_PREFIX2}: Client not initialized`);
|
|
24886
25247
|
return null;
|
|
24887
25248
|
}
|
|
24888
25249
|
try {
|
|
@@ -24905,7 +25266,7 @@ var SimulationHttpClient = class {
|
|
|
24905
25266
|
}
|
|
24906
25267
|
const userMessages = responseData.userMessages || [];
|
|
24907
25268
|
if (userMessages.length === 0) {
|
|
24908
|
-
Logger.warn(`${
|
|
25269
|
+
Logger.warn(`${LOG_PREFIX2}: No user messages in continue response`);
|
|
24909
25270
|
return null;
|
|
24910
25271
|
}
|
|
24911
25272
|
const nextMsg = userMessages[0];
|
|
@@ -24913,11 +25274,12 @@ var SimulationHttpClient = class {
|
|
|
24913
25274
|
decision,
|
|
24914
25275
|
nextTurnId: nextMsg.turnId || "",
|
|
24915
25276
|
nextUserMessage: nextMsg.userMessage || "",
|
|
24916
|
-
nextRunItemId: nextMsg.testRunItemId || ""
|
|
25277
|
+
nextRunItemId: nextMsg.testRunItemId || "",
|
|
25278
|
+
nextFiles: parseFiles(nextMsg.attachments)
|
|
24917
25279
|
};
|
|
24918
25280
|
} catch (error) {
|
|
24919
25281
|
const errorMsg = this._extractErrorMessage(error);
|
|
24920
|
-
Logger.error(`${
|
|
25282
|
+
Logger.error(`${LOG_PREFIX2}: Failed to trigger conversation:`, errorMsg);
|
|
24921
25283
|
return null;
|
|
24922
25284
|
}
|
|
24923
25285
|
}
|
|
@@ -24926,17 +25288,17 @@ var SimulationHttpClient = class {
|
|
|
24926
25288
|
*/
|
|
24927
25289
|
async reportFailure(runId, runItemId, error) {
|
|
24928
25290
|
if (!this.client) {
|
|
24929
|
-
Logger.error(`${
|
|
25291
|
+
Logger.error(`${LOG_PREFIX2}: Client not initialized`);
|
|
24930
25292
|
return;
|
|
24931
25293
|
}
|
|
24932
25294
|
try {
|
|
24933
25295
|
const url = `/evaluations/run/${runId}/item/${runItemId}/status`;
|
|
24934
25296
|
const payload = { status: "failed", failureReason: error };
|
|
24935
25297
|
await this.client.patch(url, payload);
|
|
24936
|
-
Logger.info(`${
|
|
25298
|
+
Logger.info(`${LOG_PREFIX2}: Reported failure - ${error}`);
|
|
24937
25299
|
} catch (err) {
|
|
24938
25300
|
const errorMsg = this._extractErrorMessage(err);
|
|
24939
|
-
Logger.error(`${
|
|
25301
|
+
Logger.error(`${LOG_PREFIX2}: Failed to report failure:`, errorMsg);
|
|
24940
25302
|
}
|
|
24941
25303
|
}
|
|
24942
25304
|
/**
|
|
@@ -24945,7 +25307,7 @@ var SimulationHttpClient = class {
|
|
|
24945
25307
|
async postRunStatus(runId, status) {
|
|
24946
25308
|
if (!this.client) {
|
|
24947
25309
|
Logger.error(
|
|
24948
|
-
`${
|
|
25310
|
+
`${LOG_PREFIX2}: Client not initialized; cannot post run status`
|
|
24949
25311
|
);
|
|
24950
25312
|
return { success: false };
|
|
24951
25313
|
}
|
|
@@ -24955,14 +25317,14 @@ var SimulationHttpClient = class {
|
|
|
24955
25317
|
const response = await this.client.post(url, payload);
|
|
24956
25318
|
const data = response.data;
|
|
24957
25319
|
if (data && typeof data === "object" && "data" in data) {
|
|
24958
|
-
Logger.info(`${
|
|
25320
|
+
Logger.info(`${LOG_PREFIX2}: Completed test run successfully`);
|
|
24959
25321
|
return data.data || {};
|
|
24960
25322
|
}
|
|
24961
25323
|
return data;
|
|
24962
25324
|
} catch (error) {
|
|
24963
25325
|
const errorMsg = this._extractErrorMessage(error);
|
|
24964
25326
|
Logger.error(
|
|
24965
|
-
`${
|
|
25327
|
+
`${LOG_PREFIX2}: Failed to post run status for run '${runId}':`,
|
|
24966
25328
|
errorMsg
|
|
24967
25329
|
);
|
|
24968
25330
|
return { success: false };
|
|
@@ -24986,34 +25348,6 @@ var SimulationHttpClient = class {
|
|
|
24986
25348
|
}
|
|
24987
25349
|
};
|
|
24988
25350
|
|
|
24989
|
-
// src/simulation/task.ts
|
|
24990
|
-
var BaseTask = class {
|
|
24991
|
-
};
|
|
24992
|
-
|
|
24993
|
-
// src/simulation/utils.ts
|
|
24994
|
-
var LOG_PREFIX2 = "netra.simulation";
|
|
24995
|
-
function validateSimulationInputs(datasetId, task2) {
|
|
24996
|
-
if (!datasetId) {
|
|
24997
|
-
Logger.error(`${LOG_PREFIX2}: dataset_id is required`);
|
|
24998
|
-
return false;
|
|
24999
|
-
}
|
|
25000
|
-
if (!(task2 instanceof BaseTask)) {
|
|
25001
|
-
Logger.error(`${LOG_PREFIX2}: task must be a BaseTask instance`);
|
|
25002
|
-
return false;
|
|
25003
|
-
}
|
|
25004
|
-
return true;
|
|
25005
|
-
}
|
|
25006
|
-
async function executeTask2(task2, message, sessionId) {
|
|
25007
|
-
const result = task2.run(message, sessionId);
|
|
25008
|
-
const resolvedResult = result instanceof Promise ? await result : result;
|
|
25009
|
-
if (typeof resolvedResult === "object" && resolvedResult !== null && "message" in resolvedResult && "sessionId" in resolvedResult) {
|
|
25010
|
-
return [resolvedResult.message, resolvedResult.sessionId];
|
|
25011
|
-
}
|
|
25012
|
-
throw new Error(
|
|
25013
|
-
`Task must return TaskResult, got ${typeof resolvedResult}`
|
|
25014
|
-
);
|
|
25015
|
-
}
|
|
25016
|
-
|
|
25017
25351
|
// src/simulation/api.ts
|
|
25018
25352
|
var LOG_PREFIX3 = "netra.simulation";
|
|
25019
25353
|
var SPAN_NAME = "Netra.Simulation.TestRun";
|
|
@@ -25033,14 +25367,14 @@ var Simulation = class {
|
|
|
25033
25367
|
name,
|
|
25034
25368
|
datasetId,
|
|
25035
25369
|
task: task2,
|
|
25036
|
-
context:
|
|
25370
|
+
context: context17,
|
|
25037
25371
|
maxConcurrency = 5
|
|
25038
25372
|
} = options;
|
|
25039
25373
|
if (!validateSimulationInputs(datasetId, task2)) {
|
|
25040
25374
|
return null;
|
|
25041
25375
|
}
|
|
25042
25376
|
const startTime = Date.now();
|
|
25043
|
-
const runResult = await this._client.createRun(name, datasetId,
|
|
25377
|
+
const runResult = await this._client.createRun(name, datasetId, context17);
|
|
25044
25378
|
if (!runResult) {
|
|
25045
25379
|
return null;
|
|
25046
25380
|
}
|
|
@@ -25147,29 +25481,29 @@ var Simulation = class {
|
|
|
25147
25481
|
* Execute a multi-turn conversation for a single simulation item.
|
|
25148
25482
|
*/
|
|
25149
25483
|
async _executeConversation(runId, runItem, task2) {
|
|
25150
|
-
const { runItemId, message: initialMessage, turnId: initialTurnId } = runItem;
|
|
25484
|
+
const { runItemId, message: initialMessage, turnId: initialTurnId, files: initialFiles } = runItem;
|
|
25151
25485
|
let message = initialMessage;
|
|
25152
25486
|
let turnId = initialTurnId;
|
|
25153
25487
|
let sessionId = null;
|
|
25488
|
+
let rawFiles = initialFiles ?? [];
|
|
25154
25489
|
while (true) {
|
|
25490
|
+
const span2 = new SpanWrapper(SPAN_NAME, {}, LOG_PREFIX3);
|
|
25491
|
+
span2.start();
|
|
25155
25492
|
try {
|
|
25156
|
-
const span2 = new SpanWrapper(SPAN_NAME, {}, LOG_PREFIX3);
|
|
25157
|
-
span2.start();
|
|
25158
25493
|
const traceId = span2.getCurrentSpan()?.spanContext().traceId ?? "";
|
|
25159
|
-
const [responseMessage, taskSessionId] = await
|
|
25160
|
-
task2,
|
|
25161
|
-
message,
|
|
25162
|
-
sessionId
|
|
25494
|
+
const [responseMessage, taskSessionId] = await span2.withActive(
|
|
25495
|
+
() => executeTask2(task2, message, sessionId, rawFiles)
|
|
25163
25496
|
);
|
|
25164
25497
|
if (taskSessionId) {
|
|
25165
25498
|
sessionId = taskSessionId;
|
|
25166
25499
|
}
|
|
25167
|
-
span2.
|
|
25168
|
-
|
|
25169
|
-
|
|
25170
|
-
|
|
25171
|
-
|
|
25172
|
-
|
|
25500
|
+
const response = await span2.withActive(
|
|
25501
|
+
() => this._client.triggerConversation(
|
|
25502
|
+
responseMessage,
|
|
25503
|
+
turnId,
|
|
25504
|
+
sessionId || "",
|
|
25505
|
+
traceId
|
|
25506
|
+
)
|
|
25173
25507
|
);
|
|
25174
25508
|
if (response === null) {
|
|
25175
25509
|
const errorMsg = "Failed to get conversation response";
|
|
@@ -25192,6 +25526,7 @@ var Simulation = class {
|
|
|
25192
25526
|
}
|
|
25193
25527
|
message = response.nextUserMessage;
|
|
25194
25528
|
turnId = response.nextTurnId;
|
|
25529
|
+
rawFiles = response.nextFiles || [];
|
|
25195
25530
|
} catch (error) {
|
|
25196
25531
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
25197
25532
|
Logger.error(
|
|
@@ -25204,6 +25539,8 @@ var Simulation = class {
|
|
|
25204
25539
|
error: errorMsg,
|
|
25205
25540
|
turnId
|
|
25206
25541
|
};
|
|
25542
|
+
} finally {
|
|
25543
|
+
span2.end();
|
|
25207
25544
|
}
|
|
25208
25545
|
}
|
|
25209
25546
|
}
|
|
@@ -25787,7 +26124,9 @@ exports.agent = agent;
|
|
|
25787
26124
|
exports.default = index_default;
|
|
25788
26125
|
exports.metadataField = metadataField;
|
|
25789
26126
|
exports.mistralAIInstrumentor = mistralAIInstrumentor;
|
|
26127
|
+
exports.netraExpressMiddleware = netraExpressMiddleware;
|
|
25790
26128
|
exports.openaiAgentsInstrumentor = openaiAgentsInstrumentor;
|
|
26129
|
+
exports.runWithExtractedContext = runWithExtractedContext;
|
|
25791
26130
|
exports.span = span;
|
|
25792
26131
|
exports.task = task;
|
|
25793
26132
|
exports.workflow = workflow;
|