@lmnr-ai/lmnr 0.8.44 → 0.8.45
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/cli.cjs +23 -25
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +1 -1
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +7 -8
- package/dist/cli.mjs.map +1 -1
- package/dist/{evaluations-RbBZb5yl.d.cts → evaluations-BHEE6fmA.d.cts} +17934 -8631
- package/dist/{evaluations-CVo0ms_r.d.mts → evaluations-BbIIQMLr.d.mts} +17934 -8631
- package/dist/{file-utils-1olUHMKC.mjs → file-utils-BtzEDUy6.mjs} +2 -2
- package/dist/file-utils-BtzEDUy6.mjs.map +1 -0
- package/dist/{file-utils-CMO5MuV9.cjs → file-utils-pZG20hHb.cjs} +6 -6
- package/dist/file-utils-pZG20hHb.cjs.map +1 -0
- package/dist/index.cjs +574 -435
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1533 -437
- package/dist/index.d.mts +1533 -437
- package/dist/index.mjs +287 -148
- package/dist/index.mjs.map +1 -1
- package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.cjs +159 -62
- package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.cjs.map +1 -1
- package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.d.cts +3388 -250
- package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.d.mts +3388 -250
- package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.mjs +159 -62
- package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.mjs.map +1 -1
- package/dist/{dist-BtB31bk1.cjs → utils-CatgN6Pb.cjs} +558 -558
- package/dist/utils-CatgN6Pb.cjs.map +1 -0
- package/dist/{dist-Cjres0a5.mjs → utils-UmlDPMxe.mjs} +552 -552
- package/dist/utils-UmlDPMxe.mjs.map +1 -0
- package/package.json +30 -30
- package/dist/dist-BtB31bk1.cjs.map +0 -1
- package/dist/dist-Cjres0a5.mjs.map +0 -1
- package/dist/file-utils-1olUHMKC.mjs.map +0 -1
- package/dist/file-utils-CMO5MuV9.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rolldown_runtime = require("./rolldown-runtime-CVvi-lCc.cjs");
|
|
3
|
-
const
|
|
3
|
+
const require_utils = require("./utils-CatgN6Pb.cjs");
|
|
4
4
|
const require_consts = require("./consts-9rSS0oeR.cjs");
|
|
5
|
+
let path = require("path");
|
|
6
|
+
path = require_rolldown_runtime.__toESM(path);
|
|
5
7
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
6
8
|
let _opentelemetry_context_async_hooks = require("@opentelemetry/context-async-hooks");
|
|
7
9
|
let _opentelemetry_instrumentation = require("@opentelemetry/instrumentation");
|
|
8
10
|
let _opentelemetry_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
9
11
|
let _opentelemetry_sdk_trace_node = require("@opentelemetry/sdk-trace-node");
|
|
10
12
|
let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
11
|
-
let path = require("path");
|
|
12
|
-
path = require_rolldown_runtime.__toESM(path);
|
|
13
13
|
let _traceloop_instrumentation_anthropic = require("@traceloop/instrumentation-anthropic");
|
|
14
14
|
let _traceloop_instrumentation_bedrock = require("@traceloop/instrumentation-bedrock");
|
|
15
15
|
let _traceloop_instrumentation_chromadb = require("@traceloop/instrumentation-chromadb");
|
|
@@ -183,7 +183,7 @@ var LaminarDataset = class extends EvaluationDataset {
|
|
|
183
183
|
*/
|
|
184
184
|
async push(paths, recursive = false) {
|
|
185
185
|
if (!this.client) throw new Error("Client not set");
|
|
186
|
-
const { loadFromPaths } = await Promise.resolve().then(() => require("./file-utils-
|
|
186
|
+
const { loadFromPaths } = await Promise.resolve().then(() => require("./file-utils-pZG20hHb.cjs")).then((n) => n.file_utils_exports);
|
|
187
187
|
const data = await loadFromPaths(Array.isArray(paths) ? paths : [paths], recursive);
|
|
188
188
|
if (data.length === 0) {
|
|
189
189
|
console.warn("No data to push. Skipping");
|
|
@@ -199,7 +199,7 @@ var LaminarDataset = class extends EvaluationDataset {
|
|
|
199
199
|
};
|
|
200
200
|
//#endregion
|
|
201
201
|
//#region src/opentelemetry-lib/tracing/compat.ts
|
|
202
|
-
const logger$
|
|
202
|
+
const logger$26 = require_utils.initializeLogger();
|
|
203
203
|
const makeSpanOtelV2Compatible = (span) => {
|
|
204
204
|
const spanAny = span;
|
|
205
205
|
if (spanAny.instrumentationScope && !spanAny.instrumentationLibrary) Object.assign(span, { instrumentationLibrary: spanAny.instrumentationScope });
|
|
@@ -245,7 +245,7 @@ const createResource = (attributes) => {
|
|
|
245
245
|
if (resources.Resource) return new resources.Resource(attributes);
|
|
246
246
|
throw new Error("Unable to create Resource: neither v1 nor v2 API found");
|
|
247
247
|
} catch {
|
|
248
|
-
logger$
|
|
248
|
+
logger$26.debug("Laminar failed to @opentelemetry/resources, continuing without it");
|
|
249
249
|
return;
|
|
250
250
|
}
|
|
251
251
|
};
|
|
@@ -278,6 +278,23 @@ function convertUint8ArrayToBase64(array) {
|
|
|
278
278
|
return btoa(latin1string);
|
|
279
279
|
}
|
|
280
280
|
/**
|
|
281
|
+
* Checks whether `key` looks like an AI SDK stream property WITHOUT reading it.
|
|
282
|
+
*
|
|
283
|
+
* Reading is not safe here: AI SDK exposes `textStream` / `fullStream` as getters that build a
|
|
284
|
+
* fresh stream on every access. On `streamText` that tees (and mutates) the internal base stream,
|
|
285
|
+
* leaving an abandoned branch that buffers the whole response; on `streamObject` it `pipeThrough`s
|
|
286
|
+
* the base stream directly, permanently LOCKING it so the caller's own access throws. So we only
|
|
287
|
+
* inspect the property descriptor: AI SDK's are accessors, whereas a same-named host API (e.g.
|
|
288
|
+
* Node 26's `Response.prototype.textStream`) is a data property holding a method.
|
|
289
|
+
*/
|
|
290
|
+
const hasStreamAccessor = (obj, key) => {
|
|
291
|
+
for (let o = obj; o !== null; o = Object.getPrototypeOf(o)) {
|
|
292
|
+
const descriptor = Object.getOwnPropertyDescriptor(o, key);
|
|
293
|
+
if (descriptor) return typeof descriptor.value !== "function";
|
|
294
|
+
}
|
|
295
|
+
return false;
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
281
298
|
* This function checks if an object is stream or stream-like, and returns information
|
|
282
299
|
* about the stream type and how to handle it.
|
|
283
300
|
* @param response - The result of a function, either an AI SDK result, a raw stream, or any other
|
|
@@ -286,10 +303,6 @@ function convertUint8ArrayToBase64(array) {
|
|
|
286
303
|
*/
|
|
287
304
|
const getStream = (response) => {
|
|
288
305
|
if (!response || typeof response !== "object") return { type: null };
|
|
289
|
-
if ("textStream" in response || "fullStream" in response) return {
|
|
290
|
-
type: "aisdk-result",
|
|
291
|
-
result: response
|
|
292
|
-
};
|
|
293
306
|
if (response instanceof Response) return {
|
|
294
307
|
type: "response",
|
|
295
308
|
response
|
|
@@ -298,6 +311,10 @@ const getStream = (response) => {
|
|
|
298
311
|
type: "readable-stream",
|
|
299
312
|
stream: response
|
|
300
313
|
};
|
|
314
|
+
if (hasStreamAccessor(response, "textStream") || hasStreamAccessor(response, "fullStream")) return {
|
|
315
|
+
type: "aisdk-result",
|
|
316
|
+
result: response
|
|
317
|
+
};
|
|
301
318
|
if (Symbol.asyncIterator in response && !(response instanceof ReadableStream)) return {
|
|
302
319
|
type: "async-iterable",
|
|
303
320
|
iterable: response
|
|
@@ -318,7 +335,7 @@ const consumeAISDKResult = async (result) => {
|
|
|
318
335
|
} catch (error) {
|
|
319
336
|
errors.push({
|
|
320
337
|
field: key,
|
|
321
|
-
error:
|
|
338
|
+
error: require_utils.errorMessage(error)
|
|
322
339
|
});
|
|
323
340
|
}
|
|
324
341
|
};
|
|
@@ -430,7 +447,7 @@ const consumeResponse = async (response) => {
|
|
|
430
447
|
};
|
|
431
448
|
//#endregion
|
|
432
449
|
//#region src/opentelemetry-lib/tracing/stream-utils.ts
|
|
433
|
-
const logger$
|
|
450
|
+
const logger$25 = require_utils.initializeLogger();
|
|
434
451
|
const pendingStreamProcessing = /* @__PURE__ */ new Set();
|
|
435
452
|
/**
|
|
436
453
|
* Wait for all pending stream processing to complete with a timeout
|
|
@@ -438,7 +455,7 @@ const pendingStreamProcessing = /* @__PURE__ */ new Set();
|
|
|
438
455
|
*/
|
|
439
456
|
const waitForPendingStreams = async (timeoutMs = 5e3) => {
|
|
440
457
|
if (pendingStreamProcessing.size === 0) return;
|
|
441
|
-
logger$
|
|
458
|
+
logger$25.debug(`Waiting for ${pendingStreamProcessing.size} pending stream(s)`);
|
|
442
459
|
const initialCount = pendingStreamProcessing.size;
|
|
443
460
|
const pendingPromises = Array.from(pendingStreamProcessing);
|
|
444
461
|
let timedOut = false;
|
|
@@ -449,7 +466,7 @@ const waitForPendingStreams = async (timeoutMs = 5e3) => {
|
|
|
449
466
|
}, timeoutMs);
|
|
450
467
|
});
|
|
451
468
|
await Promise.race([Promise.allSettled(pendingPromises), timeoutPromise]);
|
|
452
|
-
if (timedOut && pendingStreamProcessing.size > 0) logger$
|
|
469
|
+
if (timedOut && pendingStreamProcessing.size > 0) logger$25.warn(`Timeout waiting for ${pendingStreamProcessing.size} pending stream(s) after ${timeoutMs}ms (started with ${initialCount})`);
|
|
453
470
|
};
|
|
454
471
|
/**
|
|
455
472
|
* Track a background promise and ensure cleanup
|
|
@@ -465,34 +482,34 @@ const trackStreamProcessing = (task) => {
|
|
|
465
482
|
* while passing through the original result to the caller
|
|
466
483
|
*/
|
|
467
484
|
const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, serialize) => {
|
|
468
|
-
logger$
|
|
485
|
+
logger$25.debug(`Handling stream result of type: ${streamInfo.type}`);
|
|
469
486
|
if (streamInfo.type === "aisdk-result") {
|
|
470
487
|
trackStreamProcessing(async () => {
|
|
471
|
-
logger$
|
|
488
|
+
logger$25.debug("Starting background processing for AI SDK result");
|
|
472
489
|
let partialOutput = {};
|
|
473
490
|
try {
|
|
474
491
|
partialOutput = await consumeAISDKResult(streamInfo.result);
|
|
475
492
|
if (shouldSendTraces() && !ignoreOutput) try {
|
|
476
|
-
span.setAttribute(
|
|
493
|
+
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(partialOutput));
|
|
477
494
|
} catch (error) {
|
|
478
|
-
logger$
|
|
495
|
+
logger$25.warn("Failed to serialize AI SDK stream output: " + require_utils.errorMessage(error));
|
|
479
496
|
}
|
|
480
497
|
} catch (error) {
|
|
481
498
|
if (Object.keys(partialOutput).length > 0 && shouldSendTraces() && !ignoreOutput) try {
|
|
482
|
-
span.setAttribute(
|
|
499
|
+
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(partialOutput));
|
|
483
500
|
} catch (serError) {
|
|
484
|
-
logger$
|
|
501
|
+
logger$25.warn("Failed to serialize partial AI SDK output: " + require_utils.errorMessage(serError));
|
|
485
502
|
}
|
|
486
503
|
span.recordException(error);
|
|
487
504
|
} finally {
|
|
488
|
-
logger$
|
|
505
|
+
logger$25.debug("Ending span for AI SDK result");
|
|
489
506
|
span.end();
|
|
490
507
|
}
|
|
491
508
|
});
|
|
492
509
|
return originalResult;
|
|
493
510
|
}
|
|
494
511
|
if (streamInfo.type === "readable-stream") {
|
|
495
|
-
logger$
|
|
512
|
+
logger$25.debug("Setting up background processing for ReadableStream");
|
|
496
513
|
const { stream, dataPromise } = consumeAndTeeReadableStream(streamInfo.stream);
|
|
497
514
|
trackStreamProcessing(async () => {
|
|
498
515
|
try {
|
|
@@ -502,20 +519,20 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
|
|
|
502
519
|
type: "stream",
|
|
503
520
|
chunks
|
|
504
521
|
};
|
|
505
|
-
span.setAttribute(
|
|
522
|
+
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
|
|
506
523
|
} catch (serError) {
|
|
507
|
-
logger$
|
|
524
|
+
logger$25.warn("Failed to serialize stream output: " + require_utils.errorMessage(serError));
|
|
508
525
|
}
|
|
509
526
|
if (error) span.recordException(error);
|
|
510
527
|
} finally {
|
|
511
|
-
logger$
|
|
528
|
+
logger$25.debug("Ending span for ReadableStream");
|
|
512
529
|
span.end();
|
|
513
530
|
}
|
|
514
531
|
});
|
|
515
532
|
return stream;
|
|
516
533
|
}
|
|
517
534
|
if (streamInfo.type === "async-iterable") {
|
|
518
|
-
logger$
|
|
535
|
+
logger$25.debug("Setting up background processing for AsyncIterable");
|
|
519
536
|
const { iterable, dataPromise } = consumeAndTeeAsyncIterable(streamInfo.iterable);
|
|
520
537
|
trackStreamProcessing(async () => {
|
|
521
538
|
try {
|
|
@@ -525,20 +542,20 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
|
|
|
525
542
|
type: "async-iterable",
|
|
526
543
|
chunks
|
|
527
544
|
};
|
|
528
|
-
span.setAttribute(
|
|
545
|
+
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
|
|
529
546
|
} catch (serError) {
|
|
530
|
-
logger$
|
|
547
|
+
logger$25.warn("Failed to serialize async iterable output: " + require_utils.errorMessage(serError));
|
|
531
548
|
}
|
|
532
549
|
if (error) span.recordException(error);
|
|
533
550
|
} finally {
|
|
534
|
-
logger$
|
|
551
|
+
logger$25.debug("Ending span for AsyncIterable");
|
|
535
552
|
span.end();
|
|
536
553
|
}
|
|
537
554
|
});
|
|
538
555
|
return iterable;
|
|
539
556
|
}
|
|
540
557
|
if (streamInfo.type === "response") {
|
|
541
|
-
logger$
|
|
558
|
+
logger$25.debug("Setting up background processing for Response");
|
|
542
559
|
const originalResponse = streamInfo.response;
|
|
543
560
|
if (!originalResponse.body) {
|
|
544
561
|
span.end();
|
|
@@ -558,21 +575,21 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
|
|
|
558
575
|
type: "response",
|
|
559
576
|
chunks
|
|
560
577
|
};
|
|
561
|
-
span.setAttribute(
|
|
578
|
+
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
|
|
562
579
|
} catch (serError) {
|
|
563
|
-
logger$
|
|
580
|
+
logger$25.warn("Failed to serialize response output: " + require_utils.errorMessage(serError));
|
|
564
581
|
}
|
|
565
582
|
if (error) span.recordException(error);
|
|
566
583
|
} catch (err) {
|
|
567
584
|
span.recordException(err);
|
|
568
585
|
} finally {
|
|
569
|
-
logger$
|
|
586
|
+
logger$25.debug("Ending span for Response");
|
|
570
587
|
span.end();
|
|
571
588
|
}
|
|
572
589
|
});
|
|
573
590
|
return newResponse;
|
|
574
591
|
}
|
|
575
|
-
logger$
|
|
592
|
+
logger$25.warn("Stream type not handled, ending span immediately");
|
|
576
593
|
span.end();
|
|
577
594
|
return originalResult;
|
|
578
595
|
};
|
|
@@ -586,7 +603,7 @@ const str = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
|
586
603
|
*/
|
|
587
604
|
const readDebugSessionFile = (dir = process.cwd()) => {
|
|
588
605
|
try {
|
|
589
|
-
const raw = (0, node_fs.readFileSync)((0, node_path.join)(dir,
|
|
606
|
+
const raw = (0, node_fs.readFileSync)((0, node_path.join)(dir, require_utils.DEBUG_SESSION_DIR, require_utils.DEBUG_SESSION_FILE), "utf-8");
|
|
590
607
|
const r = JSON.parse(raw);
|
|
591
608
|
const session_id = str(r.session_id);
|
|
592
609
|
if (!session_id) return null;
|
|
@@ -632,9 +649,9 @@ const resolveDebugSessionDir = (startDir = process.cwd()) => findDebugSessionDir
|
|
|
632
649
|
*/
|
|
633
650
|
const writeDebugSessionFile = (file, dir = process.cwd()) => {
|
|
634
651
|
try {
|
|
635
|
-
const directory = (0, node_path.join)(dir,
|
|
652
|
+
const directory = (0, node_path.join)(dir, require_utils.DEBUG_SESSION_DIR);
|
|
636
653
|
(0, node_fs.mkdirSync)(directory, { recursive: true });
|
|
637
|
-
(0, node_fs.writeFileSync)((0, node_path.join)(directory,
|
|
654
|
+
(0, node_fs.writeFileSync)((0, node_path.join)(directory, require_utils.DEBUG_SESSION_FILE), JSON.stringify(file), "utf-8");
|
|
638
655
|
return true;
|
|
639
656
|
} catch {
|
|
640
657
|
return false;
|
|
@@ -650,7 +667,7 @@ const writeDebugSessionFile = (file, dir = process.cwd()) => {
|
|
|
650
667
|
* contract. This file is part of the cross-language parity surface — keep its
|
|
651
668
|
* logic line-comparable with the Python `config.py`.
|
|
652
669
|
*/
|
|
653
|
-
const logger$
|
|
670
|
+
const logger$24 = require_utils.initializeLogger();
|
|
654
671
|
const TRUTHY = new Set([
|
|
655
672
|
"true",
|
|
656
673
|
"1",
|
|
@@ -686,7 +703,7 @@ const parseCacheUntil = (value) => {
|
|
|
686
703
|
if (value === void 0 || value === "") return null;
|
|
687
704
|
const spanId = normalizeSpanId(value);
|
|
688
705
|
if (spanId !== null) return spanId;
|
|
689
|
-
logger$
|
|
706
|
+
logger$24.warn(`LMNR_DEBUG_CACHE_UNTIL=${JSON.stringify(value)} is not a span id; ignoring`);
|
|
690
707
|
return null;
|
|
691
708
|
};
|
|
692
709
|
/**
|
|
@@ -1037,7 +1054,7 @@ const resetDebugRuntime = () => {
|
|
|
1037
1054
|
};
|
|
1038
1055
|
//#endregion
|
|
1039
1056
|
//#region src/opentelemetry-lib/tracing/span.ts
|
|
1040
|
-
const logger$
|
|
1057
|
+
const logger$23 = require_utils.initializeLogger();
|
|
1041
1058
|
/**
|
|
1042
1059
|
* Build the debug block to propagate, or undefined when debug mode is off.
|
|
1043
1060
|
*
|
|
@@ -1142,24 +1159,24 @@ var LaminarSpan = class LaminarSpan {
|
|
|
1142
1159
|
return this._span.recordException(exception, time);
|
|
1143
1160
|
}
|
|
1144
1161
|
setTraceSessionId(sessionId) {
|
|
1145
|
-
this._span.setAttribute(
|
|
1162
|
+
this._span.setAttribute(require_utils.SESSION_ID, sessionId);
|
|
1146
1163
|
}
|
|
1147
1164
|
setTraceUserId(userId) {
|
|
1148
|
-
this._span.setAttribute(
|
|
1165
|
+
this._span.setAttribute(require_utils.USER_ID, userId);
|
|
1149
1166
|
}
|
|
1150
1167
|
setTraceMetadata(metadata) {
|
|
1151
|
-
this._span.setAttributes(
|
|
1168
|
+
this._span.setAttributes(require_utils.metadataToAttributes(metadata));
|
|
1152
1169
|
}
|
|
1153
1170
|
setInput(input) {
|
|
1154
1171
|
const finalInput = typeof input === "string" ? input : JSON.stringify(input);
|
|
1155
|
-
this._span.setAttribute(
|
|
1172
|
+
this._span.setAttribute(require_utils.SPAN_INPUT, require_utils.truncateSpanPayload(finalInput, "input"));
|
|
1156
1173
|
}
|
|
1157
1174
|
setOutput(output) {
|
|
1158
1175
|
const finalOutput = typeof output === "string" ? output : JSON.stringify(output);
|
|
1159
|
-
this._span.setAttribute(
|
|
1176
|
+
this._span.setAttribute(require_utils.SPAN_OUTPUT, require_utils.truncateSpanPayload(finalOutput, "output"));
|
|
1160
1177
|
}
|
|
1161
1178
|
setTags(tags) {
|
|
1162
|
-
this._span.setAttribute(`${
|
|
1179
|
+
this._span.setAttribute(`${require_utils.ASSOCIATION_PROPERTIES}.tags`, Array.from(new Set(tags)));
|
|
1163
1180
|
}
|
|
1164
1181
|
addTags(tags) {
|
|
1165
1182
|
const currentTags = this.tags;
|
|
@@ -1171,26 +1188,26 @@ var LaminarSpan = class LaminarSpan {
|
|
|
1171
1188
|
let userId;
|
|
1172
1189
|
let sessionId;
|
|
1173
1190
|
let traceType;
|
|
1174
|
-
let tracingLevel =
|
|
1191
|
+
let tracingLevel = require_utils.TracingLevel.ALL;
|
|
1175
1192
|
const metadata = {};
|
|
1176
1193
|
if (this._span.attributes) {
|
|
1177
|
-
spanPath = this._span.attributes[
|
|
1178
|
-
spanIdsPath = this._span.attributes[
|
|
1179
|
-
userId = this._span.attributes[
|
|
1180
|
-
sessionId = this._span.attributes[
|
|
1181
|
-
traceType = this._span.attributes[
|
|
1182
|
-
tracingLevel = this._span.attributes[`lmnr.association.properties.tracing_level`] ??
|
|
1194
|
+
spanPath = this._span.attributes[require_utils.SPAN_PATH];
|
|
1195
|
+
spanIdsPath = this._span.attributes[require_utils.SPAN_IDS_PATH];
|
|
1196
|
+
userId = this._span.attributes[require_utils.USER_ID];
|
|
1197
|
+
sessionId = this._span.attributes[require_utils.SESSION_ID];
|
|
1198
|
+
traceType = this._span.attributes[require_utils.TRACE_TYPE];
|
|
1199
|
+
tracingLevel = this._span.attributes[`lmnr.association.properties.tracing_level`] ?? require_utils.TracingLevel.ALL;
|
|
1183
1200
|
for (const [key, rawValue] of Object.entries(this._span.attributes)) if (key.startsWith(`lmnr.association.properties.metadata.`)) {
|
|
1184
1201
|
let value = rawValue;
|
|
1185
1202
|
try {
|
|
1186
1203
|
value = JSON.parse(value);
|
|
1187
1204
|
} catch {}
|
|
1188
|
-
metadata[key.replace(`${
|
|
1205
|
+
metadata[key.replace(`${require_utils.ASSOCIATION_PROPERTIES}.metadata.`, "")] = value;
|
|
1189
1206
|
}
|
|
1190
|
-
} else logger$
|
|
1207
|
+
} else logger$23.warn("Attributes object is not available. Most likely the span is not a LaminarSpan and not an OpenTelemetry default SDK Span. Span path and ids path will be empty.");
|
|
1191
1208
|
return {
|
|
1192
|
-
spanId:
|
|
1193
|
-
traceId:
|
|
1209
|
+
spanId: require_utils.otelSpanIdToUUID(this._span.spanContext().spanId),
|
|
1210
|
+
traceId: require_utils.otelTraceIdToUUID(this._span.spanContext().traceId),
|
|
1194
1211
|
isRemote: this._span.spanContext().isRemote ?? false,
|
|
1195
1212
|
spanPath,
|
|
1196
1213
|
spanIdsPath,
|
|
@@ -1205,23 +1222,23 @@ var LaminarSpan = class LaminarSpan {
|
|
|
1205
1222
|
spanId(format = "otel") {
|
|
1206
1223
|
const spanId = this._span.spanContext().spanId;
|
|
1207
1224
|
if (format === "otel") return spanId;
|
|
1208
|
-
return
|
|
1225
|
+
return require_utils.otelSpanIdToUUID(spanId);
|
|
1209
1226
|
}
|
|
1210
1227
|
traceId(format = "otel") {
|
|
1211
1228
|
const traceId = this._span.spanContext().traceId;
|
|
1212
1229
|
if (format === "otel") return traceId;
|
|
1213
|
-
return
|
|
1230
|
+
return require_utils.otelTraceIdToUUID(traceId);
|
|
1214
1231
|
}
|
|
1215
1232
|
get tags() {
|
|
1216
1233
|
if (!this._span.attributes) {
|
|
1217
|
-
logger$
|
|
1234
|
+
logger$23.warn("[LaminarSpan.tags] WARNING. Current span does not have attributes object. Possibly, the span was created with a custom OTel SDK. Returning an empty list. Help: OpenTelemetry API does not guarantee reading attributes from a span, but OTel SDK allows it by default. Laminar SDK allows to read attributes too.");
|
|
1218
1235
|
return [];
|
|
1219
1236
|
}
|
|
1220
1237
|
return this._span.attributes[`lmnr.association.properties.tags`] ?? [];
|
|
1221
1238
|
}
|
|
1222
1239
|
get laminarAssociationProperties() {
|
|
1223
1240
|
if (!this._span.attributes) {
|
|
1224
|
-
logger$
|
|
1241
|
+
logger$23.warn("[LaminarSpan.laminarAssociationProperties] WARNING. Current span does not have attributes object. Possibly, the span was created with a custom OTel SDK. Returning an empty object. Help: OpenTelemetry API does not guarantee reading attributes from a span, but OTel SDK allows it by default. Laminar SDK allows to read attributes too.");
|
|
1225
1242
|
return {};
|
|
1226
1243
|
}
|
|
1227
1244
|
try {
|
|
@@ -1231,14 +1248,14 @@ var LaminarSpan = class LaminarSpan {
|
|
|
1231
1248
|
if (!key.startsWith(`lmnr.association.properties.`)) continue;
|
|
1232
1249
|
let value = rawValue;
|
|
1233
1250
|
if (key.startsWith(`lmnr.association.properties.metadata.`)) {
|
|
1234
|
-
const metaKey = key.replace(`${
|
|
1251
|
+
const metaKey = key.replace(`${require_utils.ASSOCIATION_PROPERTIES}.metadata.`, "");
|
|
1235
1252
|
try {
|
|
1236
1253
|
value = JSON.parse(value);
|
|
1237
1254
|
} catch {}
|
|
1238
1255
|
metadata[metaKey] = value;
|
|
1239
1256
|
}
|
|
1240
1257
|
}
|
|
1241
|
-
properties.tracingLevel = this._span.attributes[`lmnr.association.properties.tracing_level`] ??
|
|
1258
|
+
properties.tracingLevel = this._span.attributes[`lmnr.association.properties.tracing_level`] ?? require_utils.TracingLevel.ALL;
|
|
1242
1259
|
properties.userId = this._span.attributes["lmnr.association.properties.user_id"] ?? void 0;
|
|
1243
1260
|
properties.sessionId = this._span.attributes["lmnr.association.properties.session_id"] ?? void 0;
|
|
1244
1261
|
properties.traceType = this._span.attributes["lmnr.association.properties.trace_type"] ?? void 0;
|
|
@@ -1417,7 +1434,7 @@ var LaminarContextManager = class {
|
|
|
1417
1434
|
};
|
|
1418
1435
|
//#endregion
|
|
1419
1436
|
//#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/proxy.ts
|
|
1420
|
-
const logger$
|
|
1437
|
+
const logger$22 = require_utils.initializeLogger();
|
|
1421
1438
|
const DEFAULT_ANTHROPIC_BASE_URL = "https://api.anthropic.com";
|
|
1422
1439
|
const DEFAULT_CC_PROXY_PORT = 45667;
|
|
1423
1440
|
const CC_PROXY_PORT_ATTEMPTS = 50;
|
|
@@ -1669,7 +1686,7 @@ const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL,
|
|
|
1669
1686
|
if (foundryBaseUrl) return foundryBaseUrl.replace(/\/$/, "");
|
|
1670
1687
|
const foundryResource = getEnvValue(FOUNDRY_RESOURCE_ENV);
|
|
1671
1688
|
if (foundryResource) return `https://${foundryResource}.services.ai.azure.com/anthropic`;
|
|
1672
|
-
logger$
|
|
1689
|
+
logger$22.error(`${FOUNDRY_USE_ENV} is set but neither ${FOUNDRY_BASE_URL_ENV} nor ${FOUNDRY_RESOURCE_ENV} is configured. Microsoft Foundry requires one of these values.`);
|
|
1673
1690
|
return null;
|
|
1674
1691
|
}
|
|
1675
1692
|
if (isTruthyEnv(getEnvValue(BEDROCK_USE_ENV))) {
|
|
@@ -1678,7 +1695,7 @@ const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL,
|
|
|
1678
1695
|
let region = getEnvValue(BEDROCK_AWS_REGION_ENV);
|
|
1679
1696
|
if (!region) region = getRegionFromAwsConfig(getEnvValue("AWS_PROFILE") || "default") ?? void 0;
|
|
1680
1697
|
if (region) return `https://bedrock-runtime.${region}.amazonaws.com`;
|
|
1681
|
-
logger$
|
|
1698
|
+
logger$22.error(`${BEDROCK_USE_ENV} is set but could not determine AWS region. Set ${BEDROCK_AWS_REGION_ENV} or configure a region in ~/.aws/config for the active profile.`);
|
|
1682
1699
|
return null;
|
|
1683
1700
|
}
|
|
1684
1701
|
if (isTruthyEnv(getEnvValue(VERTEX_USE_ENV))) {
|
|
@@ -1761,11 +1778,11 @@ const waitForPort = (port, timeoutMs = 5e3) => new Promise((resolve) => {
|
|
|
1761
1778
|
const registerGlobalProxyShutdown = () => {
|
|
1762
1779
|
if (!globalShutdownRegistered) {
|
|
1763
1780
|
process.on("exit", () => {
|
|
1764
|
-
logger$
|
|
1781
|
+
logger$22.debug("process.on(\"exit\") called - stopping all active proxies");
|
|
1765
1782
|
for (const proxyServer of activeProxyServers) try {
|
|
1766
1783
|
proxyServer.stopServer();
|
|
1767
1784
|
} catch (e) {
|
|
1768
|
-
logger$
|
|
1785
|
+
logger$22.debug(`Failed to stop proxy: ${require_utils.errorMessage(e)}`);
|
|
1769
1786
|
}
|
|
1770
1787
|
activeProxyServers.clear();
|
|
1771
1788
|
});
|
|
@@ -1780,28 +1797,28 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
|
|
|
1780
1797
|
try {
|
|
1781
1798
|
const port = await findAvailablePort(DEFAULT_CC_PROXY_PORT, CC_PROXY_PORT_ATTEMPTS);
|
|
1782
1799
|
if (port === null) {
|
|
1783
|
-
logger$
|
|
1800
|
+
logger$22.warn("Unable to allocate port for cc-proxy.");
|
|
1784
1801
|
return null;
|
|
1785
1802
|
}
|
|
1786
1803
|
const targetUrl = resolvedTargetUrl ?? resolveTargetUrlFromEnv(env, void 0, cwd, settingSources, settings);
|
|
1787
1804
|
if (!targetUrl) {
|
|
1788
|
-
logger$
|
|
1805
|
+
logger$22.warn("Unable to resolve target URL for cc-proxy (provider misconfigured).");
|
|
1789
1806
|
return null;
|
|
1790
1807
|
}
|
|
1791
|
-
logger$
|
|
1808
|
+
logger$22.debug(`Creating proxy instance on port ${port} targeting: ${targetUrl}`);
|
|
1792
1809
|
try {
|
|
1793
1810
|
const { ProxyServer } = require("@lmnr-ai/claude-code-proxy");
|
|
1794
1811
|
const proxyServer = new ProxyServer(port);
|
|
1795
1812
|
proxyServer.runServer(targetUrl);
|
|
1796
1813
|
if (!await waitForPort(port)) {
|
|
1797
|
-
logger$
|
|
1814
|
+
logger$22.warn(`cc-proxy failed to start on port ${port}`);
|
|
1798
1815
|
proxyServer.stopServer();
|
|
1799
1816
|
return null;
|
|
1800
1817
|
}
|
|
1801
1818
|
const proxyBaseUrl = `http://127.0.0.1:${port}`;
|
|
1802
1819
|
activeProxyServers.add(proxyServer);
|
|
1803
1820
|
registerGlobalProxyShutdown();
|
|
1804
|
-
logger$
|
|
1821
|
+
logger$22.info(`Started claude proxy server on: ${proxyBaseUrl}`);
|
|
1805
1822
|
return {
|
|
1806
1823
|
server: proxyServer,
|
|
1807
1824
|
baseUrl: proxyBaseUrl,
|
|
@@ -1809,11 +1826,11 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
|
|
|
1809
1826
|
targetUrl
|
|
1810
1827
|
};
|
|
1811
1828
|
} catch (e) {
|
|
1812
|
-
logger$
|
|
1829
|
+
logger$22.warn(`Unable to start cc-proxy: ${require_utils.errorMessage(e)}`);
|
|
1813
1830
|
return null;
|
|
1814
1831
|
}
|
|
1815
1832
|
} catch (e) {
|
|
1816
|
-
logger$
|
|
1833
|
+
logger$22.warn(`Failed to create proxy instance: ${require_utils.errorMessage(e)}`);
|
|
1817
1834
|
return null;
|
|
1818
1835
|
}
|
|
1819
1836
|
};
|
|
@@ -1823,11 +1840,11 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
|
|
|
1823
1840
|
const stopProxyInstance = (instance) => {
|
|
1824
1841
|
if (!instance) return;
|
|
1825
1842
|
try {
|
|
1826
|
-
logger$
|
|
1843
|
+
logger$22.debug(`Stopping proxy instance on port ${instance.port}`);
|
|
1827
1844
|
instance.server.stopServer();
|
|
1828
1845
|
activeProxyServers.delete(instance.server);
|
|
1829
1846
|
} catch (e) {
|
|
1830
|
-
logger$
|
|
1847
|
+
logger$22.debug(`Failed to stop proxy instance: ${require_utils.errorMessage(e)}`);
|
|
1831
1848
|
}
|
|
1832
1849
|
};
|
|
1833
1850
|
/**
|
|
@@ -1835,11 +1852,11 @@ const stopProxyInstance = (instance) => {
|
|
|
1835
1852
|
* Used during shutdown to ensure cleanup
|
|
1836
1853
|
*/
|
|
1837
1854
|
const forceReleaseProxy = () => {
|
|
1838
|
-
logger$
|
|
1855
|
+
logger$22.debug(`Force stopping all ${activeProxyServers.size} active proxy servers`);
|
|
1839
1856
|
for (const proxyServer of activeProxyServers) try {
|
|
1840
1857
|
proxyServer.stopServer();
|
|
1841
1858
|
} catch (e) {
|
|
1842
|
-
logger$
|
|
1859
|
+
logger$22.debug(`Failed to stop proxy: ${require_utils.errorMessage(e)}`);
|
|
1843
1860
|
}
|
|
1844
1861
|
activeProxyServers.clear();
|
|
1845
1862
|
};
|
|
@@ -1856,8 +1873,8 @@ const getSpanContextPayload = () => {
|
|
|
1856
1873
|
try {
|
|
1857
1874
|
const readableSpan = currentSpan;
|
|
1858
1875
|
if (readableSpan.attributes) {
|
|
1859
|
-
const idsPath = readableSpan.attributes[
|
|
1860
|
-
const path$1 = readableSpan.attributes[
|
|
1876
|
+
const idsPath = readableSpan.attributes[require_utils.SPAN_IDS_PATH];
|
|
1877
|
+
const path$1 = readableSpan.attributes[require_utils.SPAN_PATH];
|
|
1861
1878
|
if (Array.isArray(idsPath)) spanIdsPath = idsPath;
|
|
1862
1879
|
if (Array.isArray(path$1)) spanPath = path$1;
|
|
1863
1880
|
}
|
|
@@ -1889,14 +1906,14 @@ const setTraceToProxyInstance = async (instance) => {
|
|
|
1889
1906
|
spanPath: payload.span_path,
|
|
1890
1907
|
laminarUrl: payload.laminar_url
|
|
1891
1908
|
});
|
|
1892
|
-
logger$
|
|
1909
|
+
logger$22.debug(`Set trace context to proxy on port ${instance.port}`);
|
|
1893
1910
|
} catch (e) {
|
|
1894
|
-
logger$
|
|
1911
|
+
logger$22.debug(`Unable to set trace context to proxy on port ${instance.port}: ` + require_utils.errorMessage(e));
|
|
1895
1912
|
}
|
|
1896
1913
|
};
|
|
1897
1914
|
//#endregion
|
|
1898
1915
|
//#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/index.ts
|
|
1899
|
-
const logger$
|
|
1916
|
+
const logger$21 = require_utils.initializeLogger();
|
|
1900
1917
|
/**
|
|
1901
1918
|
* Create an instrumented version of the claude-agent-sdk query function.
|
|
1902
1919
|
* This can be used when importing the query function before Laminar initialization.
|
|
@@ -1911,7 +1928,7 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1911
1928
|
name: "query",
|
|
1912
1929
|
spanType: "DEFAULT"
|
|
1913
1930
|
});
|
|
1914
|
-
span.setAttribute(
|
|
1931
|
+
span.setAttribute(require_utils.SPAN_INPUT, JSON.stringify({ prompt: typeof params.prompt === "string" ? params.prompt : "<stream>" }));
|
|
1915
1932
|
const generator = async function* () {
|
|
1916
1933
|
const collected = [];
|
|
1917
1934
|
let proxyInstance = null;
|
|
@@ -1932,9 +1949,9 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1932
1949
|
targetUrl
|
|
1933
1950
|
});
|
|
1934
1951
|
if (proxyInstance && targetUrl) {
|
|
1935
|
-
logger$
|
|
1952
|
+
logger$21.debug(`Using proxy on port ${proxyInstance.port}`);
|
|
1936
1953
|
await Laminar.withSpan(span, async () => {
|
|
1937
|
-
logger$
|
|
1954
|
+
logger$21.debug("Setting trace to proxy instance...");
|
|
1938
1955
|
await setTraceToProxyInstance(proxyInstance);
|
|
1939
1956
|
});
|
|
1940
1957
|
const varsToRemove = getEnvVarsToRemove(mergedEnv, sessionCwd, settingSources);
|
|
@@ -1949,13 +1966,13 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1949
1966
|
if (isProviderEnabledInEnv(subprocessEnv, "CLAUDE_CODE_USE_BEDROCK")) subprocessEnv.ANTHROPIC_BEDROCK_BASE_URL = proxyInstance.baseUrl;
|
|
1950
1967
|
if (isProviderEnabledInEnv(subprocessEnv, "CLAUDE_CODE_USE_VERTEX")) subprocessEnv.ANTHROPIC_VERTEX_BASE_URL = proxyInstance.baseUrl;
|
|
1951
1968
|
const flagSettings = buildProxyFlagSettings(callerSettings, proxyInstance.baseUrl, sessionCwd, settingSources);
|
|
1952
|
-
if (flagSettings === null) logger$
|
|
1969
|
+
if (flagSettings === null) logger$21.warn(`Could not read options.settings ${JSON.stringify(callerSettings)}; Claude Code settings that define a base URL will bypass the Laminar proxy and produce no LLM spans.`);
|
|
1953
1970
|
else {
|
|
1954
1971
|
params.options.settings = flagSettings;
|
|
1955
|
-
const conflicting = Object.entries(readClaudeSettingsEnv(sessionCwd, settingSources)).filter(([key, value]) => PROXY_BASE_URL_ENV_KEYS.includes(key) && value !== "" && value !== proxyInstance
|
|
1956
|
-
if (conflicting.length > 0) logger$
|
|
1972
|
+
const conflicting = Object.entries(readClaudeSettingsEnv(sessionCwd, settingSources)).filter(([key, value]) => PROXY_BASE_URL_ENV_KEYS.includes(key) && value !== "" && value !== proxyInstance?.baseUrl).map(([key]) => key);
|
|
1973
|
+
if (conflicting.length > 0) logger$21.info(`Claude Code settings define ${conflicting.sort().join(", ")}, which outranks the subprocess environment. Injected settings so the Laminar proxy at ${proxyInstance.baseUrl} still intercepts API traffic; your settings files were not modified.`);
|
|
1957
1974
|
}
|
|
1958
|
-
} else logger$
|
|
1975
|
+
} else logger$21.debug("No claude proxy server available. Proceeding without proxy.");
|
|
1959
1976
|
const originalGenerator = originalQuery(params);
|
|
1960
1977
|
for await (const message of originalGenerator) {
|
|
1961
1978
|
collected.push(message);
|
|
@@ -1968,7 +1985,7 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1968
1985
|
throw error;
|
|
1969
1986
|
} finally {
|
|
1970
1987
|
stopProxyInstance(proxyInstance);
|
|
1971
|
-
span.setAttribute(
|
|
1988
|
+
span.setAttribute(require_utils.SPAN_OUTPUT, JSON.stringify(collected));
|
|
1972
1989
|
span.end();
|
|
1973
1990
|
}
|
|
1974
1991
|
};
|
|
@@ -1977,14 +1994,14 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1977
1994
|
}
|
|
1978
1995
|
var ClaudeAgentSDKInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
1979
1996
|
constructor() {
|
|
1980
|
-
super("@lmnr/claude-agent-instrumentation",
|
|
1997
|
+
super("@lmnr/claude-agent-instrumentation", require_utils.version, { enabled: true });
|
|
1981
1998
|
}
|
|
1982
1999
|
init() {
|
|
1983
2000
|
return new _opentelemetry_instrumentation.InstrumentationNodeModuleDefinition("@anthropic-ai/claude-agent-sdk", [">=0.1.0"], this.patch.bind(this), this.unpatch.bind(this));
|
|
1984
2001
|
}
|
|
1985
2002
|
manuallyInstrument(claudeAgentModule) {
|
|
1986
2003
|
if (claudeAgentModule.query && typeof claudeAgentModule.query === "function") this._wrap(claudeAgentModule, "query", this.patchQuery());
|
|
1987
|
-
else logger$
|
|
2004
|
+
else logger$21.debug("query function not found in claudeAgentSDK module, skipping instrumentation");
|
|
1988
2005
|
}
|
|
1989
2006
|
patchQuery() {
|
|
1990
2007
|
return (original) => instrumentClaudeAgentQuery(original);
|
|
@@ -2001,8 +2018,8 @@ var ClaudeAgentSDKInstrumentation = class extends _opentelemetry_instrumentation
|
|
|
2001
2018
|
};
|
|
2002
2019
|
//#endregion
|
|
2003
2020
|
//#region src/laminar.ts
|
|
2004
|
-
|
|
2005
|
-
const logger$
|
|
2021
|
+
require_utils.loadEnv();
|
|
2022
|
+
const logger$20 = require_utils.initializeLogger();
|
|
2006
2023
|
var Laminar = class Laminar {
|
|
2007
2024
|
static {
|
|
2008
2025
|
this.isInitialized = false;
|
|
@@ -2054,6 +2071,13 @@ var Laminar = class Laminar {
|
|
|
2054
2071
|
* @param {string} props.logLevel - OTel log level. Defaults to "error".
|
|
2055
2072
|
* @param {number} props.maxExportBatchSize - Maximum number of spans to export in a single batch.
|
|
2056
2073
|
* Ignored when `disableBatch` is true.
|
|
2074
|
+
* @param {boolean} props.flushBySize - Whether to also flush batches by approximate payload
|
|
2075
|
+
* size, not just by span count and schedule delay. The batch is flushed when the next span
|
|
2076
|
+
* would push it past `maxExportBatchSizeBytes`, so a few large spans are exported without
|
|
2077
|
+
* waiting for `maxExportBatchSize` spans to accumulate. Useful when spans carry large prompts
|
|
2078
|
+
* or completions and exports get rejected for being too big. Defaults to false.
|
|
2079
|
+
* @param {number} props.maxExportBatchSizeBytes - Approximate maximum size, in bytes, of the
|
|
2080
|
+
* spans buffered in one batch. Only used when `flushBySize` is true. Defaults to 32 MiB.
|
|
2057
2081
|
* @param {boolean} props.forceHttp - Whether to force HTTP export. Not recommended.
|
|
2058
2082
|
* @param {SessionRecordingOptions} props.sessionRecordingOptions - Options for browser
|
|
2059
2083
|
* session recording.
|
|
@@ -2086,13 +2110,13 @@ var Laminar = class Laminar {
|
|
|
2086
2110
|
*
|
|
2087
2111
|
* @throws {Error} - If project API key is not set
|
|
2088
2112
|
*/
|
|
2089
|
-
static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext, spanProcessor } = {}) {
|
|
2113
|
+
static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, maxExportBatchSizeBytes, flushBySize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext, spanProcessor } = {}) {
|
|
2090
2114
|
if (this.isInitialized) {
|
|
2091
|
-
logger$
|
|
2115
|
+
logger$20.warn("Laminar has already been initialized. Skipping initialization.");
|
|
2092
2116
|
return;
|
|
2093
2117
|
}
|
|
2094
2118
|
const key = projectApiKey ?? process?.env?.LMNR_PROJECT_API_KEY;
|
|
2095
|
-
|
|
2119
|
+
require_utils.validateTracingConfig(key);
|
|
2096
2120
|
this.projectApiKey = key ?? "";
|
|
2097
2121
|
let url = baseUrl ?? process?.env?.LMNR_BASE_URL;
|
|
2098
2122
|
if (key && !url) url = "https://api.lmnr.ai";
|
|
@@ -2112,7 +2136,7 @@ var Laminar = class Laminar {
|
|
|
2112
2136
|
...metadata ?? {}
|
|
2113
2137
|
};
|
|
2114
2138
|
if (inheritGlobalContext) LaminarContextManager.inheritGlobalContext = true;
|
|
2115
|
-
if (spanProcessor && !(spanProcessor instanceof LaminarSpanProcessor)) logger$
|
|
2139
|
+
if (spanProcessor && !(spanProcessor instanceof LaminarSpanProcessor)) logger$20.warn("Span processor is not a LaminarSpanProcessor. Some functionality may be impaired.");
|
|
2116
2140
|
this.isInitialized = true;
|
|
2117
2141
|
const urlWithoutSlash = url?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
|
|
2118
2142
|
const httpUrlWithoutSlash = httpUrl?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
|
|
@@ -2128,6 +2152,8 @@ var Laminar = class Laminar {
|
|
|
2128
2152
|
logLevel: logLevel ?? "error",
|
|
2129
2153
|
disableBatch,
|
|
2130
2154
|
maxExportBatchSize,
|
|
2155
|
+
maxExportBatchSizeBytes,
|
|
2156
|
+
flushBySize,
|
|
2131
2157
|
traceExportTimeoutMillis,
|
|
2132
2158
|
sessionRecordingOptions,
|
|
2133
2159
|
spanProcessor
|
|
@@ -2145,9 +2171,9 @@ var Laminar = class Laminar {
|
|
|
2145
2171
|
const envContext = process?.env?.LMNR_SPAN_CONTEXT;
|
|
2146
2172
|
if (!envContext) return;
|
|
2147
2173
|
try {
|
|
2148
|
-
const laminarContext =
|
|
2174
|
+
const laminarContext = require_utils.deserializeLaminarSpanContext(envContext);
|
|
2149
2175
|
this._armDebugRuntimeFromContext(laminarContext.debug);
|
|
2150
|
-
const otelSpanContext =
|
|
2176
|
+
const otelSpanContext = require_utils.tryToOtelSpanContext(laminarContext);
|
|
2151
2177
|
otelSpanContext.isRemote = true;
|
|
2152
2178
|
const processor = getSpanProcessor();
|
|
2153
2179
|
if (processor && processor instanceof LaminarSpanProcessor && laminarContext.spanPath && laminarContext.spanIdsPath) processor.setParentPathInfo(otelSpanContext.spanId, laminarContext.spanPath, laminarContext.spanIdsPath);
|
|
@@ -2155,13 +2181,13 @@ var Laminar = class Laminar {
|
|
|
2155
2181
|
const ctx = LaminarContextManager.setRawAssociationProperties(laminarContext, baseContext);
|
|
2156
2182
|
LaminarContextManager.pushContext(ctx);
|
|
2157
2183
|
try {
|
|
2158
|
-
getRuntime()?.recordTraceId(
|
|
2184
|
+
getRuntime()?.recordTraceId(require_utils.otelTraceIdToUUID(otelSpanContext.traceId));
|
|
2159
2185
|
} catch (e) {
|
|
2160
|
-
logger$
|
|
2186
|
+
logger$20.debug("Failed to record debug trace id from env: " + require_utils.errorMessage(e));
|
|
2161
2187
|
}
|
|
2162
|
-
logger$
|
|
2188
|
+
logger$20.debug("Initialized Laminar parent context from LMNR_SPAN_CONTEXT.");
|
|
2163
2189
|
} catch (e) {
|
|
2164
|
-
logger$
|
|
2190
|
+
logger$20.warn("LMNR_SPAN_CONTEXT is set but could not be used: " + require_utils.errorMessage(e));
|
|
2165
2191
|
}
|
|
2166
2192
|
}
|
|
2167
2193
|
/**
|
|
@@ -2184,7 +2210,7 @@ var Laminar = class Laminar {
|
|
|
2184
2210
|
"rollout.session_id": armedRuntime.sessionId
|
|
2185
2211
|
};
|
|
2186
2212
|
if (!armedRuntime.localOrigin) {
|
|
2187
|
-
const debugClient = new
|
|
2213
|
+
const debugClient = new require_utils.LaminarClient({
|
|
2188
2214
|
baseUrl,
|
|
2189
2215
|
projectApiKey: this.projectApiKey,
|
|
2190
2216
|
port: httpPort
|
|
@@ -2193,26 +2219,26 @@ var Laminar = class Laminar {
|
|
|
2193
2219
|
}
|
|
2194
2220
|
}
|
|
2195
2221
|
if (!isTruthy(process.env.LMNR_DEBUG)) return;
|
|
2196
|
-
const client = new
|
|
2222
|
+
const client = new require_utils.LaminarClient({
|
|
2197
2223
|
baseUrl,
|
|
2198
2224
|
projectApiKey: this.projectApiKey,
|
|
2199
2225
|
port: httpPort
|
|
2200
2226
|
});
|
|
2201
|
-
const debuggerUrl = process?.env?.LMNR_FRONTEND_URL ??
|
|
2227
|
+
const debuggerUrl = process?.env?.LMNR_FRONTEND_URL ?? require_utils.getFrontendUrl(baseUrl);
|
|
2202
2228
|
const { runtime } = initDebugRuntime(client.rolloutSessions, debuggerUrl);
|
|
2203
2229
|
if (runtime === null) return;
|
|
2204
2230
|
client.rolloutSessions.register({ sessionId: runtime.sessionId }).then((projectId) => {
|
|
2205
2231
|
if (projectId) {
|
|
2206
2232
|
runtime.recordProjectId(projectId);
|
|
2207
2233
|
const sessionUrl = runtime.debuggerSessionUrl();
|
|
2208
|
-
logger$
|
|
2234
|
+
logger$20.info(`Laminar debugger session: ${sessionUrl}`);
|
|
2209
2235
|
if (runtime.shouldOpenBrowser) (0, node_child_process.spawn)(process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open", [sessionUrl], {
|
|
2210
2236
|
detached: true,
|
|
2211
2237
|
stdio: "ignore"
|
|
2212
2238
|
}).unref();
|
|
2213
2239
|
}
|
|
2214
2240
|
}).catch((e) => {
|
|
2215
|
-
logger$
|
|
2241
|
+
logger$20.warn("Failed to register debug session: " + require_utils.errorMessage(e));
|
|
2216
2242
|
});
|
|
2217
2243
|
this.globalMetadata = {
|
|
2218
2244
|
...this.globalMetadata,
|
|
@@ -2222,7 +2248,7 @@ var Laminar = class Laminar {
|
|
|
2222
2248
|
this.debugExitHook = () => runtime.emitPointer();
|
|
2223
2249
|
process.once("exit", this.debugExitHook);
|
|
2224
2250
|
} catch (e) {
|
|
2225
|
-
logger$
|
|
2251
|
+
logger$20.warn("Failed to initialize debug runtime: " + require_utils.errorMessage(e));
|
|
2226
2252
|
}
|
|
2227
2253
|
}
|
|
2228
2254
|
/**
|
|
@@ -2256,18 +2282,18 @@ var Laminar = class Laminar {
|
|
|
2256
2282
|
if (!debug || debug.enabled !== true || !debug.sessionId) return;
|
|
2257
2283
|
const existing = getRuntime();
|
|
2258
2284
|
if (existing !== null && existing.localOrigin) return;
|
|
2259
|
-
const { runtime, configChanged } = initDebugRuntimeFromContext(debug, existing?.rolloutSessions ?? new
|
|
2285
|
+
const { runtime, configChanged } = initDebugRuntimeFromContext(debug, existing?.rolloutSessions ?? new require_utils.LaminarClient({
|
|
2260
2286
|
baseUrl: this.baseUrlForDebug,
|
|
2261
2287
|
projectApiKey: this.projectApiKey,
|
|
2262
2288
|
port: this.httpPortForDebug
|
|
2263
|
-
}).rolloutSessions, process?.env?.LMNR_FRONTEND_URL ??
|
|
2289
|
+
}).rolloutSessions, process?.env?.LMNR_FRONTEND_URL ?? require_utils.getFrontendUrl(this.baseUrlForDebug));
|
|
2264
2290
|
if (runtime === null) return;
|
|
2265
2291
|
if (configChanged) {
|
|
2266
2292
|
this.debugRunLive = false;
|
|
2267
2293
|
runtime.rolloutSessions.register({ sessionId: runtime.sessionId }).then((projectId) => {
|
|
2268
2294
|
if (projectId) runtime.recordProjectId(projectId);
|
|
2269
2295
|
}).catch((e) => {
|
|
2270
|
-
logger$
|
|
2296
|
+
logger$20.debug("Failed to register downstream debug session: " + require_utils.errorMessage(e));
|
|
2271
2297
|
});
|
|
2272
2298
|
this.globalMetadata = {
|
|
2273
2299
|
...this.globalMetadata,
|
|
@@ -2276,7 +2302,7 @@ var Laminar = class Laminar {
|
|
|
2276
2302
|
LaminarContextManager.setGlobalMetadata(this.globalMetadata);
|
|
2277
2303
|
}
|
|
2278
2304
|
} catch (e) {
|
|
2279
|
-
logger$
|
|
2305
|
+
logger$20.debug("Failed to arm debug runtime from context: " + require_utils.errorMessage(e));
|
|
2280
2306
|
}
|
|
2281
2307
|
}
|
|
2282
2308
|
/**
|
|
@@ -2291,7 +2317,7 @@ var Laminar = class Laminar {
|
|
|
2291
2317
|
*/
|
|
2292
2318
|
static patch(modules) {
|
|
2293
2319
|
if (!this.isInitialized) {
|
|
2294
|
-
logger$
|
|
2320
|
+
logger$20.warn("Laminar must be initialized before patching modules. Skipping patch.");
|
|
2295
2321
|
return;
|
|
2296
2322
|
}
|
|
2297
2323
|
if (!modules || Object.keys(modules).length === 0) throw new Error("Pass at least one module to patch");
|
|
@@ -2539,7 +2565,7 @@ var Laminar = class Laminar {
|
|
|
2539
2565
|
let parentUserId;
|
|
2540
2566
|
let parentSessionId;
|
|
2541
2567
|
if (parentSpanContext) try {
|
|
2542
|
-
const laminarContext = typeof parentSpanContext === "string" ?
|
|
2568
|
+
const laminarContext = typeof parentSpanContext === "string" ? require_utils.deserializeLaminarSpanContext(parentSpanContext) : parentSpanContext;
|
|
2543
2569
|
parentPath = laminarContext.spanPath;
|
|
2544
2570
|
parentIdsPath = laminarContext.spanIdsPath;
|
|
2545
2571
|
parentMetadata = laminarContext.metadata;
|
|
@@ -2548,38 +2574,38 @@ var Laminar = class Laminar {
|
|
|
2548
2574
|
parentUserId = laminarContext.userId;
|
|
2549
2575
|
parentSessionId = laminarContext.sessionId;
|
|
2550
2576
|
this._armDebugRuntimeFromContext(laminarContext.debug);
|
|
2551
|
-
const spanContext =
|
|
2577
|
+
const spanContext = require_utils.tryToOtelSpanContext(laminarContext);
|
|
2552
2578
|
entityContext = _opentelemetry_api.trace.setSpan(entityContext, _opentelemetry_api.trace.wrapSpanContext(spanContext));
|
|
2553
2579
|
} catch (e) {
|
|
2554
|
-
logger$
|
|
2580
|
+
logger$20.warn("Failed to parse parent span context: " + require_utils.errorMessage(e));
|
|
2555
2581
|
}
|
|
2556
|
-
const tagProperties = tags ? { [`${
|
|
2582
|
+
const tagProperties = tags ? { [`${require_utils.ASSOCIATION_PROPERTIES}.tags`]: Array.from(new Set(tags)) } : {};
|
|
2557
2583
|
const ctxAssociationProperties = LaminarContextManager.getAssociationProperties();
|
|
2558
2584
|
const userIdValue = userId ?? parentUserId ?? ctxAssociationProperties.userId;
|
|
2559
2585
|
const sessionIdValue = sessionId ?? parentSessionId ?? ctxAssociationProperties.sessionId;
|
|
2560
2586
|
const traceTypeValue = parentTraceType ?? (spanType === "EVALUATION" ? "EVALUATION" : void 0) ?? ctxAssociationProperties.traceType;
|
|
2561
2587
|
const tracingLevelValue = parentTracingLevel ?? ctxAssociationProperties.tracingLevel;
|
|
2562
2588
|
const ctxMetadata = ctxAssociationProperties.metadata;
|
|
2563
|
-
const userIdProperties = userIdValue ? { [
|
|
2564
|
-
const sessionIdProperties = sessionIdValue ? { [
|
|
2565
|
-
const traceTypeProperties = traceTypeValue ? { [
|
|
2566
|
-
const tracingLevelProperties = tracingLevelValue ? { [`${
|
|
2567
|
-
const metadataProperties =
|
|
2589
|
+
const userIdProperties = userIdValue ? { [require_utils.USER_ID]: userIdValue } : {};
|
|
2590
|
+
const sessionIdProperties = sessionIdValue ? { [require_utils.SESSION_ID]: sessionIdValue } : {};
|
|
2591
|
+
const traceTypeProperties = traceTypeValue ? { [require_utils.TRACE_TYPE]: traceTypeValue } : {};
|
|
2592
|
+
const tracingLevelProperties = tracingLevelValue ? { [`${require_utils.ASSOCIATION_PROPERTIES}.tracing_level`]: tracingLevelValue } : {};
|
|
2593
|
+
const metadataProperties = require_utils.metadataToAttributes({
|
|
2568
2594
|
...this.globalMetadata,
|
|
2569
2595
|
...ctxMetadata,
|
|
2570
2596
|
...parentMetadata,
|
|
2571
2597
|
...metadata
|
|
2572
2598
|
});
|
|
2573
2599
|
const attributes = {
|
|
2574
|
-
[
|
|
2600
|
+
[require_utils.SPAN_TYPE]: spanType ?? "DEFAULT",
|
|
2575
2601
|
...tagProperties,
|
|
2576
2602
|
...userIdProperties,
|
|
2577
2603
|
...sessionIdProperties,
|
|
2578
2604
|
...metadataProperties,
|
|
2579
2605
|
...traceTypeProperties,
|
|
2580
2606
|
...tracingLevelProperties,
|
|
2581
|
-
...parentPath ? { [
|
|
2582
|
-
...parentIdsPath ? { [
|
|
2607
|
+
...parentPath ? { [require_utils.PARENT_SPAN_PATH]: parentPath } : {},
|
|
2608
|
+
...parentIdsPath ? { [require_utils.PARENT_SPAN_IDS_PATH]: parentIdsPath } : {}
|
|
2583
2609
|
};
|
|
2584
2610
|
const span = new LaminarSpan(getTracer().startSpan(name, {
|
|
2585
2611
|
attributes,
|
|
@@ -2654,13 +2680,13 @@ var Laminar = class Laminar {
|
|
|
2654
2680
|
}
|
|
2655
2681
|
static async flush() {
|
|
2656
2682
|
if (this.isInitialized) {
|
|
2657
|
-
logger$
|
|
2683
|
+
logger$20.debug("Flushing spans");
|
|
2658
2684
|
await forceFlush();
|
|
2659
2685
|
}
|
|
2660
2686
|
}
|
|
2661
2687
|
static async shutdown() {
|
|
2662
2688
|
if (this.isInitialized) {
|
|
2663
|
-
logger$
|
|
2689
|
+
logger$20.debug("Shutting down Laminar");
|
|
2664
2690
|
getRuntime()?.emitPointer();
|
|
2665
2691
|
await forceFlush();
|
|
2666
2692
|
this.isInitialized = false;
|
|
@@ -2795,7 +2821,7 @@ return module.exports;
|
|
|
2795
2821
|
//#endregion
|
|
2796
2822
|
//#region src/browser/utils.ts
|
|
2797
2823
|
const LMNR_SEND_EVENTS_FUNCTION_NAME = "lmnrSendEvents";
|
|
2798
|
-
const logger$
|
|
2824
|
+
const logger$19 = require_utils.initializeLogger();
|
|
2799
2825
|
/**
|
|
2800
2826
|
* If the first argument is a string, return an object with the name of the method
|
|
2801
2827
|
* and the argument as the value.
|
|
@@ -2818,7 +2844,7 @@ const takeFullSnapshot = async (page) => await page.evaluate(() => {
|
|
|
2818
2844
|
window.lmnrRrweb.record.takeFullSnapshot();
|
|
2819
2845
|
return true;
|
|
2820
2846
|
} catch (error) {
|
|
2821
|
-
logger$
|
|
2847
|
+
logger$19.error("Error taking full snapshot: " + require_utils.errorMessage(error));
|
|
2822
2848
|
return false;
|
|
2823
2849
|
}
|
|
2824
2850
|
return false;
|
|
@@ -2829,7 +2855,7 @@ const injectSessionRecorder = async (page, sessionRecordingOptions) => {
|
|
|
2829
2855
|
try {
|
|
2830
2856
|
return await script();
|
|
2831
2857
|
} catch (error) {
|
|
2832
|
-
logger$
|
|
2858
|
+
logger$19.error("Operation " + script.name + " failed: " + require_utils.errorMessage(error));
|
|
2833
2859
|
}
|
|
2834
2860
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
2835
2861
|
}
|
|
@@ -2839,20 +2865,20 @@ const injectSessionRecorder = async (page, sessionRecordingOptions) => {
|
|
|
2839
2865
|
try {
|
|
2840
2866
|
isRrwebPresent = await castedPage.evaluate(() => typeof window.lmnrRrweb !== "undefined");
|
|
2841
2867
|
} catch (error) {
|
|
2842
|
-
logger$
|
|
2868
|
+
logger$19.debug("Failed to check if session recorder is loaded: " + require_utils.errorMessage(error));
|
|
2843
2869
|
}
|
|
2844
2870
|
if (!isRrwebPresent) {
|
|
2845
2871
|
if (!await tryRunScript(async function injectSessionRecorder() {
|
|
2846
2872
|
await castedPage.evaluate(RECORDER);
|
|
2847
2873
|
return true;
|
|
2848
2874
|
})) {
|
|
2849
|
-
logger$
|
|
2875
|
+
logger$19.error("Failed to load session recorder");
|
|
2850
2876
|
return;
|
|
2851
2877
|
}
|
|
2852
2878
|
try {
|
|
2853
2879
|
await castedPage.evaluate(injectScript, sessionRecordingOptions);
|
|
2854
2880
|
} catch (error) {
|
|
2855
|
-
logger$
|
|
2881
|
+
logger$19.debug("Failed to inject session recorder: " + require_utils.errorMessage(error));
|
|
2856
2882
|
}
|
|
2857
2883
|
}
|
|
2858
2884
|
};
|
|
@@ -2941,9 +2967,9 @@ const modelToProviderMap = {
|
|
|
2941
2967
|
"gpt-4.1-mini": "openai",
|
|
2942
2968
|
"gpt-4.1-nano": "openai",
|
|
2943
2969
|
"o4-mini": "openai",
|
|
2944
|
-
|
|
2970
|
+
o3: "openai",
|
|
2945
2971
|
"o3-mini": "openai",
|
|
2946
|
-
|
|
2972
|
+
o1: "openai",
|
|
2947
2973
|
"o1-mini": "openai",
|
|
2948
2974
|
"gpt-4o": "openai",
|
|
2949
2975
|
"gpt-4o-mini": "openai",
|
|
@@ -3115,7 +3141,7 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
|
|
|
3115
3141
|
try {
|
|
3116
3142
|
const { batchId, chunkIndex, totalChunks, data } = chunk;
|
|
3117
3143
|
if (!sessionId || !traceId) {
|
|
3118
|
-
logger$
|
|
3144
|
+
logger$19.debug("Missing sessionId or traceId in chunk");
|
|
3119
3145
|
return;
|
|
3120
3146
|
}
|
|
3121
3147
|
if (!chunkBuffers.has(batchId)) chunkBuffers.set(batchId, {
|
|
@@ -3134,7 +3160,7 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
|
|
|
3134
3160
|
traceId,
|
|
3135
3161
|
events
|
|
3136
3162
|
}).catch((error) => {
|
|
3137
|
-
logger$
|
|
3163
|
+
logger$19.debug("Failed to send events: " + require_utils.errorMessage(error));
|
|
3138
3164
|
});
|
|
3139
3165
|
chunkBuffers.delete(batchId);
|
|
3140
3166
|
}
|
|
@@ -3142,19 +3168,19 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
|
|
|
3142
3168
|
const toDelete = [];
|
|
3143
3169
|
for (const [bid, buffer] of chunkBuffers.entries()) if (currentTime - buffer.timestamp > OLD_BUFFER_TIMEOUT) toDelete.push(bid);
|
|
3144
3170
|
for (const bid of toDelete) {
|
|
3145
|
-
logger$
|
|
3171
|
+
logger$19.debug(`Cleaning up incomplete chunk buffer: ${bid}`);
|
|
3146
3172
|
chunkBuffers.delete(bid);
|
|
3147
3173
|
}
|
|
3148
3174
|
} catch (error) {
|
|
3149
|
-
logger$
|
|
3175
|
+
logger$19.debug("Could not send events: " + require_utils.errorMessage(error));
|
|
3150
3176
|
}
|
|
3151
3177
|
}
|
|
3152
3178
|
//#endregion
|
|
3153
3179
|
//#region src/browser/playwright.ts
|
|
3154
|
-
const logger$
|
|
3180
|
+
const logger$18 = require_utils.initializeLogger();
|
|
3155
3181
|
var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
3156
3182
|
constructor(client, sessionRecordingOptions) {
|
|
3157
|
-
super("@lmnr/playwright-instrumentation",
|
|
3183
|
+
super("@lmnr/playwright-instrumentation", require_utils.version, { enabled: true });
|
|
3158
3184
|
this._patchedBrowsers = /* @__PURE__ */ new Set();
|
|
3159
3185
|
this._parentSpans = /* @__PURE__ */ new Map();
|
|
3160
3186
|
this._client = client;
|
|
@@ -3215,7 +3241,7 @@ var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.Ins
|
|
|
3215
3241
|
const plugin = this;
|
|
3216
3242
|
return (original) => async function method(...args) {
|
|
3217
3243
|
const browser = await original.call(this, ...args);
|
|
3218
|
-
const sessionId =
|
|
3244
|
+
const sessionId = require_utils.newUUID();
|
|
3219
3245
|
for (const context of browser.contexts()) {
|
|
3220
3246
|
context.on("page", (page) => plugin.patchPage(page, sessionId));
|
|
3221
3247
|
for (const page of context.pages()) await plugin.patchPage(page, sessionId);
|
|
@@ -3229,7 +3255,7 @@ var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.Ins
|
|
|
3229
3255
|
const plugin = this;
|
|
3230
3256
|
return (original) => async function method(...args) {
|
|
3231
3257
|
const context = await original.bind(this).apply(this, args);
|
|
3232
|
-
const sessionId =
|
|
3258
|
+
const sessionId = require_utils.newUUID();
|
|
3233
3259
|
context.on("page", async (page) => plugin.patchPage(page, sessionId));
|
|
3234
3260
|
for (const page of context.pages()) await plugin.patchPage(page, sessionId);
|
|
3235
3261
|
return context;
|
|
@@ -3252,14 +3278,14 @@ var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.Ins
|
|
|
3252
3278
|
await takeFullSnapshot(page);
|
|
3253
3279
|
};
|
|
3254
3280
|
const currentSpan = _opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan();
|
|
3255
|
-
currentSpan?.setAttribute(
|
|
3281
|
+
currentSpan?.setAttribute(require_utils.TRACE_HAS_BROWSER_SESSION, true);
|
|
3256
3282
|
const otelTraceId = currentSpan?.spanContext().traceId;
|
|
3257
|
-
const traceId = otelTraceId ?
|
|
3283
|
+
const traceId = otelTraceId ? require_utils.otelTraceIdToUUID(otelTraceId) : require_utils.NIL_UUID;
|
|
3258
3284
|
page.on("domcontentloaded", async () => {
|
|
3259
3285
|
try {
|
|
3260
3286
|
await injectSessionRecorder(page, this._sessionRecordingOptions);
|
|
3261
3287
|
} catch (error) {
|
|
3262
|
-
logger$
|
|
3288
|
+
logger$18.error("Error in onLoad handler: " + require_utils.errorMessage(error));
|
|
3263
3289
|
}
|
|
3264
3290
|
});
|
|
3265
3291
|
const chunkBuffers = /* @__PURE__ */ new Map();
|
|
@@ -3269,7 +3295,7 @@ var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.Ins
|
|
|
3269
3295
|
await sendEvents(chunk, this._client, chunkBuffers, sessionId, traceId);
|
|
3270
3296
|
});
|
|
3271
3297
|
} catch (error) {
|
|
3272
|
-
logger$
|
|
3298
|
+
logger$18.debug("Could not expose function lmnrSendEvents: " + require_utils.errorMessage(error));
|
|
3273
3299
|
}
|
|
3274
3300
|
}
|
|
3275
3301
|
};
|
|
@@ -3296,7 +3322,7 @@ const createLLMClientCreateChatCompletionWrapper = (globalLLMClientOptions) => (
|
|
|
3296
3322
|
const recordedProvider = globalLLMClientOptions.get(this)?.provider;
|
|
3297
3323
|
const provider = recordedProvider === "aisdk" && globalLLMClientOptions.get(this)?.model ? modelToProvider(globalLLMClientOptions.get(this).model) ?? "aisdk" : recordedProvider;
|
|
3298
3324
|
span.setAttributes({
|
|
3299
|
-
[
|
|
3325
|
+
[require_utils.SPAN_TYPE]: "LLM",
|
|
3300
3326
|
...innerOptions.temperature ? { "gen_ai.request.temperature": innerOptions.temperature } : {},
|
|
3301
3327
|
...innerOptions.top_p ? { "gen_ai.request.top_p": innerOptions.top_p } : {},
|
|
3302
3328
|
...innerOptions.frequency_penalty ? { "gen_ai.request.frequency_penalty": innerOptions.frequency_penalty } : {},
|
|
@@ -3360,7 +3386,7 @@ const createLLMClientCreateChatCompletionWrapper = (globalLLMClientOptions) => (
|
|
|
3360
3386
|
//#region src/browser/stagehand/v2.ts
|
|
3361
3387
|
var StagehandV2Instrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
3362
3388
|
constructor(playwrightInstrumentation) {
|
|
3363
|
-
super("@lmnr/browserbase-stagehand-instrumentation",
|
|
3389
|
+
super("@lmnr/browserbase-stagehand-instrumentation", require_utils.version, { enabled: true });
|
|
3364
3390
|
this.globalLLMClientOptions = /* @__PURE__ */ new WeakMap();
|
|
3365
3391
|
this.globalAgentOptions = /* @__PURE__ */ new WeakMap();
|
|
3366
3392
|
this.stagehandInstanceToSessionId = /* @__PURE__ */ new WeakMap();
|
|
@@ -3434,7 +3460,7 @@ var StagehandV2Instrumentation = class extends _opentelemetry_instrumentation.In
|
|
|
3434
3460
|
patchStagehandInit() {
|
|
3435
3461
|
const instrumentation = this;
|
|
3436
3462
|
return (original) => async function method() {
|
|
3437
|
-
const sessionId =
|
|
3463
|
+
const sessionId = require_utils.newUUID();
|
|
3438
3464
|
const parentSpan = Laminar.startSpan({ name: "Stagehand" });
|
|
3439
3465
|
instrumentation.playwrightInstrumentation.setParentSpanForSession(sessionId, parentSpan);
|
|
3440
3466
|
const result = await original.bind(this).apply(this);
|
|
@@ -3694,10 +3720,10 @@ var StagehandV2Instrumentation = class extends _opentelemetry_instrumentation.In
|
|
|
3694
3720
|
};
|
|
3695
3721
|
//#endregion
|
|
3696
3722
|
//#region src/browser/puppeteer.ts
|
|
3697
|
-
const logger$
|
|
3723
|
+
const logger$17 = require_utils.initializeLogger();
|
|
3698
3724
|
var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
3699
3725
|
constructor(client, sessionRecordingOptions) {
|
|
3700
|
-
super("@lmnr/puppeteer-instrumentation",
|
|
3726
|
+
super("@lmnr/puppeteer-instrumentation", require_utils.version, { enabled: true });
|
|
3701
3727
|
this._patchedBrowsers = /* @__PURE__ */ new Set();
|
|
3702
3728
|
this._client = client;
|
|
3703
3729
|
this._sessionRecordingOptions = sessionRecordingOptions;
|
|
@@ -3734,15 +3760,15 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
3734
3760
|
const plugin = this;
|
|
3735
3761
|
return (original) => async function method(...args) {
|
|
3736
3762
|
const browser = await original.call(this, ...args);
|
|
3737
|
-
const sessionId =
|
|
3763
|
+
const sessionId = require_utils.newUUID();
|
|
3738
3764
|
for (const context of browser.browserContexts()) {
|
|
3739
3765
|
context.on("targetcreated", (target) => {
|
|
3740
3766
|
target.page().then((page) => {
|
|
3741
3767
|
if (page) plugin.patchPage(page, sessionId).catch((error) => {
|
|
3742
|
-
logger$
|
|
3768
|
+
logger$17.error("Failed to patch page: " + require_utils.errorMessage(error));
|
|
3743
3769
|
});
|
|
3744
3770
|
}).catch((error) => {
|
|
3745
|
-
logger$
|
|
3771
|
+
logger$17.error("Failed to patch page: " + require_utils.errorMessage(error));
|
|
3746
3772
|
});
|
|
3747
3773
|
});
|
|
3748
3774
|
await Promise.all((await context.pages()).map((page) => plugin.patchPage(page, sessionId)));
|
|
@@ -3756,23 +3782,23 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
3756
3782
|
const plugin = this;
|
|
3757
3783
|
return (original) => async function method(...args) {
|
|
3758
3784
|
const context = await original.bind(this).apply(this, args);
|
|
3759
|
-
const sessionId =
|
|
3785
|
+
const sessionId = require_utils.newUUID();
|
|
3760
3786
|
context.on("targetcreated", (target) => {
|
|
3761
3787
|
target.page().then((page) => {
|
|
3762
3788
|
if (page) plugin.patchPage(page, sessionId).catch((error) => {
|
|
3763
|
-
logger$
|
|
3789
|
+
logger$17.error("Failed to patch page: " + require_utils.errorMessage(error));
|
|
3764
3790
|
});
|
|
3765
3791
|
}).catch((error) => {
|
|
3766
|
-
logger$
|
|
3792
|
+
logger$17.error("Failed to patch page: " + require_utils.errorMessage(error));
|
|
3767
3793
|
});
|
|
3768
3794
|
});
|
|
3769
3795
|
context.on("targetchanged", (target) => {
|
|
3770
3796
|
target.page().then((page) => {
|
|
3771
3797
|
if (page) plugin.patchPage(page, sessionId).catch((error) => {
|
|
3772
|
-
logger$
|
|
3798
|
+
logger$17.error("Failed to patch page: " + require_utils.errorMessage(error));
|
|
3773
3799
|
});
|
|
3774
3800
|
}).catch((error) => {
|
|
3775
|
-
logger$
|
|
3801
|
+
logger$17.error("Failed to patch page: " + require_utils.errorMessage(error));
|
|
3776
3802
|
});
|
|
3777
3803
|
});
|
|
3778
3804
|
for (const page of await context.pages()) await plugin.patchPage(page, sessionId);
|
|
@@ -3791,12 +3817,12 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
3791
3817
|
await takeFullSnapshot(page);
|
|
3792
3818
|
};
|
|
3793
3819
|
const currentSpan = _opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan();
|
|
3794
|
-
currentSpan?.setAttribute(
|
|
3820
|
+
currentSpan?.setAttribute(require_utils.TRACE_HAS_BROWSER_SESSION, true);
|
|
3795
3821
|
const otelTraceId = currentSpan?.spanContext().traceId;
|
|
3796
|
-
const traceId = otelTraceId ?
|
|
3822
|
+
const traceId = otelTraceId ? require_utils.otelTraceIdToUUID(otelTraceId) : require_utils.NIL_UUID;
|
|
3797
3823
|
page.on("domcontentloaded", () => {
|
|
3798
3824
|
injectSessionRecorder(page, this._sessionRecordingOptions).catch((error) => {
|
|
3799
|
-
logger$
|
|
3825
|
+
logger$17.error("Error in onLoad handler: " + require_utils.errorMessage(error));
|
|
3800
3826
|
});
|
|
3801
3827
|
});
|
|
3802
3828
|
await injectSessionRecorder(page, this._sessionRecordingOptions);
|
|
@@ -3806,13 +3832,13 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
3806
3832
|
await sendEvents(chunk, this._client, chunkBuffers, sessionId, traceId);
|
|
3807
3833
|
});
|
|
3808
3834
|
} catch (error) {
|
|
3809
|
-
logger$
|
|
3835
|
+
logger$17.debug("Could not expose function lmnrSendEvents: " + require_utils.errorMessage(error));
|
|
3810
3836
|
}
|
|
3811
3837
|
}
|
|
3812
3838
|
};
|
|
3813
3839
|
//#endregion
|
|
3814
3840
|
//#region src/browser/stagehand/v3/constants.ts
|
|
3815
|
-
const logger$
|
|
3841
|
+
const logger$16 = require_utils.initializeLogger();
|
|
3816
3842
|
const CDP_OPERATION_TIMEOUT_MS = 1e4;
|
|
3817
3843
|
const SKIP_URL_PATTERNS = [
|
|
3818
3844
|
"about:blank",
|
|
@@ -3863,7 +3889,7 @@ async function getOrCreateIsolatedWorld(page) {
|
|
|
3863
3889
|
frameId
|
|
3864
3890
|
};
|
|
3865
3891
|
} catch (error) {
|
|
3866
|
-
logger$
|
|
3892
|
+
logger$16.debug("Failed to create isolated world: " + require_utils.errorMessage(error));
|
|
3867
3893
|
return null;
|
|
3868
3894
|
}
|
|
3869
3895
|
}
|
|
@@ -3880,7 +3906,7 @@ async function isRecorderPresent(page, contextId) {
|
|
|
3880
3906
|
if (!result) return true;
|
|
3881
3907
|
return result.result?.value === true;
|
|
3882
3908
|
} catch (error) {
|
|
3883
|
-
logger$
|
|
3909
|
+
logger$16.debug("Failed to check if recorder is present: " + require_utils.errorMessage(error));
|
|
3884
3910
|
return true;
|
|
3885
3911
|
}
|
|
3886
3912
|
}
|
|
@@ -3893,21 +3919,21 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
|
|
|
3893
3919
|
try {
|
|
3894
3920
|
url = page.url();
|
|
3895
3921
|
} catch (error) {
|
|
3896
|
-
logger$
|
|
3922
|
+
logger$16.debug("Failed to get page URL, page might be closed: " + require_utils.errorMessage(error));
|
|
3897
3923
|
return null;
|
|
3898
3924
|
}
|
|
3899
3925
|
if (shouldSkipUrl(url)) {
|
|
3900
|
-
logger$
|
|
3926
|
+
logger$16.debug(`Skipping recorder injection for URL: ${url}`);
|
|
3901
3927
|
return null;
|
|
3902
3928
|
}
|
|
3903
3929
|
const worldResult = await getOrCreateIsolatedWorld(page);
|
|
3904
3930
|
if (!worldResult) {
|
|
3905
|
-
logger$
|
|
3931
|
+
logger$16.debug("Failed to get isolated world for page");
|
|
3906
3932
|
return null;
|
|
3907
3933
|
}
|
|
3908
3934
|
const { contextId, frameId } = worldResult;
|
|
3909
3935
|
if (await isRecorderPresent(page, contextId)) {
|
|
3910
|
-
logger$
|
|
3936
|
+
logger$16.debug("Recorder already present, skipping injection");
|
|
3911
3937
|
state.contextIdToSession.set(contextId, {
|
|
3912
3938
|
sessionId: state.sessionId,
|
|
3913
3939
|
traceId: state.traceId
|
|
@@ -3920,7 +3946,7 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
|
|
|
3920
3946
|
contextId
|
|
3921
3947
|
});
|
|
3922
3948
|
} catch (error) {
|
|
3923
|
-
logger$
|
|
3949
|
+
logger$16.debug("Failed to inject rrweb: " + require_utils.errorMessage(error));
|
|
3924
3950
|
return null;
|
|
3925
3951
|
}
|
|
3926
3952
|
const optionsJson = JSON.stringify(sessionRecordingOptions ?? {});
|
|
@@ -3931,14 +3957,14 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
|
|
|
3931
3957
|
contextId
|
|
3932
3958
|
});
|
|
3933
3959
|
} catch (error) {
|
|
3934
|
-
logger$
|
|
3960
|
+
logger$16.debug("Failed to inject recording setup: " + require_utils.errorMessage(error));
|
|
3935
3961
|
return null;
|
|
3936
3962
|
}
|
|
3937
3963
|
try {
|
|
3938
3964
|
await sendCDP(page, "Runtime.addBinding", { name: "lmnrSendEvents" });
|
|
3939
|
-
logger$
|
|
3965
|
+
logger$16.debug(`Added binding 'lmnrSendEvents' for page ${frameId}, context ${contextId}`);
|
|
3940
3966
|
} catch (error) {
|
|
3941
|
-
logger$
|
|
3967
|
+
logger$16.debug("Binding may already exist: " + require_utils.errorMessage(error));
|
|
3942
3968
|
}
|
|
3943
3969
|
if (bindingHandler) try {
|
|
3944
3970
|
const pageTargetId = page.targetId();
|
|
@@ -3948,26 +3974,26 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
|
|
|
3948
3974
|
const sessionTyped = session;
|
|
3949
3975
|
if (sessionTyped.on) {
|
|
3950
3976
|
sessionTyped.on("Runtime.bindingCalled", bindingHandler);
|
|
3951
|
-
logger$
|
|
3977
|
+
logger$16.debug(`Set up binding handler on session ${sessionId}`);
|
|
3952
3978
|
}
|
|
3953
3979
|
} catch (error) {
|
|
3954
|
-
logger$
|
|
3980
|
+
logger$16.debug(`Failed to set up binding handler on session ${sessionId}: ` + require_utils.errorMessage(error));
|
|
3955
3981
|
}
|
|
3956
3982
|
state.pageSessionHandlers.set(pageTargetId, bindingHandler);
|
|
3957
3983
|
}
|
|
3958
3984
|
} catch (error) {
|
|
3959
|
-
logger$
|
|
3985
|
+
logger$16.debug("Failed to set up binding handler: " + require_utils.errorMessage(error));
|
|
3960
3986
|
}
|
|
3961
3987
|
state.contextIdToSession.set(contextId, {
|
|
3962
3988
|
sessionId: state.sessionId,
|
|
3963
3989
|
traceId: state.traceId
|
|
3964
3990
|
});
|
|
3965
|
-
logger$
|
|
3991
|
+
logger$16.debug(`Registered context mapping: contextId=${contextId}, sessionId=${state.sessionId}`);
|
|
3966
3992
|
state.instrumentedPageIds.add(frameId);
|
|
3967
|
-
logger$
|
|
3993
|
+
logger$16.debug(`Successfully injected recorder into page ${frameId}`);
|
|
3968
3994
|
return contextId;
|
|
3969
3995
|
} catch (error) {
|
|
3970
|
-
logger$
|
|
3996
|
+
logger$16.debug("Error injecting recorder: " + require_utils.errorMessage(error));
|
|
3971
3997
|
return null;
|
|
3972
3998
|
}
|
|
3973
3999
|
}
|
|
@@ -3981,13 +4007,13 @@ function createBindingHandler(state) {
|
|
|
3981
4007
|
if (event.name !== "lmnrSendEvents") return;
|
|
3982
4008
|
const sessionInfo = state.contextIdToSession.get(event.executionContextId);
|
|
3983
4009
|
if (!sessionInfo) {
|
|
3984
|
-
logger$
|
|
4010
|
+
logger$16.debug("No session info found for context ID: " + event.executionContextId);
|
|
3985
4011
|
if (state.contextIdToSession.size > 0) {
|
|
3986
4012
|
const [, fallbackInfo] = state.contextIdToSession.entries().next().value;
|
|
3987
4013
|
if (fallbackInfo) try {
|
|
3988
4014
|
sendEvents(JSON.parse(event.payload), state.client, state.chunkBuffers, fallbackInfo.sessionId, fallbackInfo.traceId);
|
|
3989
4015
|
} catch (error) {
|
|
3990
|
-
logger$
|
|
4016
|
+
logger$16.debug("Failed to parse binding payload: " + require_utils.errorMessage(error));
|
|
3991
4017
|
}
|
|
3992
4018
|
}
|
|
3993
4019
|
return;
|
|
@@ -3995,7 +4021,7 @@ function createBindingHandler(state) {
|
|
|
3995
4021
|
try {
|
|
3996
4022
|
sendEvents(JSON.parse(event.payload), state.client, state.chunkBuffers, sessionInfo.sessionId, sessionInfo.traceId);
|
|
3997
4023
|
} catch (error) {
|
|
3998
|
-
logger$
|
|
4024
|
+
logger$16.debug("Failed to handle binding event: " + require_utils.errorMessage(error));
|
|
3999
4025
|
}
|
|
4000
4026
|
};
|
|
4001
4027
|
}
|
|
@@ -4011,10 +4037,10 @@ function createTargetCreatedHandler(context, state, sessionRecordingOptions) {
|
|
|
4011
4037
|
const pageId = page.mainFrameId();
|
|
4012
4038
|
if (!state.instrumentedPageIds.has(pageId)) await injectRecorderViaCDP(page, state, context.conn, sessionRecordingOptions, state.bindingHandler ?? void 0);
|
|
4013
4039
|
} catch (error) {
|
|
4014
|
-
logger$
|
|
4040
|
+
logger$16.debug("Error injecting recorder into new page: " + require_utils.errorMessage(error));
|
|
4015
4041
|
}
|
|
4016
4042
|
} catch (error) {
|
|
4017
|
-
logger$
|
|
4043
|
+
logger$16.debug("Error handling target created event: " + require_utils.errorMessage(error));
|
|
4018
4044
|
}
|
|
4019
4045
|
};
|
|
4020
4046
|
}
|
|
@@ -4026,7 +4052,7 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
|
|
|
4026
4052
|
if (event.targetInfo.type !== "page") return;
|
|
4027
4053
|
const url = event.targetInfo.url;
|
|
4028
4054
|
if (shouldSkipUrl(url)) return;
|
|
4029
|
-
logger$
|
|
4055
|
+
logger$16.debug(`Target URL changed to ${url}, checking if recorder injection needed`);
|
|
4030
4056
|
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
4031
4057
|
try {
|
|
4032
4058
|
for (const page of context.pages()) if (page.targetId() === event.targetInfo.targetId) {
|
|
@@ -4034,7 +4060,7 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
|
|
|
4034
4060
|
break;
|
|
4035
4061
|
}
|
|
4036
4062
|
} catch (error) {
|
|
4037
|
-
logger$
|
|
4063
|
+
logger$16.debug("Error handling target info change: " + require_utils.errorMessage(error));
|
|
4038
4064
|
}
|
|
4039
4065
|
};
|
|
4040
4066
|
}
|
|
@@ -4065,7 +4091,7 @@ const safeUnwrap = (instrumentation, target, methodName) => {
|
|
|
4065
4091
|
};
|
|
4066
4092
|
var StagehandInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
4067
4093
|
constructor(sessionRecordingOptions) {
|
|
4068
|
-
super("@lmnr/browserbase-stagehand-instrumentation",
|
|
4094
|
+
super("@lmnr/browserbase-stagehand-instrumentation", require_utils.version, { enabled: true });
|
|
4069
4095
|
this.stagehandInstanceToSessionId = /* @__PURE__ */ new WeakMap();
|
|
4070
4096
|
this.globalLLMClientOptions = /* @__PURE__ */ new WeakMap();
|
|
4071
4097
|
this.globalAgentOptions = /* @__PURE__ */ new WeakMap();
|
|
@@ -4159,13 +4185,13 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4159
4185
|
patchStagehandInit() {
|
|
4160
4186
|
const instrumentation = this;
|
|
4161
4187
|
return (original) => async function method() {
|
|
4162
|
-
const sessionId =
|
|
4188
|
+
const sessionId = require_utils.newUUID();
|
|
4163
4189
|
const parentSpan = Laminar.startSpan({ name: "Stagehand" });
|
|
4164
4190
|
instrumentation.sessionIdToParentSpan.set(sessionId, parentSpan);
|
|
4165
4191
|
instrumentation.stagehandInstanceToSessionId.set(this, sessionId);
|
|
4166
|
-
(_opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan())?.setAttribute(
|
|
4192
|
+
(_opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan())?.setAttribute(require_utils.TRACE_HAS_BROWSER_SESSION, true);
|
|
4167
4193
|
const otelTraceId = parentSpan.spanContext().traceId;
|
|
4168
|
-
const traceId =
|
|
4194
|
+
const traceId = require_utils.otelTraceIdToUUID(otelTraceId);
|
|
4169
4195
|
const result = await original.bind(this).apply(this);
|
|
4170
4196
|
safeWrap(instrumentation, this, "act", instrumentation.patchStagehandGlobalMethod("act", sessionId, parentSpan));
|
|
4171
4197
|
safeWrap(instrumentation, this, "extract", instrumentation.patchStagehandGlobalMethod("extract", sessionId, parentSpan));
|
|
@@ -4195,12 +4221,12 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4195
4221
|
*/
|
|
4196
4222
|
async setupSessionRecording(stagehandInstance, sessionId, traceId) {
|
|
4197
4223
|
if (!this._client) {
|
|
4198
|
-
logger$
|
|
4224
|
+
logger$16.debug("No Laminar client available, skipping session recording setup");
|
|
4199
4225
|
return;
|
|
4200
4226
|
}
|
|
4201
4227
|
const context = stagehandInstance.context;
|
|
4202
4228
|
if (!context || !context.conn) {
|
|
4203
|
-
logger$
|
|
4229
|
+
logger$16.debug("No context or connection available, skipping session recording setup");
|
|
4204
4230
|
return;
|
|
4205
4231
|
}
|
|
4206
4232
|
const recorderState = {
|
|
@@ -4230,11 +4256,11 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4230
4256
|
for (const page of pages) try {
|
|
4231
4257
|
if (await injectRecorderViaCDP(page, recorderState, context.conn, this._sessionRecordingOptions, bindingHandler) !== null) injectedCount++;
|
|
4232
4258
|
} catch (error) {
|
|
4233
|
-
logger$
|
|
4259
|
+
logger$16.debug("Error injecting recorder into page: " + require_utils.errorMessage(error));
|
|
4234
4260
|
}
|
|
4235
|
-
logger$
|
|
4261
|
+
logger$16.debug(`Injected session recorder into ${injectedCount} of ${pages.length} existing page(s)`);
|
|
4236
4262
|
} catch (error) {
|
|
4237
|
-
logger$
|
|
4263
|
+
logger$16.debug("Error accessing pages for recorder injection: " + require_utils.errorMessage(error));
|
|
4238
4264
|
}
|
|
4239
4265
|
}
|
|
4240
4266
|
patchStagehandClose() {
|
|
@@ -4264,12 +4290,12 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4264
4290
|
if (recorderState.targetCreatedHandler) try {
|
|
4265
4291
|
context.conn.off("Target.targetCreated", recorderState.targetCreatedHandler);
|
|
4266
4292
|
} catch (error) {
|
|
4267
|
-
logger$
|
|
4293
|
+
logger$16.debug("Error removing target created handler: " + require_utils.errorMessage(error));
|
|
4268
4294
|
}
|
|
4269
4295
|
if (recorderState.targetInfoChangedHandler) try {
|
|
4270
4296
|
context.conn.off("Target.targetInfoChanged", recorderState.targetInfoChangedHandler);
|
|
4271
4297
|
} catch (error) {
|
|
4272
|
-
logger$
|
|
4298
|
+
logger$16.debug("Error removing target info changed handler: " + require_utils.errorMessage(error));
|
|
4273
4299
|
}
|
|
4274
4300
|
}
|
|
4275
4301
|
recorderState.contextIdToSession.clear();
|
|
@@ -4280,7 +4306,7 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4280
4306
|
recorderState.targetCreatedHandler = null;
|
|
4281
4307
|
recorderState.targetInfoChangedHandler = null;
|
|
4282
4308
|
this.stagehandInstanceToRecorderState.delete(stagehandInstance);
|
|
4283
|
-
logger$
|
|
4309
|
+
logger$16.debug("Cleaned up session recording for Stagehand instance");
|
|
4284
4310
|
}
|
|
4285
4311
|
patchStagehandGlobalMethod(methodName, sessionId, parentSpan) {
|
|
4286
4312
|
return (original) => async function method(...args) {
|
|
@@ -4310,7 +4336,7 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4310
4336
|
name: `stagehand.${methodName}`,
|
|
4311
4337
|
input
|
|
4312
4338
|
}, async (thisArg, rest) => {
|
|
4313
|
-
(_opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan())?.setAttribute(
|
|
4339
|
+
(_opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan())?.setAttribute(require_utils.TRACE_HAS_BROWSER_SESSION, true);
|
|
4314
4340
|
return await original.apply(thisArg, rest);
|
|
4315
4341
|
}, this, args));
|
|
4316
4342
|
};
|
|
@@ -4420,7 +4446,7 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4420
4446
|
spanType: "LLM"
|
|
4421
4447
|
}, async () => {
|
|
4422
4448
|
const span = _opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan();
|
|
4423
|
-
span?.setAttribute(
|
|
4449
|
+
span?.setAttribute(require_utils.TRACE_HAS_BROWSER_SESSION, true);
|
|
4424
4450
|
const agentOptions = instrumentation.globalAgentOptions.get(this);
|
|
4425
4451
|
const maybeModelName = agentOptions?.model?.modelName ?? (typeof agentOptions?.model === "string" ? agentOptions.model : void 0);
|
|
4426
4452
|
const provider = agentOptions?.model?.provider ?? (maybeModelName?.includes("/") ? maybeModelName?.split("/")[0] : instrumentation.globalLLMClientOptions.get(this)?.provider);
|
|
@@ -4505,12 +4531,11 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4505
4531
|
* LLM-backed calls and surface token usage from the response where available.
|
|
4506
4532
|
*/
|
|
4507
4533
|
patchStagehandApiClient(apiClient, parentSpan, stagehandInstance) {
|
|
4508
|
-
const instrumentation = this;
|
|
4509
4534
|
let baseProvider = stagehandInstance?.llmClient?.type;
|
|
4510
4535
|
const baseModel = stagehandInstance?.llmClient?.modelName;
|
|
4511
4536
|
if (baseModel && !baseProvider) baseProvider = modelToProvider(baseModel) ?? "aisdk";
|
|
4512
4537
|
const wrapApiMethod = (methodName) => {
|
|
4513
|
-
safeWrap(
|
|
4538
|
+
safeWrap(this, apiClient, methodName, (original) => async function method(...args) {
|
|
4514
4539
|
const currentSpan = _opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan();
|
|
4515
4540
|
const input = nameArgsOrCopy(args);
|
|
4516
4541
|
const spanName = `stagehand.apiClient.${methodName}`;
|
|
@@ -4522,7 +4547,7 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
4522
4547
|
ignoreOutput: true
|
|
4523
4548
|
}, async () => {
|
|
4524
4549
|
const span = _opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan();
|
|
4525
|
-
span?.setAttribute(
|
|
4550
|
+
span?.setAttribute(require_utils.TRACE_HAS_BROWSER_SESSION, true);
|
|
4526
4551
|
if (baseProvider) span?.setAttribute("gen_ai.system", baseProvider);
|
|
4527
4552
|
if (baseModel) span?.setAttribute("gen_ai.request.model", baseModel);
|
|
4528
4553
|
try {
|
|
@@ -4793,7 +4818,7 @@ const WRAPPED_SYMBOL = Symbol("lmnr.google-genai.wrapped");
|
|
|
4793
4818
|
const CLASS_PATCH_DATA_SYMBOL = Symbol("lmnr.google-genai.classPatchData");
|
|
4794
4819
|
var GoogleGenAiInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
4795
4820
|
constructor(config) {
|
|
4796
|
-
super("@lmnr/google-genai-instrumentation",
|
|
4821
|
+
super("@lmnr/google-genai-instrumentation", require_utils.version, { enabled: true });
|
|
4797
4822
|
this.traceContent = config?.traceContent ?? true;
|
|
4798
4823
|
}
|
|
4799
4824
|
init() {
|
|
@@ -4923,7 +4948,6 @@ const WRAPPED_BROWSER_METHODS = [
|
|
|
4923
4948
|
"create",
|
|
4924
4949
|
"retrieve",
|
|
4925
4950
|
"list",
|
|
4926
|
-
"delete",
|
|
4927
4951
|
"deleteByID",
|
|
4928
4952
|
"loadExtensions"
|
|
4929
4953
|
];
|
|
@@ -4946,7 +4970,7 @@ const WRAPPED_PROCESS_METHODS = [
|
|
|
4946
4970
|
];
|
|
4947
4971
|
var KernelInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
4948
4972
|
constructor() {
|
|
4949
|
-
super("@lmnr/kernel-instrumentation",
|
|
4973
|
+
super("@lmnr/kernel-instrumentation", require_utils.version, { enabled: true });
|
|
4950
4974
|
}
|
|
4951
4975
|
init() {
|
|
4952
4976
|
return new _opentelemetry_instrumentation.InstrumentationNodeModuleDefinition("@onkernel/sdk", [">=0.7.0"], this.patch.bind(this), this.unpatch.bind(this));
|
|
@@ -5151,10 +5175,10 @@ const normalizeMessages = (data, role = "user") => {
|
|
|
5151
5175
|
};
|
|
5152
5176
|
//#endregion
|
|
5153
5177
|
//#region src/opentelemetry-lib/instrumentation/openai-agents/messages.ts
|
|
5154
|
-
const logger$
|
|
5178
|
+
const logger$15 = require_utils.initializeLogger();
|
|
5155
5179
|
const setLmnrSpanIo = (lmnrSpan, inputData, outputData) => {
|
|
5156
|
-
if (inputData !== void 0 && inputData !== null) lmnrSpan.setAttribute(
|
|
5157
|
-
if (outputData !== void 0 && outputData !== null) lmnrSpan.setAttribute(
|
|
5180
|
+
if (inputData !== void 0 && inputData !== null) lmnrSpan.setAttribute(require_utils.SPAN_INPUT, JSON.stringify(inputData));
|
|
5181
|
+
if (outputData !== void 0 && outputData !== null) lmnrSpan.setAttribute(require_utils.SPAN_OUTPUT, JSON.stringify(outputData));
|
|
5158
5182
|
};
|
|
5159
5183
|
const setGenAiInputMessages = (lmnrSpan, inputData, systemInstructions) => {
|
|
5160
5184
|
const hasInput = inputData !== void 0 && inputData !== null;
|
|
@@ -5180,7 +5204,7 @@ const setGenAiOutputMessagesFromResponse = (lmnrSpan, response) => {
|
|
|
5180
5204
|
if (!outputItems) return;
|
|
5181
5205
|
const id = response.id;
|
|
5182
5206
|
if (!Array.isArray(outputItems)) {
|
|
5183
|
-
logger$
|
|
5207
|
+
logger$15.debug("Laminar OpenAI agents instrumentation, failed to parse output items. Expected array");
|
|
5184
5208
|
outputItems = [];
|
|
5185
5209
|
}
|
|
5186
5210
|
const result = {
|
|
@@ -5217,9 +5241,9 @@ const applyLlmAttributes = (lmnrSpan, data) => {
|
|
|
5217
5241
|
if (!data) return;
|
|
5218
5242
|
const model = data.model;
|
|
5219
5243
|
if (model) {
|
|
5220
|
-
lmnrSpan.setAttribute(
|
|
5221
|
-
lmnrSpan.setAttribute(
|
|
5222
|
-
lmnrSpan.setAttribute(
|
|
5244
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, model);
|
|
5245
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.RESPONSE_MODEL, model);
|
|
5246
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.PROVIDER, "openai");
|
|
5223
5247
|
}
|
|
5224
5248
|
const usage = data.usage;
|
|
5225
5249
|
if (usage != null) applyUsage$1(lmnrSpan, usage);
|
|
@@ -5238,12 +5262,12 @@ const applyUsage$1 = (lmnrSpan, usage) => {
|
|
|
5238
5262
|
let reasoningOutputTokens;
|
|
5239
5263
|
if (inputTokensDetails?.cached_tokens !== void 0 && inputTokensDetails?.cached_tokens !== null) cachedInputTokens = Number(inputTokensDetails.cached_tokens);
|
|
5240
5264
|
if (outputTokensDetails?.reasoning_tokens !== void 0 && outputTokensDetails?.reasoning_tokens !== null) reasoningOutputTokens = Number(outputTokensDetails.reasoning_tokens);
|
|
5241
|
-
if (inputTokens !== void 0 && inputTokens !== null) lmnrSpan.setAttribute(
|
|
5265
|
+
if (inputTokens !== void 0 && inputTokens !== null) lmnrSpan.setAttribute(require_utils.LaminarAttributes.INPUT_TOKEN_COUNT, Number(inputTokens));
|
|
5242
5266
|
if (cachedInputTokens !== void 0) lmnrSpan.setAttribute("gen_ai.usage.cache_read_input_tokens", cachedInputTokens);
|
|
5243
|
-
if (outputTokens !== void 0 && outputTokens !== null) lmnrSpan.setAttribute(
|
|
5267
|
+
if (outputTokens !== void 0 && outputTokens !== null) lmnrSpan.setAttribute(require_utils.LaminarAttributes.OUTPUT_TOKEN_COUNT, Number(outputTokens));
|
|
5244
5268
|
if (reasoningOutputTokens !== void 0) lmnrSpan.setAttribute("gen_ai.usage.reasoning_output_tokens", reasoningOutputTokens);
|
|
5245
|
-
if (totalTokens !== void 0 && totalTokens !== null) lmnrSpan.setAttribute(
|
|
5246
|
-
else if (inputTokens !== void 0 && inputTokens !== null && outputTokens !== void 0 && outputTokens !== null) lmnrSpan.setAttribute(
|
|
5269
|
+
if (totalTokens !== void 0 && totalTokens !== null) lmnrSpan.setAttribute(require_utils.LaminarAttributes.TOTAL_TOKEN_COUNT, Number(totalTokens));
|
|
5270
|
+
else if (inputTokens !== void 0 && inputTokens !== null && outputTokens !== void 0 && outputTokens !== null) lmnrSpan.setAttribute(require_utils.LaminarAttributes.TOTAL_TOKEN_COUNT, Number(inputTokens) + Number(outputTokens));
|
|
5247
5271
|
};
|
|
5248
5272
|
const responseToLlmData = (response) => {
|
|
5249
5273
|
if (response == null) return {};
|
|
@@ -5344,9 +5368,9 @@ const applyMcpSpanData = (lmnrSpan, spanData) => {
|
|
|
5344
5368
|
const applySpeechSpanData = (lmnrSpan, spanData) => {
|
|
5345
5369
|
const model = spanData?.model;
|
|
5346
5370
|
if (model) {
|
|
5347
|
-
lmnrSpan.setAttribute(
|
|
5348
|
-
lmnrSpan.setAttribute(
|
|
5349
|
-
lmnrSpan.setAttribute(
|
|
5371
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, model);
|
|
5372
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.RESPONSE_MODEL, model);
|
|
5373
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.PROVIDER, "openai");
|
|
5350
5374
|
}
|
|
5351
5375
|
const inputText = spanData?.input;
|
|
5352
5376
|
if (inputText) setGenAiInputMessages(lmnrSpan, inputText);
|
|
@@ -5357,9 +5381,9 @@ const applySpeechSpanData = (lmnrSpan, spanData) => {
|
|
|
5357
5381
|
const applyTranscriptionSpanData = (lmnrSpan, spanData) => {
|
|
5358
5382
|
const model = spanData?.model;
|
|
5359
5383
|
if (model) {
|
|
5360
|
-
lmnrSpan.setAttribute(
|
|
5361
|
-
lmnrSpan.setAttribute(
|
|
5362
|
-
lmnrSpan.setAttribute(
|
|
5384
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, model);
|
|
5385
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.RESPONSE_MODEL, model);
|
|
5386
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.PROVIDER, "openai");
|
|
5363
5387
|
}
|
|
5364
5388
|
const inputData = spanData?.input;
|
|
5365
5389
|
if (inputData) if (typeof inputData === "object" && !Array.isArray(inputData)) setGenAiInputMessages(lmnrSpan, inputData.data);
|
|
@@ -5375,7 +5399,7 @@ const applySpeechGroupSpanData = (lmnrSpan, spanData) => {
|
|
|
5375
5399
|
};
|
|
5376
5400
|
//#endregion
|
|
5377
5401
|
//#region src/opentelemetry-lib/instrumentation/openai-agents/processor.ts
|
|
5378
|
-
const logger$
|
|
5402
|
+
const logger$14 = require_utils.initializeLogger();
|
|
5379
5403
|
var LaminarAgentsTraceProcessor = class {
|
|
5380
5404
|
constructor() {
|
|
5381
5405
|
this.traces = /* @__PURE__ */ new Map();
|
|
@@ -5393,7 +5417,7 @@ var LaminarAgentsTraceProcessor = class {
|
|
|
5393
5417
|
} catch {}
|
|
5394
5418
|
this.applyTraceMetadata(state.rootSpan, agentsTrace);
|
|
5395
5419
|
} catch (e) {
|
|
5396
|
-
logger$
|
|
5420
|
+
logger$14.debug(`Error in onTraceStart: ${String(e)}`);
|
|
5397
5421
|
}
|
|
5398
5422
|
}
|
|
5399
5423
|
async onTraceEnd(agentsTrace) {
|
|
@@ -5442,7 +5466,7 @@ var LaminarAgentsTraceProcessor = class {
|
|
|
5442
5466
|
});
|
|
5443
5467
|
const key = span.spanId;
|
|
5444
5468
|
if (!key) {
|
|
5445
|
-
logger$
|
|
5469
|
+
logger$14.debug("Span missing spanId, cannot track");
|
|
5446
5470
|
try {
|
|
5447
5471
|
lmnrSpan.end();
|
|
5448
5472
|
} catch {}
|
|
@@ -5461,7 +5485,7 @@ var LaminarAgentsTraceProcessor = class {
|
|
|
5461
5485
|
activationContext
|
|
5462
5486
|
});
|
|
5463
5487
|
} catch (e) {
|
|
5464
|
-
logger$
|
|
5488
|
+
logger$14.debug(`Error in onSpanStart: ${String(e)}`);
|
|
5465
5489
|
if (lmnrSpan !== void 0) try {
|
|
5466
5490
|
lmnrSpan.end();
|
|
5467
5491
|
} catch {}
|
|
@@ -5579,7 +5603,7 @@ var LaminarAgentsTraceProcessor = class {
|
|
|
5579
5603
|
};
|
|
5580
5604
|
//#endregion
|
|
5581
5605
|
//#region src/opentelemetry-lib/instrumentation/openai-agents/index.ts
|
|
5582
|
-
const logger$
|
|
5606
|
+
const logger$13 = require_utils.initializeLogger();
|
|
5583
5607
|
const wrapGetResponse = (original) => function(request, ...rest) {
|
|
5584
5608
|
const systemInstructions = request?.systemInstructions;
|
|
5585
5609
|
return runWithSystemInstructions(systemInstructions, () => original.call(this, request, ...rest));
|
|
@@ -5591,7 +5615,7 @@ const wrapGetStreamedResponse = (original) => function(request, ...rest) {
|
|
|
5591
5615
|
const MODEL_METHODS = ["getResponse", "getStreamedResponse"];
|
|
5592
5616
|
var OpenAIAgentsInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
5593
5617
|
constructor() {
|
|
5594
|
-
super("@lmnr/openai-agents-instrumentation",
|
|
5618
|
+
super("@lmnr/openai-agents-instrumentation", require_utils.version, { enabled: true });
|
|
5595
5619
|
this._wrappedPrototypes = /* @__PURE__ */ new WeakSet();
|
|
5596
5620
|
}
|
|
5597
5621
|
init() {
|
|
@@ -5599,7 +5623,7 @@ var OpenAIAgentsInstrumentation = class extends _opentelemetry_instrumentation.I
|
|
|
5599
5623
|
}
|
|
5600
5624
|
manuallyInstrument(agentsModule) {
|
|
5601
5625
|
if (!agentsModule) {
|
|
5602
|
-
logger$
|
|
5626
|
+
logger$13.debug("@openai/agents module not provided, skipping");
|
|
5603
5627
|
return;
|
|
5604
5628
|
}
|
|
5605
5629
|
this.registerProcessor(agentsModule);
|
|
@@ -5609,7 +5633,7 @@ var OpenAIAgentsInstrumentation = class extends _opentelemetry_instrumentation.I
|
|
|
5609
5633
|
if (this._processor !== void 0) return;
|
|
5610
5634
|
const addTraceProcessor = module.addTraceProcessor;
|
|
5611
5635
|
if (typeof addTraceProcessor !== "function") {
|
|
5612
|
-
logger$
|
|
5636
|
+
logger$13.debug("addTraceProcessor not found in @openai/agents module");
|
|
5613
5637
|
return;
|
|
5614
5638
|
}
|
|
5615
5639
|
try {
|
|
@@ -5617,7 +5641,7 @@ var OpenAIAgentsInstrumentation = class extends _opentelemetry_instrumentation.I
|
|
|
5617
5641
|
addTraceProcessor(processor);
|
|
5618
5642
|
this._processor = processor;
|
|
5619
5643
|
} catch (e) {
|
|
5620
|
-
logger$
|
|
5644
|
+
logger$13.debug(`Failed to register Laminar Agents processor: ${String(e)}`);
|
|
5621
5645
|
}
|
|
5622
5646
|
}
|
|
5623
5647
|
patchModel(module) {
|
|
@@ -5630,7 +5654,7 @@ var OpenAIAgentsInstrumentation = class extends _opentelemetry_instrumentation.I
|
|
|
5630
5654
|
try {
|
|
5631
5655
|
this._wrap(cls.prototype, method, wrapper);
|
|
5632
5656
|
} catch (e) {
|
|
5633
|
-
logger$
|
|
5657
|
+
logger$13.debug(`Failed to wrap ${method}: ${String(e)}`);
|
|
5634
5658
|
}
|
|
5635
5659
|
}
|
|
5636
5660
|
this._wrappedPrototypes.add(cls.prototype);
|
|
@@ -5670,7 +5694,7 @@ var OpenAIAgentsInstrumentation = class extends _opentelemetry_instrumentation.I
|
|
|
5670
5694
|
//#region src/opentelemetry-lib/instrumentation/opencode.ts
|
|
5671
5695
|
var OpencodeInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
5672
5696
|
constructor() {
|
|
5673
|
-
super("lmnr-opencode-instrumentation",
|
|
5697
|
+
super("lmnr-opencode-instrumentation", require_utils.version, { enabled: true });
|
|
5674
5698
|
}
|
|
5675
5699
|
init() {
|
|
5676
5700
|
return new _opentelemetry_instrumentation.InstrumentationNodeModuleDefinition("@opencode-ai/sdk", [">=1.0.0"], this.patch.bind(this), this.unpatch.bind(this));
|
|
@@ -5735,8 +5759,115 @@ const getLangVersion = () => {
|
|
|
5735
5759
|
if (process?.versions?.node) return `node@${process.versions.node}`;
|
|
5736
5760
|
};
|
|
5737
5761
|
//#endregion
|
|
5762
|
+
//#region src/opentelemetry-lib/tracing/batch-processor.ts
|
|
5763
|
+
const logger$12 = require_utils.initializeLogger();
|
|
5764
|
+
/**
|
|
5765
|
+
* Non-string attribute values (numbers, booleans) are counted as a flat 8 bytes
|
|
5766
|
+
* instead of being measured — they never dominate a GenAI payload.
|
|
5767
|
+
*/
|
|
5768
|
+
const FIXED_ATTRIBUTE_VALUE_SIZE = 8;
|
|
5769
|
+
const valueSize = (value) => {
|
|
5770
|
+
if (typeof value === "string") return utf8Size(value);
|
|
5771
|
+
if (Array.isArray(value)) return value.reduce((total, item) => total + valueSize(item), 0);
|
|
5772
|
+
return FIXED_ATTRIBUTE_VALUE_SIZE;
|
|
5773
|
+
};
|
|
5774
|
+
const attributesSize = (attributes) => {
|
|
5775
|
+
if (!attributes) return 0;
|
|
5776
|
+
return Object.entries(attributes).reduce((total, [key, value]) => total + utf8Size(key) + valueSize(value), 0);
|
|
5777
|
+
};
|
|
5778
|
+
/**
|
|
5779
|
+
* Byte length of `value` encoded as UTF-8.
|
|
5780
|
+
*
|
|
5781
|
+
* `.length` counts UTF-16 code units, which undercounts CJK by ~3x and
|
|
5782
|
+
* Cyrillic/Arabic/emoji by ~2x — on GenAI payloads that made a batch several
|
|
5783
|
+
* times the configured limit, the exact oversized-export case this limit exists
|
|
5784
|
+
* to prevent.
|
|
5785
|
+
*
|
|
5786
|
+
* Unlike the Python SDK, which samples a strided subset of long strings, this
|
|
5787
|
+
* measures exactly. `Buffer.byteLength` walks the string in native code without
|
|
5788
|
+
* allocating the encoded bytes, so it is both cheaper and more accurate than
|
|
5789
|
+
* sampling here: measured ~27us on a 20k-character CJK string, against ~16us for
|
|
5790
|
+
* a sampled estimate that was also *wrong* for emoji (+11.7%, because indexing a
|
|
5791
|
+
* string splits surrogate pairs and each half encodes as U+FFFD). Python has no
|
|
5792
|
+
* equivalent primitive — `len(s.encode())` allocates the whole encoded copy —
|
|
5793
|
+
* which is the only reason it samples.
|
|
5794
|
+
*/
|
|
5795
|
+
const utf8Size = (value) => Buffer.byteLength(value, "utf8");
|
|
5796
|
+
/**
|
|
5797
|
+
* Approximate the exported size of a span, in bytes.
|
|
5798
|
+
*
|
|
5799
|
+
* Deliberately an underestimate: protobuf framing, ids and timestamps are
|
|
5800
|
+
* ignored, and non-string values are counted flat. Underestimating small spans
|
|
5801
|
+
* is fine — the count and schedule-delay limits fire first for those. What
|
|
5802
|
+
* matters is that a span carrying a large prompt or completion is measured close
|
|
5803
|
+
* to its real weight.
|
|
5804
|
+
*/
|
|
5805
|
+
const approximateSpanSize = (span) => {
|
|
5806
|
+
let total = utf8Size(span.name ?? "");
|
|
5807
|
+
total += attributesSize(span.attributes);
|
|
5808
|
+
for (const event of span.events ?? []) total += utf8Size(event.name ?? "") + attributesSize(event.attributes);
|
|
5809
|
+
for (const link of span.links ?? []) total += attributesSize(link.attributes);
|
|
5810
|
+
if (span.status?.message) total += utf8Size(span.status.message);
|
|
5811
|
+
return total;
|
|
5812
|
+
};
|
|
5813
|
+
/**
|
|
5814
|
+
* `BatchSpanProcessor` with a third, size-based flush trigger.
|
|
5815
|
+
*
|
|
5816
|
+
* Opt-in via `Laminar.initialize({ flushBySize: true })`; the default transport
|
|
5817
|
+
* is the plain upstream `BatchSpanProcessor`.
|
|
5818
|
+
*
|
|
5819
|
+
* Upstream flushes on whichever comes first: `maxExportBatchSize` spans
|
|
5820
|
+
* buffered, or `scheduledDelayMillis` elapsed. Neither bounds the *payload*, so
|
|
5821
|
+
* a handful of large GenAI spans can produce an export big enough for the
|
|
5822
|
+
* backend to reject. This adds `maxExportBatchSizeBytes`: when the span being
|
|
5823
|
+
* ended would push the buffer past the limit, the buffer is flushed first and
|
|
5824
|
+
* the span then starts a fresh batch.
|
|
5825
|
+
*
|
|
5826
|
+
* The Python SDK needs considerably more machinery for this — a dedicated flush
|
|
5827
|
+
* thread, a lock around the running total, a fork handler, and an inline
|
|
5828
|
+
* fallback for backpressure — none of which is needed here, because the two
|
|
5829
|
+
* runtimes behave differently in three ways:
|
|
5830
|
+
*
|
|
5831
|
+
* 1. `forceFlush()` moves the buffered spans out synchronously and only *awaits*
|
|
5832
|
+
* the network, so calling it from `onEnd` never blocks the caller (measured:
|
|
5833
|
+
* 0.34ms worst case against a 300ms export). Python's `force_flush` performs
|
|
5834
|
+
* the export itself on the calling thread, which load testing measured at a
|
|
5835
|
+
* p99 of ~664ms and is why it needs a background thread.
|
|
5836
|
+
* 2. Because the flush is synchronous with respect to the buffer, the batch stays
|
|
5837
|
+
* bounded even when a producer emits in a tight loop, so no inline-fallback
|
|
5838
|
+
* backpressure path is needed. Python's asynchronous handoff can be outrun.
|
|
5839
|
+
* 3. `onEnd` calls `super.onEnd(span)` *after* flushing, so the triggering span
|
|
5840
|
+
* is genuinely excluded from the batch it caused. Python cannot do this — its
|
|
5841
|
+
* flush is asynchronous, so the triggering span rides along, which is why it
|
|
5842
|
+
* needs a separate "span is at least half the limit" rule to bound overshoot.
|
|
5843
|
+
* Here a batch never exceeds the limit by more than the last span under it.
|
|
5844
|
+
*
|
|
5845
|
+
* Single-threaded event loop, so no lock guards the running total, and there is
|
|
5846
|
+
* no `fork` story to handle.
|
|
5847
|
+
*/
|
|
5848
|
+
var SizeLimitedBatchSpanProcessor = class extends _opentelemetry_sdk_trace_base.BatchSpanProcessor {
|
|
5849
|
+
constructor(exporter, config) {
|
|
5850
|
+
super(exporter, config);
|
|
5851
|
+
this.pendingSizeBytes = 0;
|
|
5852
|
+
this.maxExportBatchSizeBytes = config?.maxExportBatchSizeBytes ?? 33554432;
|
|
5853
|
+
}
|
|
5854
|
+
onEnd(span) {
|
|
5855
|
+
if ((span.spanContext().traceFlags & _opentelemetry_api.TraceFlags.SAMPLED) === 0) {
|
|
5856
|
+
super.onEnd(span);
|
|
5857
|
+
return;
|
|
5858
|
+
}
|
|
5859
|
+
const size = approximateSpanSize(span);
|
|
5860
|
+
const shouldFlush = this.pendingSizeBytes > 0 && this.pendingSizeBytes + size > this.maxExportBatchSizeBytes;
|
|
5861
|
+
this.pendingSizeBytes = shouldFlush ? size : this.pendingSizeBytes + size;
|
|
5862
|
+
if (shouldFlush) this.forceFlush().catch((error) => {
|
|
5863
|
+
logger$12.debug(`Size-triggered span flush failed: ${String(error)}`);
|
|
5864
|
+
});
|
|
5865
|
+
super.onEnd(span);
|
|
5866
|
+
}
|
|
5867
|
+
};
|
|
5868
|
+
//#endregion
|
|
5738
5869
|
//#region src/opentelemetry-lib/tracing/exporter.ts
|
|
5739
|
-
const logger$11 =
|
|
5870
|
+
const logger$11 = require_utils.initializeLogger();
|
|
5740
5871
|
var LaminarSpanExporter = class {
|
|
5741
5872
|
constructor(options = {}) {
|
|
5742
5873
|
let url = options.baseUrl ?? process?.env?.LMNR_BASE_URL;
|
|
@@ -5745,15 +5876,15 @@ var LaminarSpanExporter = class {
|
|
|
5745
5876
|
const key = options.apiKey ?? process?.env?.LMNR_PROJECT_API_KEY;
|
|
5746
5877
|
let headers = {};
|
|
5747
5878
|
if (key) {
|
|
5748
|
-
headers = forceHttp ? {
|
|
5879
|
+
headers = forceHttp ? { Authorization: `Bearer ${key}` } : { authorization: `Bearer ${key}` };
|
|
5749
5880
|
if (!url) url = "https://api.lmnr.ai";
|
|
5750
5881
|
} else {
|
|
5751
|
-
const otelHeaders =
|
|
5752
|
-
if (otelHeaders) headers =
|
|
5753
|
-
const otelEndpoint =
|
|
5882
|
+
const otelHeaders = require_utils.getOtelEnvVar("HEADERS");
|
|
5883
|
+
if (otelHeaders) headers = require_utils.parseOtelHeaders(otelHeaders);
|
|
5884
|
+
const otelEndpoint = require_utils.getOtelEnvVar("ENDPOINT");
|
|
5754
5885
|
if (otelEndpoint && !url) {
|
|
5755
5886
|
url = otelEndpoint;
|
|
5756
|
-
const otelProtocol =
|
|
5887
|
+
const otelProtocol = require_utils.getOtelEnvVar("PROTOCOL") || "grpc/protobuf";
|
|
5757
5888
|
const otelExporter = process?.env?.OTEL_EXPORTER;
|
|
5758
5889
|
forceHttp = otelProtocol === "http/protobuf" || otelProtocol === "http/json" || otelExporter === "otlp_http";
|
|
5759
5890
|
} else if (otelEndpoint && url) logger$11.warn("OTEL_ENDPOINT is set, but Laminar base URL is also set. Ignoring OTEL_ENDPOINT.");
|
|
@@ -5810,7 +5941,7 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
|
|
|
5810
5941
|
constructor(options = {}) {
|
|
5811
5942
|
this._spanIdToPath = /* @__PURE__ */ new Map();
|
|
5812
5943
|
this._spanIdLists = /* @__PURE__ */ new Map();
|
|
5813
|
-
this.logger =
|
|
5944
|
+
this.logger = require_utils.initializeLogger();
|
|
5814
5945
|
if (options.spanProcessor && options.spanProcessor instanceof LaminarSpanProcessor) {
|
|
5815
5946
|
this.instance = options.spanProcessor.instance;
|
|
5816
5947
|
this._spanIdToPath = options.spanProcessor._spanIdToPath;
|
|
@@ -5818,10 +5949,16 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
|
|
|
5818
5949
|
} else if (options.spanProcessor) this.instance = options.spanProcessor;
|
|
5819
5950
|
else {
|
|
5820
5951
|
const exporter = options.exporter ?? new LaminarSpanExporter(options);
|
|
5821
|
-
|
|
5952
|
+
const batchConfig = {
|
|
5822
5953
|
maxExportBatchSize: options.maxExportBatchSize ?? 512,
|
|
5823
5954
|
exportTimeoutMillis: options.traceExportTimeoutMillis ?? 3e4
|
|
5955
|
+
};
|
|
5956
|
+
if (options.disableBatch) this.instance = new _opentelemetry_sdk_trace_base.SimpleSpanProcessor(exporter);
|
|
5957
|
+
else if (options.flushBySize) this.instance = new SizeLimitedBatchSpanProcessor(exporter, {
|
|
5958
|
+
...batchConfig,
|
|
5959
|
+
maxExportBatchSizeBytes: options.maxExportBatchSizeBytes
|
|
5824
5960
|
});
|
|
5961
|
+
else this.instance = new _opentelemetry_sdk_trace_base.BatchSpanProcessor(exporter, batchConfig);
|
|
5825
5962
|
}
|
|
5826
5963
|
}
|
|
5827
5964
|
forceFlush() {
|
|
@@ -5832,37 +5969,37 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
|
|
|
5832
5969
|
}
|
|
5833
5970
|
onStart(spanArg, parentContext) {
|
|
5834
5971
|
const span = spanArg;
|
|
5835
|
-
const parentPathFromAttribute = span.attributes?.[
|
|
5836
|
-
const parentIdsPathFromAttribute = span.attributes?.[
|
|
5972
|
+
const parentPathFromAttribute = span.attributes?.[require_utils.PARENT_SPAN_PATH];
|
|
5973
|
+
const parentIdsPathFromAttribute = span.attributes?.[require_utils.PARENT_SPAN_IDS_PATH];
|
|
5837
5974
|
const parentSpanId = getParentSpanId(span);
|
|
5838
5975
|
const parentSpanPath = parentPathFromAttribute ?? (parentSpanId !== void 0 ? this._spanIdToPath.get(parentSpanId) : void 0);
|
|
5839
5976
|
const spanId = span.spanContext().spanId;
|
|
5840
|
-
const parentSpanIdsPath = parentIdsPathFromAttribute ?? (parentSpanId ? this._spanIdLists.get(parentSpanId) ?? [
|
|
5977
|
+
const parentSpanIdsPath = parentIdsPathFromAttribute ?? (parentSpanId ? this._spanIdLists.get(parentSpanId) ?? [require_utils.otelSpanIdToUUID(parentSpanId)] : []);
|
|
5841
5978
|
const spanPath = parentSpanPath ? [...parentSpanPath, span.name] : [span.name];
|
|
5842
|
-
const spanIdUuid =
|
|
5979
|
+
const spanIdUuid = require_utils.otelSpanIdToUUID(spanId);
|
|
5843
5980
|
const spanIdsPath = parentSpanIdsPath ? [...parentSpanIdsPath, spanIdUuid] : [spanIdUuid];
|
|
5844
|
-
span.setAttribute(
|
|
5981
|
+
span.setAttribute(require_utils.SPAN_IDS_PATH, spanIdsPath);
|
|
5845
5982
|
this._spanIdLists.set(spanId, spanIdsPath);
|
|
5846
|
-
span.setAttribute(
|
|
5983
|
+
span.setAttribute(require_utils.SPAN_PATH, spanPath);
|
|
5847
5984
|
_opentelemetry_api.context.active().setValue(CONTEXT_SPAN_PATH_KEY, spanPath);
|
|
5848
5985
|
this._spanIdToPath.set(spanId, spanPath);
|
|
5849
|
-
span.setAttribute(
|
|
5850
|
-
span.setAttribute(
|
|
5986
|
+
span.setAttribute(require_utils.SPAN_INSTRUMENTATION_SOURCE, "javascript");
|
|
5987
|
+
span.setAttribute(require_utils.SPAN_SDK_VERSION, require_utils.version);
|
|
5851
5988
|
const langVersion = getLangVersion();
|
|
5852
|
-
if (langVersion) span.setAttribute(
|
|
5989
|
+
if (langVersion) span.setAttribute(require_utils.SPAN_LANGUAGE_VERSION, langVersion);
|
|
5853
5990
|
const globalMetadata = LaminarContextManager.getGlobalMetadata();
|
|
5854
|
-
if (globalMetadata && Object.keys(globalMetadata).length > 0) span.setAttributes(
|
|
5991
|
+
if (globalMetadata && Object.keys(globalMetadata).length > 0) span.setAttributes(require_utils.metadataToAttributes(globalMetadata));
|
|
5855
5992
|
const associationProperties = _opentelemetry_api.context.active().getValue(ASSOCIATION_PROPERTIES_KEY);
|
|
5856
|
-
if (associationProperties) for (const [key, value] of Object.entries(associationProperties)) if (Object.keys(
|
|
5993
|
+
if (associationProperties) for (const [key, value] of Object.entries(associationProperties)) if (Object.keys(require_utils.ASSOCIATION_PROPERTIES_OVERRIDES).includes(key)) span.setAttribute(require_utils.ASSOCIATION_PROPERTIES_OVERRIDES[key], value);
|
|
5857
5994
|
else if (key === "tracing_level") span.setAttribute("lmnr.internal.tracing_level", value);
|
|
5858
5995
|
else if (key === "metadata" && typeof value === "object" && value !== null) {
|
|
5859
|
-
const metadataAttrs =
|
|
5996
|
+
const metadataAttrs = require_utils.metadataToAttributes(value);
|
|
5860
5997
|
span.setAttributes(metadataAttrs);
|
|
5861
|
-
} else if (key === "userId") span.setAttribute(
|
|
5862
|
-
else if (key === "sessionId") span.setAttribute(
|
|
5863
|
-
else if (key === "traceType") span.setAttribute(
|
|
5998
|
+
} else if (key === "userId") span.setAttribute(require_utils.USER_ID, value);
|
|
5999
|
+
else if (key === "sessionId") span.setAttribute(require_utils.SESSION_ID, value);
|
|
6000
|
+
else if (key === "traceType") span.setAttribute(require_utils.TRACE_TYPE, value);
|
|
5864
6001
|
else if (key === "tracingLevel") span.setAttribute("lmnr.internal.tracing_level", value);
|
|
5865
|
-
else span.setAttribute(`${
|
|
6002
|
+
else span.setAttribute(`${require_utils.ASSOCIATION_PROPERTIES}.${key}`, value);
|
|
5866
6003
|
makeSpanOtelV2Compatible(span);
|
|
5867
6004
|
if (parentSpanId === void 0) this.recordDebugTraceId(span);
|
|
5868
6005
|
this.instance.onStart(span, parentContext);
|
|
@@ -5876,7 +6013,7 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
|
|
|
5876
6013
|
try {
|
|
5877
6014
|
const runtime = getRuntime();
|
|
5878
6015
|
if (runtime === null) return;
|
|
5879
|
-
runtime.recordTraceId(
|
|
6016
|
+
runtime.recordTraceId(require_utils.otelTraceIdToUUID(span.spanContext().traceId));
|
|
5880
6017
|
} catch (e) {
|
|
5881
6018
|
this.logger.debug(`Failed to record debug trace id: ${String(e)}`);
|
|
5882
6019
|
}
|
|
@@ -5917,7 +6054,7 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
|
|
|
5917
6054
|
};
|
|
5918
6055
|
//#endregion
|
|
5919
6056
|
//#region src/opentelemetry-lib/instrumentation/temporal/helpers.ts
|
|
5920
|
-
const logger$10 =
|
|
6057
|
+
const logger$10 = require_utils.initializeLogger();
|
|
5921
6058
|
const _enc = new TextEncoder();
|
|
5922
6059
|
const _dec = new TextDecoder();
|
|
5923
6060
|
const encodePayload = (value) => ({
|
|
@@ -5969,13 +6106,13 @@ const restoreContextFromHeaders = (headers) => {
|
|
|
5969
6106
|
if (!headers) return void 0;
|
|
5970
6107
|
const laminarRaw = decodePayload(headers[require_consts.LAMINAR_SPAN_CONTEXT_HEADER]);
|
|
5971
6108
|
if (laminarRaw) try {
|
|
5972
|
-
const ctx =
|
|
6109
|
+
const ctx = require_utils.deserializeLaminarSpanContext(laminarRaw);
|
|
5973
6110
|
return {
|
|
5974
6111
|
laminarCtx: ctx,
|
|
5975
6112
|
otelContext: pushLaminarContext(ctx)
|
|
5976
6113
|
};
|
|
5977
6114
|
} catch (e) {
|
|
5978
|
-
logger$10.warn(`[Laminar] Could not restore ${require_consts.LAMINAR_SPAN_CONTEXT_HEADER}: ${
|
|
6115
|
+
logger$10.warn(`[Laminar] Could not restore ${require_consts.LAMINAR_SPAN_CONTEXT_HEADER}: ${require_utils.errorMessage(e)}`);
|
|
5979
6116
|
}
|
|
5980
6117
|
const traceparent = decodePayload(headers[require_consts.TRACEPARENT_HEADER]);
|
|
5981
6118
|
if (traceparent) {
|
|
@@ -5984,8 +6121,8 @@ const restoreContextFromHeaders = (headers) => {
|
|
|
5984
6121
|
const [, traceHex, spanHex] = parts;
|
|
5985
6122
|
try {
|
|
5986
6123
|
const ctx = {
|
|
5987
|
-
traceId:
|
|
5988
|
-
spanId:
|
|
6124
|
+
traceId: require_utils.otelTraceIdToUUID(traceHex),
|
|
6125
|
+
spanId: require_utils.otelSpanIdToUUID(spanHex),
|
|
5989
6126
|
isRemote: true
|
|
5990
6127
|
};
|
|
5991
6128
|
return {
|
|
@@ -5993,7 +6130,7 @@ const restoreContextFromHeaders = (headers) => {
|
|
|
5993
6130
|
otelContext: pushLaminarContext(ctx)
|
|
5994
6131
|
};
|
|
5995
6132
|
} catch (e) {
|
|
5996
|
-
logger$10.warn(`[Laminar] Could not restore traceparent: ${
|
|
6133
|
+
logger$10.warn(`[Laminar] Could not restore traceparent: ${require_utils.errorMessage(e)}`);
|
|
5997
6134
|
}
|
|
5998
6135
|
}
|
|
5999
6136
|
}
|
|
@@ -6003,7 +6140,7 @@ const restoreContextFromHeaders = (headers) => {
|
|
|
6003
6140
|
* return the enriched OTel `Context` that was pushed.
|
|
6004
6141
|
*/
|
|
6005
6142
|
const pushLaminarContext = (laminarCtx) => {
|
|
6006
|
-
const otelCtx =
|
|
6143
|
+
const otelCtx = require_utils.tryToOtelSpanContext(laminarCtx);
|
|
6007
6144
|
otelCtx.isRemote = true;
|
|
6008
6145
|
const processor = getSpanProcessor();
|
|
6009
6146
|
if (processor instanceof LaminarSpanProcessor && laminarCtx.spanPath && laminarCtx.spanIdsPath) processor.setParentPathInfo(otelCtx.spanId, laminarCtx.spanPath, laminarCtx.spanIdsPath);
|
|
@@ -6172,7 +6309,7 @@ var ActivityInboundInterceptor = class {
|
|
|
6172
6309
|
if (this.recordActivityOutput) try {
|
|
6173
6310
|
span.setOutput(res);
|
|
6174
6311
|
} catch (e) {
|
|
6175
|
-
this.logger.debug(`failed to set output to activity span: ${
|
|
6312
|
+
this.logger.debug(`failed to set output to activity span: ${require_utils.errorMessage(e)}`);
|
|
6176
6313
|
}
|
|
6177
6314
|
return res;
|
|
6178
6315
|
}, true);
|
|
@@ -6181,13 +6318,13 @@ var ActivityInboundInterceptor = class {
|
|
|
6181
6318
|
this.recordActivityArgs = options.recordActivityArgs ?? true;
|
|
6182
6319
|
this.recordActivityOutput = options.recordActivityOutput ?? true;
|
|
6183
6320
|
this.activityType = activityContext?.info?.activityType;
|
|
6184
|
-
this.logger =
|
|
6321
|
+
this.logger = require_utils.initializeLogger();
|
|
6185
6322
|
}
|
|
6186
6323
|
};
|
|
6187
6324
|
const ActivityInterceptorFactory = (options) => (ctx) => ({ inbound: new ActivityInboundInterceptor(options, ctx) });
|
|
6188
6325
|
//#endregion
|
|
6189
6326
|
//#region src/opentelemetry-lib/instrumentation/temporal/workflow-span.ts
|
|
6190
|
-
const logger$9 =
|
|
6327
|
+
const logger$9 = require_utils.initializeLogger();
|
|
6191
6328
|
const _patchedWorkflowClients = /* @__PURE__ */ new WeakSet();
|
|
6192
6329
|
const workflowName = (args) => {
|
|
6193
6330
|
const wf = args[0];
|
|
@@ -6211,7 +6348,7 @@ const wrapHandle = (handle, span) => {
|
|
|
6211
6348
|
try {
|
|
6212
6349
|
return Laminar.serializeLaminarSpanContext(span) ?? void 0;
|
|
6213
6350
|
} catch (e) {
|
|
6214
|
-
logger$9.debug(`failed to derive workflow child span parent: ${
|
|
6351
|
+
logger$9.debug(`failed to derive workflow child span parent: ${require_utils.errorMessage(e)}`);
|
|
6215
6352
|
return;
|
|
6216
6353
|
}
|
|
6217
6354
|
};
|
|
@@ -6223,7 +6360,7 @@ const wrapHandle = (handle, span) => {
|
|
|
6223
6360
|
try {
|
|
6224
6361
|
span.setOutput(res);
|
|
6225
6362
|
} catch (e) {
|
|
6226
|
-
logger$9.debug(`failed to set workflow span output: ${
|
|
6363
|
+
logger$9.debug(`failed to set workflow span output: ${require_utils.errorMessage(e)}`);
|
|
6227
6364
|
}
|
|
6228
6365
|
});
|
|
6229
6366
|
return res;
|
|
@@ -6300,7 +6437,7 @@ const patchWorkflowClient = (clientModule) => {
|
|
|
6300
6437
|
try {
|
|
6301
6438
|
span.setOutput(res);
|
|
6302
6439
|
} catch (e) {
|
|
6303
|
-
logger$9.debug(`failed to set workflow span output: ${
|
|
6440
|
+
logger$9.debug(`failed to set workflow span output: ${require_utils.errorMessage(e)}`);
|
|
6304
6441
|
}
|
|
6305
6442
|
span.end();
|
|
6306
6443
|
return res;
|
|
@@ -6384,7 +6521,7 @@ const patchWorkflowClient = (clientModule) => {
|
|
|
6384
6521
|
* const client = new temporalClient.Client({ ... });
|
|
6385
6522
|
* ```
|
|
6386
6523
|
*/
|
|
6387
|
-
const logger$8 =
|
|
6524
|
+
const logger$8 = require_utils.initializeLogger();
|
|
6388
6525
|
const _patchedWorkerModules = /* @__PURE__ */ new WeakSet();
|
|
6389
6526
|
const _patchedClientModules = /* @__PURE__ */ new WeakSet();
|
|
6390
6527
|
let _warnedWorkflowBundleOnce = false;
|
|
@@ -6462,7 +6599,7 @@ const LaminarTemporalInterceptors = {
|
|
|
6462
6599
|
};
|
|
6463
6600
|
//#endregion
|
|
6464
6601
|
//#region src/opentelemetry-lib/tracing/instrumentations.ts
|
|
6465
|
-
const logger$7 =
|
|
6602
|
+
const logger$7 = require_utils.initializeLogger();
|
|
6466
6603
|
/**
|
|
6467
6604
|
* Initialize and return Laminar instrumentations.
|
|
6468
6605
|
* Useful to use with libraries that initialize tracing and can register passed
|
|
@@ -6493,7 +6630,7 @@ const initializeLaminarInstrumentations = (options = {}) => {
|
|
|
6493
6630
|
if (apiKey) {
|
|
6494
6631
|
const url = options.baseUrl ?? process?.env?.LMNR_BASE_URL ?? "https://api.lmnr.ai";
|
|
6495
6632
|
const port = options.httpPort ?? (url.match(/:\d{1,5}$/g) ? parseInt(url.match(/:\d{1,5}$/g)[0].slice(1)) : 443);
|
|
6496
|
-
client = new
|
|
6633
|
+
client = new require_utils.LaminarClient({
|
|
6497
6634
|
baseUrl: `${url.replace(/\/$/, "").replace(/:\d{1,5}$/g, "")}:${port}`,
|
|
6498
6635
|
projectApiKey: apiKey
|
|
6499
6636
|
});
|
|
@@ -6702,7 +6839,7 @@ const isGlobalContextManagerConfigured = () => {
|
|
|
6702
6839
|
};
|
|
6703
6840
|
//#endregion
|
|
6704
6841
|
//#region src/opentelemetry-lib/tracing/index.ts
|
|
6705
|
-
const logger$6 =
|
|
6842
|
+
const logger$6 = require_utils.initializeLogger();
|
|
6706
6843
|
let spanProcessor;
|
|
6707
6844
|
let tracerProvider;
|
|
6708
6845
|
let _baseHttpUrl = "https://api.lmnr.ai:443";
|
|
@@ -6734,6 +6871,8 @@ const startTracing = (options) => {
|
|
|
6734
6871
|
forceHttp: options.forceHttp,
|
|
6735
6872
|
traceExportTimeoutMillis: options.traceExportTimeoutMillis,
|
|
6736
6873
|
maxExportBatchSize: options.maxExportBatchSize,
|
|
6874
|
+
maxExportBatchSizeBytes: options.maxExportBatchSizeBytes,
|
|
6875
|
+
flushBySize: options.flushBySize,
|
|
6737
6876
|
exporter: options.exporter,
|
|
6738
6877
|
disableBatch: options.disableBatch
|
|
6739
6878
|
});
|
|
@@ -6742,7 +6881,7 @@ const startTracing = (options) => {
|
|
|
6742
6881
|
sampler: new _opentelemetry_sdk_trace_base.AlwaysOnSampler(),
|
|
6743
6882
|
resource: createResource({
|
|
6744
6883
|
[_opentelemetry_semantic_conventions.ATTR_SERVICE_NAME]: "laminar-tracer-resource",
|
|
6745
|
-
[_opentelemetry_semantic_conventions.ATTR_SERVICE_VERSION]:
|
|
6884
|
+
[_opentelemetry_semantic_conventions.ATTR_SERVICE_VERSION]: require_utils.version
|
|
6746
6885
|
})
|
|
6747
6886
|
});
|
|
6748
6887
|
tracerProvider = newProvider;
|
|
@@ -6871,17 +7010,17 @@ const _resetConfiguration = () => {
|
|
|
6871
7010
|
};
|
|
6872
7011
|
//#endregion
|
|
6873
7012
|
//#region src/opentelemetry-lib/tracing/decorators.ts
|
|
6874
|
-
const logger$5 =
|
|
7013
|
+
const logger$5 = require_utils.initializeLogger();
|
|
6875
7014
|
function observeBase({ name, contextProperties, spanAttributes, input, ignoreInput, ignoreOutput, inputParameters, suppressTracing: shouldSuppressTracing, parentSpanContext }, fn, thisArg, ...args) {
|
|
6876
7015
|
let entityContext = LaminarContextManager.getContext();
|
|
6877
7016
|
if (shouldSuppressTracing) entityContext = (0, _opentelemetry_core.suppressTracing)(entityContext);
|
|
6878
7017
|
if (parentSpanContext) try {
|
|
6879
|
-
const laminarContext = typeof parentSpanContext === "string" ?
|
|
7018
|
+
const laminarContext = typeof parentSpanContext === "string" ? require_utils.deserializeLaminarSpanContext(parentSpanContext) : parentSpanContext;
|
|
6880
7019
|
Laminar._armDebugRuntimeFromContext(laminarContext.debug);
|
|
6881
|
-
const spanContext =
|
|
7020
|
+
const spanContext = require_utils.tryToOtelSpanContext(laminarContext);
|
|
6882
7021
|
entityContext = _opentelemetry_api.trace.setSpan(entityContext, _opentelemetry_api.trace.wrapSpanContext(spanContext));
|
|
6883
7022
|
} catch (e) {
|
|
6884
|
-
logger$5.warn("Failed to parse parent span context: " +
|
|
7023
|
+
logger$5.warn("Failed to parse parent span context: " + require_utils.errorMessage(e));
|
|
6885
7024
|
}
|
|
6886
7025
|
try {
|
|
6887
7026
|
if (contextProperties && Object.keys(contextProperties).length > 0) {
|
|
@@ -6892,16 +7031,16 @@ function observeBase({ name, contextProperties, spanAttributes, input, ignoreInp
|
|
|
6892
7031
|
});
|
|
6893
7032
|
}
|
|
6894
7033
|
} catch (e) {
|
|
6895
|
-
logger$5.warn("Failed to set context properties: " +
|
|
7034
|
+
logger$5.warn("Failed to set context properties: " + require_utils.errorMessage(e));
|
|
6896
7035
|
}
|
|
6897
7036
|
return _opentelemetry_api.context.with(entityContext, () => getTracer().startActiveSpan(name, { attributes: spanAttributes }, entityContext, (span) => {
|
|
6898
7037
|
if (shouldSendTraces() && !ignoreInput) try {
|
|
6899
7038
|
const spanInput = inputParameters ?? args;
|
|
6900
|
-
if (input !== void 0) span.setAttribute(
|
|
6901
|
-
else if (spanInput.length === 1 && typeof spanInput[0] === "object" && !(spanInput[0] instanceof Map)) span.setAttribute(
|
|
6902
|
-
else span.setAttribute(
|
|
7039
|
+
if (input !== void 0) span.setAttribute(require_utils.SPAN_INPUT, typeof input === "string" ? require_utils.truncateSpanPayload(input, "input") : serialize(input, "input"));
|
|
7040
|
+
else if (spanInput.length === 1 && typeof spanInput[0] === "object" && !(spanInput[0] instanceof Map)) span.setAttribute(require_utils.SPAN_INPUT, typeof spanInput[0] === "string" ? require_utils.truncateSpanPayload(spanInput[0], "input") : serialize(spanInput[0], "input"));
|
|
7041
|
+
else span.setAttribute(require_utils.SPAN_INPUT, serialize(spanInput.length > 0 ? spanInput : {}, "input"));
|
|
6903
7042
|
} catch (error) {
|
|
6904
|
-
logger$5.warn("Failed to serialize input: " +
|
|
7043
|
+
logger$5.warn("Failed to serialize input: " + require_utils.errorMessage(error));
|
|
6905
7044
|
}
|
|
6906
7045
|
let res;
|
|
6907
7046
|
try {
|
|
@@ -6911,7 +7050,7 @@ function observeBase({ name, contextProperties, spanAttributes, input, ignoreInp
|
|
|
6911
7050
|
span.recordException(error);
|
|
6912
7051
|
span.end();
|
|
6913
7052
|
} catch (error) {
|
|
6914
|
-
logger$5.warn("Failed to record exception and end span: " +
|
|
7053
|
+
logger$5.warn("Failed to record exception and end span: " + require_utils.errorMessage(error));
|
|
6915
7054
|
}
|
|
6916
7055
|
throw error;
|
|
6917
7056
|
}
|
|
@@ -6920,18 +7059,18 @@ function observeBase({ name, contextProperties, spanAttributes, input, ignoreInp
|
|
|
6920
7059
|
try {
|
|
6921
7060
|
streamInfo = getStream(resolvedRes);
|
|
6922
7061
|
} catch (error) {
|
|
6923
|
-
logger$5.warn("Failed to get stream info: " +
|
|
7062
|
+
logger$5.warn("Failed to get stream info: " + require_utils.errorMessage(error));
|
|
6924
7063
|
}
|
|
6925
7064
|
if (streamInfo.type !== null) return handleStreamResult(resolvedRes, streamInfo, span, ignoreOutput, serialize);
|
|
6926
7065
|
try {
|
|
6927
|
-
if (shouldSendTraces() && !ignoreOutput) span.setAttribute(
|
|
7066
|
+
if (shouldSendTraces() && !ignoreOutput) span.setAttribute(require_utils.SPAN_OUTPUT, serialize(resolvedRes));
|
|
6928
7067
|
} catch (error) {
|
|
6929
|
-
logger$5.warn("Failed to serialize async output: " +
|
|
7068
|
+
logger$5.warn("Failed to serialize async output: " + require_utils.errorMessage(error));
|
|
6930
7069
|
} finally {
|
|
6931
7070
|
try {
|
|
6932
7071
|
span.end();
|
|
6933
7072
|
} catch (error) {
|
|
6934
|
-
logger$5.warn("Failed to end span: " +
|
|
7073
|
+
logger$5.warn("Failed to end span: " + require_utils.errorMessage(error));
|
|
6935
7074
|
}
|
|
6936
7075
|
}
|
|
6937
7076
|
return resolvedRes;
|
|
@@ -6940,7 +7079,7 @@ function observeBase({ name, contextProperties, spanAttributes, input, ignoreInp
|
|
|
6940
7079
|
span.recordException(error);
|
|
6941
7080
|
span.end();
|
|
6942
7081
|
} catch (error) {
|
|
6943
|
-
logger$5.warn("Failed to record exception and end span: " +
|
|
7082
|
+
logger$5.warn("Failed to record exception and end span: " + require_utils.errorMessage(error));
|
|
6944
7083
|
}
|
|
6945
7084
|
throw error;
|
|
6946
7085
|
});
|
|
@@ -6948,18 +7087,18 @@ function observeBase({ name, contextProperties, spanAttributes, input, ignoreInp
|
|
|
6948
7087
|
try {
|
|
6949
7088
|
streamInfo = getStream(res);
|
|
6950
7089
|
} catch (error) {
|
|
6951
|
-
logger$5.warn("Failed to get stream info: " +
|
|
7090
|
+
logger$5.warn("Failed to get stream info: " + require_utils.errorMessage(error));
|
|
6952
7091
|
}
|
|
6953
7092
|
if (streamInfo.type !== null) return handleStreamResult(res, streamInfo, span, ignoreOutput, serialize);
|
|
6954
7093
|
try {
|
|
6955
|
-
if (shouldSendTraces() && !ignoreOutput) span.setAttribute(
|
|
7094
|
+
if (shouldSendTraces() && !ignoreOutput) span.setAttribute(require_utils.SPAN_OUTPUT, typeof res === "string" ? require_utils.truncateSpanPayload(res, "output") : serialize(res));
|
|
6956
7095
|
} catch (error) {
|
|
6957
|
-
logger$5.warn("Failed to serialize output: " +
|
|
7096
|
+
logger$5.warn("Failed to serialize output: " + require_utils.errorMessage(error));
|
|
6958
7097
|
} finally {
|
|
6959
7098
|
try {
|
|
6960
7099
|
span.end();
|
|
6961
7100
|
} catch (error) {
|
|
6962
|
-
logger$5.warn("Failed to end span: " +
|
|
7101
|
+
logger$5.warn("Failed to end span: " + require_utils.errorMessage(error));
|
|
6963
7102
|
}
|
|
6964
7103
|
}
|
|
6965
7104
|
return res;
|
|
@@ -6980,10 +7119,10 @@ const normalizePayload = (payload, seen) => {
|
|
|
6980
7119
|
}
|
|
6981
7120
|
return payload;
|
|
6982
7121
|
};
|
|
6983
|
-
const serialize = (payload, kind = "output") =>
|
|
7122
|
+
const serialize = (payload, kind = "output") => require_utils.truncateSpanPayload(JSON.stringify(normalizePayload(payload, /* @__PURE__ */ new WeakSet())), kind);
|
|
6984
7123
|
//#endregion
|
|
6985
7124
|
//#region src/decorators.ts
|
|
6986
|
-
const logger$4 =
|
|
7125
|
+
const logger$4 = require_utils.initializeLogger();
|
|
6987
7126
|
/**
|
|
6988
7127
|
* The main decorator entrypoint for Laminar. This is used to wrap
|
|
6989
7128
|
* functions and methods to create spans.
|
|
@@ -7066,7 +7205,7 @@ function withTracingLevel(tracingLevel, fn, ...args) {
|
|
|
7066
7205
|
const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY) ?? {};
|
|
7067
7206
|
entityContext = entityContext.setValue(ASSOCIATION_PROPERTIES_KEY, {
|
|
7068
7207
|
...currentAssociationProperties,
|
|
7069
|
-
|
|
7208
|
+
tracing_level: tracingLevel
|
|
7070
7209
|
});
|
|
7071
7210
|
const result = LaminarContextManager.runWithIsolatedContext([entityContext], () => fn(...args));
|
|
7072
7211
|
const newAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY) ?? {};
|
|
@@ -7089,14 +7228,14 @@ const buildContextProperties = (options) => {
|
|
|
7089
7228
|
let parentUserId;
|
|
7090
7229
|
let parentSessionId;
|
|
7091
7230
|
if (parentSpanContext) try {
|
|
7092
|
-
const laminarContext = typeof parentSpanContext === "string" ?
|
|
7231
|
+
const laminarContext = typeof parentSpanContext === "string" ? require_utils.deserializeLaminarSpanContext(parentSpanContext) : parentSpanContext;
|
|
7093
7232
|
parentMetadata = laminarContext.metadata;
|
|
7094
7233
|
parentTraceType = laminarContext.traceType;
|
|
7095
7234
|
parentTracingLevel = laminarContext.tracingLevel;
|
|
7096
7235
|
parentUserId = laminarContext.userId;
|
|
7097
7236
|
parentSessionId = laminarContext.sessionId;
|
|
7098
7237
|
} catch (e) {
|
|
7099
|
-
logger$4.warn("Failed to parse parent span context: " +
|
|
7238
|
+
logger$4.warn("Failed to parse parent span context: " + require_utils.errorMessage(e));
|
|
7100
7239
|
}
|
|
7101
7240
|
const contextProperties = {};
|
|
7102
7241
|
const sessionIdValue = options.sessionId ?? parentSessionId ?? ctxAssociationProperties.sessionId;
|
|
@@ -7126,14 +7265,14 @@ const buildContextProperties = (options) => {
|
|
|
7126
7265
|
*/
|
|
7127
7266
|
const buildSpanAttributes = (options) => {
|
|
7128
7267
|
const spanAttributes = {};
|
|
7129
|
-
if (options.spanType) spanAttributes[
|
|
7130
|
-
if (options.tags) spanAttributes[`${
|
|
7268
|
+
if (options.spanType) spanAttributes[require_utils.SPAN_TYPE] = options.spanType;
|
|
7269
|
+
if (options.tags) spanAttributes[`${require_utils.ASSOCIATION_PROPERTIES}.tags`] = Array.from(new Set(options.tags));
|
|
7131
7270
|
if (options.parentSpanContext) try {
|
|
7132
|
-
const laminarContext = typeof options.parentSpanContext === "string" ?
|
|
7133
|
-
if (laminarContext.spanPath) spanAttributes[
|
|
7134
|
-
if (laminarContext.spanIdsPath) spanAttributes[
|
|
7271
|
+
const laminarContext = typeof options.parentSpanContext === "string" ? require_utils.deserializeLaminarSpanContext(options.parentSpanContext) : options.parentSpanContext;
|
|
7272
|
+
if (laminarContext.spanPath) spanAttributes[require_utils.PARENT_SPAN_PATH] = laminarContext.spanPath;
|
|
7273
|
+
if (laminarContext.spanIdsPath) spanAttributes[require_utils.PARENT_SPAN_IDS_PATH] = laminarContext.spanIdsPath;
|
|
7135
7274
|
} catch (e) {
|
|
7136
|
-
logger$4.warn("Failed to parse parent span context for span attributes: " +
|
|
7275
|
+
logger$4.warn("Failed to parse parent span context for span attributes: " + require_utils.errorMessage(e));
|
|
7137
7276
|
}
|
|
7138
7277
|
return spanAttributes;
|
|
7139
7278
|
};
|
|
@@ -7265,12 +7404,12 @@ function observeExperimentalDecorator(config) {
|
|
|
7265
7404
|
}
|
|
7266
7405
|
//#endregion
|
|
7267
7406
|
//#region src/evaluations.ts
|
|
7268
|
-
|
|
7407
|
+
require_utils.loadEnv();
|
|
7269
7408
|
const DEFAULT_CONCURRENCY = 5;
|
|
7270
7409
|
const MAX_EXPORT_BATCH_SIZE = 64;
|
|
7271
|
-
const logger$3 =
|
|
7410
|
+
const logger$3 = require_utils.initializeLogger();
|
|
7272
7411
|
const getEvaluationUrl = (projectId, evaluationId, baseUrl, frontendPort) => {
|
|
7273
|
-
return `${
|
|
7412
|
+
return `${require_utils.getFrontendUrl(baseUrl, frontendPort)}/project/${projectId}/evaluations/${evaluationId}`;
|
|
7274
7413
|
};
|
|
7275
7414
|
const SESSION_METADATA_KEY = "rollout.session_id";
|
|
7276
7415
|
/**
|
|
@@ -7373,7 +7512,7 @@ var Evaluation = class {
|
|
|
7373
7512
|
this.traceExportBatchSize = config.traceExportBatchSize ?? MAX_EXPORT_BATCH_SIZE;
|
|
7374
7513
|
}
|
|
7375
7514
|
if (Laminar.initialized()) {
|
|
7376
|
-
this.client = new
|
|
7515
|
+
this.client = new require_utils.LaminarClient({
|
|
7377
7516
|
baseUrl: Laminar.getHttpUrl(),
|
|
7378
7517
|
projectApiKey: Laminar.getProjectApiKey()
|
|
7379
7518
|
});
|
|
@@ -7386,7 +7525,7 @@ var Evaluation = class {
|
|
|
7386
7525
|
const httpUrl = config?.baseHttpUrl ?? url;
|
|
7387
7526
|
const httpPort = config?.httpPort ?? (httpUrl.match(/:\d{1,5}$/g) ? parseInt(httpUrl.match(/:\d{1,5}$/g)[0].slice(1)) : 443);
|
|
7388
7527
|
const baseHttpUrl = `${httpUrl.replace(/\/$/, "").replace(/:\d{1,5}$/g, "")}:${httpPort}`;
|
|
7389
|
-
this.client = new
|
|
7528
|
+
this.client = new require_utils.LaminarClient({
|
|
7390
7529
|
baseUrl: baseHttpUrl,
|
|
7391
7530
|
projectApiKey: key
|
|
7392
7531
|
});
|
|
@@ -7412,7 +7551,7 @@ var Evaluation = class {
|
|
|
7412
7551
|
if (datasets.length > 0) source.id = datasets[0].id;
|
|
7413
7552
|
else logger$3.warn(`Dataset ${source.name} not found`);
|
|
7414
7553
|
} catch (error) {
|
|
7415
|
-
logger$3.warn(`Error getting dataset ${source.name}: ` +
|
|
7554
|
+
logger$3.warn(`Error getting dataset ${source.name}: ` + require_utils.errorMessage(error));
|
|
7416
7555
|
}
|
|
7417
7556
|
}
|
|
7418
7557
|
let resultDatapoints;
|
|
@@ -7446,7 +7585,7 @@ var Evaluation = class {
|
|
|
7446
7585
|
projectId: "",
|
|
7447
7586
|
evaluationId: "",
|
|
7448
7587
|
url: "",
|
|
7449
|
-
errorMessage:
|
|
7588
|
+
errorMessage: require_utils.errorMessage(e)
|
|
7450
7589
|
};
|
|
7451
7590
|
}
|
|
7452
7591
|
}
|
|
@@ -7461,7 +7600,7 @@ var Evaluation = class {
|
|
|
7461
7600
|
}
|
|
7462
7601
|
});
|
|
7463
7602
|
return LaminarContextManager.runWithIsolatedContext([entityContext], async () => {
|
|
7464
|
-
const semaphore = new
|
|
7603
|
+
const semaphore = new require_utils.Semaphore(this.concurrencyLimit);
|
|
7465
7604
|
const tasks = [];
|
|
7466
7605
|
const evaluateTask = async (datapoint, index) => {
|
|
7467
7606
|
try {
|
|
@@ -7485,20 +7624,20 @@ var Evaluation = class {
|
|
|
7485
7624
|
name: "evaluation",
|
|
7486
7625
|
traceType: "EVALUATION"
|
|
7487
7626
|
}, async () => {
|
|
7488
|
-
_opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()).setAttribute(
|
|
7627
|
+
_opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()).setAttribute(require_utils.SPAN_TYPE, "EVALUATION");
|
|
7489
7628
|
const executorSpan = Laminar.startSpan({
|
|
7490
7629
|
name: "executor",
|
|
7491
7630
|
input: datapoint.data
|
|
7492
7631
|
});
|
|
7493
|
-
executorSpan.setAttribute(
|
|
7494
|
-
const executorSpanId =
|
|
7495
|
-
const datapointId =
|
|
7632
|
+
executorSpan.setAttribute(require_utils.SPAN_TYPE, "EXECUTOR");
|
|
7633
|
+
const executorSpanId = require_utils.otelSpanIdToUUID(executorSpan.spanContext().spanId);
|
|
7634
|
+
const datapointId = require_utils.newUUID();
|
|
7496
7635
|
const partialDatapoint = {
|
|
7497
7636
|
id: datapointId,
|
|
7498
7637
|
data: datapoint.data,
|
|
7499
7638
|
target: datapoint.target,
|
|
7500
7639
|
metadata: datapoint.metadata,
|
|
7501
|
-
traceId:
|
|
7640
|
+
traceId: require_utils.otelTraceIdToUUID(_opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()).spanContext().traceId),
|
|
7502
7641
|
executorSpanId,
|
|
7503
7642
|
index
|
|
7504
7643
|
};
|
|
@@ -7524,13 +7663,13 @@ var Evaluation = class {
|
|
|
7524
7663
|
if (evaluator instanceof HumanEvaluator) {
|
|
7525
7664
|
const activeSpan = _opentelemetry_api.trace.getSpan(LaminarContextManager.getContext());
|
|
7526
7665
|
if (activeSpan) {
|
|
7527
|
-
activeSpan.setAttribute(
|
|
7528
|
-
if (evaluator.options) activeSpan.setAttribute(
|
|
7666
|
+
activeSpan.setAttribute(require_utils.SPAN_TYPE, "HUMAN_EVALUATOR");
|
|
7667
|
+
if (evaluator.options) activeSpan.setAttribute(require_utils.HUMAN_EVALUATOR_OPTIONS, JSON.stringify(evaluator.options));
|
|
7529
7668
|
}
|
|
7530
7669
|
return null;
|
|
7531
7670
|
} else {
|
|
7532
7671
|
const activeSpan = _opentelemetry_api.trace.getSpan(LaminarContextManager.getContext());
|
|
7533
|
-
if (activeSpan) activeSpan.setAttribute(
|
|
7672
|
+
if (activeSpan) activeSpan.setAttribute(require_utils.SPAN_TYPE, "EVALUATOR");
|
|
7534
7673
|
return await evaluator(output, target, data);
|
|
7535
7674
|
}
|
|
7536
7675
|
}, output, datapoint.target, datapoint.data);
|
|
@@ -7553,7 +7692,7 @@ var Evaluation = class {
|
|
|
7553
7692
|
target,
|
|
7554
7693
|
metadata: datapoint.metadata,
|
|
7555
7694
|
scores,
|
|
7556
|
-
traceId:
|
|
7695
|
+
traceId: require_utils.otelTraceIdToUUID(_opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()).spanContext().traceId),
|
|
7557
7696
|
executorSpanId,
|
|
7558
7697
|
index
|
|
7559
7698
|
};
|
|
@@ -7612,7 +7751,7 @@ async function evaluate({ data, executor, evaluators, groupName, name, metadata,
|
|
|
7612
7751
|
}
|
|
7613
7752
|
//#endregion
|
|
7614
7753
|
//#region src/integrations/eve.ts
|
|
7615
|
-
const logger$2 =
|
|
7754
|
+
const logger$2 = require_utils.initializeLogger();
|
|
7616
7755
|
const EVE_REPORTER_TRACER_NAME = "@lmnr-ai/lmnr/eve-reporter";
|
|
7617
7756
|
const EVE_CLIENT_MODULE = "eve/client";
|
|
7618
7757
|
const TRACEPARENT_HEADER$1 = "traceparent";
|
|
@@ -7660,7 +7799,7 @@ const openSessionTrace = (clientSession) => {
|
|
|
7660
7799
|
if (minted) traceByClientSession.set(clientSession, minted);
|
|
7661
7800
|
return minted;
|
|
7662
7801
|
} catch (error) {
|
|
7663
|
-
logger$2.warn(`Laminar eve reporter: failed to open a session trace: ` +
|
|
7802
|
+
logger$2.warn(`Laminar eve reporter: failed to open a session trace: ` + require_utils.errorMessage(error));
|
|
7664
7803
|
return;
|
|
7665
7804
|
}
|
|
7666
7805
|
};
|
|
@@ -7688,11 +7827,11 @@ const recordEveSessionId = (response, sessionTrace) => {
|
|
|
7688
7827
|
const buildTraceHeaders = (rootSpan, executorSpan) => {
|
|
7689
7828
|
const spanContext = executorSpan.spanContext();
|
|
7690
7829
|
const laminarContext = {
|
|
7691
|
-
traceId:
|
|
7692
|
-
spanId:
|
|
7830
|
+
traceId: require_utils.otelTraceIdToUUID(spanContext.traceId),
|
|
7831
|
+
spanId: require_utils.otelSpanIdToUUID(spanContext.spanId),
|
|
7693
7832
|
isRemote: true,
|
|
7694
7833
|
spanPath: [ROOT_SPAN_NAME, EXECUTOR_SPAN_NAME],
|
|
7695
|
-
spanIdsPath: [
|
|
7834
|
+
spanIdsPath: [require_utils.otelSpanIdToUUID(rootSpan.spanContext().spanId), require_utils.otelSpanIdToUUID(spanContext.spanId)]
|
|
7696
7835
|
};
|
|
7697
7836
|
return {
|
|
7698
7837
|
[TRACEPARENT_HEADER$1]: `00-${spanContext.traceId}-${spanContext.spanId}-01`,
|
|
@@ -7729,7 +7868,7 @@ const bindEvalContext = (sessionTrace) => {
|
|
|
7729
7868
|
try {
|
|
7730
7869
|
LaminarContextManager.pushContext(_opentelemetry_api.trace.setSpan(_opentelemetry_api.ROOT_CONTEXT, sessionTrace.rootSpan));
|
|
7731
7870
|
} catch (error) {
|
|
7732
|
-
logger$2.warn(`Laminar eve reporter: failed to bind the eval context: ` +
|
|
7871
|
+
logger$2.warn(`Laminar eve reporter: failed to bind the eval context: ` + require_utils.errorMessage(error));
|
|
7733
7872
|
}
|
|
7734
7873
|
};
|
|
7735
7874
|
/**
|
|
@@ -7752,7 +7891,7 @@ const patchEveClientSession = (sessionClass) => {
|
|
|
7752
7891
|
try {
|
|
7753
7892
|
recordEveSessionId(response, sessionTrace);
|
|
7754
7893
|
} catch (error) {
|
|
7755
|
-
logger$2.warn(`Laminar eve reporter: failed to record the eve session id: ` +
|
|
7894
|
+
logger$2.warn(`Laminar eve reporter: failed to record the eve session id: ` + require_utils.errorMessage(error));
|
|
7756
7895
|
}
|
|
7757
7896
|
return response;
|
|
7758
7897
|
};
|
|
@@ -7814,7 +7953,7 @@ const failedAssertionsMetadata = (assertions) => {
|
|
|
7814
7953
|
}));
|
|
7815
7954
|
return failed.length > 0 ? { failedAssertions: failed } : {};
|
|
7816
7955
|
};
|
|
7817
|
-
const traceIdFromSpan = (span) =>
|
|
7956
|
+
const traceIdFromSpan = (span) => require_utils.otelTraceIdToUUID(span.spanContext().traceId);
|
|
7818
7957
|
/**
|
|
7819
7958
|
* A Laminar reporter for eve evals. Register it globally in `evals.config.ts`
|
|
7820
7959
|
* or per-eval via the `reporters` field — eve runs and grades each eval, then
|
|
@@ -7878,7 +8017,7 @@ var LaminarReporter = class {
|
|
|
7878
8017
|
this.index = 0;
|
|
7879
8018
|
this.finishOpenSessionTraces();
|
|
7880
8019
|
try {
|
|
7881
|
-
this.client = this.options.client ?? new
|
|
8020
|
+
this.client = this.options.client ?? new require_utils.LaminarClient({
|
|
7882
8021
|
baseUrl: this.options.baseUrl,
|
|
7883
8022
|
projectApiKey: this.options.projectApiKey
|
|
7884
8023
|
});
|
|
@@ -7895,10 +8034,10 @@ var LaminarReporter = class {
|
|
|
7895
8034
|
evalCount: evaluations.length
|
|
7896
8035
|
});
|
|
7897
8036
|
this.evalId = evaluation.id;
|
|
7898
|
-
const url =
|
|
8037
|
+
const url = require_utils.getFrontendUrl(this.client.configuredBaseUrl ?? this.options.baseUrl) + `/project/${evaluation.projectId}/evaluations/${evaluation.id}`;
|
|
7899
8038
|
process.stdout.write(`\nLaminar: check eve eval results at ${url}\n`);
|
|
7900
8039
|
} catch (error) {
|
|
7901
|
-
logger$2.error(`Laminar eve reporter: failed to start run: ${
|
|
8040
|
+
logger$2.error(`Laminar eve reporter: failed to start run: ${require_utils.errorMessage(error)}`);
|
|
7902
8041
|
if (!this.evalId) {
|
|
7903
8042
|
this.client = void 0;
|
|
7904
8043
|
if (activeSessionTraceFactory === this.sessionTraceFactory) activeSessionTraceFactory = null;
|
|
@@ -7954,7 +8093,7 @@ var LaminarReporter = class {
|
|
|
7954
8093
|
});
|
|
7955
8094
|
} catch (error) {
|
|
7956
8095
|
if (traceResolution.source === "reporter-fallback") traceResolution.span.recordException(error);
|
|
7957
|
-
logger$2.error(`Laminar eve reporter: failed to report eval "${result.id ?? index}": ${
|
|
8096
|
+
logger$2.error(`Laminar eve reporter: failed to report eval "${result.id ?? index}": ${require_utils.errorMessage(error)}`);
|
|
7958
8097
|
} finally {
|
|
7959
8098
|
if (traceResolution.source === "reporter-fallback") traceResolution.span.end();
|
|
7960
8099
|
if (traceResolution.source === "propagated") this.finishSessionTrace(traceResolution.sessionTrace, {
|
|
@@ -8008,7 +8147,7 @@ var LaminarReporter = class {
|
|
|
8008
8147
|
try {
|
|
8009
8148
|
await Laminar.flush();
|
|
8010
8149
|
} catch (error) {
|
|
8011
|
-
logger$2.warn(`Laminar eve reporter: failed to flush spans: ` +
|
|
8150
|
+
logger$2.warn(`Laminar eve reporter: failed to flush spans: ` + require_utils.errorMessage(error));
|
|
8012
8151
|
}
|
|
8013
8152
|
}
|
|
8014
8153
|
/**
|
|
@@ -8019,16 +8158,16 @@ var LaminarReporter = class {
|
|
|
8019
8158
|
mintSessionTrace() {
|
|
8020
8159
|
const tracer = getTracer();
|
|
8021
8160
|
const rootSpan = tracer.startSpan(ROOT_SPAN_NAME, { attributes: {
|
|
8022
|
-
[
|
|
8023
|
-
[
|
|
8161
|
+
[require_utils.SPAN_TYPE]: "EVALUATION",
|
|
8162
|
+
[require_utils.TRACE_TYPE]: "EVALUATION",
|
|
8024
8163
|
"lmnr.eve.reporter": EVE_REPORTER_TRACER_NAME
|
|
8025
8164
|
} }, _opentelemetry_api.ROOT_CONTEXT);
|
|
8026
8165
|
const executorSpan = tracer.startSpan(EXECUTOR_SPAN_NAME, { attributes: {
|
|
8027
|
-
[
|
|
8028
|
-
[
|
|
8166
|
+
[require_utils.SPAN_TYPE]: "EXECUTOR",
|
|
8167
|
+
[require_utils.TRACE_TYPE]: "EVALUATION"
|
|
8029
8168
|
} }, _opentelemetry_api.trace.setSpan(_opentelemetry_api.ROOT_CONTEXT, rootSpan));
|
|
8030
8169
|
const sessionTrace = {
|
|
8031
|
-
traceId:
|
|
8170
|
+
traceId: require_utils.otelTraceIdToUUID(rootSpan.spanContext().traceId),
|
|
8032
8171
|
rootSpan,
|
|
8033
8172
|
executorSpan,
|
|
8034
8173
|
tracer,
|
|
@@ -8050,12 +8189,12 @@ var LaminarReporter = class {
|
|
|
8050
8189
|
"lmnr.eve.eval.id": grade.evalId ?? "",
|
|
8051
8190
|
"lmnr.eve.eval.verdict": grade.verdict ?? "",
|
|
8052
8191
|
"lmnr.eve.eval.status": grade.status ?? "",
|
|
8053
|
-
[
|
|
8192
|
+
[require_utils.SPAN_INPUT]: JSON.stringify({
|
|
8054
8193
|
evalId: grade.evalId,
|
|
8055
8194
|
description: grade.description
|
|
8056
8195
|
}),
|
|
8057
|
-
[
|
|
8058
|
-
...
|
|
8196
|
+
[require_utils.SPAN_OUTPUT]: JSON.stringify(grade.output ?? null),
|
|
8197
|
+
...require_utils.metadataToAttributes({
|
|
8059
8198
|
source: "eve",
|
|
8060
8199
|
eveEvalId: grade.evalId ?? "",
|
|
8061
8200
|
eveEvalDescription: grade.description ?? "",
|
|
@@ -8063,12 +8202,12 @@ var LaminarReporter = class {
|
|
|
8063
8202
|
eveSessionId: [...sessionTrace.sessionIds].join(",")
|
|
8064
8203
|
})
|
|
8065
8204
|
});
|
|
8066
|
-
sessionTrace.executorSpan.setAttribute(
|
|
8205
|
+
sessionTrace.executorSpan.setAttribute(require_utils.SPAN_OUTPUT, JSON.stringify(grade.output ?? null));
|
|
8067
8206
|
this.recordEvaluatorSpans(sessionTrace, grade.assertions ?? []);
|
|
8068
8207
|
sessionTrace.executorSpan.end();
|
|
8069
8208
|
sessionTrace.rootSpan.end();
|
|
8070
8209
|
} catch (error) {
|
|
8071
|
-
logger$2.warn(`Laminar eve reporter: failed to finish the session trace: ` +
|
|
8210
|
+
logger$2.warn(`Laminar eve reporter: failed to finish the session trace: ` + require_utils.errorMessage(error));
|
|
8072
8211
|
}
|
|
8073
8212
|
}
|
|
8074
8213
|
/**
|
|
@@ -8089,9 +8228,9 @@ var LaminarReporter = class {
|
|
|
8089
8228
|
message: assertion.message
|
|
8090
8229
|
});
|
|
8091
8230
|
sessionTrace.tracer.startSpan(name, { attributes: {
|
|
8092
|
-
[
|
|
8093
|
-
[
|
|
8094
|
-
[
|
|
8231
|
+
[require_utils.SPAN_TYPE]: "EVALUATOR",
|
|
8232
|
+
[require_utils.TRACE_TYPE]: "EVALUATION",
|
|
8233
|
+
[require_utils.SPAN_OUTPUT]: output
|
|
8095
8234
|
} }, rootContext).end();
|
|
8096
8235
|
}
|
|
8097
8236
|
}
|
|
@@ -8111,14 +8250,14 @@ var LaminarReporter = class {
|
|
|
8111
8250
|
sessionTrace
|
|
8112
8251
|
};
|
|
8113
8252
|
const span = getTracer().startSpan(`eve eval ${evalId}`, { attributes: {
|
|
8114
|
-
[
|
|
8115
|
-
[
|
|
8253
|
+
[require_utils.SPAN_TYPE]: "EVALUATION",
|
|
8254
|
+
[require_utils.TRACE_TYPE]: "EVALUATION",
|
|
8116
8255
|
"lmnr.eve.reporter": EVE_REPORTER_TRACER_NAME,
|
|
8117
8256
|
"lmnr.eve.eval.id": evalId,
|
|
8118
8257
|
"lmnr.eve.eval.verdict": verdict ?? "",
|
|
8119
8258
|
...sessionId ? { "lmnr.eve.session.id": sessionId } : {},
|
|
8120
8259
|
"lmnr.eve.trace_resolution": "reporter-fallback",
|
|
8121
|
-
...
|
|
8260
|
+
...require_utils.metadataToAttributes({
|
|
8122
8261
|
source: "eve",
|
|
8123
8262
|
eveEvalId: evalId,
|
|
8124
8263
|
eveEvalDescription: description ?? "",
|
|
@@ -8261,10 +8400,10 @@ const normalizeProvider$1 = (provider) => {
|
|
|
8261
8400
|
};
|
|
8262
8401
|
const applyUsage = (attributes, usage) => {
|
|
8263
8402
|
if (!usage || typeof usage !== "object") return;
|
|
8264
|
-
if (typeof usage.inputTokens === "number") attributes[
|
|
8265
|
-
if (typeof usage.outputTokens === "number") attributes[
|
|
8266
|
-
if (typeof usage.totalTokens === "number") attributes[
|
|
8267
|
-
else if (typeof usage.inputTokens === "number" || typeof usage.outputTokens === "number") attributes[
|
|
8403
|
+
if (typeof usage.inputTokens === "number") attributes[require_utils.LaminarAttributes.INPUT_TOKEN_COUNT] = usage.inputTokens;
|
|
8404
|
+
if (typeof usage.outputTokens === "number") attributes[require_utils.LaminarAttributes.OUTPUT_TOKEN_COUNT] = usage.outputTokens;
|
|
8405
|
+
if (typeof usage.totalTokens === "number") attributes[require_utils.LaminarAttributes.TOTAL_TOKEN_COUNT] = usage.totalTokens;
|
|
8406
|
+
else if (typeof usage.inputTokens === "number" || typeof usage.outputTokens === "number") attributes[require_utils.LaminarAttributes.TOTAL_TOKEN_COUNT] = (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);
|
|
8268
8407
|
if (typeof usage.reasoningTokens === "number") attributes["gen_ai.usage.reasoning_tokens"] = usage.reasoningTokens;
|
|
8269
8408
|
else if (typeof usage.outputTokenDetails?.reasoningTokens === "number") attributes["gen_ai.usage.reasoning_tokens"] = usage.outputTokenDetails.reasoningTokens;
|
|
8270
8409
|
if (typeof usage.cachedInputTokens === "number") attributes["gen_ai.usage.cache_read_input_tokens"] = usage.cachedInputTokens;
|
|
@@ -8310,11 +8449,11 @@ const applyFinishReason = (span, finishReason) => {
|
|
|
8310
8449
|
const applyRequestModelAttributes = (span, event) => {
|
|
8311
8450
|
if (typeof event.provider === "string") {
|
|
8312
8451
|
const provider = normalizeProvider$1(event.provider);
|
|
8313
|
-
if (provider) span.setAttribute(
|
|
8452
|
+
if (provider) span.setAttribute(require_utils.LaminarAttributes.PROVIDER, provider);
|
|
8314
8453
|
span.setAttribute("ai.model.provider", event.provider);
|
|
8315
8454
|
}
|
|
8316
8455
|
if (typeof event.modelId === "string") {
|
|
8317
|
-
span.setAttribute(
|
|
8456
|
+
span.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, event.modelId);
|
|
8318
8457
|
span.setAttribute("ai.model.id", event.modelId);
|
|
8319
8458
|
}
|
|
8320
8459
|
};
|
|
@@ -8822,7 +8961,7 @@ const AI_FUNCTIONS = [
|
|
|
8822
8961
|
* falls back to the older `experimental_telemetry: { tracer }` path.
|
|
8823
8962
|
*/
|
|
8824
8963
|
const isAISDKv7 = (ai) => typeof ai.registerTelemetry === "function";
|
|
8825
|
-
const logger$1 =
|
|
8964
|
+
const logger$1 = require_utils.initializeLogger();
|
|
8826
8965
|
let wrapAISDKv7WarnedOnce = false;
|
|
8827
8966
|
const wrapAISDK = (ai) => {
|
|
8828
8967
|
const wrapped = {};
|
|
@@ -8941,8 +9080,8 @@ const getAiSdkPackageVersions = () => {
|
|
|
8941
9080
|
*/
|
|
8942
9081
|
const buildAiSdkInstrumentationAttributes = () => {
|
|
8943
9082
|
const { aiVersion, aiSdkPackages } = getAiSdkPackageVersions();
|
|
8944
|
-
const attributes = { [
|
|
8945
|
-
if (aiVersion) attributes[
|
|
9083
|
+
const attributes = { [require_utils.SPAN_INSTRUMENTATION_SCOPE_NAME]: "ai" };
|
|
9084
|
+
if (aiVersion) attributes[require_utils.SPAN_INSTRUMENTATION_SCOPE_VERSION] = aiVersion;
|
|
8946
9085
|
for (const [pkg, version] of Object.entries(aiSdkPackages)) attributes[`lmnr.span.instrumentation.${pkg}.version`] = version;
|
|
8947
9086
|
return attributes;
|
|
8948
9087
|
};
|
|
@@ -8972,7 +9111,7 @@ var LaminarAiSdkTelemetry = class {
|
|
|
8972
9111
|
this.toolByCallId = /* @__PURE__ */ new Map();
|
|
8973
9112
|
this.activeStreamStepByCallId = /* @__PURE__ */ new Map();
|
|
8974
9113
|
this.promptByCallId = /* @__PURE__ */ new Map();
|
|
8975
|
-
this.logger =
|
|
9114
|
+
this.logger = require_utils.initializeLogger();
|
|
8976
9115
|
this.onStart = (event) => {
|
|
8977
9116
|
const callId = event?.callId;
|
|
8978
9117
|
if (!callId) return;
|
|
@@ -8983,7 +9122,7 @@ var LaminarAiSdkTelemetry = class {
|
|
|
8983
9122
|
const span = tracer.startSpan(spanName, {
|
|
8984
9123
|
kind: _opentelemetry_api.SpanKind.CLIENT,
|
|
8985
9124
|
attributes: {
|
|
8986
|
-
[
|
|
9125
|
+
[require_utils.SPAN_TYPE]: "DEFAULT",
|
|
8987
9126
|
...buildAiSdkInstrumentationAttributes(),
|
|
8988
9127
|
...typeof event.functionId === "string" ? {
|
|
8989
9128
|
"operation.name": event.functionId,
|
|
@@ -8992,24 +9131,24 @@ var LaminarAiSdkTelemetry = class {
|
|
|
8992
9131
|
}
|
|
8993
9132
|
}, parentCtx);
|
|
8994
9133
|
const spanCtx = _opentelemetry_api.trace.setSpan(parentCtx, span);
|
|
8995
|
-
span.setAttribute(
|
|
9134
|
+
span.setAttribute(require_utils.SPAN_TYPE, "DEFAULT");
|
|
8996
9135
|
if (typeof event.operationId === "string") span.setAttribute("ai.operation", event.operationId);
|
|
8997
9136
|
if (typeof event.provider === "string") {
|
|
8998
9137
|
const provider = normalizeProvider$1(event.provider);
|
|
8999
|
-
if (provider) span.setAttribute(
|
|
9138
|
+
if (provider) span.setAttribute(require_utils.LaminarAttributes.PROVIDER, provider);
|
|
9000
9139
|
}
|
|
9001
9140
|
if (typeof event.modelId === "string") {
|
|
9002
|
-
span.setAttribute(
|
|
9141
|
+
span.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, event.modelId);
|
|
9003
9142
|
span.setAttribute("ai.model.id", event.modelId);
|
|
9004
9143
|
}
|
|
9005
9144
|
if (typeof event.functionId === "string") span.setAttribute("ai.functionId", event.functionId);
|
|
9006
|
-
if (event.operationId === "ai.embed" || event.operationId === "ai.embedMany" || event.operationId === "ai.rerank") span.setAttribute(
|
|
9145
|
+
if (event.operationId === "ai.embed" || event.operationId === "ai.embedMany" || event.operationId === "ai.rerank") span.setAttribute(require_utils.SPAN_TYPE, "LLM");
|
|
9007
9146
|
if (this.recordInputs) {
|
|
9008
9147
|
if (Array.isArray(event.messages) || event.system !== void 0 || event.instructions !== void 0) {
|
|
9009
9148
|
const msgs = verbatimStandardizedMessages(event);
|
|
9010
|
-
if (msgs.length > 0) span.setAttribute(
|
|
9011
|
-
} else if (event.value !== void 0) span.setAttribute(
|
|
9012
|
-
else if (event.query !== void 0 || event.documents !== void 0) span.setAttribute(
|
|
9149
|
+
if (msgs.length > 0) span.setAttribute(require_utils.SPAN_INPUT, serializeJSON$1(msgs));
|
|
9150
|
+
} else if (event.value !== void 0) span.setAttribute(require_utils.SPAN_INPUT, serializeJSON$1(event.value));
|
|
9151
|
+
else if (event.query !== void 0 || event.documents !== void 0) span.setAttribute(require_utils.SPAN_INPUT, serializeJSON$1({
|
|
9013
9152
|
query: event.query,
|
|
9014
9153
|
documents: event.documents
|
|
9015
9154
|
}));
|
|
@@ -9035,12 +9174,12 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9035
9174
|
if (!op) return;
|
|
9036
9175
|
const span = getTracer().startSpan(`ai.step`, { kind: _opentelemetry_api.SpanKind.CLIENT }, op.ctx);
|
|
9037
9176
|
const spanCtx = _opentelemetry_api.trace.setSpan(op.ctx, span);
|
|
9038
|
-
span.setAttribute(
|
|
9177
|
+
span.setAttribute(require_utils.SPAN_TYPE, "DEFAULT");
|
|
9039
9178
|
span.setAttributes(buildAiSdkInstrumentationAttributes());
|
|
9040
9179
|
span.setAttribute("ai.step.number", stepNumber);
|
|
9041
9180
|
if (this.recordInputs) {
|
|
9042
9181
|
const msgs = verbatimStandardizedMessages(event);
|
|
9043
|
-
if (msgs.length > 0) span.setAttribute(
|
|
9182
|
+
if (msgs.length > 0) span.setAttribute(require_utils.SPAN_INPUT, serializeJSON$1(msgs));
|
|
9044
9183
|
}
|
|
9045
9184
|
this.stepByKey.set(stepKey(callId, stepNumber), {
|
|
9046
9185
|
span,
|
|
@@ -9056,14 +9195,14 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9056
9195
|
const parentCtx = step?.ctx ?? this.operationByCallId.get(callId)?.ctx;
|
|
9057
9196
|
if (!parentCtx) return;
|
|
9058
9197
|
const span = getTracer().startSpan(`ai.llm ${event.provider ?? ""}:${event.modelId ?? ""}`, { kind: _opentelemetry_api.SpanKind.CLIENT }, parentCtx);
|
|
9059
|
-
span.setAttribute(
|
|
9198
|
+
span.setAttribute(require_utils.SPAN_TYPE, "LLM");
|
|
9060
9199
|
span.setAttributes(buildAiSdkInstrumentationAttributes());
|
|
9061
9200
|
applyRequestModelAttributes(span, event);
|
|
9062
9201
|
if (this.recordInputs) {
|
|
9063
9202
|
if (event.tools) try {
|
|
9064
9203
|
span.setAttribute("gen_ai.tool.definitions", JSON.stringify(event.tools));
|
|
9065
9204
|
} catch (e) {
|
|
9066
|
-
this.logger.debug(`Failed to record span tool definitions: ${
|
|
9205
|
+
this.logger.debug(`Failed to record span tool definitions: ${require_utils.errorMessage(e)}`);
|
|
9067
9206
|
}
|
|
9068
9207
|
const serialized = this.promptByCallId.get(callId);
|
|
9069
9208
|
if (serialized !== void 0) span.setAttribute("gen_ai.input.messages", serialized);
|
|
@@ -9083,9 +9222,9 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9083
9222
|
const span = llm.span;
|
|
9084
9223
|
if (typeof event.provider === "string") {
|
|
9085
9224
|
const provider = normalizeProvider$1(event.provider);
|
|
9086
|
-
if (provider) span.setAttribute(
|
|
9225
|
+
if (provider) span.setAttribute(require_utils.LaminarAttributes.PROVIDER, provider);
|
|
9087
9226
|
}
|
|
9088
|
-
if (typeof event.modelId === "string") span.setAttribute(
|
|
9227
|
+
if (typeof event.modelId === "string") span.setAttribute(require_utils.LaminarAttributes.RESPONSE_MODEL, event.modelId);
|
|
9089
9228
|
if (typeof event.finishReason === "string") applyFinishReason(span, event.finishReason);
|
|
9090
9229
|
if (typeof event.responseId === "string") span.setAttribute("gen_ai.response.id", event.responseId);
|
|
9091
9230
|
applyUsageToSpan(span, event.usage);
|
|
@@ -9140,7 +9279,7 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9140
9279
|
if (typeof event.finishReason === "string") applyFinishReason(step.span, event.finishReason);
|
|
9141
9280
|
if (this.recordOutputs) {
|
|
9142
9281
|
const outputMessages = buildVerbatimOutputMessages(Array.isArray(event.content) ? event.content : void 0);
|
|
9143
|
-
if (outputMessages) step.span.setAttribute(
|
|
9282
|
+
if (outputMessages) step.span.setAttribute(require_utils.SPAN_OUTPUT, outputMessages);
|
|
9144
9283
|
}
|
|
9145
9284
|
step.span.setStatus({ code: _opentelemetry_api.SpanStatusCode.OK });
|
|
9146
9285
|
step.span.end();
|
|
@@ -9152,7 +9291,7 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9152
9291
|
const op = this.operationByCallId.get(callId);
|
|
9153
9292
|
if (!op) return;
|
|
9154
9293
|
const span = getTracer().startSpan(`ai.llm ${event.provider ?? ""}:${event.modelId ?? ""}`, { kind: _opentelemetry_api.SpanKind.CLIENT }, op.ctx);
|
|
9155
|
-
span.setAttribute(
|
|
9294
|
+
span.setAttribute(require_utils.SPAN_TYPE, "LLM");
|
|
9156
9295
|
span.setAttributes(buildAiSdkInstrumentationAttributes());
|
|
9157
9296
|
applyRequestModelAttributes(span, event);
|
|
9158
9297
|
if (this.recordInputs && Array.isArray(event?.promptMessages)) {
|
|
@@ -9173,7 +9312,7 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9173
9312
|
if (typeof event.finishReason === "string") applyFinishReason(llm.span, event.finishReason);
|
|
9174
9313
|
const response = event?.response;
|
|
9175
9314
|
if (response && typeof response === "object") {
|
|
9176
|
-
if (typeof response.modelId === "string") llm.span.setAttribute(
|
|
9315
|
+
if (typeof response.modelId === "string") llm.span.setAttribute(require_utils.LaminarAttributes.RESPONSE_MODEL, response.modelId);
|
|
9177
9316
|
if (typeof response.id === "string") llm.span.setAttribute("gen_ai.response.id", response.id);
|
|
9178
9317
|
}
|
|
9179
9318
|
applyUsageToSpan(llm.span, event.usage);
|
|
@@ -9196,14 +9335,14 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9196
9335
|
if (!parentCtx) return;
|
|
9197
9336
|
const span = getTracer().startSpan(`ai.tool ${toolName ?? "unknown"}`, { kind: _opentelemetry_api.SpanKind.CLIENT }, parentCtx);
|
|
9198
9337
|
const spanCtx = _opentelemetry_api.trace.setSpan(parentCtx, span);
|
|
9199
|
-
span.setAttribute(
|
|
9338
|
+
span.setAttribute(require_utils.SPAN_TYPE, "TOOL");
|
|
9200
9339
|
span.setAttributes(buildAiSdkInstrumentationAttributes());
|
|
9201
9340
|
if (toolName) span.setAttribute("ai.toolCall.name", toolName);
|
|
9202
9341
|
span.setAttribute("ai.toolCall.id", toolCallId);
|
|
9203
9342
|
if (this.recordInputs && toolCall?.input !== void 0) {
|
|
9204
9343
|
const serialized = serializeJSON$1(toolCall.input);
|
|
9205
9344
|
span.setAttribute("ai.toolCall.args", serialized);
|
|
9206
|
-
span.setAttribute(
|
|
9345
|
+
span.setAttribute(require_utils.SPAN_INPUT, serialized);
|
|
9207
9346
|
}
|
|
9208
9347
|
this.toolByCallId.set(toolCallId, {
|
|
9209
9348
|
span,
|
|
@@ -9228,14 +9367,14 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9228
9367
|
message
|
|
9229
9368
|
});
|
|
9230
9369
|
if (this.recordOutputs) {
|
|
9231
|
-
tool.span.setAttribute(
|
|
9370
|
+
tool.span.setAttribute(require_utils.SPAN_OUTPUT, message);
|
|
9232
9371
|
tool.span.setAttribute("ai.toolCall.error", message);
|
|
9233
9372
|
}
|
|
9234
9373
|
} else if (output.type === "tool-result") {
|
|
9235
9374
|
if (this.recordOutputs && output.output !== void 0) {
|
|
9236
9375
|
const serialized = serializeJSON$1(output.output);
|
|
9237
9376
|
tool.span.setAttribute("ai.toolCall.result", serialized);
|
|
9238
|
-
tool.span.setAttribute(
|
|
9377
|
+
tool.span.setAttribute(require_utils.SPAN_OUTPUT, serialized);
|
|
9239
9378
|
}
|
|
9240
9379
|
tool.span.setStatus({ code: _opentelemetry_api.SpanStatusCode.OK });
|
|
9241
9380
|
}
|
|
@@ -9256,7 +9395,7 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9256
9395
|
if (!callId) return;
|
|
9257
9396
|
const op = this.operationByCallId.get(callId);
|
|
9258
9397
|
if (!op) return;
|
|
9259
|
-
if (typeof event.modelId === "string") op.span.setAttribute(
|
|
9398
|
+
if (typeof event.modelId === "string") op.span.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, event.modelId);
|
|
9260
9399
|
};
|
|
9261
9400
|
this.onEmbedEnd = (event) => {
|
|
9262
9401
|
const callId = event?.callId;
|
|
@@ -9276,7 +9415,7 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9276
9415
|
if (op.operationId === "ai.embed" || op.operationId === "ai.embedMany" || op.operationId === "ai.rerank") applyUsageToSpan(op.span, event.totalUsage ?? event.usage);
|
|
9277
9416
|
if (this.recordOutputs) {
|
|
9278
9417
|
const outputMessages = buildVerbatimOutputMessages(Array.isArray(event.content) ? event.content : void 0);
|
|
9279
|
-
if (outputMessages) op.span.setAttribute(
|
|
9418
|
+
if (outputMessages) op.span.setAttribute(require_utils.SPAN_OUTPUT, outputMessages);
|
|
9280
9419
|
if (event.embedding !== void 0) {
|
|
9281
9420
|
const emb = event.embedding;
|
|
9282
9421
|
if (Array.isArray(emb) && Array.isArray(emb[0])) op.span.setAttribute("ai.embed.count", emb.length);
|
|
@@ -9284,7 +9423,7 @@ var LaminarAiSdkTelemetry = class {
|
|
|
9284
9423
|
}
|
|
9285
9424
|
if (Array.isArray(event.ranking)) {
|
|
9286
9425
|
op.span.setAttribute("ai.rerank.ranking", serializeJSON$1(event.ranking));
|
|
9287
|
-
op.span.setAttribute(
|
|
9426
|
+
op.span.setAttribute(require_utils.SPAN_OUTPUT, serializeJSON$1(event.ranking));
|
|
9288
9427
|
}
|
|
9289
9428
|
}
|
|
9290
9429
|
if (event.finishReason === "error") op.span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
@@ -9559,10 +9698,10 @@ const stringifyArgs = (raw) => {
|
|
|
9559
9698
|
const formatUsage = (usage) => {
|
|
9560
9699
|
if (!usage) return {};
|
|
9561
9700
|
const out = {};
|
|
9562
|
-
if (typeof usage.inputTokens === "number") out[
|
|
9563
|
-
if (typeof usage.outputTokens === "number") out[
|
|
9701
|
+
if (typeof usage.inputTokens === "number") out[require_utils.LaminarAttributes.INPUT_TOKEN_COUNT] = usage.inputTokens;
|
|
9702
|
+
if (typeof usage.outputTokens === "number") out[require_utils.LaminarAttributes.OUTPUT_TOKEN_COUNT] = usage.outputTokens;
|
|
9564
9703
|
const total = (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);
|
|
9565
|
-
if (total > 0) out[
|
|
9704
|
+
if (total > 0) out[require_utils.LaminarAttributes.TOTAL_TOKEN_COUNT] = total;
|
|
9566
9705
|
if (typeof usage.inputDetails?.cacheWrite === "number") out["gen_ai.usage.cache_creation_input_tokens"] = usage.inputDetails.cacheWrite;
|
|
9567
9706
|
if (typeof usage.inputDetails?.cacheRead === "number") out["gen_ai.usage.cache_read_input_tokens"] = usage.inputDetails.cacheRead;
|
|
9568
9707
|
if (typeof usage.outputDetails?.reasoning === "number") out["gen_ai.usage.reasoning_tokens"] = usage.outputDetails.reasoning;
|
|
@@ -9570,7 +9709,7 @@ const formatUsage = (usage) => {
|
|
|
9570
9709
|
};
|
|
9571
9710
|
//#endregion
|
|
9572
9711
|
//#region src/opentelemetry-lib/instrumentation/mastra/exporter.ts
|
|
9573
|
-
const logger =
|
|
9712
|
+
const logger = require_utils.initializeLogger();
|
|
9574
9713
|
/**
|
|
9575
9714
|
* Bridges Mastra's ObservabilityExporter contract to Laminar's OTLP ingestion.
|
|
9576
9715
|
*
|
|
@@ -9634,7 +9773,7 @@ var MastraExporter = class {
|
|
|
9634
9773
|
try {
|
|
9635
9774
|
await processor.forceFlush();
|
|
9636
9775
|
} catch (err) {
|
|
9637
|
-
logger.error(`[MastraExporter] forceFlush failed: ${
|
|
9776
|
+
logger.error(`[MastraExporter] forceFlush failed: ${require_utils.errorMessage(err)}`);
|
|
9638
9777
|
}
|
|
9639
9778
|
}
|
|
9640
9779
|
shutdown() {
|
|
@@ -9664,7 +9803,7 @@ var MastraExporter = class {
|
|
|
9664
9803
|
const parentId = span.parentSpanId;
|
|
9665
9804
|
const parentPath = parentId ? traceState.spanPathById.get(parentId) : traceState.otelParentSpanPath;
|
|
9666
9805
|
const parentIdsPath = parentId ? traceState.spanIdsPathById.get(parentId) : traceState.otelParentSpanIdsPath;
|
|
9667
|
-
const spanUuid =
|
|
9806
|
+
const spanUuid = require_utils.otelSpanIdToUUID(require_utils.normalizeOtelSpanId(span.id));
|
|
9668
9807
|
const spanPath = parentPath ? [...parentPath, span.name] : [span.name];
|
|
9669
9808
|
const spanIdsPath = parentIdsPath ? [...parentIdsPath, spanUuid] : [spanUuid];
|
|
9670
9809
|
traceState.spanPathById.set(span.id, spanPath);
|
|
@@ -9703,7 +9842,7 @@ var MastraExporter = class {
|
|
|
9703
9842
|
otelSpan.end(endTime);
|
|
9704
9843
|
if (this.config.realtime) await getSpanProcessor()?.forceFlush();
|
|
9705
9844
|
} catch (err) {
|
|
9706
|
-
logger.error(`[MastraExporter] failed to export span ${span.id}: ${
|
|
9845
|
+
logger.error(`[MastraExporter] failed to export span ${span.id}: ${require_utils.errorMessage(err)}`);
|
|
9707
9846
|
} finally {
|
|
9708
9847
|
traceState.activeSpanIds.delete(span.id);
|
|
9709
9848
|
if (traceState.activeSpanIds.size === 0) this.traceMap.delete(span.traceId);
|
|
@@ -9814,13 +9953,13 @@ var MastraExporter = class {
|
|
|
9814
9953
|
const activeSpan = _opentelemetry_api.trace.getSpan(LaminarContextManager.getContext()) ?? _opentelemetry_api.trace.getActiveSpan();
|
|
9815
9954
|
const ctx = activeSpan?.spanContext();
|
|
9816
9955
|
if (ctx && ctx.traceId && ctx.spanId) {
|
|
9817
|
-
created.otelTraceId =
|
|
9818
|
-
created.otelRootParentSpanId =
|
|
9956
|
+
created.otelTraceId = require_utils.normalizeOtelTraceId(ctx.traceId);
|
|
9957
|
+
created.otelRootParentSpanId = require_utils.normalizeOtelSpanId(ctx.spanId);
|
|
9819
9958
|
const attrs = activeSpan.attributes;
|
|
9820
9959
|
if (attrs) {
|
|
9821
|
-
const parentPath = attrs[
|
|
9960
|
+
const parentPath = attrs[require_utils.SPAN_PATH];
|
|
9822
9961
|
if (Array.isArray(parentPath) && parentPath.every((p) => typeof p === "string")) created.otelParentSpanPath = parentPath;
|
|
9823
|
-
const parentIdsPath = attrs[
|
|
9962
|
+
const parentIdsPath = attrs[require_utils.SPAN_IDS_PATH];
|
|
9824
9963
|
if (Array.isArray(parentIdsPath) && parentIdsPath.every((p) => typeof p === "string")) created.otelParentSpanIdsPath = parentIdsPath;
|
|
9825
9964
|
}
|
|
9826
9965
|
}
|
|
@@ -9829,7 +9968,7 @@ var MastraExporter = class {
|
|
|
9829
9968
|
return created;
|
|
9830
9969
|
}
|
|
9831
9970
|
startOtelSpan(span, traceState) {
|
|
9832
|
-
const tracer = getTracerProvider().getTracer("@lmnr-ai/lmnr",
|
|
9971
|
+
const tracer = getTracerProvider().getTracer("@lmnr-ai/lmnr", require_utils.version);
|
|
9833
9972
|
const parentCtx = this.buildParentContext(span, traceState);
|
|
9834
9973
|
const otelSpan = tracer.startSpan(span.name, {
|
|
9835
9974
|
startTime: dateToHrTime(span.startTime),
|
|
@@ -9840,14 +9979,14 @@ var MastraExporter = class {
|
|
|
9840
9979
|
return;
|
|
9841
9980
|
}
|
|
9842
9981
|
const sdkAllocatedSpanId = otelSpan.spanContext().spanId;
|
|
9843
|
-
const mastraSpanId =
|
|
9844
|
-
const mastraTraceId = traceState.otelTraceId ??
|
|
9982
|
+
const mastraSpanId = require_utils.normalizeOtelSpanId(span.id);
|
|
9983
|
+
const mastraTraceId = traceState.otelTraceId ?? require_utils.normalizeOtelTraceId(span.traceId);
|
|
9845
9984
|
Object.assign(otelSpan.spanContext(), {
|
|
9846
9985
|
traceId: mastraTraceId,
|
|
9847
9986
|
spanId: mastraSpanId
|
|
9848
9987
|
});
|
|
9849
9988
|
if (sdkAllocatedSpanId !== mastraSpanId) getSpanProcessor()?.dropPathInfo(sdkAllocatedSpanId);
|
|
9850
|
-
const parentSpanIdNormalized = span.parentSpanId ?
|
|
9989
|
+
const parentSpanIdNormalized = span.parentSpanId ? require_utils.normalizeOtelSpanId(span.parentSpanId) : traceState.otelRootParentSpanId;
|
|
9851
9990
|
if (parentSpanIdNormalized) {
|
|
9852
9991
|
const parentSpanContext = {
|
|
9853
9992
|
traceId: mastraTraceId,
|
|
@@ -9865,8 +10004,8 @@ var MastraExporter = class {
|
|
|
9865
10004
|
});
|
|
9866
10005
|
const spanPath = traceState.spanPathById.get(span.id);
|
|
9867
10006
|
const spanIdsPath = traceState.spanIdsPathById.get(span.id);
|
|
9868
|
-
if (spanPath) otelSpan.setAttribute(
|
|
9869
|
-
if (spanIdsPath) otelSpan.setAttribute(
|
|
10007
|
+
if (spanPath) otelSpan.setAttribute(require_utils.SPAN_PATH, spanPath);
|
|
10008
|
+
if (spanIdsPath) otelSpan.setAttribute(require_utils.SPAN_IDS_PATH, spanIdsPath);
|
|
9870
10009
|
this.liveOtelSpanByMastraId.set(span.id, otelSpan);
|
|
9871
10010
|
}
|
|
9872
10011
|
warnNotInitializedOnce() {
|
|
@@ -9893,39 +10032,39 @@ var MastraExporter = class {
|
|
|
9893
10032
|
}
|
|
9894
10033
|
applyEndAttributes(span, otelSpan, traceState) {
|
|
9895
10034
|
const attributes = this.buildLaminarAttributes(span, traceState);
|
|
9896
|
-
delete attributes[
|
|
9897
|
-
delete attributes[
|
|
10035
|
+
delete attributes[require_utils.SPAN_PATH];
|
|
10036
|
+
delete attributes[require_utils.SPAN_IDS_PATH];
|
|
9898
10037
|
otelSpan.setAttributes(attributes);
|
|
9899
10038
|
}
|
|
9900
10039
|
buildLaminarAttributes(span, traceState) {
|
|
9901
10040
|
const attributes = {};
|
|
9902
10041
|
const spanPath = traceState.spanPathById.get(span.id);
|
|
9903
10042
|
const spanIdsPath = traceState.spanIdsPathById.get(span.id);
|
|
9904
|
-
if (spanPath) attributes[
|
|
9905
|
-
if (spanIdsPath) attributes[
|
|
10043
|
+
if (spanPath) attributes[require_utils.SPAN_PATH] = spanPath;
|
|
10044
|
+
if (spanIdsPath) attributes[require_utils.SPAN_IDS_PATH] = spanIdsPath;
|
|
9906
10045
|
const laminarSpanType = mapLaminarSpanType(span.type);
|
|
9907
|
-
attributes[
|
|
9908
|
-
attributes[
|
|
9909
|
-
attributes[
|
|
10046
|
+
attributes[require_utils.SPAN_TYPE] = laminarSpanType;
|
|
10047
|
+
attributes[require_utils.SPAN_INSTRUMENTATION_SOURCE] = "javascript";
|
|
10048
|
+
attributes[require_utils.SPAN_SDK_VERSION] = require_utils.version;
|
|
9910
10049
|
const langVersion = getLangVersion();
|
|
9911
|
-
if (langVersion) attributes[
|
|
10050
|
+
if (langVersion) attributes[require_utils.SPAN_LANGUAGE_VERSION] = langVersion;
|
|
9912
10051
|
attributes["lmnr.internal.mastra.span_type"] = span.type;
|
|
9913
10052
|
const metadata = span.metadata ?? {};
|
|
9914
10053
|
const sessionId = metadata.sessionId ?? metadata.session_id;
|
|
9915
|
-
if (typeof sessionId === "string" && sessionId.length > 0) attributes[
|
|
10054
|
+
if (typeof sessionId === "string" && sessionId.length > 0) attributes[require_utils.SESSION_ID] = sessionId;
|
|
9916
10055
|
const userId = metadata.userId ?? metadata.user_id;
|
|
9917
|
-
if (typeof userId === "string" && userId.length > 0) attributes[
|
|
10056
|
+
if (typeof userId === "string" && userId.length > 0) attributes[require_utils.USER_ID] = userId;
|
|
9918
10057
|
for (const [key, value] of Object.entries(metadata)) {
|
|
9919
10058
|
if (key === "sessionId" || key === "session_id" || key === "userId" || key === "user_id" || value === void 0 || value === null) continue;
|
|
9920
10059
|
const av = toAttributeValue(value);
|
|
9921
|
-
if (av !== void 0) attributes[`${
|
|
10060
|
+
if (av !== void 0) attributes[`${require_utils.ASSOCIATION_PROPERTIES}.metadata.${key}`] = av;
|
|
9922
10061
|
}
|
|
9923
|
-
if (span.isRootSpan && span.tags?.length) attributes[`${
|
|
10062
|
+
if (span.isRootSpan && span.tags?.length) attributes[`${require_utils.ASSOCIATION_PROPERTIES}.tags`] = span.tags;
|
|
9924
10063
|
if (laminarSpanType === "LLM") this.applyLlmAttributes(span, attributes);
|
|
9925
10064
|
else if (laminarSpanType === "TOOL") this.applyToolAttributes(span, attributes);
|
|
9926
10065
|
else {
|
|
9927
|
-
if (span.input !== void 0) attributes[
|
|
9928
|
-
if (span.output !== void 0) attributes[
|
|
10066
|
+
if (span.input !== void 0) attributes[require_utils.SPAN_INPUT] = serializeJSON(span.input);
|
|
10067
|
+
if (span.output !== void 0) attributes[require_utils.SPAN_OUTPUT] = serializeJSON(span.output);
|
|
9929
10068
|
}
|
|
9930
10069
|
return attributes;
|
|
9931
10070
|
}
|
|
@@ -9938,10 +10077,10 @@ var MastraExporter = class {
|
|
|
9938
10077
|
const provider = generationAttrs?.provider;
|
|
9939
10078
|
const model = generationAttrs?.model;
|
|
9940
10079
|
const responseModel = generationAttrs?.responseModel;
|
|
9941
|
-
if (provider) attributes[
|
|
9942
|
-
if (model) attributes[
|
|
9943
|
-
if (responseModel) attributes[
|
|
9944
|
-
else if (model) attributes[
|
|
10080
|
+
if (provider) attributes[require_utils.LaminarAttributes.PROVIDER] = normalizeProvider(provider);
|
|
10081
|
+
if (model) attributes[require_utils.LaminarAttributes.REQUEST_MODEL] = model;
|
|
10082
|
+
if (responseModel) attributes[require_utils.LaminarAttributes.RESPONSE_MODEL] = responseModel;
|
|
10083
|
+
else if (model) attributes[require_utils.LaminarAttributes.RESPONSE_MODEL] = model;
|
|
9945
10084
|
const usage = stepAttrs.usage ?? generationAttrs?.usage;
|
|
9946
10085
|
Object.assign(attributes, formatUsage(usage));
|
|
9947
10086
|
if (typeof stepAttrs.finishReason === "string") {
|
|
@@ -9954,7 +10093,7 @@ var MastraExporter = class {
|
|
|
9954
10093
|
if (turn) messages.push(...turn);
|
|
9955
10094
|
}
|
|
9956
10095
|
if (messages.length > 0) attributes["ai.prompt.messages"] = serializeJSON(messages);
|
|
9957
|
-
else if (span.input !== void 0) attributes[
|
|
10096
|
+
else if (span.input !== void 0) attributes[require_utils.SPAN_INPUT] = serializeJSON(span.input);
|
|
9958
10097
|
const out = span.output;
|
|
9959
10098
|
const reasoningText = gen?.reasoningTextByStepIndex.get(stepIndex);
|
|
9960
10099
|
if (out && typeof out === "object") {
|
|
@@ -9993,11 +10132,11 @@ var MastraExporter = class {
|
|
|
9993
10132
|
parts
|
|
9994
10133
|
}]);
|
|
9995
10134
|
}
|
|
9996
|
-
} else if (out !== void 0) attributes[
|
|
10135
|
+
} else if (out !== void 0) attributes[require_utils.SPAN_OUTPUT] = serializeJSON(out);
|
|
9997
10136
|
}
|
|
9998
10137
|
applyToolAttributes(span, attributes) {
|
|
9999
|
-
if (span.input !== void 0) attributes[
|
|
10000
|
-
if (span.output !== void 0) attributes[
|
|
10138
|
+
if (span.input !== void 0) attributes[require_utils.SPAN_INPUT] = serializeJSON(span.input);
|
|
10139
|
+
if (span.output !== void 0) attributes[require_utils.SPAN_OUTPUT] = serializeJSON(span.output);
|
|
10001
10140
|
const toolAttrs = span.attributes ?? {};
|
|
10002
10141
|
const cleanedName = cleanMastraToolName(span.name) || span.name;
|
|
10003
10142
|
if (cleanedName) attributes["ai.toolCall.name"] = cleanedName;
|
|
@@ -10013,8 +10152,8 @@ exports.LAMINAR_TEMPORAL_SPAN_CONTEXT_HEADER = require_consts.LAMINAR_SPAN_CONTE
|
|
|
10013
10152
|
exports.LAMINAR_TEMPORAL_TRACEPARENT_HEADER = require_consts.TRACEPARENT_HEADER;
|
|
10014
10153
|
exports.Laminar = Laminar;
|
|
10015
10154
|
exports.LaminarAiSdkTelemetry = LaminarAiSdkTelemetry;
|
|
10016
|
-
exports.LaminarAttributes =
|
|
10017
|
-
exports.LaminarClient =
|
|
10155
|
+
exports.LaminarAttributes = require_utils.LaminarAttributes;
|
|
10156
|
+
exports.LaminarClient = require_utils.LaminarClient;
|
|
10018
10157
|
exports.LaminarDataset = LaminarDataset;
|
|
10019
10158
|
exports.LaminarReporter = LaminarReporter;
|
|
10020
10159
|
exports.LaminarSpanProcessor = LaminarSpanProcessor;
|
|
@@ -10024,7 +10163,7 @@ exports.LaminarTemporalInterceptors = LaminarTemporalInterceptors;
|
|
|
10024
10163
|
exports.LaminarTemporalScheduleClientInterceptor = ScheduleClientInterceptor;
|
|
10025
10164
|
exports.LaminarTemporalWorkflowClientInterceptor = WorkflowClientInterceptor;
|
|
10026
10165
|
exports.MastraExporter = MastraExporter;
|
|
10027
|
-
exports.TracingLevel =
|
|
10166
|
+
exports.TracingLevel = require_utils.TracingLevel;
|
|
10028
10167
|
exports.aiSdkTelemetry = aiSdkTelemetry;
|
|
10029
10168
|
exports.enableAiSdkTelemetryDebug = enableAiSdkTelemetryDebug;
|
|
10030
10169
|
exports.evaluate = evaluate;
|