lmnr 0.6.14__tar.gz → 0.6.16__tar.gz

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 (60) hide show
  1. {lmnr-0.6.14 → lmnr-0.6.16}/PKG-INFO +3 -3
  2. {lmnr-0.6.14 → lmnr-0.6.16}/pyproject.toml +10 -3
  3. lmnr-0.6.16/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/skyvern/__init__.py +193 -0
  4. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/tracing/_instrument_initializers.py +8 -0
  5. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/tracing/instruments.py +2 -1
  6. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/browser/browser_use_otel.py +10 -3
  7. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/browser/pw_utils.py +7 -26
  8. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/version.py +1 -1
  9. {lmnr-0.6.14 → lmnr-0.6.16}/LICENSE +0 -0
  10. {lmnr-0.6.14 → lmnr-0.6.16}/README.md +0 -0
  11. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/__init__.py +0 -0
  12. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/cli.py +0 -0
  13. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/.flake8 +0 -0
  14. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/__init__.py +0 -0
  15. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/decorators/__init__.py +0 -0
  16. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/litellm/__init__.py +0 -0
  17. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/litellm/utils.py +0 -0
  18. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +0 -0
  19. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py +0 -0
  20. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +0 -0
  21. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/__init__.py +0 -0
  22. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/utils.py +0 -0
  23. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/tracing/__init__.py +0 -0
  24. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/tracing/attributes.py +0 -0
  25. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/tracing/context_properties.py +0 -0
  26. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/tracing/exporter.py +0 -0
  27. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/tracing/processor.py +0 -0
  28. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/tracing/tracer.py +0 -0
  29. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/utils/__init__.py +0 -0
  30. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/utils/json_encoder.py +0 -0
  31. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/opentelemetry_lib/utils/package_check.py +0 -0
  32. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/py.typed +0 -0
  33. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/__init__.py +0 -0
  34. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/browser/__init__.py +0 -0
  35. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/browser/patchright_otel.py +0 -0
  36. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/browser/playwright_otel.py +0 -0
  37. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/browser/rrweb/rrweb.umd.min.cjs +0 -0
  38. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/browser/utils.py +0 -0
  39. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/asynchronous/async_client.py +0 -0
  40. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/asynchronous/resources/__init__.py +0 -0
  41. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/asynchronous/resources/agent.py +0 -0
  42. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/asynchronous/resources/base.py +0 -0
  43. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/asynchronous/resources/browser_events.py +0 -0
  44. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/asynchronous/resources/evals.py +0 -0
  45. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/asynchronous/resources/tags.py +0 -0
  46. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/synchronous/resources/__init__.py +0 -0
  47. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/synchronous/resources/agent.py +0 -0
  48. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/synchronous/resources/base.py +0 -0
  49. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/synchronous/resources/browser_events.py +0 -0
  50. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/synchronous/resources/evals.py +0 -0
  51. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/synchronous/resources/tags.py +0 -0
  52. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/client/synchronous/sync_client.py +0 -0
  53. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/datasets.py +0 -0
  54. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/decorators.py +0 -0
  55. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/eval_control.py +0 -0
  56. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/evaluations.py +0 -0
  57. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/laminar.py +0 -0
  58. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/log.py +0 -0
  59. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/types.py +0 -0
  60. {lmnr-0.6.14 → lmnr-0.6.16}/src/lmnr/sdk/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lmnr
3
- Version: 0.6.14
3
+ Version: 0.6.16
4
4
  Summary: Python SDK for Laminar
5
5
  License: Apache-2.0
6
6
  Author: lmnr.ai
@@ -58,8 +58,8 @@ Requires-Dist: opentelemetry-instrumentation-cohere (>=0.40.12) ; extra == "all"
58
58
  Requires-Dist: opentelemetry-instrumentation-cohere (>=0.40.12) ; extra == "cohere"
59
59
  Requires-Dist: opentelemetry-instrumentation-crewai (>=0.40.12) ; extra == "all"
60
60
  Requires-Dist: opentelemetry-instrumentation-crewai (>=0.40.12) ; extra == "crewai"
