lmnr 0.7.17__py3-none-any.whl → 0.7.18__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.
Potentially problematic release.
This version of lmnr might be problematic. Click here for more details.
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +21 -9
- lmnr/sdk/laminar.py +93 -7
- lmnr/version.py +1 -1
- {lmnr-0.7.17.dist-info → lmnr-0.7.18.dist-info}/METADATA +1 -1
- {lmnr-0.7.17.dist-info → lmnr-0.7.18.dist-info}/RECORD +7 -7
- {lmnr-0.7.17.dist-info → lmnr-0.7.18.dist-info}/WHEEL +0 -0
- {lmnr-0.7.17.dist-info → lmnr-0.7.18.dist-info}/entry_points.txt +0 -0
|
@@ -206,15 +206,17 @@ def _set_request_attributes(span, args, kwargs):
|
|
|
206
206
|
contents = [contents]
|
|
207
207
|
for content in contents:
|
|
208
208
|
processed_content = process_content_union(content)
|
|
209
|
-
|
|
209
|
+
content_payload = get_content(processed_content)
|
|
210
|
+
if isinstance(content_payload, dict):
|
|
211
|
+
content_payload = [content_payload]
|
|
210
212
|
|
|
211
213
|
set_span_attribute(
|
|
212
214
|
span,
|
|
213
215
|
f"{gen_ai_attributes.GEN_AI_PROMPT}.{i}.content",
|
|
214
216
|
(
|
|
215
|
-
|
|
216
|
-
if isinstance(
|
|
217
|
-
else json_dumps(
|
|
217
|
+
content_payload
|
|
218
|
+
if isinstance(content_payload, str)
|
|
219
|
+
else json_dumps(content_payload)
|
|
218
220
|
),
|
|
219
221
|
)
|
|
220
222
|
blocks = (
|
|
@@ -318,20 +320,22 @@ def _set_response_attributes(span, response: types.GenerateContentResponse):
|
|
|
318
320
|
for candidate in candidates_list:
|
|
319
321
|
has_content = False
|
|
320
322
|
processed_content = process_content_union(candidate.content)
|
|
321
|
-
|
|
323
|
+
content_payload = get_content(processed_content)
|
|
324
|
+
if isinstance(content_payload, dict):
|
|
325
|
+
content_payload = [content_payload]
|
|
322
326
|
|
|
323
327
|
set_span_attribute(
|
|
324
328
|
span, f"{gen_ai_attributes.GEN_AI_COMPLETION}.{i}.role", "model"
|
|
325
329
|
)
|
|
326
|
-
if
|
|
330
|
+
if content_payload:
|
|
327
331
|
has_content = True
|
|
328
332
|
set_span_attribute(
|
|
329
333
|
span,
|
|
330
334
|
f"{gen_ai_attributes.GEN_AI_COMPLETION}.{i}.content",
|
|
331
335
|
(
|
|
332
|
-
|
|
333
|
-
if isinstance(
|
|
334
|
-
else json_dumps(
|
|
336
|
+
content_payload
|
|
337
|
+
if isinstance(content_payload, str)
|
|
338
|
+
else json_dumps(content_payload)
|
|
335
339
|
),
|
|
336
340
|
)
|
|
337
341
|
blocks = (
|
|
@@ -380,6 +384,10 @@ def _build_from_streaming_response(
|
|
|
380
384
|
aggregated_usage_metadata = defaultdict(int)
|
|
381
385
|
model_version = None
|
|
382
386
|
for chunk in response:
|
|
387
|
+
try:
|
|
388
|
+
span.add_event("llm.content.completion.chunk")
|
|
389
|
+
except Exception:
|
|
390
|
+
pass
|
|
383
391
|
# Important: do all processing in a separate sync function, that is
|
|
384
392
|
# wrapped in @dont_throw. If we did it here, the @dont_throw on top of
|
|
385
393
|
# this function would not be able to catch the errors, as they are
|
|
@@ -430,6 +438,10 @@ async def _abuild_from_streaming_response(
|
|
|
430
438
|
aggregated_usage_metadata = defaultdict(int)
|
|
431
439
|
model_version = None
|
|
432
440
|
async for chunk in response:
|
|
441
|
+
try:
|
|
442
|
+
span.add_event("llm.content.completion.chunk")
|
|
443
|
+
except Exception:
|
|
444
|
+
pass
|
|
433
445
|
# Important: do all processing in a separate sync function, that is
|
|
434
446
|
# wrapped in @dont_throw. If we did it here, the @dont_throw on top of
|
|
435
447
|
# this function would not be able to catch the errors, as they are
|
lmnr/sdk/laminar.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from contextlib import contextmanager
|
|
2
|
-
from contextvars import Context
|
|
2
|
+
from contextvars import Context, Token
|
|
3
3
|
import warnings
|
|
4
4
|
from lmnr.opentelemetry_lib import TracerManager
|
|
5
5
|
from lmnr.opentelemetry_lib.tracing import TracerWrapper, get_current_context
|
|
@@ -434,17 +434,17 @@ class Laminar:
|
|
|
434
434
|
with Laminar.use_span(span):
|
|
435
435
|
with Laminar.start_as_current_span("foo_inner"):
|
|
436
436
|
some_function()
|
|
437
|
-
|
|
437
|
+
|
|
438
438
|
def bar():
|
|
439
439
|
with Laminar.use_span(span):
|
|
440
440
|
openai_client.chat.completions.create()
|
|
441
|
-
|
|
441
|
+
|
|
442
442
|
span = Laminar.start_span("outer")
|
|
443
443
|
foo(span)
|
|
444
444
|
bar(span)
|
|
445
445
|
# IMPORTANT: End the span manually
|
|
446
446
|
span.end()
|
|
447
|
-
|
|
447
|
+
|
|
448
448
|
# Results in:
|
|
449
449
|
# | outer
|
|
450
450
|
# | | foo
|
|
@@ -642,6 +642,92 @@ class Laminar:
|
|
|
642
642
|
if end_on_exit:
|
|
643
643
|
span.end()
|
|
644
644
|
|
|
645
|
+
@classmethod
|
|
646
|
+
def start_active_span(
|
|
647
|
+
cls,
|
|
648
|
+
name: str,
|
|
649
|
+
input: Any = None,
|
|
650
|
+
span_type: Literal["DEFAULT", "LLM", "TOOL"] = "DEFAULT",
|
|
651
|
+
context: Context | None = None,
|
|
652
|
+
parent_span_context: LaminarSpanContext | None = None,
|
|
653
|
+
tags: list[str] | None = None,
|
|
654
|
+
) -> tuple[Span, Token[Context] | None]:
|
|
655
|
+
"""Start a new span. Useful for manual instrumentation.
|
|
656
|
+
If `span_type` is set to `"LLM"`, you should report usage and response
|
|
657
|
+
attributes manually. See `Laminar.set_span_attributes` for more
|
|
658
|
+
information. Returns the span and a context token that can be used to
|
|
659
|
+
detach the context.
|
|
660
|
+
|
|
661
|
+
Usage example:
|
|
662
|
+
```python
|
|
663
|
+
from src.lmnr import Laminar
|
|
664
|
+
def foo():
|
|
665
|
+
with Laminar.start_active_span("foo_inner"):
|
|
666
|
+
some_function()
|
|
667
|
+
|
|
668
|
+
def bar():
|
|
669
|
+
openai_client.chat.completions.create()
|
|
670
|
+
|
|
671
|
+
span, ctx_token = Laminar.start_active_span("outer")
|
|
672
|
+
foo()
|
|
673
|
+
bar()
|
|
674
|
+
# IMPORTANT: End the span manually
|
|
675
|
+
Laminar.end_active_span(span, ctx_token)
|
|
676
|
+
|
|
677
|
+
# Results in:
|
|
678
|
+
# | outer
|
|
679
|
+
# | | foo
|
|
680
|
+
# | | | foo_inner
|
|
681
|
+
# | | bar
|
|
682
|
+
# | | | openai.chat
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
Args:
|
|
686
|
+
name (str): name of the span
|
|
687
|
+
input (Any, optional): input to the span. Will be sent as an\
|
|
688
|
+
attribute, so must be json serializable. Defaults to None.
|
|
689
|
+
span_type (Literal["DEFAULT", "LLM", "TOOL"], optional):\
|
|
690
|
+
type of the span. If you use `"LLM"`, you should report usage\
|
|
691
|
+
and response attributes manually. Defaults to "DEFAULT".
|
|
692
|
+
context (Context | None, optional): raw OpenTelemetry context\
|
|
693
|
+
to attach the span to. Defaults to None.
|
|
694
|
+
parent_span_context (LaminarSpanContext | None, optional): parent\
|
|
695
|
+
span context to use for the span. Useful for continuing traces\
|
|
696
|
+
across services. If parent_span_context is a\
|
|
697
|
+
raw OpenTelemetry span context, or if it is a dictionary or string\
|
|
698
|
+
obtained from `Laminar.get_laminar_span_context_dict()` or\
|
|
699
|
+
`Laminar.get_laminar_span_context_str()` respectively, it will be\
|
|
700
|
+
converted to a `LaminarSpanContext` if possible. See also\
|
|
701
|
+
`Laminar.get_span_context`, `Laminar.get_span_context_dict` and\
|
|
702
|
+
`Laminar.get_span_context_str` for more information.
|
|
703
|
+
Defaults to None.
|
|
704
|
+
tags (list[str] | None, optional): tags to set for the span.
|
|
705
|
+
Defaults to None.
|
|
706
|
+
"""
|
|
707
|
+
span = cls.start_span(
|
|
708
|
+
name, input, span_type, context, parent_span_context, tags
|
|
709
|
+
)
|
|
710
|
+
if not cls.is_initialized():
|
|
711
|
+
return span, None
|
|
712
|
+
wrapper = TracerWrapper()
|
|
713
|
+
context = wrapper.push_span_context(span)
|
|
714
|
+
context_token = context_api.attach(context)
|
|
715
|
+
return span, context_token
|
|
716
|
+
|
|
717
|
+
@classmethod
|
|
718
|
+
def end_active_span(cls, span: Span, ctx_token: Token[Context]):
|
|
719
|
+
"""End an active span."""
|
|
720
|
+
span.end()
|
|
721
|
+
if not cls.is_initialized():
|
|
722
|
+
return
|
|
723
|
+
wrapper = TracerWrapper()
|
|
724
|
+
try:
|
|
725
|
+
wrapper.pop_span_context()
|
|
726
|
+
if ctx_token is not None:
|
|
727
|
+
context_api.detach(ctx_token)
|
|
728
|
+
except Exception:
|
|
729
|
+
pass
|
|
730
|
+
|
|
645
731
|
@classmethod
|
|
646
732
|
def set_span_output(cls, output: Any = None):
|
|
647
733
|
"""Set the output of the current span. Useful for manual
|
|
@@ -671,12 +757,12 @@ class Laminar:
|
|
|
671
757
|
instrumentation.
|
|
672
758
|
Example:
|
|
673
759
|
```python
|
|
674
|
-
with
|
|
760
|
+
with Laminar.start_as_current_span(
|
|
675
761
|
name="my_span_name", input=input["messages"], span_type="LLM"
|
|
676
762
|
):
|
|
677
763
|
response = await my_custom_call_to_openai(input)
|
|
678
|
-
|
|
679
|
-
|
|
764
|
+
Laminar.set_span_output(response["choices"][0]["message"]["content"])
|
|
765
|
+
Laminar.set_span_attributes({
|
|
680
766
|
Attributes.PROVIDER: 'openai',
|
|
681
767
|
Attributes.REQUEST_MODEL: input["model"],
|
|
682
768
|
Attributes.RESPONSE_MODEL: response["model"],
|
lmnr/version.py
CHANGED
|
@@ -16,7 +16,7 @@ lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/version.py,sha256
|
|
|
16
16
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_agent/__init__.py,sha256=48391d935883506fe1dc4f6ace6011ecaed76a8f82f8026ccb553b2180afdb8c,3455
|
|
17
17
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_computer/__init__.py,sha256=61d2681e99c3084d1bcc27f7ca551f44a70126df6c5f23320c1e9c1654e05c42,15037
|
|
18
18
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_computer/utils.py,sha256=19090d4d9a0511645f66112ebe6f05a9993905b11d8ae3060dab2dcc4c1a5fb2,329
|
|
19
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py,sha256=
|
|
19
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py,sha256=df9f06eda1f16f1ab99dbfdfae20ff55da1fb7842b53d51179b4fccdf9b0ac8f,20691
|
|
20
20
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py,sha256=db9cdebc9ee0dccb493ffe608eede3047efec20ed26c3924b72b2e50edbd92c2,245
|
|
21
21
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/schema_utils.py,sha256=b10619e76e5893f8b891f92531d29dcf6651e8f9a7dcbf81c3f35341ce311f6e,753
|
|
22
22
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py,sha256=ac662208d336cb9f5eb086389cd77d73e1a5a8bcc22ce8fffccd12a828b4e5cd,11092
|
|
@@ -93,12 +93,12 @@ lmnr/sdk/datasets.py,sha256=3fd851c5f97bf88eaa84b1451a053eaff23b4497cbb45eac2f9e
|
|
|
93
93
|
lmnr/sdk/decorators.py,sha256=c709b76a814e019c919fd811591850787a2f266b7b6f46123f66ddd92e1092d5,6920
|
|
94
94
|
lmnr/sdk/eval_control.py,sha256=291394ac385c653ae9b5167e871bebeb4fe8fc6b7ff2ed38e636f87015dcba86,184
|
|
95
95
|
lmnr/sdk/evaluations.py,sha256=7e55cbca77fa32cb64cb77aed8076a1994258a5b652c7f1d45231928e4aefe26,23885
|
|
96
|
-
lmnr/sdk/laminar.py,sha256=
|
|
96
|
+
lmnr/sdk/laminar.py,sha256=5fcb699577b19d60b0cf5c494eb366420d69d0ba17ac2cde979f0648ac38486e,41772
|
|
97
97
|
lmnr/sdk/log.py,sha256=9edfd83263f0d4845b1b2d1beeae2b4ed3f8628de941f371a893d72b79c348d4,2213
|
|
98
98
|
lmnr/sdk/types.py,sha256=d8061ca90dd582b408a893ebbbeb1586e8750ed30433ef4f6d63423a078511b0,14574
|
|
99
99
|
lmnr/sdk/utils.py,sha256=4114559ba6ae57fcba2de2bfaa09339688ce5752c36f028a7b55e51eae624947,6307
|
|
100
|
-
lmnr/version.py,sha256=
|
|
101
|
-
lmnr-0.7.
|
|
102
|
-
lmnr-0.7.
|
|
103
|
-
lmnr-0.7.
|
|
104
|
-
lmnr-0.7.
|
|
100
|
+
lmnr/version.py,sha256=98f78bacb066c12efdabeed4190a9b7a2386c093d36e8d1ce91276954fcab806,1322
|
|
101
|
+
lmnr-0.7.18.dist-info/WHEEL,sha256=ab6157bc637547491fb4567cd7ddf26b04d63382916ca16c29a5c8e94c9c9ef7,79
|
|
102
|
+
lmnr-0.7.18.dist-info/entry_points.txt,sha256=abdf3411b7dd2d7329a241f2da6669bab4e314a747a586ecdb9f888f3035003c,39
|
|
103
|
+
lmnr-0.7.18.dist-info/METADATA,sha256=b69c7b58f2b88f8839580b89bf55a7e732f92e60f88588dfe68f406579899be3,14258
|
|
104
|
+
lmnr-0.7.18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|