lmnr 0.7.0__py3-none-any.whl → 0.7.1__py3-none-any.whl
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.
- lmnr/opentelemetry_lib/decorators/__init__.py +43 -4
- lmnr/opentelemetry_lib/litellm/__init__.py +5 -2
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +8 -3
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/__init__.py +6 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +139 -10
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/completion_wrappers.py +8 -3
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +6 -2
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +6 -3
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +4 -1
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/responses_wrappers.py +14 -5
- lmnr/opentelemetry_lib/tracing/context.py +18 -1
- lmnr/sdk/browser/pw_utils.py +43 -108
- lmnr/sdk/browser/recorder/record.umd.min.cjs +84 -0
- lmnr/sdk/laminar.py +51 -26
- lmnr/sdk/types.py +17 -5
- lmnr/version.py +1 -1
- {lmnr-0.7.0.dist-info → lmnr-0.7.1.dist-info}/METADATA +1 -1
- {lmnr-0.7.0.dist-info → lmnr-0.7.1.dist-info}/RECORD +20 -20
- lmnr/sdk/browser/rrweb/rrweb.umd.min.cjs +0 -98
- {lmnr-0.7.0.dist-info → lmnr-0.7.1.dist-info}/WHEEL +0 -0
- {lmnr-0.7.0.dist-info → lmnr-0.7.1.dist-info}/entry_points.txt +0 -0
lmnr/sdk/browser/pw_utils.py
CHANGED
@@ -33,7 +33,7 @@ except ImportError as e:
|
|
33
33
|
logger = logging.getLogger(__name__)
|
34
34
|
|
35
35
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
36
|
-
with open(os.path.join(current_dir, "
|
36
|
+
with open(os.path.join(current_dir, "recorder", "record.umd.min.cjs"), "r") as f:
|
37
37
|
RRWEB_CONTENT = f"() => {{ {f.read()} }}"
|
38
38
|
|
39
39
|
INJECT_PLACEHOLDER = """
|
@@ -358,14 +358,6 @@ INJECT_PLACEHOLDER = """
|
|
358
358
|
|
359
359
|
setInterval(sendBatchIfReady, BATCH_TIMEOUT);
|
360
360
|
|
361
|
-
// Add heartbeat events
|
362
|
-
setInterval(() => {
|
363
|
-
window.lmnrRrweb.record.addCustomEvent('heartbeat', {
|
364
|
-
title: document.title,
|
365
|
-
url: document.URL,
|
366
|
-
})
|
367
|
-
}, HEARTBEAT_INTERVAL);
|
368
|
-
|
369
361
|
async function bufferToBase64(buffer) {
|
370
362
|
const base64url = await new Promise(r => {
|
371
363
|
const reader = new FileReader()
|
@@ -397,63 +389,22 @@ INJECT_PLACEHOLDER = """
|
|
397
389
|
collectFonts: true,
|
398
390
|
recordCrossOriginIframes: true
|
399
391
|
});
|
400
|
-
}
|
401
|
-
"""
|
402
|
-
|
403
|
-
|
404
|
-
async def send_events_async(
|
405
|
-
page: Page, session_id: str, trace_id: str, client: AsyncLaminarClient
|
406
|
-
):
|
407
|
-
"""Fetch events from the page and send them to the server"""
|
408
|
-
try:
|
409
|
-
# Check if function exists first
|
410
|
-
events = await page.evaluate(
|
411
|
-
"""
|
412
|
-
() => {
|
413
|
-
if (typeof window.lmnrGetAndClearEvents !== 'function') {
|
414
|
-
return [];
|
415
|
-
}
|
416
|
-
return window.lmnrGetAndClearEvents();
|
417
|
-
}
|
418
|
-
"""
|
419
|
-
)
|
420
|
-
|
421
|
-
if not events or len(events) == 0:
|
422
|
-
return
|
423
392
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
):
|
435
|
-
"""Synchronous version of send_events"""
|
436
|
-
try:
|
437
|
-
events = page.evaluate(
|
438
|
-
"""
|
439
|
-
() => {
|
440
|
-
if (typeof window.lmnrGetAndClearEvents !== 'function') {
|
441
|
-
return [];
|
442
|
-
}
|
443
|
-
return window.lmnrGetAndClearEvents();
|
444
|
-
}
|
445
|
-
"""
|
446
|
-
)
|
447
|
-
if not events or len(events) == 0:
|
448
|
-
return
|
393
|
+
function heartbeat() {
|
394
|
+
// Add heartbeat events
|
395
|
+
setInterval(() => {
|
396
|
+
window.lmnrRrweb.record.addCustomEvent('heartbeat', {
|
397
|
+
title: document.title,
|
398
|
+
url: document.URL,
|
399
|
+
})
|
400
|
+
}, HEARTBEAT_INTERVAL
|
401
|
+
);
|
402
|
+
}
|
449
403
|
|
450
|
-
|
404
|
+
heartbeat();
|
451
405
|
|
452
|
-
|
453
|
-
|
454
|
-
e
|
455
|
-
):
|
456
|
-
logger.debug(f"Could not send events: {e}")
|
406
|
+
}
|
407
|
+
"""
|
457
408
|
|
458
409
|
|
459
410
|
def inject_session_recorder_sync(page: SyncPage):
|
@@ -483,10 +434,10 @@ def inject_session_recorder_sync(page: SyncPage):
|
|
483
434
|
):
|
484
435
|
return
|
485
436
|
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
437
|
+
try:
|
438
|
+
page.evaluate(INJECT_PLACEHOLDER)
|
439
|
+
except Exception as e:
|
440
|
+
logger.debug(f"Failed to inject session recorder: {e}")
|
490
441
|
|
491
442
|
except Exception as e:
|
492
443
|
logger.error(f"Error during session recorder injection: {e}")
|
@@ -519,10 +470,10 @@ async def inject_session_recorder_async(page: Page):
|
|
519
470
|
):
|
520
471
|
return
|
521
472
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
473
|
+
try:
|
474
|
+
await page.evaluate(INJECT_PLACEHOLDER)
|
475
|
+
except Exception as e:
|
476
|
+
logger.debug(f"Failed to inject session recorder placeholder: {e}")
|
526
477
|
|
527
478
|
except Exception as e:
|
528
479
|
logger.error(f"Error during session recorder injection: {e}")
|
@@ -542,24 +493,6 @@ def start_recording_events_sync(page: SyncPage, session_id: str, client: Laminar
|
|
542
493
|
except Exception:
|
543
494
|
pass
|
544
495
|
|
545
|
-
def on_load():
|
546
|
-
try:
|
547
|
-
inject_session_recorder_sync(page)
|
548
|
-
except Exception as e:
|
549
|
-
logger.error(f"Error in on_load handler: {e}")
|
550
|
-
|
551
|
-
def on_close():
|
552
|
-
try:
|
553
|
-
send_events_sync(page, session_id, trace_id, client)
|
554
|
-
except Exception:
|
555
|
-
pass
|
556
|
-
|
557
|
-
page.on("load", on_load)
|
558
|
-
page.on("close", on_close)
|
559
|
-
|
560
|
-
inject_session_recorder_sync(page)
|
561
|
-
|
562
|
-
# Expose function to browser so it can call us when events are ready
|
563
496
|
def send_events_from_browser(events):
|
564
497
|
try:
|
565
498
|
if events and len(events) > 0:
|
@@ -572,6 +505,16 @@ def start_recording_events_sync(page: SyncPage, session_id: str, client: Laminar
|
|
572
505
|
except Exception as e:
|
573
506
|
logger.debug(f"Could not expose function: {e}")
|
574
507
|
|
508
|
+
inject_session_recorder_sync(page)
|
509
|
+
|
510
|
+
def on_load(p):
|
511
|
+
try:
|
512
|
+
inject_session_recorder_sync(p)
|
513
|
+
except Exception as e:
|
514
|
+
logger.error(f"Error in on_load handler: {e}")
|
515
|
+
|
516
|
+
page.on("domcontentloaded", on_load)
|
517
|
+
|
575
518
|
|
576
519
|
@observe(name="playwright.page", ignore_input=True, ignore_output=True)
|
577
520
|
async def start_recording_events_async(
|
@@ -589,25 +532,7 @@ async def start_recording_events_async(
|
|
589
532
|
return
|
590
533
|
except Exception:
|
591
534
|
pass
|
592
|
-
|
593
|
-
async def on_load(p):
|
594
|
-
try:
|
595
|
-
await inject_session_recorder_async(p)
|
596
|
-
except Exception as e:
|
597
|
-
logger.error(f"Error in on_load handler: {e}")
|
598
|
-
|
599
|
-
async def on_close(p):
|
600
|
-
try:
|
601
|
-
# Send any remaining events before closing
|
602
|
-
await send_events_async(p, session_id, trace_id, client)
|
603
|
-
except Exception:
|
604
|
-
pass
|
605
|
-
|
606
|
-
page.on("load", on_load)
|
607
|
-
page.on("close", on_close)
|
608
|
-
|
609
|
-
await inject_session_recorder_async(page)
|
610
|
-
|
535
|
+
|
611
536
|
async def send_events_from_browser(events):
|
612
537
|
try:
|
613
538
|
if events and len(events) > 0:
|
@@ -620,6 +545,16 @@ async def start_recording_events_async(
|
|
620
545
|
except Exception as e:
|
621
546
|
logger.debug(f"Could not expose function: {e}")
|
622
547
|
|
548
|
+
await inject_session_recorder_async(page)
|
549
|
+
|
550
|
+
async def on_load(p):
|
551
|
+
try:
|
552
|
+
await inject_session_recorder_async(p)
|
553
|
+
except Exception as e:
|
554
|
+
logger.error(f"Error in on_load handler: {e}")
|
555
|
+
|
556
|
+
page.on("domcontentloaded", on_load)
|
557
|
+
|
623
558
|
|
624
559
|
def take_full_snapshot(page: Page):
|
625
560
|
return page.evaluate(
|