61
- Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.40.12) ; extra == "all"
62
- Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.40.12) ; extra == "google-generativeai"
61
+ Requires-Dist: opentelemetry-instrumentation-google-generativeai (<0.40.10) ; extra == "all"
62
+ Requires-Dist: opentelemetry-instrumentation-google-generativeai (<0.40.10) ; extra == "google-generativeai"
63
63
  Requires-Dist: opentelemetry-instrumentation-groq (>=0.40.12) ; extra == "all"
64
64
  Requires-Dist: opentelemetry-instrumentation-groq (>=0.40.12) ; extra == "groq"
65
65
  Requires-Dist: opentelemetry-instrumentation-haystack (>=0.40.12) ; extra == "all"
@@ -6,7 +6,7 @@
6
6
 
7
7
  [project]
8
8
  name = "lmnr"
9
- version = "0.6.14"
9
+ version = "0.6.16"
10
10
  description = "Python SDK for Laminar"
11
11
  authors = [
12
12
  { name = "lmnr.ai", email = "founders@lmnr.ai" }
@@ -57,7 +57,13 @@ bedrock=["opentelemetry-instrumentation-bedrock>=0.40.12"]
57
57
  chromadb=["opentelemetry-instrumentation-chromadb>=0.40.12"]
58
58
  cohere=["opentelemetry-instrumentation-cohere>=0.40.12"]
59
59
  crewai=["opentelemetry-instrumentation-crewai>=0.40.12"]
60
- google-generativeai=["opentelemetry-instrumentation-google-generativeai>=0.40.12"]
60
+ # Newer versions of the instrumentation library try to wrap both
61
+ # google-generativeai and google-genai. The latter seems not very
62
+ # thoroughly tested. We have our own instrumentation of the latter; the
63
+ # former is on deprecation path, so we pin it to the latest version not
64
+ # wrapping google-genai.
65
+ # https://github.com/traceloop/openllmetry/pull/3014
66
+ google-generativeai=["opentelemetry-instrumentation-google-generativeai<0.40.10"]
61
67
  groq=["opentelemetry-instrumentation-groq>=0.40.12"]
62
68
  haystack=["opentelemetry-instrumentation-haystack>=0.40.12"]
63
69
  lancedb=["opentelemetry-instrumentation-lancedb>=0.40.12"]
@@ -89,7 +95,8 @@ all = [
89
95
  "opentelemetry-instrumentation-chromadb>=0.40.12",
90
96
  "opentelemetry-instrumentation-cohere>=0.40.12",
91
97
  "opentelemetry-instrumentation-crewai>=0.40.12",
92
- "opentelemetry-instrumentation-google-generativeai>=0.40.12",
98
+ # See comment above on the google-generativeai extra.
99
+ "opentelemetry-instrumentation-google-generativeai<0.40.10",
93
100
  "opentelemetry-instrumentation-groq>=0.40.12",
94
101
  "opentelemetry-instrumentation-haystack>=0.40.12",
95
102
  "opentelemetry-instrumentation-lancedb>=0.40.12",
@@ -0,0 +1,193 @@
1
+ from lmnr.opentelemetry_lib.decorators import json_dumps
2
+ from lmnr.sdk.browser.utils import with_tracer_wrapper
3
+ from lmnr.sdk.utils import get_input_from_func_args
4
+ from lmnr.version import __version__
5
+
6
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
7
+ from opentelemetry.instrumentation.utils import unwrap
8
+ from opentelemetry.trace import get_tracer, Tracer
9
+ from typing import Collection
10
+ from wrapt import wrap_function_wrapper
11
+ import pydantic
12
+
13
+ try:
14
+ from skyvern import Skyvern
15
+ except ImportError as e:
16
+ raise ImportError(
17
+ f"Attempted to import {__file__}, but it is designed "
18
+ "to patch Skyvern, which is not installed. Use `pip install skyvern` "
19
+ "to install Skyvern or remove this import."
20
+ ) from e
21
+
22
+ _instruments = ("skyvern >= 0.1.0",)
23
+
24
+ WRAPPED_METHODS = [
25
+ {
26
+ "package": "skyvern.library.skyvern",
27
+ "object": "Skyvern", # Class name
28
+ "method": "run_task", # Method name
29
+ "span_name": "Skyvern.run_task",
30
+ "span_type": "DEFAULT",
31
+ },
32
+ {
33
+ "package": "skyvern.webeye.scraper.scraper",
34
+ # No "object" field for module-level functions
35
+ "method": "get_interactable_element_tree", # Function name
36
+ "span_name": "get_interactable_element_tree",
37
+ "span_type": "DEFAULT",
38
+ },
39
+ {
40
+ "package": "skyvern.forge.agent",
41
+ "object": "ForgeAgent",
42
+ "method": "execute_step",
43
+ "span_name": "ForgeAgent.execute_step",
44
+ "span_type": "DEFAULT",
45
+ },
46
+ {
47
+ "package": "skyvern.services.task_v2_service",
48
+ "method": "initialize_task_v2",
49
+ "span_name": "initialize_task_v2",
50
+ "span_type": "DEFAULT",
51
+ },
52
+ {
53
+ "package": "skyvern.services.task_v2_service",
54
+ "method": "run_task_v2_helper",
55
+ "span_name": "run_task_v2_helper",
56
+ "span_type": "DEFAULT",
57
+ },
58
+ {
59
+ "package": "skyvern.forge.sdk.workflow.models.block",
60
+ "object": "Block",
61
+ "method": "_generate_workflow_run_block_description",
62
+ "span_name": "Block._generate_workflow_run_block_description",
63
+ "span_type": "DEFAULT",
64
+ },
65
+ {
66
+ "package": "skyvern.webeye.actions.handler",
67
+ "method": "extract_information_for_navigation_goal",
68
+ "span_name": "extract_information_for_navigation_goal",
69
+ "span_type": "DEFAULT",
70
+ },
71
+ ]
72
+
73
+
74
+ @with_tracer_wrapper
75
+ async def _wrap(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
76
+ span_name = to_wrap.get("span_name")
77
+ attributes = {
78
+ "lmnr.span.type": to_wrap.get("span_type"),
79
+ }
80
+
81
+ attributes["lmnr.span.input"] = json_dumps(
82
+ get_input_from_func_args(wrapped, True, args, kwargs)
83
+ )
84
+
85
+ with tracer.start_as_current_span(span_name, attributes=attributes) as span:
86
+ try:
87
+ result = await wrapped(*args, **kwargs)
88
+
89
+ to_serialize = result
90
+ serialized = (
91
+ to_serialize.model_dump_json()
92
+ if isinstance(to_serialize, pydantic.BaseModel)
93
+ else json_dumps(to_serialize)
94
+ )
95
+ span.set_attribute("lmnr.span.output", serialized)
96
+ return result
97
+
98
+ except Exception as e:
99
+ span.record_exception(e)
100
+ raise
101
+
102
+
103
+ def instrument_llm_handler(tracer: Tracer):
104
+ from skyvern.forge import app
105
+
106
+ # Store the original handler
107
+ original_handler = app.LLM_API_HANDLER
108
+
109
+ async def wrapped_llm_handler(*args, **kwargs):
110
+
111
+ prompt_name = kwargs.get("prompt_name", "")
112
+
113
+ if prompt_name:
114
+ span_name = f"{prompt_name}"
115
+ else:
116
+ span_name = "app.LLM_API_HANDLER"
117
+
118
+ attributes = {
119
+ "lmnr.span.type": "DEFAULT",
120
+ }
121
+
122
+ with tracer.start_as_current_span(span_name, attributes=attributes) as span:
123
+ try:
124
+ result = await original_handler(*args, **kwargs)
125
+
126
+ to_serialize = result
127
+ serialized = (
128
+ to_serialize.model_dump_json()
129
+ if isinstance(to_serialize, pydantic.BaseModel)
130
+ else json_dumps(to_serialize)
131
+ )
132
+ span.set_attribute("lmnr.span.output", serialized)
133
+ return result
134
+ except Exception as e:
135
+ span.record_exception(e)
136
+ raise
137
+
138
+ # Replace the global handler
139
+ app.LLM_API_HANDLER = wrapped_llm_handler
140
+
141
+
142
+ class SkyvernInstrumentor(BaseInstrumentor):
143
+ def __init__(self):
144
+ super().__init__()
145
+
146
+ def instrumentation_dependencies(self) -> Collection[str]:
147
+ return _instruments
148
+
149
+ def _instrument(self, **kwargs):
150
+
151
+ tracer_provider = kwargs.get("tracer_provider")
152
+ tracer = get_tracer(__name__, __version__, tracer_provider)
153
+
154
+ instrument_llm_handler(tracer)
155
+
156
+ for wrapped_method in WRAPPED_METHODS:
157
+ wrap_package = wrapped_method.get("package")
158
+ wrap_object = wrapped_method.get("object")
159
+ wrap_method = wrapped_method.get("method")
160
+
161
+ # For class methods: "Class.method", for module functions: just "function_name"
162
+ if wrap_object:
163
+ target = f"{wrap_object}.{wrap_method}"
164
+ else:
165
+ target = wrap_method
166
+
167
+ try:
168
+ wrap_function_wrapper(
169
+ wrap_package,
170
+ target,
171
+ _wrap(
172
+ tracer,
173
+ wrapped_method,
174
+ ),
175
+ )
176
+ except ModuleNotFoundError:
177
+ pass # that's ok, we're not instrumenting everything
178
+
179
+ def _uninstrument(self, **kwargs):
180
+
181
+ for wrapped_method in WRAPPED_METHODS:
182
+ wrap_package = wrapped_method.get("package")
183
+ wrap_object = wrapped_method.get("object")
184
+ wrap_method = wrapped_method.get("method")
185
+
186
+ # For class methods: "package.Class", for module functions: just "package"
187
+ if wrap_object:
188
+ module_path = f"{wrap_package}.{wrap_object}"
189
+ else:
190
+ module_path = wrap_package
191
+
192
+ unwrap(module_path, wrap_method)
193
+
@@ -345,6 +345,14 @@ class SageMakerInstrumentorInitializer(InstrumentorInitializer):
345
345
 
346
346
  return SageMakerInstrumentor()
347
347
 
348
+ class SkyvernInstrumentorInitializer(InstrumentorInitializer):
349
+ def init_instrumentor(self, *args, **kwargs) -> BaseInstrumentor | None:
350
+ if not is_package_installed("skyvern"):
351
+ return None
352
+
353
+ from ..opentelemetry.instrumentation.skyvern import SkyvernInstrumentor
354
+
355
+ return SkyvernInstrumentor()
348
356
 
349
357
  class TogetherInstrumentorInitializer(InstrumentorInitializer):
350
358
  def init_instrumentor(self, *args, **kwargs) -> BaseInstrumentor | None:
@@ -40,13 +40,13 @@ class Instruments(Enum):
40
40
  QDRANT = "qdrant"
41
41
  REPLICATE = "replicate"
42
42
  SAGEMAKER = "sagemaker"
43
+ SKYVERN = "skyvern"
43
44
  TOGETHER = "together"
44
45
  TRANSFORMERS = "transformers"
45
46
  VERTEXAI = "vertexai"
46
47
  WATSONX = "watsonx"
47
48
  WEAVIATE = "weaviate"
48
49
 
49
-
50
50
  INSTRUMENTATION_INITIALIZERS: dict[
51
51
  Instruments, initializers.InstrumentorInitializer
52
52
  ] = {
@@ -77,6 +77,7 @@ INSTRUMENTATION_INITIALIZERS: dict[
77
77
  Instruments.QDRANT: initializers.QdrantInstrumentorInitializer(),
78
78
  Instruments.REPLICATE: initializers.ReplicateInstrumentorInitializer(),
79
79
  Instruments.SAGEMAKER: initializers.SageMakerInstrumentorInitializer(),
80
+ Instruments.SKYVERN: initializers.SkyvernInstrumentorInitializer(),
80
81
  Instruments.TOGETHER: initializers.TogetherInstrumentorInitializer(),
81
82
  Instruments.TRANSFORMERS: initializers.TransformersInstrumentorInitializer(),
82
83
  Instruments.VERTEXAI: initializers.VertexAIInstrumentorInitializer(),
@@ -76,9 +76,16 @@ async def _wrap(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
76
76
  )
77
77
  else:
78
78
  if not to_wrap.get("ignore_input"):
79
- attributes["lmnr.span.input"] = json_dumps(
80
- get_input_from_func_args(wrapped, True, args, kwargs)
81
- )
79
+ inp_dict = get_input_from_func_args(wrapped, True, args, kwargs)
80
+ # Add task to the `agent.run` span input
81
+ if to_wrap.get("method") == "run" and hasattr(instance, "task"):
82
+ inp_dict["task"] = instance.task
83
+ attributes["lmnr.span.input"] = json_dumps(inp_dict)
84
+ if to_wrap.get("method") == "step" and to_wrap.get("object") == "Agent":
85
+ # Add step number to the `agent.step` span name
86
+ step_info = kwargs.get("step_info", args[0] if len(args) > 0 else None)
87
+ if step_info and hasattr(step_info, "step_number"):
88
+ span_name = f"agent.step.{step_info.step_number}"
82
89
  with tracer.start_as_current_span(span_name, attributes=attributes) as span:
83
90
  span.set_attributes(attributes)
84
91
  result = await wrapped(*args, **kwargs)
@@ -45,19 +45,6 @@ INJECT_PLACEHOLDER = """
45
45
 
46
46
  window.lmnrRrwebEventsBatch = new Set();
47
47
 
48
- // Track page focus state
49
- window.lmnrPageIsFocused = true;
50
-
51
- window.addEventListener('blur', () => {
52
- window.lmnrPageIsFocused = false;
53
- console.log('Page lost focus');
54
- });
55
-
56
- window.addEventListener('focus', () => {
57
- window.lmnrPageIsFocused = true;
58
- console.log('Page gained focus');
59
- });
60
-
61
48
  // Utility function to compress individual event data
62
49
  async function compressEventData(data) {
63
50
  const jsonString = JSON.stringify(data);
@@ -76,10 +63,6 @@ INJECT_PLACEHOLDER = """
76
63
 
77
64
  // Add heartbeat events
78
65
  setInterval(async () => {
79
- if (!window.lmnrPageIsFocused) {
80
- return;
81
- }
82
-
83
66
  window.lmnrRrweb.record.addCustomEvent('heartbeat', {
84
67
  title: document.title,
85
68
  url: document.URL,
@@ -88,19 +71,17 @@ INJECT_PLACEHOLDER = """
88
71
  }, 1000);
89
72
 
90
73
  window.lmnrRrweb.record({
91
- async emit(event) {
92
- // Ignore events when page is not focused
93
- if (!window.lmnrPageIsFocused) {
94
- return;
95
- }
96
-
74
+ async emit(event) {
97
75
  // Compress the data field
98
76
  const compressedEvent = {
99
77
  ...event,
100
78
  data: await compressEventData(event.data)
101
79
  };
102
80
  window.lmnrRrwebEventsBatch.add(compressedEvent);
103
- }
81
+ },
82
+ recordCanvas: true,
83
+ collectFonts: true,
84
+ recordCrossOriginIframes: true
104
85
  });
105
86
  }
106
87
  """
@@ -115,7 +96,7 @@ async def send_events_async(
115
96
  events = await page.evaluate(
116
97
  """
117
98
  () => {
118
- if (!window.lmnrPageIsFocused || typeof window.lmnrGetAndClearEvents !== 'function') {
99
+ if (typeof window.lmnrGetAndClearEvents !== 'function') {
119
100
  return [];
120
101
  }
121
102
  return window.lmnrGetAndClearEvents();
@@ -144,7 +125,7 @@ def send_events_sync(
144
125
  events = page.evaluate(
145
126
  """
146
127
  () => {
147
- if (!window.lmnrPageIsFocused || typeof window.lmnrGetAndClearEvents !== 'function') {
128
+ if (typeof window.lmnrGetAndClearEvents !== 'function') {
148
129
  return [];
149
130
  }
150
131
  return window.lmnrGetAndClearEvents();
@@ -3,7 +3,7 @@ import httpx
3
3
  from packaging import version
4
4
 
5
5
 
6
- __version__ = "0.6.14"
6
+ __version__ = "0.6.16"
7
7
  PYTHON_VERSION = f"{sys.version_info.major}.{sys.version_info.minor}"
8
8
 
9
9
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes