lmnr 0.6.1__py3-none-any.whl → 0.6.3__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/cli.py CHANGED
@@ -8,7 +8,7 @@ from typing import Optional
8
8
 
9
9
  from lmnr.sdk.evaluations import Evaluation
10
10
 
11
- from .sdk.eval_control import PREPARE_ONLY, EVALUATION_INSTANCE
11
+ from .sdk.eval_control import PREPARE_ONLY, EVALUATION_INSTANCES
12
12
  from .sdk.log import get_default_logger
13
13
 
14
14
  LOG = get_default_logger(__name__)
@@ -38,10 +38,10 @@ async def run_evaluation(args):
38
38
  else:
39
39
  files = [args.file]
40
40
 
41
- for file in files:
42
- prep_token = PREPARE_ONLY.set(True)
43
- LOG.info(f"Running evaluation from {file}")
44
- try:
41
+ prep_token = PREPARE_ONLY.set(True)
42
+ try:
43
+ for file in files:
44
+ LOG.info(f"Running evaluation from {file}")
45
45
  file = os.path.abspath(file)
46
46
  name = "user_module" + file
47
47
 
@@ -55,16 +55,24 @@ async def run_evaluation(args):
55
55
  sys.modules[name] = mod
56
56
 
57
57
  spec.loader.exec_module(mod)
58
- evaluation: Optional[Evaluation] = EVALUATION_INSTANCE.get()
59
- if evaluation is None:
58
+ evaluations: Optional[list[Evaluation]] = EVALUATION_INSTANCES.get()
59
+ if evaluations is None:
60
60
  LOG.warning("Evaluation instance not found")
61
61
  if args.fail_on_error:
62
62
  return
63
63
  continue
64
64
 
65
- await evaluation.run()
66
- finally:
67
- PREPARE_ONLY.reset(prep_token)
65
+ LOG.info(f"Loaded {len(evaluations)} evaluations from {file}")
66
+
67
+ for evaluation in evaluations:
68
+ try:
69
+ await evaluation.run()
70
+ except Exception as e:
71
+ LOG.error(f"Error running evaluation: {e}")
72
+ if args.fail_on_error:
73
+ raise
74
+ finally:
75
+ PREPARE_ONLY.reset(prep_token)
68
76
 
69
77
 
70
78
  def cli():
@@ -9,6 +9,10 @@ from opentelemetry import trace
9
9
  from opentelemetry import context as context_api
10
10
  from opentelemetry.trace import Span
11
11
 
12
+ from lmnr.opentelemetry_lib.tracing.context_properties import (
13
+ remove_association_properties,
14
+ update_association_properties,
15
+ )
12
16
  from lmnr.sdk.utils import get_input_from_func_args, is_method
13
17
  from lmnr.opentelemetry_lib import MAX_MANUAL_SPAN_PAYLOAD_SIZE
14
18
  from lmnr.opentelemetry_lib.tracing.tracer import get_tracer
@@ -42,6 +46,7 @@ def entity_method(
42
46
  ignore_inputs: Optional[list[str]] = None,
43
47
  ignore_output: bool = False,
44
48
  span_type: Union[Literal["DEFAULT"], Literal["LLM"], Literal["TOOL"]] = "DEFAULT",
49
+ association_properties: Optional[dict[str, Any]] = None,
45
50
  ):
46
51
  def decorate(fn):
47
52
  @wraps(fn)
