@lmnr-ai/lmnr 0.8.20 → 0.8.21
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/worker/build.cjs +1 -1
- package/dist/cli/worker/build.mjs +1 -1
- package/dist/cli/worker/index.cjs +1 -1
- package/dist/cli/worker/index.mjs +1 -1
- package/dist/cli.cjs +3 -3
- package/dist/cli.d.cts +1 -1
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +3 -3
- package/dist/{decorators-Cf0xs-v_.mjs → decorators-BDFgXfgI.mjs} +820 -139
- package/dist/decorators-BDFgXfgI.mjs.map +1 -0
- package/dist/{decorators-u7xFb_9W.cjs → decorators-CaTC0lJq.cjs} +831 -138
- package/dist/decorators-CaTC0lJq.cjs.map +1 -0
- package/dist/{dist-BwllJ__m.mjs → dist-B5CmOQ4s.mjs} +3 -3
- package/dist/{dist-BwllJ__m.mjs.map → dist-B5CmOQ4s.mjs.map} +1 -1
- package/dist/{dist-zDtQ_gVq.cjs → dist-B5cKzRzq.cjs} +3 -3
- package/dist/{dist-zDtQ_gVq.cjs.map → dist-B5cKzRzq.cjs.map} +1 -1
- package/dist/{evaluations-D2duRqbG.d.cts → evaluations-BJkIwpmH.d.cts} +15 -1
- package/dist/{evaluations-DEbBIXng.d.mts → evaluations-tqpNgp0P.d.mts} +15 -1
- package/dist/{file-utils-C-auksVC.mjs → file-utils-CHoR9VB8.mjs} +2 -2
- package/dist/{file-utils-C-auksVC.mjs.map → file-utils-CHoR9VB8.mjs.map} +1 -1
- package/dist/file-utils-IBEBwZxq.cjs +2 -0
- package/dist/{file-utils-0mVr0eIv.cjs → file-utils-yJ5ephze.cjs} +2 -2
- package/dist/{file-utils-0mVr0eIv.cjs.map → file-utils-yJ5ephze.cjs.map} +1 -1
- package/dist/index.cjs +563 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +125 -3
- package/dist/index.d.mts +125 -3
- package/dist/index.mjs +564 -11
- package/dist/index.mjs.map +1 -1
- package/dist/{utils-BmWNkeX5.cjs → utils-C8Tl1vKD.cjs} +23 -1
- package/dist/utils-C8Tl1vKD.cjs.map +1 -0
- package/dist/{utils-0WC6BVqs.mjs → utils-CHJ0KZUR.mjs} +12 -2
- package/dist/utils-CHJ0KZUR.mjs.map +1 -0
- package/package.json +4 -3
- package/dist/decorators-Cf0xs-v_.mjs.map +0 -1
- package/dist/decorators-u7xFb_9W.cjs.map +0 -1
- package/dist/file-utils-2hY2DP65.cjs +0 -2
- package/dist/utils-0WC6BVqs.mjs.map +0 -1
- package/dist/utils-BmWNkeX5.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Do9eywBl.cjs");
|
|
2
|
-
const require_dist = require("./dist-
|
|
3
|
-
const require_utils = require("./utils-
|
|
2
|
+
const require_dist = require("./dist-B5cKzRzq.cjs");
|
|
3
|
+
const require_utils = require("./utils-C8Tl1vKD.cjs");
|
|
4
4
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
5
5
|
let _opentelemetry_context_async_hooks = require("@opentelemetry/context-async-hooks");
|
|
6
6
|
let _opentelemetry_instrumentation = require("@opentelemetry/instrumentation");
|
|
@@ -33,7 +33,7 @@ let _grpc_grpc_js = require("@grpc/grpc-js");
|
|
|
33
33
|
let _opentelemetry_exporter_trace_otlp_grpc = require("@opentelemetry/exporter-trace-otlp-grpc");
|
|
34
34
|
let _opentelemetry_exporter_trace_otlp_proto = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
35
35
|
//#region src/opentelemetry-lib/tracing/compat.ts
|
|
36
|
-
const logger$
|
|
36
|
+
const logger$17 = require_utils.initializeLogger();
|
|
37
37
|
const makeSpanOtelV2Compatible = (span) => {
|
|
38
38
|
const spanAny = span;
|
|
39
39
|
if (spanAny.instrumentationScope && !spanAny.instrumentationLibrary) Object.assign(span, { instrumentationLibrary: spanAny.instrumentationScope });
|
|
@@ -79,7 +79,7 @@ const createResource = (attributes) => {
|
|
|
79
79
|
if (resources.Resource) return new resources.Resource(attributes);
|
|
80
80
|
throw new Error("Unable to create Resource: neither v1 nor v2 API found");
|
|
81
81
|
} catch {
|
|
82
|
-
logger$
|
|
82
|
+
logger$17.debug("Laminar failed to @opentelemetry/resources, continuing without it");
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
85
|
};
|
|
@@ -261,7 +261,7 @@ const consumeResponse = async (response) => {
|
|
|
261
261
|
};
|
|
262
262
|
//#endregion
|
|
263
263
|
//#region src/opentelemetry-lib/tracing/stream-utils.ts
|
|
264
|
-
const logger$
|
|
264
|
+
const logger$16 = require_utils.initializeLogger();
|
|
265
265
|
const pendingStreamProcessing = /* @__PURE__ */ new Set();
|
|
266
266
|
/**
|
|
267
267
|
* Wait for all pending stream processing to complete with a timeout
|
|
@@ -269,7 +269,7 @@ const pendingStreamProcessing = /* @__PURE__ */ new Set();
|
|
|
269
269
|
*/
|
|
270
270
|
const waitForPendingStreams = async (timeoutMs = 5e3) => {
|
|
271
271
|
if (pendingStreamProcessing.size === 0) return;
|
|
272
|
-
logger$
|
|
272
|
+
logger$16.debug(`Waiting for ${pendingStreamProcessing.size} pending stream(s)`);
|
|
273
273
|
const initialCount = pendingStreamProcessing.size;
|
|
274
274
|
const pendingPromises = Array.from(pendingStreamProcessing);
|
|
275
275
|
let timedOut = false;
|
|
@@ -280,7 +280,7 @@ const waitForPendingStreams = async (timeoutMs = 5e3) => {
|
|
|
280
280
|
}, timeoutMs);
|
|
281
281
|
});
|
|
282
282
|
await Promise.race([Promise.allSettled(pendingPromises), timeoutPromise]);
|
|
283
|
-
if (timedOut && pendingStreamProcessing.size > 0) logger$
|
|
283
|
+
if (timedOut && pendingStreamProcessing.size > 0) logger$16.warn(`Timeout waiting for ${pendingStreamProcessing.size} pending stream(s) after ${timeoutMs}ms (started with ${initialCount})`);
|
|
284
284
|
};
|
|
285
285
|
/**
|
|
286
286
|
* Consumes a stream result to ensure background processing completes.
|
|
@@ -291,15 +291,15 @@ const waitForPendingStreams = async (timeoutMs = 5e3) => {
|
|
|
291
291
|
const consumeStreamResult = async (result) => {
|
|
292
292
|
const streamInfo = getStream(result);
|
|
293
293
|
if (streamInfo.type === null) {
|
|
294
|
-
logger$
|
|
294
|
+
logger$16.debug("Result is not a stream, returning as-is");
|
|
295
295
|
return result;
|
|
296
296
|
}
|
|
297
|
-
logger$
|
|
297
|
+
logger$16.debug("Result is a stream, consuming...");
|
|
298
298
|
if (streamInfo.type === "aisdk-result") {
|
|
299
299
|
try {
|
|
300
300
|
if ("text" in streamInfo.result) await streamInfo.result.text;
|
|
301
301
|
} catch (error) {
|
|
302
|
-
logger$
|
|
302
|
+
logger$16.warn(`Error consuming AI SDK result stream: ${error instanceof Error ? error.message : String(error)}`);
|
|
303
303
|
}
|
|
304
304
|
return result;
|
|
305
305
|
}
|
|
@@ -317,7 +317,7 @@ const consumeStreamResult = async (result) => {
|
|
|
317
317
|
reader.releaseLock();
|
|
318
318
|
}
|
|
319
319
|
} catch (error) {
|
|
320
|
-
logger$
|
|
320
|
+
logger$16.warn(`Error consuming ReadableStream: ${error instanceof Error ? error.message : String(error)}`);
|
|
321
321
|
}
|
|
322
322
|
return {
|
|
323
323
|
type: "stream",
|
|
@@ -329,7 +329,7 @@ const consumeStreamResult = async (result) => {
|
|
|
329
329
|
try {
|
|
330
330
|
for await (const chunk of streamInfo.iterable) chunks.push(chunk);
|
|
331
331
|
} catch (error) {
|
|
332
|
-
logger$
|
|
332
|
+
logger$16.warn(`Error consuming AsyncIterable: ${error instanceof Error ? error.message : String(error)}`);
|
|
333
333
|
}
|
|
334
334
|
return {
|
|
335
335
|
type: "async-iterable",
|
|
@@ -338,13 +338,13 @@ const consumeStreamResult = async (result) => {
|
|
|
338
338
|
}
|
|
339
339
|
if (streamInfo.type === "response") try {
|
|
340
340
|
const { chunks, error } = await consumeResponse(streamInfo.response);
|
|
341
|
-
if (error) logger$
|
|
341
|
+
if (error) logger$16.warn(`Error consuming Response: ${error instanceof Error ? error.message : String(error)}`);
|
|
342
342
|
return {
|
|
343
343
|
type: "response",
|
|
344
344
|
chunks
|
|
345
345
|
};
|
|
346
346
|
} catch (error) {
|
|
347
|
-
logger$
|
|
347
|
+
logger$16.warn(`Error consuming Response: ${error instanceof Error ? error.message : String(error)}`);
|
|
348
348
|
return result;
|
|
349
349
|
}
|
|
350
350
|
return result;
|
|
@@ -363,34 +363,34 @@ const trackStreamProcessing = (task) => {
|
|
|
363
363
|
* while passing through the original result to the caller
|
|
364
364
|
*/
|
|
365
365
|
const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, serialize) => {
|
|
366
|
-
logger$
|
|
366
|
+
logger$16.debug(`Handling stream result of type: ${streamInfo.type}`);
|
|
367
367
|
if (streamInfo.type === "aisdk-result") {
|
|
368
368
|
trackStreamProcessing(async () => {
|
|
369
|
-
logger$
|
|
369
|
+
logger$16.debug("Starting background processing for AI SDK result");
|
|
370
370
|
let partialOutput = {};
|
|
371
371
|
try {
|
|
372
372
|
partialOutput = await consumeAISDKResult(streamInfo.result);
|
|
373
373
|
if (shouldSendTraces() && !ignoreOutput) try {
|
|
374
374
|
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(partialOutput));
|
|
375
375
|
} catch (error) {
|
|
376
|
-
logger$
|
|
376
|
+
logger$16.warn(`Failed to serialize AI SDK stream output: ${error instanceof Error ? error.message : String(error)}`);
|
|
377
377
|
}
|
|
378
378
|
} catch (error) {
|
|
379
379
|
if (Object.keys(partialOutput).length > 0 && shouldSendTraces() && !ignoreOutput) try {
|
|
380
380
|
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(partialOutput));
|
|
381
381
|
} catch (serError) {
|
|
382
|
-
logger$
|
|
382
|
+
logger$16.warn(`Failed to serialize partial AI SDK output: ${serError instanceof Error ? serError.message : String(serError)}`);
|
|
383
383
|
}
|
|
384
384
|
span.recordException(error);
|
|
385
385
|
} finally {
|
|
386
|
-
logger$
|
|
386
|
+
logger$16.debug("Ending span for AI SDK result");
|
|
387
387
|
span.end();
|
|
388
388
|
}
|
|
389
389
|
});
|
|
390
390
|
return originalResult;
|
|
391
391
|
}
|
|
392
392
|
if (streamInfo.type === "readable-stream") {
|
|
393
|
-
logger$
|
|
393
|
+
logger$16.debug("Setting up background processing for ReadableStream");
|
|
394
394
|
const { stream, dataPromise } = consumeAndTeeReadableStream(streamInfo.stream);
|
|
395
395
|
trackStreamProcessing(async () => {
|
|
396
396
|
try {
|
|
@@ -402,18 +402,18 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
|
|
|
402
402
|
};
|
|
403
403
|
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
|
|
404
404
|
} catch (serError) {
|
|
405
|
-
logger$
|
|
405
|
+
logger$16.warn(`Failed to serialize stream output: ${serError instanceof Error ? serError.message : String(serError)}`);
|
|
406
406
|
}
|
|
407
407
|
if (error) span.recordException(error);
|
|
408
408
|
} finally {
|
|
409
|
-
logger$
|
|
409
|
+
logger$16.debug("Ending span for ReadableStream");
|
|
410
410
|
span.end();
|
|
411
411
|
}
|
|
412
412
|
});
|
|
413
413
|
return stream;
|
|
414
414
|
}
|
|
415
415
|
if (streamInfo.type === "async-iterable") {
|
|
416
|
-
logger$
|
|
416
|
+
logger$16.debug("Setting up background processing for AsyncIterable");
|
|
417
417
|
const { iterable, dataPromise } = consumeAndTeeAsyncIterable(streamInfo.iterable);
|
|
418
418
|
trackStreamProcessing(async () => {
|
|
419
419
|
try {
|
|
@@ -425,18 +425,18 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
|
|
|
425
425
|
};
|
|
426
426
|
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
|
|
427
427
|
} catch (serError) {
|
|
428
|
-
logger$
|
|
428
|
+
logger$16.warn(`Failed to serialize async iterable output: ${serError instanceof Error ? serError.message : String(serError)}`);
|
|
429
429
|
}
|
|
430
430
|
if (error) span.recordException(error);
|
|
431
431
|
} finally {
|
|
432
|
-
logger$
|
|
432
|
+
logger$16.debug("Ending span for AsyncIterable");
|
|
433
433
|
span.end();
|
|
434
434
|
}
|
|
435
435
|
});
|
|
436
436
|
return iterable;
|
|
437
437
|
}
|
|
438
438
|
if (streamInfo.type === "response") {
|
|
439
|
-
logger$
|
|
439
|
+
logger$16.debug("Setting up background processing for Response");
|
|
440
440
|
const originalResponse = streamInfo.response;
|
|
441
441
|
if (!originalResponse.body) {
|
|
442
442
|
span.end();
|
|
@@ -458,19 +458,19 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
|
|
|
458
458
|
};
|
|
459
459
|
span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
|
|
460
460
|
} catch (serError) {
|
|
461
|
-
logger$
|
|
461
|
+
logger$16.warn(`Failed to serialize response output: ${serError instanceof Error ? serError.message : String(serError)}`);
|
|
462
462
|
}
|
|
463
463
|
if (error) span.recordException(error);
|
|
464
464
|
} catch (err) {
|
|
465
465
|
span.recordException(err);
|
|
466
466
|
} finally {
|
|
467
|
-
logger$
|
|
467
|
+
logger$16.debug("Ending span for Response");
|
|
468
468
|
span.end();
|
|
469
469
|
}
|
|
470
470
|
});
|
|
471
471
|
return newResponse;
|
|
472
472
|
}
|
|
473
|
-
logger$
|
|
473
|
+
logger$16.warn("Stream type not handled, ending span immediately");
|
|
474
474
|
span.end();
|
|
475
475
|
return originalResult;
|
|
476
476
|
};
|
|
@@ -491,7 +491,7 @@ let TracingLevel = /* @__PURE__ */ function(TracingLevel) {
|
|
|
491
491
|
}({});
|
|
492
492
|
//#endregion
|
|
493
493
|
//#region src/opentelemetry-lib/tracing/span.ts
|
|
494
|
-
const logger$
|
|
494
|
+
const logger$15 = require_utils.initializeLogger();
|
|
495
495
|
var LaminarSpan = class LaminarSpan {
|
|
496
496
|
constructor(span, activated) {
|
|
497
497
|
if (span instanceof LaminarSpan) {
|
|
@@ -554,8 +554,15 @@ var LaminarSpan = class LaminarSpan {
|
|
|
554
554
|
if (!this._span.isRecording()) return this._span.end(endTime);
|
|
555
555
|
LaminarContextManager.removeActiveSpan(this.spanContext().spanId);
|
|
556
556
|
if (this._activated) LaminarContextManager.popContext();
|
|
557
|
+
if (this._globalActiveContext !== void 0) {
|
|
558
|
+
LaminarContextManager.popGlobalContext(this._globalActiveContext);
|
|
559
|
+
this._globalActiveContext = void 0;
|
|
560
|
+
}
|
|
557
561
|
return this._span.end(endTime);
|
|
558
562
|
}
|
|
563
|
+
setGlobalActiveContext(context) {
|
|
564
|
+
this._globalActiveContext = context;
|
|
565
|
+
}
|
|
559
566
|
set activated(activated) {
|
|
560
567
|
this._activated = activated;
|
|
561
568
|
}
|
|
@@ -616,7 +623,7 @@ var LaminarSpan = class LaminarSpan {
|
|
|
616
623
|
} catch {}
|
|
617
624
|
metadata[key.replace(`${require_utils.ASSOCIATION_PROPERTIES}.metadata.`, "")] = value;
|
|
618
625
|
}
|
|
619
|
-
} else logger$
|
|
626
|
+
} else logger$15.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.");
|
|
620
627
|
return {
|
|
621
628
|
spanId: require_utils.otelSpanIdToUUID(this._span.spanContext().spanId),
|
|
622
629
|
traceId: require_utils.otelTraceIdToUUID(this._span.spanContext().traceId),
|
|
@@ -643,14 +650,14 @@ var LaminarSpan = class LaminarSpan {
|
|
|
643
650
|
}
|
|
644
651
|
get tags() {
|
|
645
652
|
if (!this._span.attributes) {
|
|
646
|
-
logger$
|
|
653
|
+
logger$15.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.");
|
|
647
654
|
return [];
|
|
648
655
|
}
|
|
649
656
|
return this._span.attributes[`lmnr.association.properties.tags`] ?? [];
|
|
650
657
|
}
|
|
651
658
|
get laminarAssociationProperties() {
|
|
652
659
|
if (!this._span.attributes) {
|
|
653
|
-
logger$
|
|
660
|
+
logger$15.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.");
|
|
654
661
|
return {};
|
|
655
662
|
}
|
|
656
663
|
try {
|
|
@@ -720,24 +727,32 @@ var LaminarContextManager = class {
|
|
|
720
727
|
static {
|
|
721
728
|
this._activeSpans = /* @__PURE__ */ new Set();
|
|
722
729
|
}
|
|
730
|
+
static {
|
|
731
|
+
this._globalActiveContexts = [];
|
|
732
|
+
}
|
|
723
733
|
constructor() {
|
|
724
734
|
throw new Error("LaminarContextManager is a static class and cannot be instantiated");
|
|
725
735
|
}
|
|
726
|
-
static
|
|
727
|
-
const
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
if (this._activeSpans.has(span.spanContext().spanId)) return context;
|
|
737
|
-
} catch {
|
|
738
|
-
return context;
|
|
739
|
-
}
|
|
736
|
+
static isValidContext(context) {
|
|
737
|
+
const span = _opentelemetry_api.trace.getSpan(context);
|
|
738
|
+
if (!span) return true;
|
|
739
|
+
if (!span.isRecording() && span.spanContext().isRemote) return true;
|
|
740
|
+
if (!(span instanceof LaminarSpan)) return true;
|
|
741
|
+
if (!span.isActivated) return true;
|
|
742
|
+
try {
|
|
743
|
+
return this._activeSpans.has(span.spanContext().spanId);
|
|
744
|
+
} catch {
|
|
745
|
+
return true;
|
|
740
746
|
}
|
|
747
|
+
}
|
|
748
|
+
static findLatestValidContext(contexts) {
|
|
749
|
+
for (let i = contexts.length - 1; i >= 0; i--) if (this.isValidContext(contexts[i])) return contexts[i];
|
|
750
|
+
}
|
|
751
|
+
static getContext() {
|
|
752
|
+
const asyncContext = this.findLatestValidContext(this.getContextStack());
|
|
753
|
+
if (asyncContext !== void 0) return asyncContext;
|
|
754
|
+
const globalContext = this.findLatestValidContext(this._globalActiveContexts);
|
|
755
|
+
if (globalContext !== void 0) return globalContext;
|
|
741
756
|
return _opentelemetry_api.ROOT_CONTEXT;
|
|
742
757
|
}
|
|
743
758
|
static pushContext(context) {
|
|
@@ -759,8 +774,31 @@ var LaminarContextManager = class {
|
|
|
759
774
|
this._asyncLocalStorage.enterWith(newContexts);
|
|
760
775
|
}
|
|
761
776
|
}
|
|
777
|
+
static pushGlobalContext(context) {
|
|
778
|
+
this._globalActiveContexts.push(context);
|
|
779
|
+
}
|
|
780
|
+
static removeContext(context) {
|
|
781
|
+
const contexts = this.getContextStack();
|
|
782
|
+
if (contexts.length === 0) return;
|
|
783
|
+
for (let i = contexts.length - 1; i >= 0; i--) if (contexts[i] === context) {
|
|
784
|
+
const newContexts = contexts.slice(0, i).concat(contexts.slice(i + 1));
|
|
785
|
+
this._asyncLocalStorage.enterWith(newContexts);
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
static popGlobalContext(context) {
|
|
790
|
+
if (context !== void 0) {
|
|
791
|
+
for (let i = this._globalActiveContexts.length - 1; i >= 0; i--) if (this._globalActiveContexts[i] === context) {
|
|
792
|
+
this._globalActiveContexts.splice(i, 1);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
if (this._globalActiveContexts.length > 0) this._globalActiveContexts.pop();
|
|
798
|
+
}
|
|
762
799
|
static clearContexts() {
|
|
763
800
|
this._asyncLocalStorage.enterWith([]);
|
|
801
|
+
this._globalActiveContexts = [];
|
|
764
802
|
}
|
|
765
803
|
static clearActiveSpans() {
|
|
766
804
|
this._activeSpans.clear();
|
|
@@ -818,7 +856,7 @@ var LaminarContextManager = class {
|
|
|
818
856
|
};
|
|
819
857
|
//#endregion
|
|
820
858
|
//#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/proxy.ts
|
|
821
|
-
const logger$
|
|
859
|
+
const logger$14 = require_utils.initializeLogger();
|
|
822
860
|
const DEFAULT_ANTHROPIC_BASE_URL = "https://api.anthropic.com";
|
|
823
861
|
const DEFAULT_CC_PROXY_PORT = 45667;
|
|
824
862
|
const CC_PROXY_PORT_ATTEMPTS = 50;
|
|
@@ -828,6 +866,8 @@ const FOUNDRY_USE_ENV = "CLAUDE_CODE_USE_FOUNDRY";
|
|
|
828
866
|
const BEDROCK_BASE_URL_ENV = "ANTHROPIC_BEDROCK_BASE_URL";
|
|
829
867
|
const BEDROCK_USE_ENV = "CLAUDE_CODE_USE_BEDROCK";
|
|
830
868
|
const BEDROCK_AWS_REGION_ENV = "AWS_REGION";
|
|
869
|
+
const VERTEX_BASE_URL_ENV = "ANTHROPIC_VERTEX_BASE_URL";
|
|
870
|
+
const VERTEX_USE_ENV = "CLAUDE_CODE_USE_VERTEX";
|
|
831
871
|
const activeProxyServers = /* @__PURE__ */ new Set();
|
|
832
872
|
let globalShutdownRegistered = false;
|
|
833
873
|
/**
|
|
@@ -866,6 +906,9 @@ const getRegionFromAwsConfig = (profile) => {
|
|
|
866
906
|
* - Use ANTHROPIC_BEDROCK_BASE_URL, or
|
|
867
907
|
* - Construct from AWS_REGION env var, or
|
|
868
908
|
* - Construct by reading region from ~/.aws/config via AWS_PROFILE
|
|
909
|
+
* - If CLAUDE_CODE_USE_VERTEX is truthy:
|
|
910
|
+
* - Use ANTHROPIC_VERTEX_BASE_URL, or
|
|
911
|
+
* - Construct from CLOUD_ML_REGION and ANTHROPIC_VERTEX_PROJECT_ID
|
|
869
912
|
* 4. ANTHROPIC_BASE_URL - standard Anthropic API base URL
|
|
870
913
|
* 5. Fall back to default (https://api.anthropic.com)
|
|
871
914
|
*
|
|
@@ -886,7 +929,7 @@ const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL)
|
|
|
886
929
|
if (foundryBaseUrl) return foundryBaseUrl.replace(/\/$/, "");
|
|
887
930
|
const foundryResource = getEnvValue(FOUNDRY_RESOURCE_ENV);
|
|
888
931
|
if (foundryResource) return `https://${foundryResource}.services.ai.azure.com/anthropic`;
|
|
889
|
-
logger$
|
|
932
|
+
logger$14.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.`);
|
|
890
933
|
return null;
|
|
891
934
|
}
|
|
892
935
|
if (isTruthyEnv(getEnvValue(BEDROCK_USE_ENV))) {
|
|
@@ -895,9 +938,14 @@ const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL)
|
|
|
895
938
|
let region = getEnvValue(BEDROCK_AWS_REGION_ENV);
|
|
896
939
|
if (!region) region = getRegionFromAwsConfig(getEnvValue("AWS_PROFILE") || "default") ?? void 0;
|
|
897
940
|
if (region) return `https://bedrock-runtime.${region}.amazonaws.com`;
|
|
898
|
-
logger$
|
|
941
|
+
logger$14.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.`);
|
|
899
942
|
return null;
|
|
900
943
|
}
|
|
944
|
+
if (isTruthyEnv(getEnvValue(VERTEX_USE_ENV))) {
|
|
945
|
+
const vertexBaseUrl = getEnvValue(VERTEX_BASE_URL_ENV);
|
|
946
|
+
if (vertexBaseUrl) return vertexBaseUrl.replace(/\/$/, "");
|
|
947
|
+
return `https://aiplatform.googleapis.com/v1`;
|
|
948
|
+
}
|
|
901
949
|
const anthropicBaseUrl = getEnvValue("ANTHROPIC_BASE_URL");
|
|
902
950
|
if (anthropicBaseUrl) return anthropicBaseUrl.replace(/\/$/, "");
|
|
903
951
|
return fallback;
|
|
@@ -972,11 +1020,11 @@ const waitForPort = (port, timeoutMs = 5e3) => new Promise((resolve) => {
|
|
|
972
1020
|
const registerGlobalProxyShutdown = () => {
|
|
973
1021
|
if (!globalShutdownRegistered) {
|
|
974
1022
|
process.on("exit", () => {
|
|
975
|
-
logger$
|
|
1023
|
+
logger$14.debug("process.on(\"exit\") called - stopping all active proxies");
|
|
976
1024
|
for (const proxyServer of activeProxyServers) try {
|
|
977
1025
|
proxyServer.stopServer();
|
|
978
1026
|
} catch (e) {
|
|
979
|
-
logger$
|
|
1027
|
+
logger$14.debug(`Failed to stop proxy: ${e instanceof Error ? e.message : String(e)}`);
|
|
980
1028
|
}
|
|
981
1029
|
activeProxyServers.clear();
|
|
982
1030
|
});
|
|
@@ -991,28 +1039,28 @@ const createProxyInstance = async ({ env }) => {
|
|
|
991
1039
|
try {
|
|
992
1040
|
const port = await findAvailablePort(DEFAULT_CC_PROXY_PORT, CC_PROXY_PORT_ATTEMPTS);
|
|
993
1041
|
if (port === null) {
|
|
994
|
-
logger$
|
|
1042
|
+
logger$14.warn("Unable to allocate port for cc-proxy.");
|
|
995
1043
|
return null;
|
|
996
1044
|
}
|
|
997
1045
|
const targetUrl = resolveTargetUrlFromEnv(env);
|
|
998
1046
|
if (!targetUrl) {
|
|
999
|
-
logger$
|
|
1047
|
+
logger$14.warn("Unable to resolve target URL for cc-proxy (provider misconfigured).");
|
|
1000
1048
|
return null;
|
|
1001
1049
|
}
|
|
1002
|
-
logger$
|
|
1050
|
+
logger$14.debug(`Creating proxy instance on port ${port} targeting: ${targetUrl}`);
|
|
1003
1051
|
try {
|
|
1004
1052
|
const { ProxyServer } = require("@lmnr-ai/claude-code-proxy");
|
|
1005
1053
|
const proxyServer = new ProxyServer(port);
|
|
1006
1054
|
proxyServer.runServer(targetUrl);
|
|
1007
1055
|
if (!await waitForPort(port)) {
|
|
1008
|
-
logger$
|
|
1056
|
+
logger$14.warn(`cc-proxy failed to start on port ${port}`);
|
|
1009
1057
|
proxyServer.stopServer();
|
|
1010
1058
|
return null;
|
|
1011
1059
|
}
|
|
1012
1060
|
const proxyBaseUrl = `http://127.0.0.1:${port}`;
|
|
1013
1061
|
activeProxyServers.add(proxyServer);
|
|
1014
1062
|
registerGlobalProxyShutdown();
|
|
1015
|
-
logger$
|
|
1063
|
+
logger$14.info(`Started claude proxy server on: ${proxyBaseUrl}`);
|
|
1016
1064
|
return {
|
|
1017
1065
|
server: proxyServer,
|
|
1018
1066
|
baseUrl: proxyBaseUrl,
|
|
@@ -1020,11 +1068,11 @@ const createProxyInstance = async ({ env }) => {
|
|
|
1020
1068
|
targetUrl
|
|
1021
1069
|
};
|
|
1022
1070
|
} catch (e) {
|
|
1023
|
-
logger$
|
|
1071
|
+
logger$14.warn(`Unable to start cc-proxy: ${e instanceof Error ? e.message : String(e)}`);
|
|
1024
1072
|
return null;
|
|
1025
1073
|
}
|
|
1026
1074
|
} catch (e) {
|
|
1027
|
-
logger$
|
|
1075
|
+
logger$14.warn(`Failed to create proxy instance: ${e instanceof Error ? e.message : String(e)}`);
|
|
1028
1076
|
return null;
|
|
1029
1077
|
}
|
|
1030
1078
|
};
|
|
@@ -1034,11 +1082,11 @@ const createProxyInstance = async ({ env }) => {
|
|
|
1034
1082
|
const stopProxyInstance = (instance) => {
|
|
1035
1083
|
if (!instance) return;
|
|
1036
1084
|
try {
|
|
1037
|
-
logger$
|
|
1085
|
+
logger$14.debug(`Stopping proxy instance on port ${instance.port}`);
|
|
1038
1086
|
instance.server.stopServer();
|
|
1039
1087
|
activeProxyServers.delete(instance.server);
|
|
1040
1088
|
} catch (e) {
|
|
1041
|
-
logger$
|
|
1089
|
+
logger$14.debug(`Failed to stop proxy instance: ${e instanceof Error ? e.message : String(e)}`);
|
|
1042
1090
|
}
|
|
1043
1091
|
};
|
|
1044
1092
|
/**
|
|
@@ -1046,11 +1094,11 @@ const stopProxyInstance = (instance) => {
|
|
|
1046
1094
|
* Used during shutdown to ensure cleanup
|
|
1047
1095
|
*/
|
|
1048
1096
|
const forceReleaseProxy = () => {
|
|
1049
|
-
logger$
|
|
1097
|
+
logger$14.debug(`Force stopping all ${activeProxyServers.size} active proxy servers`);
|
|
1050
1098
|
for (const proxyServer of activeProxyServers) try {
|
|
1051
1099
|
proxyServer.stopServer();
|
|
1052
1100
|
} catch (e) {
|
|
1053
|
-
logger$
|
|
1101
|
+
logger$14.debug(`Failed to stop proxy: ${e instanceof Error ? e.message : String(e)}`);
|
|
1054
1102
|
}
|
|
1055
1103
|
activeProxyServers.clear();
|
|
1056
1104
|
};
|
|
@@ -1100,14 +1148,14 @@ const setTraceToProxyInstance = async (instance) => {
|
|
|
1100
1148
|
spanPath: payload.span_path,
|
|
1101
1149
|
laminarUrl: payload.laminar_url
|
|
1102
1150
|
});
|
|
1103
|
-
logger$
|
|
1151
|
+
logger$14.debug(`Set trace context to proxy on port ${instance.port}`);
|
|
1104
1152
|
} catch (e) {
|
|
1105
|
-
logger$
|
|
1153
|
+
logger$14.debug(`Unable to set trace context to proxy on port ${instance.port}: ` + (e instanceof Error ? e.message : String(e)));
|
|
1106
1154
|
}
|
|
1107
1155
|
};
|
|
1108
1156
|
//#endregion
|
|
1109
1157
|
//#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/index.ts
|
|
1110
|
-
const logger$
|
|
1158
|
+
const logger$13 = require_utils.initializeLogger();
|
|
1111
1159
|
/**
|
|
1112
1160
|
* Create an instrumented version of the claude-agent-sdk query function.
|
|
1113
1161
|
* This can be used when importing the query function before Laminar initialization.
|
|
@@ -1134,9 +1182,9 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1134
1182
|
const targetUrl = resolveTargetUrlFromEnv(mergedEnv);
|
|
1135
1183
|
proxyInstance = await createProxyInstance({ env: mergedEnv });
|
|
1136
1184
|
if (proxyInstance && targetUrl) {
|
|
1137
|
-
logger$
|
|
1185
|
+
logger$13.debug(`Using proxy on port ${proxyInstance.port}`);
|
|
1138
1186
|
await Laminar.withSpan(span, async () => {
|
|
1139
|
-
logger$
|
|
1187
|
+
logger$13.debug("Setting trace to proxy instance...");
|
|
1140
1188
|
await setTraceToProxyInstance(proxyInstance);
|
|
1141
1189
|
});
|
|
1142
1190
|
const varsToRemove = getEnvVarsToRemove(mergedEnv);
|
|
@@ -1148,7 +1196,8 @@ function instrumentClaudeAgentQuery(originalQuery) {
|
|
|
1148
1196
|
for (const varName of varsToRemove) delete params.options.env[varName];
|
|
1149
1197
|
if (params.options.env.CLAUDE_CODE_USE_FOUNDRY === "1") params.options.env.ANTHROPIC_FOUNDRY_BASE_URL = proxyInstance.baseUrl;
|
|
1150
1198
|
if (params.options.env.CLAUDE_CODE_USE_BEDROCK === "1") params.options.env.ANTHROPIC_BEDROCK_BASE_URL = proxyInstance.baseUrl;
|
|
1151
|
-
|
|
1199
|
+
if (params.options.env.CLAUDE_CODE_USE_VERTEX === "1") params.options.env.ANTHROPIC_VERTEX_BASE_URL = proxyInstance.baseUrl;
|
|
1200
|
+
} else logger$13.debug("No claude proxy server available. Proceeding without proxy.");
|
|
1152
1201
|
const originalGenerator = originalQuery(params);
|
|
1153
1202
|
for await (const message of originalGenerator) {
|
|
1154
1203
|
collected.push(message);
|
|
@@ -1177,7 +1226,7 @@ var ClaudeAgentSDKInstrumentation = class extends _opentelemetry_instrumentation
|
|
|
1177
1226
|
}
|
|
1178
1227
|
manuallyInstrument(claudeAgentModule) {
|
|
1179
1228
|
if (claudeAgentModule.query && typeof claudeAgentModule.query === "function") this._wrap(claudeAgentModule, "query", this.patchQuery());
|
|
1180
|
-
else logger$
|
|
1229
|
+
else logger$13.debug("query function not found in claudeAgentSDK module, skipping instrumentation");
|
|
1181
1230
|
}
|
|
1182
1231
|
patchQuery() {
|
|
1183
1232
|
return (original) => instrumentClaudeAgentQuery(original);
|
|
@@ -1195,7 +1244,7 @@ var ClaudeAgentSDKInstrumentation = class extends _opentelemetry_instrumentation
|
|
|
1195
1244
|
//#endregion
|
|
1196
1245
|
//#region src/laminar.ts
|
|
1197
1246
|
require_utils.loadEnv();
|
|
1198
|
-
const logger$
|
|
1247
|
+
const logger$12 = require_utils.initializeLogger();
|
|
1199
1248
|
var Laminar = class Laminar {
|
|
1200
1249
|
static {
|
|
1201
1250
|
this.isInitialized = false;
|
|
@@ -1269,7 +1318,7 @@ var Laminar = class Laminar {
|
|
|
1269
1318
|
*/
|
|
1270
1319
|
static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext, spanProcessor } = {}) {
|
|
1271
1320
|
if (this.isInitialized) {
|
|
1272
|
-
logger$
|
|
1321
|
+
logger$12.warn("Laminar has already been initialized. Skipping initialization.");
|
|
1273
1322
|
return;
|
|
1274
1323
|
}
|
|
1275
1324
|
const key = projectApiKey ?? process?.env?.LMNR_PROJECT_API_KEY;
|
|
@@ -1289,7 +1338,7 @@ var Laminar = class Laminar {
|
|
|
1289
1338
|
this.globalMetadata = metadata ?? {};
|
|
1290
1339
|
LaminarContextManager.setGlobalMetadata(this.globalMetadata);
|
|
1291
1340
|
if (inheritGlobalContext) LaminarContextManager.inheritGlobalContext = true;
|
|
1292
|
-
if (spanProcessor && !(spanProcessor instanceof LaminarSpanProcessor)) logger$
|
|
1341
|
+
if (spanProcessor && !(spanProcessor instanceof LaminarSpanProcessor)) logger$12.warn("Span processor is not a LaminarSpanProcessor. Some functionality may be impaired.");
|
|
1293
1342
|
this.isInitialized = true;
|
|
1294
1343
|
const urlWithoutSlash = url?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
|
|
1295
1344
|
const httpUrlWithoutSlash = httpUrl?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
|
|
@@ -1328,9 +1377,9 @@ var Laminar = class Laminar {
|
|
|
1328
1377
|
const baseContext = _opentelemetry_api.trace.setSpan(LaminarContextManager.getContext(), _opentelemetry_api.trace.wrapSpanContext(otelSpanContext));
|
|
1329
1378
|
const ctx = LaminarContextManager.setRawAssociationProperties(laminarContext, baseContext);
|
|
1330
1379
|
LaminarContextManager.pushContext(ctx);
|
|
1331
|
-
logger$
|
|
1380
|
+
logger$12.debug("Initialized Laminar parent context from LMNR_SPAN_CONTEXT.");
|
|
1332
1381
|
} catch (e) {
|
|
1333
|
-
logger$
|
|
1382
|
+
logger$12.warn("LMNR_SPAN_CONTEXT is set but could not be used: " + (e instanceof Error ? e.message : String(e)));
|
|
1334
1383
|
}
|
|
1335
1384
|
}
|
|
1336
1385
|
/**
|
|
@@ -1345,7 +1394,7 @@ var Laminar = class Laminar {
|
|
|
1345
1394
|
*/
|
|
1346
1395
|
static patch(modules) {
|
|
1347
1396
|
if (!this.isInitialized) {
|
|
1348
|
-
logger$
|
|
1397
|
+
logger$12.warn("Laminar must be initialized before patching modules. Skipping patch.");
|
|
1349
1398
|
return;
|
|
1350
1399
|
}
|
|
1351
1400
|
if (!modules || Object.keys(modules).length === 0) throw new Error("Pass at least one module to patch");
|
|
@@ -1529,6 +1578,14 @@ var Laminar = class Laminar {
|
|
|
1529
1578
|
* @param {string} options.userId - user ID to associate with the span.
|
|
1530
1579
|
* @param {string} options.sessionId - session ID to associate with the span.
|
|
1531
1580
|
* @param {Record<string, any>} options.metadata - metadata to associate with the span.
|
|
1581
|
+
* @param {boolean} options.global - when true, the span is registered on a
|
|
1582
|
+
* process-global context stack so that any subsequent `startSpan` /
|
|
1583
|
+
* `startActiveSpan` call (including from unrelated async tasks) uses it as
|
|
1584
|
+
* the parent. Use this for spans that span multiple disconnected async
|
|
1585
|
+
* callbacks — e.g. the root span of an OpenAI Agents trace, where child
|
|
1586
|
+
* spans are created from independent `TracingProcessor` callbacks that do
|
|
1587
|
+
* not share an async context. Defaults to false; the span still activates
|
|
1588
|
+
* within the current async context as usual.
|
|
1532
1589
|
* @returns The started span.
|
|
1533
1590
|
*
|
|
1534
1591
|
* @example
|
|
@@ -1559,7 +1616,7 @@ var Laminar = class Laminar {
|
|
|
1559
1616
|
* // | | bar
|
|
1560
1617
|
* // | | | openai.chat
|
|
1561
1618
|
*/
|
|
1562
|
-
static startActiveSpan({ name, input, spanType, context, parentSpanContext, tags, userId, sessionId, metadata, startTime }) {
|
|
1619
|
+
static startActiveSpan({ name, input, spanType, context, parentSpanContext, tags, userId, sessionId, metadata, startTime, global }) {
|
|
1563
1620
|
return this._startSpan({
|
|
1564
1621
|
name,
|
|
1565
1622
|
input,
|
|
@@ -1571,10 +1628,11 @@ var Laminar = class Laminar {
|
|
|
1571
1628
|
sessionId,
|
|
1572
1629
|
metadata,
|
|
1573
1630
|
activated: true,
|
|
1574
|
-
startTime
|
|
1631
|
+
startTime,
|
|
1632
|
+
global
|
|
1575
1633
|
});
|
|
1576
1634
|
}
|
|
1577
|
-
static _startSpan({ name, input, spanType, context, parentSpanContext, tags, userId, sessionId, metadata, activated, startTime }) {
|
|
1635
|
+
static _startSpan({ name, input, spanType, context, parentSpanContext, tags, userId, sessionId, metadata, activated, startTime, global }) {
|
|
1578
1636
|
let entityContext = context ?? LaminarContextManager.getContext();
|
|
1579
1637
|
let parentPath;
|
|
1580
1638
|
let parentIdsPath;
|
|
@@ -1594,9 +1652,8 @@ var Laminar = class Laminar {
|
|
|
1594
1652
|
parentSessionId = laminarContext.sessionId;
|
|
1595
1653
|
const spanContext = require_utils.tryToOtelSpanContext(laminarContext);
|
|
1596
1654
|
entityContext = _opentelemetry_api.trace.setSpan(entityContext, _opentelemetry_api.trace.wrapSpanContext(spanContext));
|
|
1597
|
-
LaminarContextManager.pushContext(entityContext);
|
|
1598
1655
|
} catch (e) {
|
|
1599
|
-
logger$
|
|
1656
|
+
logger$12.warn("Failed to parse parent span context: " + (e instanceof Error ? e.message : String(e)));
|
|
1600
1657
|
}
|
|
1601
1658
|
const tagProperties = tags ? { [`${require_utils.ASSOCIATION_PROPERTIES}.tags`]: Array.from(new Set(tags)) } : {};
|
|
1602
1659
|
const ctxAssociationProperties = LaminarContextManager.getAssociationProperties();
|
|
@@ -1636,6 +1693,10 @@ var Laminar = class Laminar {
|
|
|
1636
1693
|
entityContext = LaminarContextManager.setAssociationProperties(span, entityContext);
|
|
1637
1694
|
entityContext = _opentelemetry_api.trace.setSpan(entityContext, span);
|
|
1638
1695
|
LaminarContextManager.pushContext(entityContext);
|
|
1696
|
+
if (global) {
|
|
1697
|
+
LaminarContextManager.pushGlobalContext(entityContext);
|
|
1698
|
+
span.setGlobalActiveContext(entityContext);
|
|
1699
|
+
}
|
|
1639
1700
|
}
|
|
1640
1701
|
return span;
|
|
1641
1702
|
}
|
|
@@ -1695,13 +1756,13 @@ var Laminar = class Laminar {
|
|
|
1695
1756
|
}
|
|
1696
1757
|
static async flush() {
|
|
1697
1758
|
if (this.isInitialized) {
|
|
1698
|
-
logger$
|
|
1759
|
+
logger$12.debug("Flushing spans");
|
|
1699
1760
|
await forceFlush();
|
|
1700
1761
|
}
|
|
1701
1762
|
}
|
|
1702
1763
|
static async shutdown() {
|
|
1703
1764
|
if (this.isInitialized) {
|
|
1704
|
-
logger$
|
|
1765
|
+
logger$12.debug("Shutting down Laminar");
|
|
1705
1766
|
await forceFlush();
|
|
1706
1767
|
this.isInitialized = false;
|
|
1707
1768
|
_resetConfiguration();
|
|
@@ -1829,7 +1890,7 @@ return module.exports;
|
|
|
1829
1890
|
//#endregion
|
|
1830
1891
|
//#region src/browser/utils.ts
|
|
1831
1892
|
const LMNR_SEND_EVENTS_FUNCTION_NAME = "lmnrSendEvents";
|
|
1832
|
-
const logger$
|
|
1893
|
+
const logger$11 = require_utils.initializeLogger();
|
|
1833
1894
|
/**
|
|
1834
1895
|
* If the first argument is a string, return an object with the name of the method
|
|
1835
1896
|
* and the argument as the value.
|
|
@@ -1852,7 +1913,7 @@ const takeFullSnapshot = async (page) => await page.evaluate(() => {
|
|
|
1852
1913
|
window.lmnrRrweb.record.takeFullSnapshot();
|
|
1853
1914
|
return true;
|
|
1854
1915
|
} catch (error) {
|
|
1855
|
-
logger$
|
|
1916
|
+
logger$11.error(`Error taking full snapshot: ${error instanceof Error ? error.message : String(error)}`);
|
|
1856
1917
|
return false;
|
|
1857
1918
|
}
|
|
1858
1919
|
return false;
|
|
@@ -1863,7 +1924,7 @@ const injectSessionRecorder = async (page, sessionRecordingOptions) => {
|
|
|
1863
1924
|
try {
|
|
1864
1925
|
return await script();
|
|
1865
1926
|
} catch (error) {
|
|
1866
|
-
logger$
|
|
1927
|
+
logger$11.error("Operation " + script.name + ` failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1867
1928
|
}
|
|
1868
1929
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
1869
1930
|
}
|
|
@@ -1873,20 +1934,20 @@ const injectSessionRecorder = async (page, sessionRecordingOptions) => {
|
|
|
1873
1934
|
try {
|
|
1874
1935
|
isRrwebPresent = await castedPage.evaluate(() => typeof window.lmnrRrweb !== "undefined");
|
|
1875
1936
|
} catch (error) {
|
|
1876
|
-
logger$
|
|
1937
|
+
logger$11.debug(`ailed to check if session recorder is loaded: ${error instanceof Error ? error.message : String(error)}`);
|
|
1877
1938
|
}
|
|
1878
1939
|
if (!isRrwebPresent) {
|
|
1879
1940
|
if (!await tryRunScript(async function injectSessionRecorder() {
|
|
1880
1941
|
await castedPage.evaluate(RECORDER);
|
|
1881
1942
|
return true;
|
|
1882
1943
|
})) {
|
|
1883
|
-
logger$
|
|
1944
|
+
logger$11.error("Failed to load session recorder");
|
|
1884
1945
|
return;
|
|
1885
1946
|
}
|
|
1886
1947
|
try {
|
|
1887
1948
|
await castedPage.evaluate(injectScript, sessionRecordingOptions);
|
|
1888
1949
|
} catch (error) {
|
|
1889
|
-
logger$
|
|
1950
|
+
logger$11.debug(`Failed to inject session recorder: ${error instanceof Error ? error.message : String(error)}`);
|
|
1890
1951
|
}
|
|
1891
1952
|
}
|
|
1892
1953
|
};
|
|
@@ -2144,7 +2205,7 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
|
|
|
2144
2205
|
try {
|
|
2145
2206
|
const { batchId, chunkIndex, totalChunks, data } = chunk;
|
|
2146
2207
|
if (!sessionId || !traceId) {
|
|
2147
|
-
logger$
|
|
2208
|
+
logger$11.debug("Missing sessionId or traceId in chunk");
|
|
2148
2209
|
return;
|
|
2149
2210
|
}
|
|
2150
2211
|
if (!chunkBuffers.has(batchId)) chunkBuffers.set(batchId, {
|
|
@@ -2163,7 +2224,7 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
|
|
|
2163
2224
|
traceId,
|
|
2164
2225
|
events
|
|
2165
2226
|
}).catch((error) => {
|
|
2166
|
-
logger$
|
|
2227
|
+
logger$11.debug(`Failed to send events: ${error instanceof Error ? error.message : String(error)}`);
|
|
2167
2228
|
});
|
|
2168
2229
|
chunkBuffers.delete(batchId);
|
|
2169
2230
|
}
|
|
@@ -2171,16 +2232,16 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
|
|
|
2171
2232
|
const toDelete = [];
|
|
2172
2233
|
for (const [bid, buffer] of chunkBuffers.entries()) if (currentTime - buffer.timestamp > OLD_BUFFER_TIMEOUT) toDelete.push(bid);
|
|
2173
2234
|
for (const bid of toDelete) {
|
|
2174
|
-
logger$
|
|
2235
|
+
logger$11.debug(`Cleaning up incomplete chunk buffer: ${bid}`);
|
|
2175
2236
|
chunkBuffers.delete(bid);
|
|
2176
2237
|
}
|
|
2177
2238
|
} catch (error) {
|
|
2178
|
-
logger$
|
|
2239
|
+
logger$11.debug(`Could not send events: ${error instanceof Error ? error.message : String(error)}`);
|
|
2179
2240
|
}
|
|
2180
2241
|
}
|
|
2181
2242
|
//#endregion
|
|
2182
2243
|
//#region src/browser/playwright.ts
|
|
2183
|
-
const logger$
|
|
2244
|
+
const logger$10 = require_utils.initializeLogger();
|
|
2184
2245
|
var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
2185
2246
|
constructor(client, sessionRecordingOptions) {
|
|
2186
2247
|
super("@lmnr/playwright-instrumentation", require_dist.version, { enabled: true });
|
|
@@ -2288,7 +2349,7 @@ var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.Ins
|
|
|
2288
2349
|
try {
|
|
2289
2350
|
await injectSessionRecorder(page, this._sessionRecordingOptions);
|
|
2290
2351
|
} catch (error) {
|
|
2291
|
-
logger$
|
|
2352
|
+
logger$10.error(`Error in onLoad handler: ${error instanceof Error ? error.message : String(error)}`);
|
|
2292
2353
|
}
|
|
2293
2354
|
});
|
|
2294
2355
|
const chunkBuffers = /* @__PURE__ */ new Map();
|
|
@@ -2298,7 +2359,7 @@ var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.Ins
|
|
|
2298
2359
|
await sendEvents(chunk, this._client, chunkBuffers, sessionId, traceId);
|
|
2299
2360
|
});
|
|
2300
2361
|
} catch (error) {
|
|
2301
|
-
logger$
|
|
2362
|
+
logger$10.debug("Could not expose function " + LMNR_SEND_EVENTS_FUNCTION_NAME + `: ${error instanceof Error ? error.message : String(error)}`);
|
|
2302
2363
|
}
|
|
2303
2364
|
}
|
|
2304
2365
|
};
|
|
@@ -2723,7 +2784,7 @@ var StagehandV2Instrumentation = class extends _opentelemetry_instrumentation.In
|
|
|
2723
2784
|
};
|
|
2724
2785
|
//#endregion
|
|
2725
2786
|
//#region src/browser/puppeteer.ts
|
|
2726
|
-
const logger$
|
|
2787
|
+
const logger$9 = require_utils.initializeLogger();
|
|
2727
2788
|
var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
2728
2789
|
constructor(client, sessionRecordingOptions) {
|
|
2729
2790
|
super("@lmnr/puppeteer-instrumentation", require_dist.version, { enabled: true });
|
|
@@ -2768,10 +2829,10 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
2768
2829
|
context.on("targetcreated", (target) => {
|
|
2769
2830
|
target.page().then((page) => {
|
|
2770
2831
|
if (page) plugin.patchPage(page, sessionId).catch((error) => {
|
|
2771
|
-
logger$
|
|
2832
|
+
logger$9.error(`Failed to patch page: ${error instanceof Error ? error.message : String(error)}`);
|
|
2772
2833
|
});
|
|
2773
2834
|
}).catch((error) => {
|
|
2774
|
-
logger$
|
|
2835
|
+
logger$9.error(`Failed to patch page: ${error instanceof Error ? error.message : String(error)}`);
|
|
2775
2836
|
});
|
|
2776
2837
|
});
|
|
2777
2838
|
await Promise.all((await context.pages()).map((page) => plugin.patchPage(page, sessionId)));
|
|
@@ -2789,19 +2850,19 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
2789
2850
|
context.on("targetcreated", (target) => {
|
|
2790
2851
|
target.page().then((page) => {
|
|
2791
2852
|
if (page) plugin.patchPage(page, sessionId).catch((error) => {
|
|
2792
|
-
logger$
|
|
2853
|
+
logger$9.error(`Failed to patch page: ${error instanceof Error ? error.message : String(error)}`);
|
|
2793
2854
|
});
|
|
2794
2855
|
}).catch((error) => {
|
|
2795
|
-
logger$
|
|
2856
|
+
logger$9.error(`Failed to patch page: ${error instanceof Error ? error.message : String(error)}`);
|
|
2796
2857
|
});
|
|
2797
2858
|
});
|
|
2798
2859
|
context.on("targetchanged", (target) => {
|
|
2799
2860
|
target.page().then((page) => {
|
|
2800
2861
|
if (page) plugin.patchPage(page, sessionId).catch((error) => {
|
|
2801
|
-
logger$
|
|
2862
|
+
logger$9.error(`Failed to patch page: ${error instanceof Error ? error.message : String(error)}`);
|
|
2802
2863
|
});
|
|
2803
2864
|
}).catch((error) => {
|
|
2804
|
-
logger$
|
|
2865
|
+
logger$9.error(`Failed to patch page: ${error instanceof Error ? error.message : String(error)}`);
|
|
2805
2866
|
});
|
|
2806
2867
|
});
|
|
2807
2868
|
for (const page of await context.pages()) await plugin.patchPage(page, sessionId);
|
|
@@ -2825,7 +2886,7 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
2825
2886
|
const traceId = otelTraceId ? require_utils.otelTraceIdToUUID(otelTraceId) : require_utils.NIL_UUID;
|
|
2826
2887
|
page.on("domcontentloaded", () => {
|
|
2827
2888
|
injectSessionRecorder(page, this._sessionRecordingOptions).catch((error) => {
|
|
2828
|
-
logger$
|
|
2889
|
+
logger$9.error(`Error in onLoad handler: ${error instanceof Error ? error.message : String(error)}`);
|
|
2829
2890
|
});
|
|
2830
2891
|
});
|
|
2831
2892
|
await injectSessionRecorder(page, this._sessionRecordingOptions);
|
|
@@ -2835,13 +2896,13 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
2835
2896
|
await sendEvents(chunk, this._client, chunkBuffers, sessionId, traceId);
|
|
2836
2897
|
});
|
|
2837
2898
|
} catch (error) {
|
|
2838
|
-
logger$
|
|
2899
|
+
logger$9.debug("Could not expose function " + LMNR_SEND_EVENTS_FUNCTION_NAME + `: ${error instanceof Error ? error.message : String(error)}`);
|
|
2839
2900
|
}
|
|
2840
2901
|
}
|
|
2841
2902
|
};
|
|
2842
2903
|
//#endregion
|
|
2843
2904
|
//#region src/browser/stagehand/v3/constants.ts
|
|
2844
|
-
const logger$
|
|
2905
|
+
const logger$8 = require_utils.initializeLogger();
|
|
2845
2906
|
const CDP_OPERATION_TIMEOUT_MS = 1e4;
|
|
2846
2907
|
const SKIP_URL_PATTERNS = [
|
|
2847
2908
|
"about:blank",
|
|
@@ -2880,7 +2941,7 @@ async function getOrCreateIsolatedWorld(page) {
|
|
|
2880
2941
|
frameId
|
|
2881
2942
|
};
|
|
2882
2943
|
} catch (error) {
|
|
2883
|
-
logger$
|
|
2944
|
+
logger$8.debug(`Failed to create isolated world: ${error instanceof Error ? error.message : String(error)}`);
|
|
2884
2945
|
return null;
|
|
2885
2946
|
}
|
|
2886
2947
|
}
|
|
@@ -2897,7 +2958,7 @@ async function isRecorderPresent(page, contextId) {
|
|
|
2897
2958
|
if (!result) return true;
|
|
2898
2959
|
return result.result?.value === true;
|
|
2899
2960
|
} catch (error) {
|
|
2900
|
-
logger$
|
|
2961
|
+
logger$8.debug(`Failed to check if recorder is present: ${error instanceof Error ? error.message : String(error)}`);
|
|
2901
2962
|
return true;
|
|
2902
2963
|
}
|
|
2903
2964
|
}
|
|
@@ -2910,21 +2971,21 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
|
|
|
2910
2971
|
try {
|
|
2911
2972
|
url = page.url();
|
|
2912
2973
|
} catch (error) {
|
|
2913
|
-
logger$
|
|
2974
|
+
logger$8.debug(`Failed to get page URL, page might be closed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2914
2975
|
return null;
|
|
2915
2976
|
}
|
|
2916
2977
|
if (shouldSkipUrl(url)) {
|
|
2917
|
-
logger$
|
|
2978
|
+
logger$8.debug(`Skipping recorder injection for URL: ${url}`);
|
|
2918
2979
|
return null;
|
|
2919
2980
|
}
|
|
2920
2981
|
const worldResult = await getOrCreateIsolatedWorld(page);
|
|
2921
2982
|
if (!worldResult) {
|
|
2922
|
-
logger$
|
|
2983
|
+
logger$8.debug("Failed to get isolated world for page");
|
|
2923
2984
|
return null;
|
|
2924
2985
|
}
|
|
2925
2986
|
const { contextId, frameId } = worldResult;
|
|
2926
2987
|
if (await isRecorderPresent(page, contextId)) {
|
|
2927
|
-
logger$
|
|
2988
|
+
logger$8.debug("Recorder already present, skipping injection");
|
|
2928
2989
|
state.contextIdToSession.set(contextId, {
|
|
2929
2990
|
sessionId: state.sessionId,
|
|
2930
2991
|
traceId: state.traceId
|
|
@@ -2937,7 +2998,7 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
|
|
|
2937
2998
|
contextId
|
|
2938
2999
|
});
|
|
2939
3000
|
} catch (error) {
|
|
2940
|
-
logger$
|
|
3001
|
+
logger$8.debug(`Failed to inject rrweb: ${error instanceof Error ? error.message : String(error)}`);
|
|
2941
3002
|
return null;
|
|
2942
3003
|
}
|
|
2943
3004
|
const optionsJson = JSON.stringify(sessionRecordingOptions ?? {});
|
|
@@ -2948,14 +3009,14 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
|
|
|
2948
3009
|
contextId
|
|
2949
3010
|
});
|
|
2950
3011
|
} catch (error) {
|
|
2951
|
-
logger$
|
|
3012
|
+
logger$8.debug(`Failed to inject recording setup: ${error instanceof Error ? error.message : String(error)}`);
|
|
2952
3013
|
return null;
|
|
2953
3014
|
}
|
|
2954
3015
|
try {
|
|
2955
3016
|
await page.sendCDP("Runtime.addBinding", { name: "lmnrSendEvents" });
|
|
2956
|
-
logger$
|
|
3017
|
+
logger$8.debug(`Added binding 'lmnrSendEvents' for page ${frameId}, context ${contextId}`);
|
|
2957
3018
|
} catch (error) {
|
|
2958
|
-
logger$
|
|
3019
|
+
logger$8.debug(`Binding may already exist: ${error instanceof Error ? error.message : String(error)}`);
|
|
2959
3020
|
}
|
|
2960
3021
|
if (bindingHandler) try {
|
|
2961
3022
|
const pageTargetId = page.targetId();
|
|
@@ -2965,26 +3026,26 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
|
|
|
2965
3026
|
const sessionTyped = session;
|
|
2966
3027
|
if (sessionTyped.on) {
|
|
2967
3028
|
sessionTyped.on("Runtime.bindingCalled", bindingHandler);
|
|
2968
|
-
logger$
|
|
3029
|
+
logger$8.debug(`Set up binding handler on session ${sessionId}`);
|
|
2969
3030
|
}
|
|
2970
3031
|
} catch (error) {
|
|
2971
|
-
logger$
|
|
3032
|
+
logger$8.debug(`Failed to set up binding handler on session ${sessionId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2972
3033
|
}
|
|
2973
3034
|
state.pageSessionHandlers.set(pageTargetId, bindingHandler);
|
|
2974
3035
|
}
|
|
2975
3036
|
} catch (error) {
|
|
2976
|
-
logger$
|
|
3037
|
+
logger$8.debug(`Failed to set up binding handler: ${error instanceof Error ? error.message : String(error)}`);
|
|
2977
3038
|
}
|
|
2978
3039
|
state.contextIdToSession.set(contextId, {
|
|
2979
3040
|
sessionId: state.sessionId,
|
|
2980
3041
|
traceId: state.traceId
|
|
2981
3042
|
});
|
|
2982
|
-
logger$
|
|
3043
|
+
logger$8.debug(`Registered context mapping: contextId=${contextId}, sessionId=${state.sessionId}`);
|
|
2983
3044
|
state.instrumentedPageIds.add(frameId);
|
|
2984
|
-
logger$
|
|
3045
|
+
logger$8.debug(`Successfully injected recorder into page ${frameId}`);
|
|
2985
3046
|
return contextId;
|
|
2986
3047
|
} catch (error) {
|
|
2987
|
-
logger$
|
|
3048
|
+
logger$8.debug(`Error injecting recorder: ${error instanceof Error ? error.message : String(error)}`);
|
|
2988
3049
|
return null;
|
|
2989
3050
|
}
|
|
2990
3051
|
}
|
|
@@ -2998,13 +3059,13 @@ function createBindingHandler(state) {
|
|
|
2998
3059
|
if (event.name !== "lmnrSendEvents") return;
|
|
2999
3060
|
const sessionInfo = state.contextIdToSession.get(event.executionContextId);
|
|
3000
3061
|
if (!sessionInfo) {
|
|
3001
|
-
logger$
|
|
3062
|
+
logger$8.debug("No session info found for context ID: " + event.executionContextId);
|
|
3002
3063
|
if (state.contextIdToSession.size > 0) {
|
|
3003
3064
|
const [, fallbackInfo] = state.contextIdToSession.entries().next().value;
|
|
3004
3065
|
if (fallbackInfo) try {
|
|
3005
3066
|
sendEvents(JSON.parse(event.payload), state.client, state.chunkBuffers, fallbackInfo.sessionId, fallbackInfo.traceId);
|
|
3006
3067
|
} catch (error) {
|
|
3007
|
-
logger$
|
|
3068
|
+
logger$8.debug(`Failed to parse binding payload: ${error instanceof Error ? error.message : String(error)}`);
|
|
3008
3069
|
}
|
|
3009
3070
|
}
|
|
3010
3071
|
return;
|
|
@@ -3012,7 +3073,7 @@ function createBindingHandler(state) {
|
|
|
3012
3073
|
try {
|
|
3013
3074
|
sendEvents(JSON.parse(event.payload), state.client, state.chunkBuffers, sessionInfo.sessionId, sessionInfo.traceId);
|
|
3014
3075
|
} catch (error) {
|
|
3015
|
-
logger$
|
|
3076
|
+
logger$8.debug(`Failed to handle binding event: ${error instanceof Error ? error.message : String(error)}`);
|
|
3016
3077
|
}
|
|
3017
3078
|
};
|
|
3018
3079
|
}
|
|
@@ -3028,10 +3089,10 @@ function createTargetCreatedHandler(context, state, sessionRecordingOptions) {
|
|
|
3028
3089
|
const pageId = page.mainFrameId();
|
|
3029
3090
|
if (!state.instrumentedPageIds.has(pageId)) await injectRecorderViaCDP(page, state, context.conn, sessionRecordingOptions, state.bindingHandler ?? void 0);
|
|
3030
3091
|
} catch (error) {
|
|
3031
|
-
logger$
|
|
3092
|
+
logger$8.debug(`Error injecting recorder into new page: ${error instanceof Error ? error.message : String(error)}`);
|
|
3032
3093
|
}
|
|
3033
3094
|
} catch (error) {
|
|
3034
|
-
logger$
|
|
3095
|
+
logger$8.debug(`Error handling target created event: ${error instanceof Error ? error.message : String(error)}`);
|
|
3035
3096
|
}
|
|
3036
3097
|
};
|
|
3037
3098
|
}
|
|
@@ -3043,7 +3104,7 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
|
|
|
3043
3104
|
if (event.targetInfo.type !== "page") return;
|
|
3044
3105
|
const url = event.targetInfo.url;
|
|
3045
3106
|
if (shouldSkipUrl(url)) return;
|
|
3046
|
-
logger$
|
|
3107
|
+
logger$8.debug(`Target URL changed to ${url}, checking if recorder injection needed`);
|
|
3047
3108
|
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
3048
3109
|
try {
|
|
3049
3110
|
for (const page of context.pages()) if (page.targetId() === event.targetInfo.targetId) {
|
|
@@ -3051,7 +3112,7 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
|
|
|
3051
3112
|
break;
|
|
3052
3113
|
}
|
|
3053
3114
|
} catch (error) {
|
|
3054
|
-
logger$
|
|
3115
|
+
logger$8.debug(`Error handling target info change: ${error instanceof Error ? error.message : String(error)}`);
|
|
3055
3116
|
}
|
|
3056
3117
|
};
|
|
3057
3118
|
}
|
|
@@ -3181,12 +3242,12 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
3181
3242
|
*/
|
|
3182
3243
|
async setupSessionRecording(stagehandInstance, sessionId, traceId) {
|
|
3183
3244
|
if (!this._client) {
|
|
3184
|
-
logger$
|
|
3245
|
+
logger$8.debug("No Laminar client available, skipping session recording setup");
|
|
3185
3246
|
return;
|
|
3186
3247
|
}
|
|
3187
3248
|
const context = stagehandInstance.context;
|
|
3188
3249
|
if (!context || !context.conn) {
|
|
3189
|
-
logger$
|
|
3250
|
+
logger$8.debug("No context or connection available, skipping session recording setup");
|
|
3190
3251
|
return;
|
|
3191
3252
|
}
|
|
3192
3253
|
const recorderState = {
|
|
@@ -3216,11 +3277,11 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
3216
3277
|
for (const page of pages) try {
|
|
3217
3278
|
if (await injectRecorderViaCDP(page, recorderState, context.conn, this._sessionRecordingOptions, bindingHandler) !== null) injectedCount++;
|
|
3218
3279
|
} catch (error) {
|
|
3219
|
-
logger$
|
|
3280
|
+
logger$8.debug(`Error injecting recorder into page: ${error instanceof Error ? error.message : String(error)}`);
|
|
3220
3281
|
}
|
|
3221
|
-
logger$
|
|
3282
|
+
logger$8.debug(`Injected session recorder into ${injectedCount} of ${pages.length} existing page(s)`);
|
|
3222
3283
|
} catch (error) {
|
|
3223
|
-
logger$
|
|
3284
|
+
logger$8.debug(`Error accessing pages for recorder injection: ${error instanceof Error ? error.message : String(error)}`);
|
|
3224
3285
|
}
|
|
3225
3286
|
}
|
|
3226
3287
|
patchStagehandClose() {
|
|
@@ -3250,12 +3311,12 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
3250
3311
|
if (recorderState.targetCreatedHandler) try {
|
|
3251
3312
|
context.conn.off("Target.targetCreated", recorderState.targetCreatedHandler);
|
|
3252
3313
|
} catch (error) {
|
|
3253
|
-
logger$
|
|
3314
|
+
logger$8.debug(`Error removing target created handler: ${error instanceof Error ? error.message : String(error)}`);
|
|
3254
3315
|
}
|
|
3255
3316
|
if (recorderState.targetInfoChangedHandler) try {
|
|
3256
3317
|
context.conn.off("Target.targetInfoChanged", recorderState.targetInfoChangedHandler);
|
|
3257
3318
|
} catch (error) {
|
|
3258
|
-
logger$
|
|
3319
|
+
logger$8.debug(`Error removing target info changed handler: ${error instanceof Error ? error.message : String(error)}`);
|
|
3259
3320
|
}
|
|
3260
3321
|
}
|
|
3261
3322
|
recorderState.contextIdToSession.clear();
|
|
@@ -3266,7 +3327,7 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
|
|
|
3266
3327
|
recorderState.targetCreatedHandler = null;
|
|
3267
3328
|
recorderState.targetInfoChangedHandler = null;
|
|
3268
3329
|
this.stagehandInstanceToRecorderState.delete(stagehandInstance);
|
|
3269
|
-
logger$
|
|
3330
|
+
logger$8.debug("Cleaned up session recording for Stagehand instance");
|
|
3270
3331
|
}
|
|
3271
3332
|
patchStagehandGlobalMethod(methodName, sessionId, parentSpan) {
|
|
3272
3333
|
return (original) => async function method(...args) {
|
|
@@ -3986,6 +4047,610 @@ var KernelInstrumentation = class extends _opentelemetry_instrumentation.Instrum
|
|
|
3986
4047
|
this._unwrap(moduleExports.Kernel.prototype, "app");
|
|
3987
4048
|
}
|
|
3988
4049
|
};
|
|
4050
|
+
const DISABLE_OPENAI_RESPONSES_INSTRUMENTATION_CONTEXT_KEY = (0, _opentelemetry_api.createContextKey)("LMNR_DISABLE_OPENAI_RESPONSES_INSTRUMENTATION");
|
|
4051
|
+
const systemInstructionsStorage = new async_hooks.AsyncLocalStorage();
|
|
4052
|
+
const getCurrentSystemInstructions = () => systemInstructionsStorage.getStore();
|
|
4053
|
+
const runWithSystemInstructions = (value, fn) => systemInstructionsStorage.run(value, fn);
|
|
4054
|
+
const wrapStreamWithSystemInstructions = (value, source) => ({ [Symbol.asyncIterator]() {
|
|
4055
|
+
let iterator;
|
|
4056
|
+
const getIterator = () => {
|
|
4057
|
+
if (iterator === void 0) iterator = systemInstructionsStorage.run(value, () => source[Symbol.asyncIterator]());
|
|
4058
|
+
return iterator;
|
|
4059
|
+
};
|
|
4060
|
+
return {
|
|
4061
|
+
next: (..._args) => systemInstructionsStorage.run(value, () => getIterator().next()),
|
|
4062
|
+
return: (returnValue) => {
|
|
4063
|
+
const it = getIterator();
|
|
4064
|
+
return it.return ? systemInstructionsStorage.run(value, () => it.return(returnValue)) : Promise.resolve({
|
|
4065
|
+
done: true,
|
|
4066
|
+
value: returnValue
|
|
4067
|
+
});
|
|
4068
|
+
},
|
|
4069
|
+
throw: (err) => {
|
|
4070
|
+
const it = getIterator();
|
|
4071
|
+
return it.throw ? systemInstructionsStorage.run(value, () => it.throw(err)) : Promise.reject(err);
|
|
4072
|
+
}
|
|
4073
|
+
};
|
|
4074
|
+
} });
|
|
4075
|
+
const spanKind = (spanData) => {
|
|
4076
|
+
if (spanData == null) return "";
|
|
4077
|
+
return typeof spanData.type === "string" ? spanData.type : "";
|
|
4078
|
+
};
|
|
4079
|
+
const spanName = (span, spanData) => {
|
|
4080
|
+
const name = span?.name;
|
|
4081
|
+
if (typeof name === "string" && name) return name;
|
|
4082
|
+
const kind = spanKind(spanData);
|
|
4083
|
+
if (kind) {
|
|
4084
|
+
if (kind === "agent" || kind === "custom" || kind === "function" || kind === "tool") return nameFromSpanData(spanData) || `agents.${kind}`;
|
|
4085
|
+
return `agents.${kind}`;
|
|
4086
|
+
}
|
|
4087
|
+
return "agents.span";
|
|
4088
|
+
};
|
|
4089
|
+
const mapSpanType = (spanData) => {
|
|
4090
|
+
const kind = spanKind(spanData);
|
|
4091
|
+
if (kind === "generation" || kind === "response" || kind === "transcription" || kind === "speech" || kind === "speech_group") return "LLM";
|
|
4092
|
+
if (kind === "function" || kind === "tool" || kind === "mcp_list_tools" || kind === "mcp_tools" || kind === "handoff") return "TOOL";
|
|
4093
|
+
return "DEFAULT";
|
|
4094
|
+
};
|
|
4095
|
+
const nameFromSpanData = (agent) => {
|
|
4096
|
+
if (agent == null) return "";
|
|
4097
|
+
if (typeof agent === "string") return agent;
|
|
4098
|
+
if (typeof agent === "object") {
|
|
4099
|
+
if (typeof agent.name === "string") return agent.name;
|
|
4100
|
+
}
|
|
4101
|
+
return "";
|
|
4102
|
+
};
|
|
4103
|
+
const getFirstNotNull = (d, ...keys) => {
|
|
4104
|
+
if (d == null) return;
|
|
4105
|
+
for (const key of keys) {
|
|
4106
|
+
const v = d[key];
|
|
4107
|
+
if (v !== void 0 && v !== null) return v;
|
|
4108
|
+
}
|
|
4109
|
+
};
|
|
4110
|
+
const modelAsDict = (obj) => {
|
|
4111
|
+
if (obj == null) return;
|
|
4112
|
+
if (typeof obj !== "object") return;
|
|
4113
|
+
if (Array.isArray(obj)) return;
|
|
4114
|
+
return obj;
|
|
4115
|
+
};
|
|
4116
|
+
const normalizeMessages = (data, role = "user") => {
|
|
4117
|
+
if (data == null) return [];
|
|
4118
|
+
if (typeof data === "string") return [{
|
|
4119
|
+
role,
|
|
4120
|
+
content: data
|
|
4121
|
+
}];
|
|
4122
|
+
if (Array.isArray(data)) {
|
|
4123
|
+
const messages = [];
|
|
4124
|
+
for (const item of data) if (item != null && typeof item === "object" && !Array.isArray(item)) messages.push(item);
|
|
4125
|
+
else messages.push({
|
|
4126
|
+
role,
|
|
4127
|
+
content: String(item)
|
|
4128
|
+
});
|
|
4129
|
+
return messages;
|
|
4130
|
+
}
|
|
4131
|
+
if (typeof data === "object") return [data];
|
|
4132
|
+
return [{
|
|
4133
|
+
role,
|
|
4134
|
+
content: String(data)
|
|
4135
|
+
}];
|
|
4136
|
+
};
|
|
4137
|
+
//#endregion
|
|
4138
|
+
//#region src/opentelemetry-lib/instrumentation/openai-agents/messages.ts
|
|
4139
|
+
const logger$7 = require_utils.initializeLogger();
|
|
4140
|
+
const setLmnrSpanIo = (lmnrSpan, inputData, outputData) => {
|
|
4141
|
+
if (inputData !== void 0 && inputData !== null) lmnrSpan.setAttribute(require_utils.SPAN_INPUT, JSON.stringify(inputData));
|
|
4142
|
+
if (outputData !== void 0 && outputData !== null) lmnrSpan.setAttribute(require_utils.SPAN_OUTPUT, JSON.stringify(outputData));
|
|
4143
|
+
};
|
|
4144
|
+
const setGenAiInputMessages = (lmnrSpan, inputData, systemInstructions) => {
|
|
4145
|
+
const hasInput = inputData !== void 0 && inputData !== null;
|
|
4146
|
+
if (!hasInput && !systemInstructions) return;
|
|
4147
|
+
const messages = hasInput ? normalizeMessages(inputData) : [];
|
|
4148
|
+
if (systemInstructions) messages.unshift({
|
|
4149
|
+
role: "system",
|
|
4150
|
+
content: [{
|
|
4151
|
+
type: "input_text",
|
|
4152
|
+
text: systemInstructions
|
|
4153
|
+
}]
|
|
4154
|
+
});
|
|
4155
|
+
if (messages.length > 0) lmnrSpan.setAttribute("gen_ai.input.messages", JSON.stringify(messages));
|
|
4156
|
+
};
|
|
4157
|
+
const setGenAiOutputMessages = (lmnrSpan, outputData) => {
|
|
4158
|
+
if (outputData === void 0 || outputData === null) return;
|
|
4159
|
+
const messages = normalizeMessages(outputData, "assistant");
|
|
4160
|
+
if (messages.length > 0) lmnrSpan.setAttribute("gen_ai.output.messages", JSON.stringify(messages));
|
|
4161
|
+
};
|
|
4162
|
+
const setGenAiOutputMessagesFromResponse = (lmnrSpan, response) => {
|
|
4163
|
+
if (response == null) return;
|
|
4164
|
+
let outputItems = response.output;
|
|
4165
|
+
if (!outputItems) return;
|
|
4166
|
+
const id = response.id;
|
|
4167
|
+
if (!Array.isArray(outputItems)) {
|
|
4168
|
+
logger$7.debug("Laminar OpenAI agents instrumentation, failed to parse output items. Expected array");
|
|
4169
|
+
outputItems = [];
|
|
4170
|
+
}
|
|
4171
|
+
const result = {
|
|
4172
|
+
id,
|
|
4173
|
+
object: "response",
|
|
4174
|
+
output: outputItems
|
|
4175
|
+
};
|
|
4176
|
+
lmnrSpan.setAttribute("gen_ai.output.messages", JSON.stringify(result));
|
|
4177
|
+
};
|
|
4178
|
+
const setToolDefinitionsFromResponse = (lmnrSpan, response) => {
|
|
4179
|
+
const tools = response?.tools;
|
|
4180
|
+
if (!tools || !Array.isArray(tools)) return;
|
|
4181
|
+
const toolDefs = [];
|
|
4182
|
+
for (const tool of tools) {
|
|
4183
|
+
const toolDict = modelAsDict(tool);
|
|
4184
|
+
if (!toolDict) continue;
|
|
4185
|
+
if (toolDict.type === "function") {
|
|
4186
|
+
const funcDef = { type: "function" };
|
|
4187
|
+
const functionInfo = toolDict.function ?? toolDict;
|
|
4188
|
+
const fn = { name: functionInfo.name ?? "" };
|
|
4189
|
+
const desc = functionInfo.description;
|
|
4190
|
+
if (desc) fn.description = desc;
|
|
4191
|
+
const params = functionInfo.parameters;
|
|
4192
|
+
if (params) fn.parameters = params;
|
|
4193
|
+
const strict = functionInfo.strict;
|
|
4194
|
+
if (strict !== void 0 && strict !== null) fn.strict = strict;
|
|
4195
|
+
funcDef.function = fn;
|
|
4196
|
+
toolDefs.push(funcDef);
|
|
4197
|
+
} else toolDefs.push(toolDict);
|
|
4198
|
+
}
|
|
4199
|
+
if (toolDefs.length > 0) lmnrSpan.setAttribute("gen_ai.tool.definitions", JSON.stringify(toolDefs));
|
|
4200
|
+
};
|
|
4201
|
+
const applyLlmAttributes = (lmnrSpan, data) => {
|
|
4202
|
+
if (!data) return;
|
|
4203
|
+
const model = data.model;
|
|
4204
|
+
if (model) {
|
|
4205
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, model);
|
|
4206
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.RESPONSE_MODEL, model);
|
|
4207
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.PROVIDER, "openai");
|
|
4208
|
+
}
|
|
4209
|
+
const usage = data.usage;
|
|
4210
|
+
if (usage != null) applyUsage(lmnrSpan, usage);
|
|
4211
|
+
let responseId = data.response_id;
|
|
4212
|
+
if (responseId == null) responseId = data.id;
|
|
4213
|
+
if (responseId != null) lmnrSpan.setAttribute("gen_ai.response.id", responseId);
|
|
4214
|
+
};
|
|
4215
|
+
const applyUsage = (lmnrSpan, usage) => {
|
|
4216
|
+
if (usage == null) return;
|
|
4217
|
+
const inputTokens = getFirstNotNull(usage, "input_tokens", "prompt_tokens", "input");
|
|
4218
|
+
const outputTokens = getFirstNotNull(usage, "output_tokens", "completion_tokens", "output");
|
|
4219
|
+
const totalTokens = getFirstNotNull(usage, "total_tokens", "total");
|
|
4220
|
+
const inputTokensDetails = getFirstNotNull(usage, "input_tokens_details", "prompt_tokens_details");
|
|
4221
|
+
const outputTokensDetails = getFirstNotNull(usage, "output_tokens_details", "completion_tokens_details");
|
|
4222
|
+
let cachedInputTokens;
|
|
4223
|
+
let reasoningOutputTokens;
|
|
4224
|
+
if (inputTokensDetails?.cached_tokens !== void 0 && inputTokensDetails?.cached_tokens !== null) cachedInputTokens = Number(inputTokensDetails.cached_tokens);
|
|
4225
|
+
if (outputTokensDetails?.reasoning_tokens !== void 0 && outputTokensDetails?.reasoning_tokens !== null) reasoningOutputTokens = Number(outputTokensDetails.reasoning_tokens);
|
|
4226
|
+
if (inputTokens !== void 0 && inputTokens !== null) lmnrSpan.setAttribute(require_utils.LaminarAttributes.INPUT_TOKEN_COUNT, Number(inputTokens));
|
|
4227
|
+
if (cachedInputTokens !== void 0) lmnrSpan.setAttribute("gen_ai.usage.cache_read_input_tokens", cachedInputTokens);
|
|
4228
|
+
if (outputTokens !== void 0 && outputTokens !== null) lmnrSpan.setAttribute(require_utils.LaminarAttributes.OUTPUT_TOKEN_COUNT, Number(outputTokens));
|
|
4229
|
+
if (reasoningOutputTokens !== void 0) lmnrSpan.setAttribute("gen_ai.usage.reasoning_output_tokens", reasoningOutputTokens);
|
|
4230
|
+
if (totalTokens !== void 0 && totalTokens !== null) lmnrSpan.setAttribute(require_utils.LaminarAttributes.TOTAL_TOKEN_COUNT, Number(totalTokens));
|
|
4231
|
+
else if (inputTokens !== void 0 && inputTokens !== null && outputTokens !== void 0 && outputTokens !== null) lmnrSpan.setAttribute(require_utils.LaminarAttributes.TOTAL_TOKEN_COUNT, Number(inputTokens) + Number(outputTokens));
|
|
4232
|
+
};
|
|
4233
|
+
const responseToLlmData = (response) => {
|
|
4234
|
+
if (response == null) return {};
|
|
4235
|
+
return {
|
|
4236
|
+
model: response.model,
|
|
4237
|
+
usage: response.usage,
|
|
4238
|
+
response_id: response.id
|
|
4239
|
+
};
|
|
4240
|
+
};
|
|
4241
|
+
//#endregion
|
|
4242
|
+
//#region src/opentelemetry-lib/instrumentation/openai-agents/span-data.ts
|
|
4243
|
+
const applySpanError = (lmnrSpan, span) => {
|
|
4244
|
+
const error = span?.error;
|
|
4245
|
+
if (!error) return;
|
|
4246
|
+
try {
|
|
4247
|
+
const message = error.message ?? String(error);
|
|
4248
|
+
lmnrSpan.setStatus({
|
|
4249
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
4250
|
+
message
|
|
4251
|
+
});
|
|
4252
|
+
} catch {}
|
|
4253
|
+
};
|
|
4254
|
+
const applySpanData = (lmnrSpan, spanData) => {
|
|
4255
|
+
if (spanData == null) return;
|
|
4256
|
+
const kind = spanKind(spanData);
|
|
4257
|
+
if (kind === "agent") applyAgentSpanData(lmnrSpan, spanData);
|
|
4258
|
+
else if (kind === "function" || kind === "tool") applyFunctionSpanData(lmnrSpan, spanData);
|
|
4259
|
+
else if (kind === "generation") applyGenerationSpanData(lmnrSpan, spanData);
|
|
4260
|
+
else if (kind === "response") applyResponseSpanData(lmnrSpan, spanData);
|
|
4261
|
+
else if (kind === "handoff") applyHandoffSpanData(lmnrSpan, spanData);
|
|
4262
|
+
else if (kind === "guardrail") applyGuardrailSpanData(lmnrSpan, spanData);
|
|
4263
|
+
else if (kind === "custom") applyCustomSpanData(lmnrSpan, spanData);
|
|
4264
|
+
else if (kind === "mcp_list_tools" || kind === "mcp_tools") applyMcpSpanData(lmnrSpan, spanData);
|
|
4265
|
+
else if (kind === "speech") applySpeechSpanData(lmnrSpan, spanData);
|
|
4266
|
+
else if (kind === "transcription") applyTranscriptionSpanData(lmnrSpan, spanData);
|
|
4267
|
+
else if (kind === "speech_group") applySpeechGroupSpanData(lmnrSpan, spanData);
|
|
4268
|
+
else setLmnrSpanIo(lmnrSpan, spanData?.input, spanData?.output);
|
|
4269
|
+
};
|
|
4270
|
+
const applyAgentSpanData = (lmnrSpan, spanData) => {
|
|
4271
|
+
const res = {};
|
|
4272
|
+
const name = spanData?.name;
|
|
4273
|
+
if (name) res.name = name;
|
|
4274
|
+
const handoffs = spanData?.handoffs;
|
|
4275
|
+
if (handoffs) res.handoffs = handoffs;
|
|
4276
|
+
const tools = spanData?.tools;
|
|
4277
|
+
if (tools) res.tools = tools;
|
|
4278
|
+
const outputType = spanData?.output_type;
|
|
4279
|
+
if (outputType) res.output_type = outputType;
|
|
4280
|
+
setLmnrSpanIo(lmnrSpan, res, null);
|
|
4281
|
+
};
|
|
4282
|
+
const applyFunctionSpanData = (lmnrSpan, spanData) => {
|
|
4283
|
+
setLmnrSpanIo(lmnrSpan, spanData?.input, spanData?.output);
|
|
4284
|
+
};
|
|
4285
|
+
const applyGenerationSpanData = (lmnrSpan, spanData) => {
|
|
4286
|
+
const inputData = spanData?.input;
|
|
4287
|
+
setGenAiInputMessages(lmnrSpan, inputData, getCurrentSystemInstructions());
|
|
4288
|
+
const outputData = spanData?.output;
|
|
4289
|
+
setGenAiOutputMessages(lmnrSpan, outputData);
|
|
4290
|
+
applyLlmAttributes(lmnrSpan, {
|
|
4291
|
+
model: spanData?.model,
|
|
4292
|
+
usage: spanData?.usage,
|
|
4293
|
+
response_id: spanData?.response_id ?? spanData?.id
|
|
4294
|
+
});
|
|
4295
|
+
};
|
|
4296
|
+
const applyResponseSpanData = (lmnrSpan, spanData) => {
|
|
4297
|
+
const response = spanData?._response ?? spanData?.response;
|
|
4298
|
+
setGenAiInputMessages(lmnrSpan, spanData?._input ?? spanData?.input, getCurrentSystemInstructions());
|
|
4299
|
+
if (response != null) {
|
|
4300
|
+
setGenAiOutputMessagesFromResponse(lmnrSpan, response);
|
|
4301
|
+
setToolDefinitionsFromResponse(lmnrSpan, response);
|
|
4302
|
+
applyLlmAttributes(lmnrSpan, responseToLlmData(response));
|
|
4303
|
+
} else if (spanData?.response_id) lmnrSpan.setAttribute("gen_ai.response.id", spanData.response_id);
|
|
4304
|
+
};
|
|
4305
|
+
const applyHandoffSpanData = (lmnrSpan, spanData) => {
|
|
4306
|
+
const fromAgent = spanData?.from_agent;
|
|
4307
|
+
const toAgent = spanData?.to_agent;
|
|
4308
|
+
if (fromAgent) lmnrSpan.setAttribute("openai.agents.handoff.from", nameFromSpanData(fromAgent));
|
|
4309
|
+
if (toAgent) lmnrSpan.setAttribute("openai.agents.handoff.to", nameFromSpanData(toAgent));
|
|
4310
|
+
};
|
|
4311
|
+
const applyGuardrailSpanData = (lmnrSpan, spanData) => {
|
|
4312
|
+
const name = spanData?.name;
|
|
4313
|
+
if (name) lmnrSpan.setAttribute("openai.agents.guardrail.name", name);
|
|
4314
|
+
const triggered = spanData?.triggered;
|
|
4315
|
+
if (triggered !== void 0 && triggered !== null) lmnrSpan.setAttribute("openai.agents.guardrail.triggered", Boolean(triggered));
|
|
4316
|
+
};
|
|
4317
|
+
const applyCustomSpanData = (lmnrSpan, spanData) => {
|
|
4318
|
+
const name = spanData?.name;
|
|
4319
|
+
if (name) lmnrSpan.setAttribute("openai.agents.custom.name", name);
|
|
4320
|
+
const customData = spanData?.data;
|
|
4321
|
+
if (customData !== void 0 && customData !== null) lmnrSpan.setAttribute("openai.agents.custom.data", JSON.stringify(customData));
|
|
4322
|
+
};
|
|
4323
|
+
const applyMcpSpanData = (lmnrSpan, spanData) => {
|
|
4324
|
+
const server = spanData?.server;
|
|
4325
|
+
if (server) lmnrSpan.setAttribute("openai.agents.mcp.server", server);
|
|
4326
|
+
const result = spanData?.result;
|
|
4327
|
+
if (result !== void 0 && result !== null) lmnrSpan.setAttribute("openai.agents.mcp.result", JSON.stringify(result));
|
|
4328
|
+
};
|
|
4329
|
+
const applySpeechSpanData = (lmnrSpan, spanData) => {
|
|
4330
|
+
const model = spanData?.model;
|
|
4331
|
+
if (model) {
|
|
4332
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, model);
|
|
4333
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.RESPONSE_MODEL, model);
|
|
4334
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.PROVIDER, "openai");
|
|
4335
|
+
}
|
|
4336
|
+
const inputText = spanData?.input;
|
|
4337
|
+
if (inputText) setGenAiInputMessages(lmnrSpan, inputText);
|
|
4338
|
+
const outputData = spanData?.output;
|
|
4339
|
+
if (outputData) if (typeof outputData === "object" && !Array.isArray(outputData)) setGenAiOutputMessages(lmnrSpan, outputData.data);
|
|
4340
|
+
else setGenAiOutputMessages(lmnrSpan, outputData);
|
|
4341
|
+
};
|
|
4342
|
+
const applyTranscriptionSpanData = (lmnrSpan, spanData) => {
|
|
4343
|
+
const model = spanData?.model;
|
|
4344
|
+
if (model) {
|
|
4345
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.REQUEST_MODEL, model);
|
|
4346
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.RESPONSE_MODEL, model);
|
|
4347
|
+
lmnrSpan.setAttribute(require_utils.LaminarAttributes.PROVIDER, "openai");
|
|
4348
|
+
}
|
|
4349
|
+
const inputData = spanData?.input;
|
|
4350
|
+
if (inputData) if (typeof inputData === "object" && !Array.isArray(inputData)) setGenAiInputMessages(lmnrSpan, inputData.data);
|
|
4351
|
+
else setGenAiInputMessages(lmnrSpan, inputData);
|
|
4352
|
+
const outputText = spanData?.output;
|
|
4353
|
+
if (outputText) setGenAiOutputMessages(lmnrSpan, outputText);
|
|
4354
|
+
};
|
|
4355
|
+
const applySpeechGroupSpanData = (lmnrSpan, spanData) => {
|
|
4356
|
+
const inputText = spanData?.input;
|
|
4357
|
+
if (inputText) setGenAiInputMessages(lmnrSpan, inputText);
|
|
4358
|
+
const outputText = spanData?.output;
|
|
4359
|
+
if (outputText) setGenAiOutputMessages(lmnrSpan, outputText);
|
|
4360
|
+
};
|
|
4361
|
+
//#endregion
|
|
4362
|
+
//#region src/opentelemetry-lib/instrumentation/openai-agents/processor.ts
|
|
4363
|
+
const logger$6 = require_utils.initializeLogger();
|
|
4364
|
+
var LaminarAgentsTraceProcessor = class {
|
|
4365
|
+
constructor() {
|
|
4366
|
+
this.traces = /* @__PURE__ */ new Map();
|
|
4367
|
+
this.disabled = false;
|
|
4368
|
+
}
|
|
4369
|
+
start() {}
|
|
4370
|
+
async onTraceStart(agentsTrace) {
|
|
4371
|
+
if (this.disabled) return;
|
|
4372
|
+
if (!agentsTrace.traceId) return;
|
|
4373
|
+
try {
|
|
4374
|
+
const state = this.getOrCreateTrace(agentsTrace);
|
|
4375
|
+
const traceName = agentsTrace.name;
|
|
4376
|
+
if (traceName && state.rootSpan !== void 0) try {
|
|
4377
|
+
state.rootSpan.updateName(traceName);
|
|
4378
|
+
} catch {}
|
|
4379
|
+
this.applyTraceMetadata(state.rootSpan, agentsTrace);
|
|
4380
|
+
} catch (e) {
|
|
4381
|
+
logger$6.debug(`Error in onTraceStart: ${String(e)}`);
|
|
4382
|
+
}
|
|
4383
|
+
}
|
|
4384
|
+
async onTraceEnd(agentsTrace) {
|
|
4385
|
+
if (this.disabled) return;
|
|
4386
|
+
const traceId = agentsTrace.traceId;
|
|
4387
|
+
if (!traceId) return;
|
|
4388
|
+
const state = this.traces.get(traceId);
|
|
4389
|
+
if (!state || state.ended) return;
|
|
4390
|
+
state.ended = true;
|
|
4391
|
+
this.endTraceState(state);
|
|
4392
|
+
this.traces.delete(traceId);
|
|
4393
|
+
}
|
|
4394
|
+
async onSpanStart(span) {
|
|
4395
|
+
if (this.disabled) return;
|
|
4396
|
+
if (!span.traceId) return;
|
|
4397
|
+
let lmnrSpan;
|
|
4398
|
+
try {
|
|
4399
|
+
const state = this.getOrCreateTrace(span);
|
|
4400
|
+
let parentSpanContext;
|
|
4401
|
+
const spanData = span.spanData;
|
|
4402
|
+
if (spanKind(spanData) === "agent") {
|
|
4403
|
+
const thisAgentName = nameFromSpanData(spanData?.name ?? spanData);
|
|
4404
|
+
const handoffCtx = state.pendingHandoffCtxs.get(thisAgentName);
|
|
4405
|
+
if (handoffCtx !== void 0) {
|
|
4406
|
+
state.pendingHandoffCtxs.delete(thisAgentName);
|
|
4407
|
+
parentSpanContext = handoffCtx;
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
if (parentSpanContext === void 0) {
|
|
4411
|
+
const parentId = span.parentId;
|
|
4412
|
+
const parentEntry = parentId != null ? state.spans.get(parentId) : void 0;
|
|
4413
|
+
const parentLmnrSpan = parentEntry !== void 0 ? parentEntry.lmnrSpan : state.rootSpan;
|
|
4414
|
+
if (parentLmnrSpan !== void 0) try {
|
|
4415
|
+
const ctx = parentLmnrSpan.getLaminarSpanContext?.();
|
|
4416
|
+
if (ctx) parentSpanContext = JSON.stringify(ctx);
|
|
4417
|
+
} catch {}
|
|
4418
|
+
}
|
|
4419
|
+
const spanType = mapSpanType(spanData);
|
|
4420
|
+
const name = spanName(span, spanData);
|
|
4421
|
+
const ctx = _opentelemetry_api.ROOT_CONTEXT.setValue(DISABLE_OPENAI_RESPONSES_INSTRUMENTATION_CONTEXT_KEY, true);
|
|
4422
|
+
lmnrSpan = Laminar.startSpan({
|
|
4423
|
+
name,
|
|
4424
|
+
spanType,
|
|
4425
|
+
parentSpanContext,
|
|
4426
|
+
context: ctx
|
|
4427
|
+
});
|
|
4428
|
+
const key = span.spanId;
|
|
4429
|
+
if (!key) {
|
|
4430
|
+
logger$6.debug("Span missing spanId, cannot track");
|
|
4431
|
+
try {
|
|
4432
|
+
lmnrSpan.end();
|
|
4433
|
+
} catch {}
|
|
4434
|
+
return;
|
|
4435
|
+
}
|
|
4436
|
+
let activationContext;
|
|
4437
|
+
try {
|
|
4438
|
+
activationContext = _opentelemetry_api.trace.setSpan(ctx, lmnrSpan);
|
|
4439
|
+
LaminarContextManager.pushContext(activationContext);
|
|
4440
|
+
} catch {
|
|
4441
|
+
activationContext = void 0;
|
|
4442
|
+
}
|
|
4443
|
+
state.spans.set(key, {
|
|
4444
|
+
lmnrSpan,
|
|
4445
|
+
agentsSpan: span,
|
|
4446
|
+
activationContext
|
|
4447
|
+
});
|
|
4448
|
+
} catch (e) {
|
|
4449
|
+
logger$6.debug(`Error in onSpanStart: ${String(e)}`);
|
|
4450
|
+
if (lmnrSpan !== void 0) try {
|
|
4451
|
+
lmnrSpan.end();
|
|
4452
|
+
} catch {}
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4455
|
+
async onSpanEnd(span) {
|
|
4456
|
+
if (this.disabled) return;
|
|
4457
|
+
const traceId = span.traceId;
|
|
4458
|
+
if (!traceId) return;
|
|
4459
|
+
const key = span.spanId;
|
|
4460
|
+
if (!key) return;
|
|
4461
|
+
const state = this.traces.get(traceId);
|
|
4462
|
+
const entry = state?.spans.get(key);
|
|
4463
|
+
if (!entry || !state) return;
|
|
4464
|
+
state.spans.delete(key);
|
|
4465
|
+
const spanData = span.spanData;
|
|
4466
|
+
try {
|
|
4467
|
+
try {
|
|
4468
|
+
applySpanData(entry.lmnrSpan, spanData);
|
|
4469
|
+
applySpanError(entry.lmnrSpan, span);
|
|
4470
|
+
} catch {}
|
|
4471
|
+
if (spanKind(spanData) === "handoff") try {
|
|
4472
|
+
const toAgent = nameFromSpanData(spanData?.to_agent);
|
|
4473
|
+
if (toAgent) {
|
|
4474
|
+
const parentId = span.parentId;
|
|
4475
|
+
const parentEntry = parentId != null ? state.spans.get(parentId) : void 0;
|
|
4476
|
+
const parentLmnrSpan = parentEntry !== void 0 ? parentEntry.lmnrSpan : state.rootSpan;
|
|
4477
|
+
if (parentLmnrSpan !== void 0) {
|
|
4478
|
+
const handoffCtx = parentLmnrSpan.getLaminarSpanContext?.();
|
|
4479
|
+
if (handoffCtx) state.pendingHandoffCtxs.set(toAgent, JSON.stringify(handoffCtx));
|
|
4480
|
+
}
|
|
4481
|
+
}
|
|
4482
|
+
} catch {}
|
|
4483
|
+
if (entry.activationContext !== void 0) try {
|
|
4484
|
+
LaminarContextManager.removeContext(entry.activationContext);
|
|
4485
|
+
} catch {}
|
|
4486
|
+
try {
|
|
4487
|
+
entry.lmnrSpan.end();
|
|
4488
|
+
} catch {}
|
|
4489
|
+
} catch {}
|
|
4490
|
+
}
|
|
4491
|
+
async shutdown(_timeout) {
|
|
4492
|
+
this.disabled = true;
|
|
4493
|
+
const states = Array.from(this.traces.values()).filter((s) => !s.ended);
|
|
4494
|
+
for (const s of states) s.ended = true;
|
|
4495
|
+
this.traces.clear();
|
|
4496
|
+
for (const state of states) this.endTraceState(state);
|
|
4497
|
+
try {
|
|
4498
|
+
await Laminar.flush();
|
|
4499
|
+
} catch {}
|
|
4500
|
+
}
|
|
4501
|
+
async forceFlush() {
|
|
4502
|
+
try {
|
|
4503
|
+
await Laminar.flush();
|
|
4504
|
+
} catch {}
|
|
4505
|
+
}
|
|
4506
|
+
endTraceState(state) {
|
|
4507
|
+
const remaining = Array.from(state.spans.values());
|
|
4508
|
+
state.spans.clear();
|
|
4509
|
+
for (let i = remaining.length - 1; i >= 0; i--) {
|
|
4510
|
+
const entry = remaining[i];
|
|
4511
|
+
try {
|
|
4512
|
+
const spanData = entry.agentsSpan?.spanData;
|
|
4513
|
+
applySpanData(entry.lmnrSpan, spanData);
|
|
4514
|
+
applySpanError(entry.lmnrSpan, entry.agentsSpan);
|
|
4515
|
+
} catch {}
|
|
4516
|
+
if (entry.activationContext !== void 0) try {
|
|
4517
|
+
LaminarContextManager.removeContext(entry.activationContext);
|
|
4518
|
+
} catch {}
|
|
4519
|
+
try {
|
|
4520
|
+
entry.lmnrSpan.end();
|
|
4521
|
+
} catch {}
|
|
4522
|
+
}
|
|
4523
|
+
try {
|
|
4524
|
+
state.rootSpan?.end();
|
|
4525
|
+
} catch {}
|
|
4526
|
+
}
|
|
4527
|
+
getOrCreateTrace(traceOrSpan) {
|
|
4528
|
+
let traceId = traceOrSpan.traceId;
|
|
4529
|
+
if (!traceId) traceId = "unknown";
|
|
4530
|
+
const existing = this.traces.get(traceId);
|
|
4531
|
+
if (existing) return existing;
|
|
4532
|
+
const state = {
|
|
4533
|
+
rootSpan: Laminar.startSpan({
|
|
4534
|
+
name: "agents.trace",
|
|
4535
|
+
context: _opentelemetry_api.ROOT_CONTEXT
|
|
4536
|
+
}),
|
|
4537
|
+
spans: /* @__PURE__ */ new Map(),
|
|
4538
|
+
ended: false,
|
|
4539
|
+
pendingHandoffCtxs: /* @__PURE__ */ new Map()
|
|
4540
|
+
};
|
|
4541
|
+
this.traces.set(traceId, state);
|
|
4542
|
+
return state;
|
|
4543
|
+
}
|
|
4544
|
+
applyTraceMetadata(rootSpan, agentsTrace) {
|
|
4545
|
+
if (rootSpan === void 0) return;
|
|
4546
|
+
const metadata = {};
|
|
4547
|
+
const traceMetadata = agentsTrace.metadata;
|
|
4548
|
+
if (traceMetadata !== void 0 && traceMetadata !== null) Object.assign(metadata, traceMetadata);
|
|
4549
|
+
const groupId = agentsTrace.groupId;
|
|
4550
|
+
if (groupId) metadata["openai.agents.group_id"] = groupId;
|
|
4551
|
+
if (agentsTrace.name) metadata["openai.agents.trace_name"] = agentsTrace.name;
|
|
4552
|
+
if (Object.keys(metadata).length > 0) try {
|
|
4553
|
+
rootSpan.setTraceMetadata?.(metadata);
|
|
4554
|
+
} catch {}
|
|
4555
|
+
const sessionId = metadata.session_id;
|
|
4556
|
+
const userId = metadata.user_id;
|
|
4557
|
+
if (sessionId) try {
|
|
4558
|
+
rootSpan.setTraceSessionId?.(String(sessionId));
|
|
4559
|
+
} catch {}
|
|
4560
|
+
if (userId) try {
|
|
4561
|
+
rootSpan.setTraceUserId?.(String(userId));
|
|
4562
|
+
} catch {}
|
|
4563
|
+
}
|
|
4564
|
+
};
|
|
4565
|
+
//#endregion
|
|
4566
|
+
//#region src/opentelemetry-lib/instrumentation/openai-agents/index.ts
|
|
4567
|
+
const logger$5 = require_utils.initializeLogger();
|
|
4568
|
+
const wrapGetResponse = (original) => function(request, ...rest) {
|
|
4569
|
+
const systemInstructions = request?.systemInstructions;
|
|
4570
|
+
return runWithSystemInstructions(systemInstructions, () => original.call(this, request, ...rest));
|
|
4571
|
+
};
|
|
4572
|
+
const wrapGetStreamedResponse = (original) => function(request, ...rest) {
|
|
4573
|
+
const systemInstructions = request?.systemInstructions;
|
|
4574
|
+
return wrapStreamWithSystemInstructions(systemInstructions, original.call(this, request, ...rest));
|
|
4575
|
+
};
|
|
4576
|
+
const MODEL_METHODS = ["getResponse", "getStreamedResponse"];
|
|
4577
|
+
var OpenAIAgentsInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
4578
|
+
constructor() {
|
|
4579
|
+
super("@lmnr/openai-agents-instrumentation", require_dist.version, { enabled: true });
|
|
4580
|
+
this._wrappedPrototypes = /* @__PURE__ */ new WeakSet();
|
|
4581
|
+
}
|
|
4582
|
+
init() {
|
|
4583
|
+
return [new _opentelemetry_instrumentation.InstrumentationNodeModuleDefinition("@openai/agents", [">=0.0.1"], this.patchAgents.bind(this), this.unpatchAgents.bind(this)), new _opentelemetry_instrumentation.InstrumentationNodeModuleDefinition("@openai/agents-openai", [">=0.0.1"], this.patchAgentsOpenAI.bind(this), this.unpatchAgentsOpenAI.bind(this))];
|
|
4584
|
+
}
|
|
4585
|
+
manuallyInstrument(agentsModule) {
|
|
4586
|
+
if (!agentsModule) {
|
|
4587
|
+
logger$5.debug("@openai/agents module not provided, skipping");
|
|
4588
|
+
return;
|
|
4589
|
+
}
|
|
4590
|
+
this.registerProcessor(agentsModule);
|
|
4591
|
+
this.patchModel(agentsModule);
|
|
4592
|
+
}
|
|
4593
|
+
registerProcessor(module) {
|
|
4594
|
+
if (this._processor !== void 0) return;
|
|
4595
|
+
const addTraceProcessor = module.addTraceProcessor;
|
|
4596
|
+
if (typeof addTraceProcessor !== "function") {
|
|
4597
|
+
logger$5.debug("addTraceProcessor not found in @openai/agents module");
|
|
4598
|
+
return;
|
|
4599
|
+
}
|
|
4600
|
+
try {
|
|
4601
|
+
const processor = new LaminarAgentsTraceProcessor();
|
|
4602
|
+
addTraceProcessor(processor);
|
|
4603
|
+
this._processor = processor;
|
|
4604
|
+
} catch (e) {
|
|
4605
|
+
logger$5.debug(`Failed to register Laminar Agents processor: ${String(e)}`);
|
|
4606
|
+
}
|
|
4607
|
+
}
|
|
4608
|
+
patchModel(module) {
|
|
4609
|
+
for (const cls of [module.OpenAIResponsesModel, module.OpenAIChatCompletionsModel]) {
|
|
4610
|
+
if (!cls || !cls.prototype) continue;
|
|
4611
|
+
if (this._wrappedPrototypes.has(cls.prototype)) continue;
|
|
4612
|
+
for (const method of MODEL_METHODS) {
|
|
4613
|
+
if (typeof cls.prototype[method] !== "function") continue;
|
|
4614
|
+
const wrapper = method === "getResponse" ? wrapGetResponse : wrapGetStreamedResponse;
|
|
4615
|
+
try {
|
|
4616
|
+
this._wrap(cls.prototype, method, wrapper);
|
|
4617
|
+
} catch (e) {
|
|
4618
|
+
logger$5.debug(`Failed to wrap ${method}: ${String(e)}`);
|
|
4619
|
+
}
|
|
4620
|
+
}
|
|
4621
|
+
this._wrappedPrototypes.add(cls.prototype);
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
unpatchModel(module) {
|
|
4625
|
+
for (const cls of [module.OpenAIResponsesModel, module.OpenAIChatCompletionsModel]) {
|
|
4626
|
+
if (!cls || !cls.prototype) continue;
|
|
4627
|
+
if (!this._wrappedPrototypes.has(cls.prototype)) continue;
|
|
4628
|
+
for (const method of MODEL_METHODS) try {
|
|
4629
|
+
this._unwrap(cls.prototype, method);
|
|
4630
|
+
} catch {}
|
|
4631
|
+
this._wrappedPrototypes.delete(cls.prototype);
|
|
4632
|
+
}
|
|
4633
|
+
}
|
|
4634
|
+
patchAgents(moduleExports) {
|
|
4635
|
+
_opentelemetry_api.diag.debug("Patching @openai/agents");
|
|
4636
|
+
this.registerProcessor(moduleExports);
|
|
4637
|
+
this.patchModel(moduleExports);
|
|
4638
|
+
return moduleExports;
|
|
4639
|
+
}
|
|
4640
|
+
unpatchAgents(moduleExports) {
|
|
4641
|
+
_opentelemetry_api.diag.debug("Unpatching @openai/agents");
|
|
4642
|
+
this.unpatchModel(moduleExports);
|
|
4643
|
+
}
|
|
4644
|
+
patchAgentsOpenAI(moduleExports) {
|
|
4645
|
+
_opentelemetry_api.diag.debug("Patching @openai/agents-openai");
|
|
4646
|
+
this.patchModel(moduleExports);
|
|
4647
|
+
return moduleExports;
|
|
4648
|
+
}
|
|
4649
|
+
unpatchAgentsOpenAI(moduleExports) {
|
|
4650
|
+
_opentelemetry_api.diag.debug("Unpatching @openai/agents-openai");
|
|
4651
|
+
this.unpatchModel(moduleExports);
|
|
4652
|
+
}
|
|
4653
|
+
};
|
|
3989
4654
|
//#endregion
|
|
3990
4655
|
//#region src/opentelemetry-lib/instrumentation/opencode.ts
|
|
3991
4656
|
var OpencodeInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
|
|
@@ -4133,6 +4798,7 @@ const initInstrumentations = (client, suppressContentTracing, sessionRecordingOp
|
|
|
4133
4798
|
instrumentations.push(new KernelInstrumentation());
|
|
4134
4799
|
instrumentations.push(new ClaudeAgentSDKInstrumentation());
|
|
4135
4800
|
instrumentations.push(new OpencodeInstrumentation());
|
|
4801
|
+
instrumentations.push(new OpenAIAgentsInstrumentation());
|
|
4136
4802
|
return instrumentations;
|
|
4137
4803
|
};
|
|
4138
4804
|
const manuallyInitInstrumentations = (client, instrumentModules, suppressContentTracing, sessionRecordingOptions) => {
|
|
@@ -4251,6 +4917,11 @@ const manuallyInitInstrumentations = (client, instrumentModules, suppressContent
|
|
|
4251
4917
|
instrumentations.push(opencodeInstrumentation);
|
|
4252
4918
|
opencodeInstrumentation.manuallyInstrument(instrumentModules.opencode);
|
|
4253
4919
|
}
|
|
4920
|
+
if (instrumentModules?.openAIAgents) {
|
|
4921
|
+
const openAIAgentsInstrumentation = new OpenAIAgentsInstrumentation();
|
|
4922
|
+
instrumentations.push(openAIAgentsInstrumentation);
|
|
4923
|
+
openAIAgentsInstrumentation.manuallyInstrument(instrumentModules.openAIAgents);
|
|
4924
|
+
}
|
|
4254
4925
|
return instrumentations;
|
|
4255
4926
|
};
|
|
4256
4927
|
//#endregion
|
|
@@ -4429,6 +5100,16 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
|
|
|
4429
5100
|
this._spanIdToPath.set(parentSpanId, spanPath);
|
|
4430
5101
|
this._spanIdLists.set(parentSpanId, spanIdsPath);
|
|
4431
5102
|
}
|
|
5103
|
+
/**
|
|
5104
|
+
* Drop cached path entries for a given span id. For exporters that stamp
|
|
5105
|
+
* their own span id over the SDK-allocated one after `startSpan` has fired
|
|
5106
|
+
* `onStart` — without this, `onEnd` reads the mutated id and its delete is
|
|
5107
|
+
* a no-op, so the original entry leaks one pair of map entries per span.
|
|
5108
|
+
*/
|
|
5109
|
+
dropPathInfo(spanId) {
|
|
5110
|
+
this._spanIdToPath.delete(spanId);
|
|
5111
|
+
this._spanIdLists.delete(spanId);
|
|
5112
|
+
}
|
|
4432
5113
|
clear() {
|
|
4433
5114
|
this._spanIdToPath.clear();
|
|
4434
5115
|
this._spanIdLists.clear();
|
|
@@ -5129,6 +5810,18 @@ Object.defineProperty(exports, "consumeStreamResult", {
|
|
|
5129
5810
|
return consumeStreamResult;
|
|
5130
5811
|
}
|
|
5131
5812
|
});
|
|
5813
|
+
Object.defineProperty(exports, "getLangVersion", {
|
|
5814
|
+
enumerable: true,
|
|
5815
|
+
get: function() {
|
|
5816
|
+
return getLangVersion;
|
|
5817
|
+
}
|
|
5818
|
+
});
|
|
5819
|
+
Object.defineProperty(exports, "getSpanProcessor", {
|
|
5820
|
+
enumerable: true,
|
|
5821
|
+
get: function() {
|
|
5822
|
+
return getSpanProcessor;
|
|
5823
|
+
}
|
|
5824
|
+
});
|
|
5132
5825
|
Object.defineProperty(exports, "getTracer", {
|
|
5133
5826
|
enumerable: true,
|
|
5134
5827
|
get: function() {
|
|
@@ -5184,4 +5877,4 @@ Object.defineProperty(exports, "withTracingLevel", {
|
|
|
5184
5877
|
}
|
|
5185
5878
|
});
|
|
5186
5879
|
|
|
5187
|
-
//# sourceMappingURL=decorators-
|
|
5880
|
+
//# sourceMappingURL=decorators-CaTC0lJq.cjs.map
|