lmnr 0.4.53.dev0__py3-none-any.whl → 0.7.26__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.
Files changed (133) hide show
  1. lmnr/__init__.py +32 -11
  2. lmnr/cli/__init__.py +270 -0
  3. lmnr/cli/datasets.py +371 -0
  4. lmnr/cli/evals.py +111 -0
  5. lmnr/cli/rules.py +42 -0
  6. lmnr/opentelemetry_lib/__init__.py +70 -0
  7. lmnr/opentelemetry_lib/decorators/__init__.py +337 -0
  8. lmnr/opentelemetry_lib/litellm/__init__.py +685 -0
  9. lmnr/opentelemetry_lib/litellm/utils.py +100 -0
  10. lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/__init__.py +849 -0
  11. lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/config.py +13 -0
  12. lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_emitter.py +211 -0
  13. lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_models.py +41 -0
  14. lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/span_utils.py +401 -0
  15. lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/streaming.py +425 -0
  16. lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/utils.py +332 -0
  17. lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/version.py +1 -0
  18. lmnr/opentelemetry_lib/opentelemetry/instrumentation/claude_agent/__init__.py +451 -0
  19. lmnr/opentelemetry_lib/opentelemetry/instrumentation/claude_agent/proxy.py +144 -0
  20. lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_agent/__init__.py +100 -0
  21. lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_computer/__init__.py +476 -0
  22. lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_computer/utils.py +12 -0
  23. lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +599 -0
  24. lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py +9 -0
  25. lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/schema_utils.py +26 -0
  26. lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +330 -0
  27. lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/__init__.py +488 -0
  28. lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/config.py +8 -0
  29. lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_emitter.py +143 -0
  30. lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_models.py +41 -0
  31. lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/span_utils.py +229 -0
  32. lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/utils.py +92 -0
  33. lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/version.py +1 -0
  34. lmnr/opentelemetry_lib/opentelemetry/instrumentation/kernel/__init__.py +381 -0
  35. lmnr/opentelemetry_lib/opentelemetry/instrumentation/kernel/utils.py +36 -0
  36. lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/__init__.py +121 -0
  37. lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/utils.py +60 -0
  38. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/__init__.py +61 -0
  39. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/__init__.py +472 -0
  40. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +1185 -0
  41. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/completion_wrappers.py +305 -0
  42. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/config.py +16 -0
  43. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +312 -0
  44. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_emitter.py +100 -0
  45. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_models.py +41 -0
  46. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/image_gen_wrappers.py +68 -0
  47. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/utils.py +197 -0
  48. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v0/__init__.py +176 -0
  49. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/__init__.py +368 -0
  50. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +325 -0
  51. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +135 -0
  52. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/responses_wrappers.py +786 -0
  53. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/version.py +1 -0
  54. lmnr/opentelemetry_lib/opentelemetry/instrumentation/openhands_ai/__init__.py +388 -0
  55. lmnr/opentelemetry_lib/opentelemetry/instrumentation/opentelemetry/__init__.py +69 -0
  56. lmnr/opentelemetry_lib/opentelemetry/instrumentation/skyvern/__init__.py +191 -0
  57. lmnr/opentelemetry_lib/opentelemetry/instrumentation/threading/__init__.py +197 -0
  58. lmnr/opentelemetry_lib/tracing/__init__.py +263 -0
  59. lmnr/opentelemetry_lib/tracing/_instrument_initializers.py +516 -0
  60. lmnr/{openllmetry_sdk → opentelemetry_lib}/tracing/attributes.py +21 -8
  61. lmnr/opentelemetry_lib/tracing/context.py +200 -0
  62. lmnr/opentelemetry_lib/tracing/exporter.py +153 -0
  63. lmnr/opentelemetry_lib/tracing/instruments.py +140 -0
  64. lmnr/opentelemetry_lib/tracing/processor.py +193 -0
  65. lmnr/opentelemetry_lib/tracing/span.py +398 -0
  66. lmnr/opentelemetry_lib/tracing/tracer.py +57 -0
  67. lmnr/opentelemetry_lib/tracing/utils.py +62 -0
  68. lmnr/opentelemetry_lib/utils/package_check.py +18 -0
  69. lmnr/opentelemetry_lib/utils/wrappers.py +11 -0
  70. lmnr/sdk/browser/__init__.py +0 -0
  71. lmnr/sdk/browser/background_send_events.py +158 -0
  72. lmnr/sdk/browser/browser_use_cdp_otel.py +100 -0
  73. lmnr/sdk/browser/browser_use_otel.py +142 -0
  74. lmnr/sdk/browser/bubus_otel.py +71 -0
  75. lmnr/sdk/browser/cdp_utils.py +518 -0
  76. lmnr/sdk/browser/inject_script.js +514 -0
  77. lmnr/sdk/browser/patchright_otel.py +151 -0
  78. lmnr/sdk/browser/playwright_otel.py +322 -0
  79. lmnr/sdk/browser/pw_utils.py +363 -0
  80. lmnr/sdk/browser/recorder/record.umd.min.cjs +84 -0
  81. lmnr/sdk/browser/utils.py +70 -0
  82. lmnr/sdk/client/asynchronous/async_client.py +180 -0
  83. lmnr/sdk/client/asynchronous/resources/__init__.py +6 -0
  84. lmnr/sdk/client/asynchronous/resources/base.py +32 -0
  85. lmnr/sdk/client/asynchronous/resources/browser_events.py +41 -0
  86. lmnr/sdk/client/asynchronous/resources/datasets.py +131 -0
  87. lmnr/sdk/client/asynchronous/resources/evals.py +266 -0
  88. lmnr/sdk/client/asynchronous/resources/evaluators.py +85 -0
  89. lmnr/sdk/client/asynchronous/resources/tags.py +83 -0
  90. lmnr/sdk/client/synchronous/resources/__init__.py +6 -0
  91. lmnr/sdk/client/synchronous/resources/base.py +32 -0
  92. lmnr/sdk/client/synchronous/resources/browser_events.py +40 -0
  93. lmnr/sdk/client/synchronous/resources/datasets.py +131 -0
  94. lmnr/sdk/client/synchronous/resources/evals.py +263 -0
  95. lmnr/sdk/client/synchronous/resources/evaluators.py +85 -0
  96. lmnr/sdk/client/synchronous/resources/tags.py +83 -0
  97. lmnr/sdk/client/synchronous/sync_client.py +191 -0
  98. lmnr/sdk/datasets/__init__.py +94 -0
  99. lmnr/sdk/datasets/file_utils.py +91 -0
  100. lmnr/sdk/decorators.py +163 -26
  101. lmnr/sdk/eval_control.py +3 -2
  102. lmnr/sdk/evaluations.py +403 -191
  103. lmnr/sdk/laminar.py +1080 -549
  104. lmnr/sdk/log.py +7 -2
  105. lmnr/sdk/types.py +246 -134
  106. lmnr/sdk/utils.py +151 -7
  107. lmnr/version.py +46 -0
  108. {lmnr-0.4.53.dev0.dist-info → lmnr-0.7.26.dist-info}/METADATA +152 -106
  109. lmnr-0.7.26.dist-info/RECORD +116 -0
  110. lmnr-0.7.26.dist-info/WHEEL +4 -0
  111. lmnr-0.7.26.dist-info/entry_points.txt +3 -0
  112. lmnr/cli.py +0 -101
  113. lmnr/openllmetry_sdk/.python-version +0 -1
  114. lmnr/openllmetry_sdk/__init__.py +0 -72
  115. lmnr/openllmetry_sdk/config/__init__.py +0 -9
  116. lmnr/openllmetry_sdk/decorators/base.py +0 -185
  117. lmnr/openllmetry_sdk/instruments.py +0 -38
  118. lmnr/openllmetry_sdk/tracing/__init__.py +0 -1
  119. lmnr/openllmetry_sdk/tracing/content_allow_list.py +0 -24
  120. lmnr/openllmetry_sdk/tracing/context_manager.py +0 -13
  121. lmnr/openllmetry_sdk/tracing/tracing.py +0 -884
  122. lmnr/openllmetry_sdk/utils/in_memory_span_exporter.py +0 -61
  123. lmnr/openllmetry_sdk/utils/package_check.py +0 -7
  124. lmnr/openllmetry_sdk/version.py +0 -1
  125. lmnr/sdk/datasets.py +0 -55
  126. lmnr-0.4.53.dev0.dist-info/LICENSE +0 -75
  127. lmnr-0.4.53.dev0.dist-info/RECORD +0 -33
  128. lmnr-0.4.53.dev0.dist-info/WHEEL +0 -4
  129. lmnr-0.4.53.dev0.dist-info/entry_points.txt +0 -3
  130. /lmnr/{openllmetry_sdk → opentelemetry_lib}/.flake8 +0 -0
  131. /lmnr/{openllmetry_sdk → opentelemetry_lib}/utils/__init__.py +0 -0
  132. /lmnr/{openllmetry_sdk → opentelemetry_lib}/utils/json_encoder.py +0 -0
  133. /lmnr/{openllmetry_sdk/decorators/__init__.py → py.typed} +0 -0