@@ -51,6 +56,9 @@ def entity_method(
51
56
 
52
57
  span_name = name or fn.__name__
53
58
 
59
+ if association_properties is not None:
60
+ update_association_properties(association_properties)
61
+
54
62
  with get_tracer() as tracer:
55
63
  span = tracer.start_span(span_name, attributes={SPAN_TYPE: span_type})
56
64
 
@@ -111,7 +119,8 @@ def entity_method(
111
119
 
112
120
  span.end()
113
121
  context_api.detach(ctx_token)
114
-
122
+ if association_properties is not None:
123
+ remove_association_properties(association_properties)
115
124
  return res
116
125
 
117
126
  return wrap
@@ -126,6 +135,7 @@ def aentity_method(
126
135
  ignore_inputs: Optional[list[str]] = None,
127
136
  ignore_output: bool = False,
128
137
  span_type: Union[Literal["DEFAULT"], Literal["LLM"], Literal["TOOL"]] = "DEFAULT",
138
+ association_properties: Optional[dict[str, Any]] = None,
129
139
  ):
130
140
  def decorate(fn):
131
141
  @wraps(fn)
@@ -135,6 +145,9 @@ def aentity_method(
135
145
 
136
146
  span_name = name or fn.__name__
137
147
 
148
+ if association_properties is not None:
149
+ update_association_properties(association_properties)
150
+
138
151
  with get_tracer() as tracer:
139
152
  span = tracer.start_span(span_name, attributes={SPAN_TYPE: span_type})
140
153
 
@@ -187,6 +200,8 @@ def aentity_method(
187
200
  pass
188
201
 
189
202
  span.end()
203
+ if association_properties is not None:
204
+ remove_association_properties(association_properties)
190
205
  context_api.detach(ctx_token)
191
206
 
192
207
  return res
@@ -83,12 +83,13 @@ async def _wrap(tracer: Tracer, to_wrap, wrapped, instance, args, kwargs):
83
83
  span.set_attributes(attributes)
84
84
  result = await wrapped(*args, **kwargs)
85
85
  if not to_wrap.get("ignore_output"):
86
+ to_serialize = result
86
87
  if isinstance(result, AgentHistoryList):
87
- result = result.final_result()
88
+ to_serialize = result.final_result()
88
89
  serialized = (
89
- result.model_dump_json()
90
- if isinstance(result, pydantic.BaseModel)
91
- else json_dumps(result)
90
+ to_serialize.model_dump_json()
91
+ if isinstance(to_serialize, pydantic.BaseModel)
92
+ else json_dumps(to_serialize)
92
93
  )
93
94
  span.set_attribute("lmnr.span.output", serialized)
94
95
  return result
@@ -1,12 +1,13 @@
1
1
  """Evals resource for interacting with Laminar evaluations API."""
2
2
 
3
3
  import uuid
4
- from typing import Optional
4
+ from typing import Optional, Union
5
5
 
6
6
  from lmnr.sdk.client.asynchronous.resources.base import BaseAsyncResource
7
7
  from lmnr.sdk.types import (
8
8
  InitEvaluationResponse,
9
9
  EvaluationResultDatapoint,
10
+ PartialEvaluationDatapoint,
10
11
  )
11
12
 
12
13
 
@@ -39,14 +40,14 @@ class AsyncEvals(BaseAsyncResource):
39
40
  async def save_datapoints(
40
41
  self,
41
42
  eval_id: uuid.UUID,
42
- datapoints: list[EvaluationResultDatapoint],
43
+ datapoints: list[Union[EvaluationResultDatapoint, PartialEvaluationDatapoint]],
43
44
  group_name: Optional[str] = None,
44
45
  ):
45
46
  """Save evaluation datapoints.
46
47
 
47
48
  Args:
48
49
  eval_id (uuid.UUID): The evaluation ID.
49
- datapoints (list[EvaluationResultDatapoint]): The datapoints to save.
50
+ datapoints (list[Union[EvaluationResultDatapoint, PartialEvaluationDatapoint]]): The datapoints to save.
50
51
  group_name (Optional[str], optional): Group name for the datapoints. Defaults to None.
51
52
 
52
53
  Raises:
@@ -2,12 +2,13 @@
2
2
 
3
3
  import uuid
4
4
  import urllib.parse
5
- from typing import Optional
5
+ from typing import Optional, Union
6
6
 
7
7
  from lmnr.sdk.client.synchronous.resources.base import BaseResource
8
8
  from lmnr.sdk.types import (
9
9
  InitEvaluationResponse,
10
10
  EvaluationResultDatapoint,
11
+ PartialEvaluationDatapoint,
11
12
  GetDatapointsResponse,
12
13
  )
13
14
 
@@ -41,14 +42,14 @@ class Evals(BaseResource):
41
42
  def save_datapoints(
42
43
  self,
43
44
  eval_id: uuid.UUID,
44
- datapoints: list[EvaluationResultDatapoint],
45
+ datapoints: list[Union[EvaluationResultDatapoint, PartialEvaluationDatapoint]],
45
46
  group_name: Optional[str] = None,
46
47
  ):
47
48
  """Save evaluation datapoints.
48
49
 
49
50
  Args:
50
51
  eval_id (uuid.UUID): The evaluation ID.
51
- datapoints (list[EvaluationResultDatapoint]): The datapoints to save.
52
+ datapoints (list[Union[EvaluationResultDatapoint, PartialEvaluationDatapoint]]): The datapoints to save.
52
53
  group_name (Optional[str], optional): Group name for the datapoints. Defaults to None.
53
54
 
54
55
  Raises:
lmnr/sdk/decorators.py CHANGED
@@ -1,16 +1,14 @@
1
1
  from lmnr.opentelemetry_lib.decorators import (
2
2
  entity_method,
3
3
  aentity_method,
4
+ json_dumps,
4
5
  )
5
6
  from opentelemetry.trace import INVALID_SPAN, get_current_span
6
7
 
7
- from typing import Callable, Literal, Optional, TypeVar, Union, cast
8
+ from typing import Any, Callable, Literal, Optional, TypeVar, Union, cast
8
9
  from typing_extensions import ParamSpec
9
10
 
10
11
  from lmnr.opentelemetry_lib.tracing.attributes import SESSION_ID
11
- from lmnr.opentelemetry_lib.tracing.context_properties import (
12
- update_association_properties,
13
- )
14
12
 
15
13
  from .utils import is_async
16
14
 
@@ -23,10 +21,12 @@ def observe(
23
21
  *,
24
22
  name: Optional[str] = None,
25
23
  session_id: Optional[str] = None,
24
+ user_id: Optional[str] = None,
26
25
  ignore_input: bool = False,
27
26
  ignore_output: bool = False,
28
27
  span_type: Union[Literal["DEFAULT"], Literal["LLM"], Literal["TOOL"]] = "DEFAULT",
29
28
  ignore_inputs: Optional[list[str]] = None,
29
+ metadata: Optional[dict[str, Any]] = None,
30
30
  ) -> Callable[[Callable[P, R]], Callable[P, R]]:
31
31
  """The main decorator entrypoint for Laminar. This is used to wrap
32
32
  functions and methods to create spans.
@@ -37,6 +37,9 @@ def observe(
37
37
  Defaults to None.
38
38
  session_id (Optional[str], optional): Session ID to associate with the\
39
39
  span and the following context. Defaults to None.
40
+ user_id (Optional[str], optional): User ID to associate with the\
41
+ span and the following context. This is different from \
42
+ ID of a Laminar user. Defaults to None.
40
43
  ignore_input (bool, optional): Whether to ignore ALL input of the\
41
44
  wrapped function. Defaults to False.
42
45
  ignore_output (bool, optional): Whether to ignore ALL output of the\
@@ -49,6 +52,8 @@ def observe(
49
52
  `sensitive_data` argument, you can pass ["sensitive_data"] to\
50
53
  this argument.
51
54
  Defaults to None.
55
+ metadata (Optional[dict[str, Any]], optional): Metadata to associate with the\
56
+ trace. Must be JSON serializable. Defaults to None.
52
57
  Raises:
53
58
  Exception: re-raises the exception if the wrapped function raises
54
59
  an exception
@@ -65,14 +70,25 @@ def observe(
65
70
  association_properties = {}
66
71
  if session_id is not None:
67
72
  association_properties["session_id"] = session_id
68
- update_association_properties(association_properties)
69
- return (
73
+ if user_id is not None:
74
+ association_properties["user_id"] = user_id
75
+ if metadata is not None:
76
+ association_properties.update(
77
+ {
78
+ f"metadata.{k}": (
79
+ v if isinstance(v, (str, int, float, bool)) else json_dumps(v)
80
+ )
81
+ for k, v in metadata.items()
82
+ }
83
+ )
84
+ result = (
70
85
  aentity_method(
71
86
  name=name,
72
87
  ignore_input=ignore_input,
73
88
  ignore_output=ignore_output,
74
89
  span_type=span_type,
75
90
  ignore_inputs=ignore_inputs,
91
+ association_properties=association_properties,
76
92
  )(func)
77
93
  if is_async(func)
78
94
  else entity_method(
@@ -81,7 +97,9 @@ def observe(
81
97
  ignore_output=ignore_output,
82
98
  span_type=span_type,
83
99
  ignore_inputs=ignore_inputs,
100
+ association_properties=association_properties,
84
101
  )(func)
85
102
  )
103
+ return result
86
104
 
87
105
  return cast(Callable, decorator)
lmnr/sdk/eval_control.py CHANGED
@@ -2,4 +2,4 @@ from contextvars import ContextVar
2
2
 
3
3
 
4
4
  PREPARE_ONLY: ContextVar[bool] = ContextVar("__lmnr_prepare_only", default=False)
5
- EVALUATION_INSTANCE = ContextVar("__lmnr_evaluation_instance")
5
+ EVALUATION_INSTANCES = ContextVar("__lmnr_evaluation_instances")
lmnr/sdk/evaluations.py CHANGED
@@ -11,7 +11,7 @@ from lmnr.opentelemetry_lib.tracing.attributes import SPAN_TYPE
11
11
  from lmnr.sdk.client.asynchronous.async_client import AsyncLaminarClient
12
12
  from lmnr.sdk.client.synchronous.sync_client import LaminarClient
13
13
  from lmnr.sdk.datasets import EvaluationDataset, LaminarDataset
14
- from lmnr.sdk.eval_control import EVALUATION_INSTANCE, PREPARE_ONLY
14
+ from lmnr.sdk.eval_control import EVALUATION_INSTANCES, PREPARE_ONLY
15
15
  from lmnr.sdk.laminar import Laminar as L
16
16
  from lmnr.sdk.log import get_default_logger
17
17
  from lmnr.sdk.types import (
@@ -204,6 +204,18 @@ class Evaluation:
204
204
  )
205
205
  self.project_api_key = api_key
206
206
 
207
+ if L.is_initialized():
208
+ self.client = AsyncLaminarClient(
209
+ base_url=L.get_base_http_url(),
210
+ project_api_key=L.get_project_api_key(),
211
+ )
212
+ if project_api_key and project_api_key != L.get_project_api_key():
213
+ self._logger.warning(
214
+ "Project API key is different from the one used to initialize"
215
+ " Laminar. Ignoring the project API key passed to the evaluation."
216
+ )
217
+ return
218
+
207
219
  self.client = AsyncLaminarClient(
208
220
  base_url=self.base_http_url,
209
221
  project_api_key=self.project_api_key,
@@ -312,6 +324,7 @@ class Evaluation:
312
324
  index=index,
313
325
  trace_id=trace_id,
314
326
  executor_span_id=executor_span_id,
327
+ metadata=datapoint.metadata,
315
328
  )
316
329
  # First, create datapoint with trace_id so that we can show the dp in the UI
317
330
  await self.client._evals.save_datapoints(
@@ -367,6 +380,7 @@ class Evaluation:
367
380
  human_evaluators=self.human_evaluators,
368
381
  executor_span_id=executor_span_id,
369
382
  index=index,
383
+ metadata=datapoint.metadata,
370
384
  )
371
385
 
372
386
  # Create background upload task without awaiting it
@@ -470,10 +484,16 @@ def evaluate(
470
484
  )
471
485
 
472
486
  if PREPARE_ONLY.get():
473
- EVALUATION_INSTANCE.set(evaluation)
487
+ existing_evaluations = EVALUATION_INSTANCES.get([])
488
+ new_evaluations = (existing_evaluations or []) + [evaluation]
489
+ EVALUATION_INSTANCES.set(new_evaluations)
490
+ return None
474
491
  else:
475
- loop = asyncio.get_event_loop()
476
- if loop.is_running():
477
- return evaluation.run()
478
- else:
492
+ try:
493
+ loop = asyncio.get_event_loop()
494
+ if loop.is_running():
495
+ return evaluation.run()
496
+ else:
497
+ return asyncio.run(evaluation.run())
498
+ except RuntimeError:
479
499
  return asyncio.run(evaluation.run())
lmnr/sdk/laminar.py CHANGED
@@ -50,6 +50,7 @@ from .types import (
50
50
  class Laminar:
51
51
  __project_api_key: Optional[str] = None
52
52
  __initialized: bool = False
53
+ __base_http_url: Optional[str] = None
53
54
 
54
55
  @classmethod
55
56
  def initialize(
@@ -133,6 +134,7 @@ class Laminar:
133
134
  cls.__logger.info(f"Using HTTP port passed as an argument: {http_port}")
134
135
 
135
136
  cls.__initialized = True
137
+ cls.__base_http_url = f"{url}:{http_port or 443}"
136
138
 
137
139
  if not os.getenv("OTEL_ATTRIBUTE_COUNT_LIMIT"):
138
140
  # each message is at least 2 attributes: role and content,
@@ -700,6 +702,14 @@ class Laminar:
700
702
  props.pop("user_id", None)
701
703
  set_association_properties(props)
702
704
 
705
+ @classmethod
706
+ def get_base_http_url(cls):
707
+ return cls.__base_http_url
708
+
709
+ @classmethod
710
+ def get_project_api_key(cls):
711
+ return cls.__project_api_key
712
+
703
713
  @classmethod
704
714
  def _headers(cls):
705
715
  assert cls.__project_api_key is not None, "Project API key is not set"
lmnr/sdk/types.py CHANGED
@@ -66,6 +66,7 @@ class PartialEvaluationDatapoint(pydantic.BaseModel):
66
66
  index: int
67
67
  trace_id: uuid.UUID
68
68
  executor_span_id: uuid.UUID
69
+ metadata: EvaluationDatapointMetadata = pydantic.Field(default=None)
69
70
 
70
71
  # uuid is not serializable by default, so we need to convert it to a string
71
72
  def to_dict(self):
@@ -77,6 +78,7 @@ class PartialEvaluationDatapoint(pydantic.BaseModel):
77
78
  "index": self.index,
78
79
  "traceId": str(self.trace_id),
79
80
  "executorSpanId": str(self.executor_span_id),
81
+ "metadata": serialize(self.metadata) if self.metadata is not None else None,
80
82
  }
81
83
  except Exception as e:
82
84
  raise ValueError(f"Error serializing PartialEvaluationDatapoint: {e}")
@@ -92,6 +94,7 @@ class EvaluationResultDatapoint(pydantic.BaseModel):
92
94
  human_evaluators: list[HumanEvaluator] = pydantic.Field(default_factory=list)
93
95
  trace_id: uuid.UUID
94
96
  executor_span_id: uuid.UUID
97
+ metadata: EvaluationDatapointMetadata = pydantic.Field(default=None)
95
98
 
96
99
  # uuid is not serializable by default, so we need to convert it to a string
97
100
  def to_dict(self):
@@ -115,6 +118,7 @@ class EvaluationResultDatapoint(pydantic.BaseModel):
115
118
  ],
116
119
  "executorSpanId": str(self.executor_span_id),
117
120
  "index": self.index,
121
+ "metadata": serialize(self.metadata) if self.metadata is not None else None,
118
122
  }
119
123
  except Exception as e:
120
124
  raise ValueError(f"Error serializing EvaluationResultDatapoint: {e}")
lmnr/version.py CHANGED
@@ -3,7 +3,7 @@ import httpx
3
3
  from packaging import version
4
4
 
5
5
 
6
- __version__ = "0.6.1"
6
+ __version__ = "0.6.3"
7
7
  PYTHON_VERSION = f"{sys.version_info.major}.{sys.version_info.minor}"
8
8
 
9
9
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lmnr
3
- Version: 0.6.1
3
+ Version: 0.6.3
4
4
  Summary: Python SDK for Laminar
5
5
  License: Apache-2.0
6
6
  Author: lmnr.ai
@@ -1,8 +1,8 @@
1
1
  lmnr/__init__.py,sha256=eJ-gIHEk8KV-BeaU8c9spQww_T2G5_OMu4F8JEzngvA,1281
2
- lmnr/cli.py,sha256=e_Jgcwn3Q-hgR6VLLar2ccWLAhJb8yB4cwoIdg5vwDs,3013
2
+ lmnr/cli.py,sha256=kB2mxLaCwC2PIlVqPc9juP158NygHoTPC9ueiT9nO9M,3339
3
3
  lmnr/opentelemetry_lib/.flake8,sha256=bCxuDlGx3YQ55QHKPiGJkncHanh9qGjQJUujcFa3lAU,150
4
4
  lmnr/opentelemetry_lib/__init__.py,sha256=QMPaVYATF_rT50A-lqoJZaH6YlzRu1BQKPgw0L3Rxs0,2107
5
- lmnr/opentelemetry_lib/decorators/__init__.py,sha256=fTO-p6CaLFw2-8HDVGUS1dvnfCMwUH5vZSYc6_NVAuU,7995
5
+ lmnr/opentelemetry_lib/decorators/__init__.py,sha256=5mJlt05O1QEDR73NZMSjOMb54u-E34xOBPrTMACxx6M,8754
6
6
  lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py,sha256=jrvHu8aq2EBGZI3ypucUltR4-v8HqTKnqGtWXF5Qbb8,15339
7
7
  lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py,sha256=FeQOcC3RNq-yOd8KZ_VoBuZgDl6tnkxx6I2MKVH1GMI,256
8
8
  lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py,sha256=P0fOmGi_0nv3cMFcdWblRuTsDRCZnvdM8GQ3zJT0qbM,6229
@@ -20,7 +20,7 @@ lmnr/opentelemetry_lib/utils/package_check.py,sha256=ST2BvDxt0bax-ih9F9Wf0jlKAEr
20
20
  lmnr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  lmnr/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  lmnr/sdk/browser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- lmnr/sdk/browser/browser_use_otel.py,sha256=Cx8ZLoEGLAAOIvglmZEAxMkfmdwUfjrvxgiZ5vfY3Ko,4519
23
+ lmnr/sdk/browser/browser_use_otel.py,sha256=I3Qoc8y1hqTxRJtzh84qJKz1sz2s_b68YNEYxI0CTV4,4577
24
24
  lmnr/sdk/browser/patchright_otel.py,sha256=O7n1dB_Mw-_L70zi0zqpnFFiKuTPEEpO7ry1ia6IXWQ,5454
25
25
  lmnr/sdk/browser/playwright_otel.py,sha256=LFg1iJXbez-BEgEIY9eaO_2T2uR6SxyfFL46fHcS7Mg,13423
26
26
  lmnr/sdk/browser/pw_utils.py,sha256=nFqVujQb7owVFzT-31_g09CbfbBwUIXKxs3JxuE47ws,10835
@@ -31,24 +31,24 @@ lmnr/sdk/client/asynchronous/resources/__init__.py,sha256=WL2ehX1LfxG3n7bsxzTRO8
31
31
  lmnr/sdk/client/asynchronous/resources/agent.py,sha256=NiX2azmQnzNYHpZT_Sme7Dm5cmDf2xp37YAwZIqCCrI,18276
32
32
  lmnr/sdk/client/asynchronous/resources/base.py,sha256=aJ43Q1rltg23IQaI4eeaZKckxVTgDUbCJrChhQCUEoE,986
33
33
  lmnr/sdk/client/asynchronous/resources/browser_events.py,sha256=T-DUbbAfMQ2VqiVfgVplxuTaJZuoNcC1O6RCxdfw7UQ,1163
34
- lmnr/sdk/client/asynchronous/resources/evals.py,sha256=bm3ATwqLozUoW2Ed6psmdjmeJ7joBaQHSv6mBeA_cws,2187
34
+ lmnr/sdk/client/asynchronous/resources/evals.py,sha256=ZSJKBWgrRjgy03Y7Mp4ExXGrcERKjQErNCt59enjtc0,2296
35
35
  lmnr/sdk/client/synchronous/resources/__init__.py,sha256=Sk0_5Y1UkqwUhJKRct9R3JAnHk6sPe8lDokpYVqehdY,250
36
36
  lmnr/sdk/client/synchronous/resources/agent.py,sha256=vwf3XOHX4nF_W0t4qwqcpaGC2vdccaJ5iI920G1jPf0,18150
37
37
  lmnr/sdk/client/synchronous/resources/base.py,sha256=ne1ZZ10UmNkMrECVvClcEJfcFJlSGvaXOC8K6mZTPdY,971
38
38
  lmnr/sdk/client/synchronous/resources/browser_events.py,sha256=9rFYWZesXQomnFgbZ590tGFMTaNj0OAzT9RcFwD8q_Y,1135
39
- lmnr/sdk/client/synchronous/resources/evals.py,sha256=sMMAai7_IW842z_J0W9OpthDhGQPCkTVJZamIkKq0wk,3496
39
+ lmnr/sdk/client/synchronous/resources/evals.py,sha256=ERIpZP6JKdG4cNJDIxZ7ca0pVQ-gNLosqLw51QuhgjQ,3605
40
40
  lmnr/sdk/client/synchronous/sync_client.py,sha256=-sSMbUvgDLt98tT-nDyE_xfTohcGdn00lAmul1713Wo,4396
41
41
  lmnr/sdk/datasets.py,sha256=jl5Wj5nEI9pww4Jwn4XKF8h0gXBU4TOIrhqNjTJsHZQ,1709
42
- lmnr/sdk/decorators.py,sha256=NIen6dUhcryiWnoZTP6C6_llwPZqbGoOr8iWPorKWuY,3346
43
- lmnr/sdk/eval_control.py,sha256=qMiAI6FnHdIwKX8-W1nDhEcS5Cjm5lYRoIN7x4J-AVI,182
44
- lmnr/sdk/evaluations.py,sha256=SMCoYMHGwMKEXaGT6tR10dvXXU_OrazlYZCy11hKlQc,20444
45
- lmnr/sdk/laminar.py,sha256=QbMbxdAhFzVIWzKQRtoVv9M5qMQj_cdhJ4ph3d22Rxs,28158
42
+ lmnr/sdk/decorators.py,sha256=zUZiFQeP72UN-CKLh9Xyo0Q9thRaEl-MZvMFIulHjws,4229
43
+ lmnr/sdk/eval_control.py,sha256=KROUrDhcZTrptRZ-hxvr60_o_Gt_8u045jb4cBXcuoY,184
44
+ lmnr/sdk/evaluations.py,sha256=Ehr_6oDhrTlumCVDYgXJnooMWKC3ecLViXrdafo_kj0,21323
45
+ lmnr/sdk/laminar.py,sha256=A0J_UksBRBmWhV86v2v91Wl3WFCjeQBObOAZ7te2Xz8,28432
46
46
  lmnr/sdk/log.py,sha256=nt_YMmPw1IRbGy0b7q4rTtP4Yo3pQfNxqJPXK3nDSNQ,2213
47
- lmnr/sdk/types.py,sha256=QOIZ18ELzts5AG1Tx-_twHI43_PHoB4X8JYynTH0MCA,12287
47
+ lmnr/sdk/types.py,sha256=ZVmaDmmd0QdPGyks5w-a4bDHgdh7s17KE931Lp0ToMQ,12619
48
48
  lmnr/sdk/utils.py,sha256=_kUn43AEn7Cdqcsg1CkQvzVQ7PhQT27m-iuLcRrwlZM,3891
49
- lmnr/version.py,sha256=gIiYGEDo229n5RGCEUAivOOfgZPjhsZSIzuJPxtIZvQ,1321
50
- lmnr-0.6.1.dist-info/LICENSE,sha256=67b_wJHVV1CBaWkrKFWU1wyqTPSdzH77Ls-59631COg,10411
51
- lmnr-0.6.1.dist-info/METADATA,sha256=dBBwpBlKLQXHADF1afzpoffOLDIEJmA9ac8diguBYWM,15135
52
- lmnr-0.6.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
53
- lmnr-0.6.1.dist-info/entry_points.txt,sha256=K1jE20ww4jzHNZLnsfWBvU3YKDGBgbOiYG5Y7ivQcq4,37
54
- lmnr-0.6.1.dist-info/RECORD,,
49
+ lmnr/version.py,sha256=av7X7FZrRqgZKp2E6X7inFPyLJUVHm48PqGbdbKJtqM,1321
50
+ lmnr-0.6.3.dist-info/LICENSE,sha256=67b_wJHVV1CBaWkrKFWU1wyqTPSdzH77Ls-59631COg,10411
51
+ lmnr-0.6.3.dist-info/METADATA,sha256=PACDOKRQJbXmQJUkwW-K29LmQ5odCh2UWoWhixMuAHY,15135
52
+ lmnr-0.6.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
53
+ lmnr-0.6.3.dist-info/entry_points.txt,sha256=K1jE20ww4jzHNZLnsfWBvU3YKDGBgbOiYG5Y7ivQcq4,37
54
+ lmnr-0.6.3.dist-info/RECORD,,
File without changes
File without changes