@@ -1,72 +0,0 @@
1
- import sys
2
-
3
- from typing import Optional, Set
4
- from opentelemetry.sdk.trace import SpanProcessor
5
- from opentelemetry.sdk.trace.export import SpanExporter
6
- from opentelemetry.sdk.resources import SERVICE_NAME
7
- from opentelemetry.propagators.textmap import TextMapPropagator
8
- from opentelemetry.util.re import parse_env_headers
9
-
10
- from lmnr.openllmetry_sdk.instruments import Instruments
11
- from lmnr.openllmetry_sdk.config import (
12
- is_content_tracing_enabled,
13
- is_tracing_enabled,
14
- )
15
- from lmnr.openllmetry_sdk.tracing.tracing import TracerWrapper
16
- from typing import Dict
17
-
18
-
19
- class Traceloop:
20
- __tracer_wrapper: TracerWrapper
21
-
22
- @staticmethod
23
- def init(
24
- app_name: Optional[str] = sys.argv[0],
25
- api_endpoint: str = "https://api.lmnr.ai",
26
- api_key: Optional[str] = None,
27
- headers: Dict[str, str] = {},
28
- disable_batch=False,
29
- exporter: Optional[SpanExporter] = None,
30
- processor: Optional[SpanProcessor] = None,
31
- propagator: Optional[TextMapPropagator] = None,
32
- should_enrich_metrics: bool = False,
33
- resource_attributes: dict = {},
34
- instruments: Optional[Set[Instruments]] = None,
35
- ) -> None:
36
- if not is_tracing_enabled():
37
- return
38
-
39
- enable_content_tracing = is_content_tracing_enabled()
40
-
41
- if isinstance(headers, str):
42
- headers = parse_env_headers(headers)
43
-
44
- if (
45
- not exporter
46
- and not processor
47
- and api_endpoint == "https://api.lmnr.ai"
48
- and not api_key
49
- ):
50
- print(
51
- "Set the LMNR_PROJECT_API_KEY environment variable to your project API key"
52
- )
53
- return
54
-
55
- if api_key and not exporter and not processor and not headers:
56
- headers = {
57
- "Authorization": f"Bearer {api_key}",
58
- }
59
-
60
- # Tracer init
61
- resource_attributes.update({SERVICE_NAME: app_name})
62
- TracerWrapper.set_static_params(
63
- resource_attributes, enable_content_tracing, api_endpoint, headers
64
- )
65
- Traceloop.__tracer_wrapper = TracerWrapper(
66
- disable_batch=disable_batch,
67
- processor=processor,
68
- propagator=propagator,
69
- exporter=exporter,
70
- should_enrich_metrics=should_enrich_metrics,
71
- instruments=instruments,
72
- )
@@ -1,9 +0,0 @@
1
- import os
2
-
3
-
4
- def is_tracing_enabled() -> bool:
5
- return (os.getenv("TRACELOOP_TRACING_ENABLED") or "true").lower() == "true"
6
-
7
-
8
- def is_content_tracing_enabled() -> bool:
9
- return (os.getenv("TRACELOOP_TRACE_CONTENT") or "true").lower() == "true"
@@ -1,185 +0,0 @@
1
- import json
2
- from functools import wraps
3
- import logging
4
- import os
5
- import pydantic
6
- import types
7
- from typing import Any, Optional
8
-
9
- from opentelemetry import trace
10
- from opentelemetry import context as context_api
11
- from opentelemetry.trace import Span
12
-
13
- from lmnr.sdk.utils import get_input_from_func_args, is_method
14
- from lmnr.openllmetry_sdk.tracing import get_tracer
15
- from lmnr.openllmetry_sdk.tracing.attributes import SPAN_INPUT, SPAN_OUTPUT
16
- from lmnr.openllmetry_sdk.tracing.tracing import TracerWrapper
17
- from lmnr.openllmetry_sdk.utils.json_encoder import JSONEncoder
18
-
19
-
20
- class CustomJSONEncoder(JSONEncoder):
21
- def default(self, o: Any) -> Any:
22
- if isinstance(o, pydantic.BaseModel):
23
- return o.model_dump_json()
24
- try:
25
- return super().default(o)
26
- except TypeError:
27
- return str(o) # Fallback to string representation for unsupported types
28
-
29
-
30
- def json_dumps(data: dict) -> str:
31
- try:
32
- return json.dumps(data, cls=CustomJSONEncoder)
33
- except Exception:
34
- # Log the exception and return a placeholder if serialization completely fails
35
- logging.warning("Failed to serialize data to JSON, type: %s", type(data))
36
- return "{}" # Return an empty JSON object as a fallback
37
-
38
-
39
- def entity_method(
40
- name: Optional[str] = None,
41
- ):
42
- def decorate(fn):
43
- @wraps(fn)
44
- def wrap(*args, **kwargs):
45
- if not TracerWrapper.verify_initialized():
46
- return fn(*args, **kwargs)
47
-
48
- span_name = name or fn.__name__
49
-
50
- with get_tracer() as tracer:
51
- span = tracer.start_span(span_name)
52
-
53
- ctx = trace.set_span_in_context(span, context_api.get_current())
54
- ctx_token = context_api.attach(ctx)
55
-
56
- try:
57
- if _should_send_prompts():
58
- span.set_attribute(
59
- SPAN_INPUT,
60
- json_dumps(
61
- get_input_from_func_args(
62
- fn, is_method(fn), args, kwargs
63
- )
64
- ),
65
- )
66
- except TypeError:
67
- pass
68
-
69
- try:
70
- res = fn(*args, **kwargs)
71
- except Exception as e:
72
- _process_exception(span, e)
73
- span.end()
74
- raise e
75
-
76
- # span will be ended in the generator
77
- if isinstance(res, types.GeneratorType):
78
- return _handle_generator(span, res)
79
-
80
- try:
81
- if _should_send_prompts():
82
- span.set_attribute(
83
- SPAN_OUTPUT,
84
- json_dumps(res),
85
- )
86
- except TypeError:
87
- pass
88
-
89
- span.end()
90
- context_api.detach(ctx_token)
91
-
92
- return res
93
-
94
- return wrap
95
-
96
- return decorate
97
-
98
-
99
- # Async Decorators
100
- def aentity_method(
101
- name: Optional[str] = None,
102
- ):
103
- def decorate(fn):
104
- @wraps(fn)
105
- async def wrap(*args, **kwargs):
106
- if not TracerWrapper.verify_initialized():
107
- return await fn(*args, **kwargs)
108
-
109
- span_name = name or fn.__name__
110
-
111
- with get_tracer() as tracer:
112
- span = tracer.start_span(span_name)
113
-
114
- ctx = trace.set_span_in_context(span, context_api.get_current())
115
- ctx_token = context_api.attach(ctx)
116
-
117
- try:
118
- if _should_send_prompts():
119
- span.set_attribute(
120
- SPAN_INPUT,
121
- json_dumps(
122
- get_input_from_func_args(
123
- fn, is_method(fn), args, kwargs
124
- )
125
- ),
126
- )
127
- except TypeError:
128
- pass
129
-
130
- try:
131
- res = await fn(*args, **kwargs)
132
- except Exception as e:
133
- _process_exception(span, e)
134
- span.end()
135
- raise e
136
-
137
- # span will be ended in the generator
138
- if isinstance(res, types.AsyncGeneratorType):
139
- return await _ahandle_generator(span, ctx_token, res)
140
-
141
- try:
142
- if _should_send_prompts():
143
- span.set_attribute(SPAN_OUTPUT, json_dumps(res))
144
- except TypeError:
145
- pass
146
-
147
- span.end()
148
- context_api.detach(ctx_token)
149
-
150
- return res
151
-
152
- return wrap
153
-
154
- return decorate
155
-
156
-
157
- def _handle_generator(span, res):
158
- # for some reason the SPAN_KEY is not being set in the context of the generator, so we re-set it
159
- context_api.attach(trace.set_span_in_context(span))
160
- yield from res
161
-
162
- span.end()
163
-
164
- # Note: we don't detach the context here as this fails in some situations
165
- # https://github.com/open-telemetry/opentelemetry-python/issues/2606
166
- # This is not a problem since the context will be detached automatically during garbage collection
167
-
168
-
169
- async def _ahandle_generator(span, ctx_token, res):
170
- async for part in res:
171
- yield part
172
-
173
- span.end()
174
- context_api.detach(ctx_token)
175
-
176
-
177
- def _should_send_prompts():
178
- return (
179
- os.getenv("TRACELOOP_TRACE_CONTENT") or "true"
180
- ).lower() == "true" or context_api.get_value("override_enable_content_tracing")
181
-
182
-
183
- def _process_exception(span: Span, e: Exception):
184
- # Note that this `escaped` is sent as a StringValue("True"), not a boolean.
185
- span.record_exception(e, escaped=True)
@@ -1,38 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class Instruments(Enum):
5
- # The list of libraries which will be autoinstrumented
6
- # if no specific instruments are provided to initialize()
7
- ALEPHALPHA = "alephalpha"
8
- ANTHROPIC = "anthropic"
9
- BEDROCK = "bedrock"
10
- CHROMA = "chroma"
11
- COHERE = "cohere"
12
- GOOGLE_GENERATIVEAI = "google_generativeai"
13
- GROQ = "groq"
14
- HAYSTACK = "haystack"
15
- LANCEDB = "lancedb"
16
- LANGCHAIN = "langchain"
17
- LLAMA_INDEX = "llama_index"
18
- MARQO = "marqo"
19
- MILVUS = "milvus"
20
- MISTRAL = "mistral"
21
- OLLAMA = "ollama"
22
- OPENAI = "openai"
23
- PINECONE = "pinecone"
24
- QDRANT = "qdrant"
25
- REPLICATE = "replicate"
26
- SAGEMAKER = "sagemaker"
27
- TOGETHER = "together"
28
- TRANSFORMERS = "transformers"
29
- VERTEXAI = "vertexai"
30
- WATSONX = "watsonx"
31
- WEAVIATE = "weaviate"
32
-
33
- # The following libraries will not be autoinstrumented unless
34
- # specified explicitly in the initialize() call.
35
- REDIS = "redis"
36
- REQUESTS = "requests"
37
- URLLIB3 = "urllib3"
38
- PYMYSQL = "pymysql"
@@ -1 +0,0 @@
1
- from lmnr.openllmetry_sdk.tracing.context_manager import get_tracer
@@ -1,24 +0,0 @@
1
- # Manages list of associated properties for which content tracing
2
- # (prompts, vector embeddings, etc.) is allowed.
3
- class ContentAllowList:
4
- def __new__(cls) -> "ContentAllowList":
5
- if not hasattr(cls, "instance"):
6
- obj = cls.instance = super(ContentAllowList, cls).__new__(cls)
7
- obj._allow_list: list[dict] = []
8
-
9
- return cls.instance
10
-
11
- def is_allowed(self, association_properties: dict) -> bool:
12
- for allow_list_item in self._allow_list:
13
- if all(
14
- [
15
- association_properties.get(key) == value
16
- for key, value in allow_list_item.items()
17
- ]
18
- ):
19
- return True
20
-
21
- return False
22
-
23
- def load(self, response_json: dict):
24
- self._allow_list = response_json["associationPropertyAllowList"]
@@ -1,13 +0,0 @@
1
- from contextlib import contextmanager
2
-
3
- from lmnr.openllmetry_sdk.tracing.tracing import TracerWrapper
4
-
5
-
6
- @contextmanager
7
- def get_tracer(flush_on_exit: bool = False):
8
- wrapper = TracerWrapper()
9
- try:
10
- yield wrapper.get_tracer()
11
- finally:
12
- if flush_on_exit:
13
- wrapper.flush()