agenta 0.27.0__py3-none-any.whl → 0.27.0a1__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 agenta might be problematic. Click here for more details.

Files changed (68) hide show
  1. agenta/__init__.py +3 -22
  2. agenta/cli/helper.py +1 -5
  3. agenta/client/backend/__init__.py +0 -14
  4. agenta/client/backend/apps/client.py +20 -28
  5. agenta/client/backend/client.py +2 -25
  6. agenta/client/backend/containers/client.py +1 -5
  7. agenta/client/backend/core/__init__.py +1 -2
  8. agenta/client/backend/core/client_wrapper.py +6 -6
  9. agenta/client/backend/core/file.py +11 -33
  10. agenta/client/backend/core/http_client.py +18 -24
  11. agenta/client/backend/core/pydantic_utilities.py +29 -144
  12. agenta/client/backend/core/request_options.py +0 -3
  13. agenta/client/backend/core/serialization.py +42 -139
  14. agenta/client/backend/evaluations/client.py +2 -7
  15. agenta/client/backend/evaluators/client.py +1 -349
  16. agenta/client/backend/observability/client.py +2 -11
  17. agenta/client/backend/testsets/client.py +10 -10
  18. agenta/client/backend/types/__init__.py +0 -14
  19. agenta/client/backend/types/app.py +0 -1
  20. agenta/client/backend/types/app_variant_response.py +1 -3
  21. agenta/client/backend/types/create_span.py +2 -3
  22. agenta/client/backend/types/environment_output.py +0 -1
  23. agenta/client/backend/types/environment_output_extended.py +0 -1
  24. agenta/client/backend/types/evaluation.py +2 -1
  25. agenta/client/backend/types/evaluator.py +0 -2
  26. agenta/client/backend/types/evaluator_config.py +0 -1
  27. agenta/client/backend/types/human_evaluation.py +2 -1
  28. agenta/client/backend/types/llm_tokens.py +2 -2
  29. agenta/client/backend/types/span.py +0 -1
  30. agenta/client/backend/types/span_detail.py +1 -7
  31. agenta/client/backend/types/test_set_output_response.py +2 -5
  32. agenta/client/backend/types/trace_detail.py +1 -7
  33. agenta/client/backend/types/with_pagination.py +2 -4
  34. agenta/client/backend/variants/client.py +273 -1566
  35. agenta/docker/docker-assets/Dockerfile.cloud.template +1 -1
  36. agenta/sdk/__init__.py +5 -20
  37. agenta/sdk/agenta_init.py +26 -30
  38. agenta/sdk/config_manager.py +205 -0
  39. agenta/sdk/context/routing.py +5 -6
  40. agenta/sdk/decorators/routing.py +135 -142
  41. agenta/sdk/decorators/tracing.py +245 -206
  42. agenta/sdk/litellm/litellm.py +36 -47
  43. agenta/sdk/tracing/attributes.py +2 -7
  44. agenta/sdk/tracing/context.py +2 -5
  45. agenta/sdk/tracing/conventions.py +8 -10
  46. agenta/sdk/tracing/exporters.py +6 -15
  47. agenta/sdk/tracing/inline.py +98 -70
  48. agenta/sdk/tracing/processors.py +14 -55
  49. agenta/sdk/tracing/spans.py +4 -16
  50. agenta/sdk/tracing/tracing.py +50 -54
  51. agenta/sdk/types.py +2 -61
  52. agenta/sdk/utils/exceptions.py +1 -31
  53. {agenta-0.27.0.dist-info → agenta-0.27.0a1.dist-info}/METADATA +1 -1
  54. {agenta-0.27.0.dist-info → agenta-0.27.0a1.dist-info}/RECORD +56 -67
  55. agenta/client/backend/types/config_dto.py +0 -32
  56. agenta/client/backend/types/config_response_model.py +0 -32
  57. agenta/client/backend/types/evaluator_mapping_output_interface.py +0 -21
  58. agenta/client/backend/types/evaluator_output_interface.py +0 -21
  59. agenta/client/backend/types/lifecycle_dto.py +0 -24
  60. agenta/client/backend/types/reference_dto.py +0 -23
  61. agenta/client/backend/types/reference_request_model.py +0 -23
  62. agenta/sdk/managers/__init__.py +0 -6
  63. agenta/sdk/managers/config.py +0 -318
  64. agenta/sdk/managers/deployment.py +0 -45
  65. agenta/sdk/managers/shared.py +0 -639
  66. agenta/sdk/managers/variant.py +0 -182
  67. {agenta-0.27.0.dist-info → agenta-0.27.0a1.dist-info}/WHEEL +0 -0
  68. {agenta-0.27.0.dist-info → agenta-0.27.0a1.dist-info}/entry_points.txt +0 -0
@@ -10,7 +10,6 @@ import typing_extensions
10
10
  import pydantic
11
11
 
12
12
  from .datetime_utils import serialize_datetime
13
- from .serialization import convert_and_respect_annotation_metadata
14
13
 
15
14
  IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
16
15
 
@@ -57,14 +56,11 @@ Model = typing.TypeVar("Model", bound=pydantic.BaseModel)
57
56
 
58
57
 
59
58
  def parse_obj_as(type_: typing.Type[T], object_: typing.Any) -> T:
60
- dealiased_object = convert_and_respect_annotation_metadata(
61
- object_=object_, annotation=type_, direction="read"
62
- )
63
59
  if IS_PYDANTIC_V2:
64
60
  adapter = pydantic.TypeAdapter(type_) # type: ignore # Pydantic v2
65
- return adapter.validate_python(dealiased_object)
61
+ return adapter.validate_python(object_)
66
62
  else:
67
- return pydantic.parse_obj_as(type_, dealiased_object)
63
+ return pydantic.parse_obj_as(type_, object_)
68
64
 
69
65
 
70
66
  def to_jsonable_with_fallback(
@@ -79,53 +75,9 @@ def to_jsonable_with_fallback(
79
75
 
80
76
 
81
77
  class UniversalBaseModel(pydantic.BaseModel):
82
- if IS_PYDANTIC_V2:
83
- model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
84
- # Allow fields begining with `model_` to be used in the model
85
- protected_namespaces=(),
86
- ) # type: ignore # Pydantic v2
87
-
88
- @pydantic.model_serializer(mode="wrap", when_used="json") # type: ignore # Pydantic v2
89
- def serialize_model(
90
- self, handler: pydantic.SerializerFunctionWrapHandler
91
- ) -> typing.Any: # type: ignore # Pydantic v2
92
- serialized = handler(self)
93
- data = {
94
- k: serialize_datetime(v) if isinstance(v, dt.datetime) else v
95
- for k, v in serialized.items()
96
- }
97
- return data
98
-
99
- else:
100
-
101
- class Config:
102
- smart_union = True
103
- json_encoders = {dt.datetime: serialize_datetime}
104
-
105
- @classmethod
106
- def model_construct(
107
- cls: typing.Type["Model"],
108
- _fields_set: typing.Optional[typing.Set[str]] = None,
109
- **values: typing.Any,
110
- ) -> "Model":
111
- dealiased_object = convert_and_respect_annotation_metadata(
112
- object_=values, annotation=cls, direction="read"
113
- )
114
- return cls.construct(_fields_set, **dealiased_object)
115
-
116
- @classmethod
117
- def construct(
118
- cls: typing.Type["Model"],
119
- _fields_set: typing.Optional[typing.Set[str]] = None,
120
- **values: typing.Any,
121
- ) -> "Model":
122
- dealiased_object = convert_and_respect_annotation_metadata(
123
- object_=values, annotation=cls, direction="read"
124
- )
125
- if IS_PYDANTIC_V2:
126
- return super().model_construct(_fields_set, **dealiased_object) # type: ignore # Pydantic v2
127
- else:
128
- return super().construct(_fields_set, **dealiased_object)
78
+ class Config:
79
+ populate_by_name = True
80
+ json_encoders = {dt.datetime: serialize_datetime}
129
81
 
130
82
  def json(self, **kwargs: typing.Any) -> str:
131
83
  kwargs_with_defaults: typing.Any = {
@@ -143,97 +95,30 @@ class UniversalBaseModel(pydantic.BaseModel):
143
95
  Override the default dict method to `exclude_unset` by default. This function patches
144
96
  `exclude_unset` to work include fields within non-None default values.
145
97
  """
146
- # Note: the logic here is multi-plexed given the levers exposed in Pydantic V1 vs V2
147
- # Pydantic V1's .dict can be extremely slow, so we do not want to call it twice.
148
- #
149
- # We'd ideally do the same for Pydantic V2, but it shells out to a library to serialize models
150
- # that we have less control over, and this is less intrusive than custom serializers for now.
151
- if IS_PYDANTIC_V2:
152
- kwargs_with_defaults_exclude_unset: typing.Any = {
153
- **kwargs,
154
- "by_alias": True,
155
- "exclude_unset": True,
156
- "exclude_none": False,
157
- }
158
- kwargs_with_defaults_exclude_none: typing.Any = {
159
- **kwargs,
160
- "by_alias": True,
161
- "exclude_none": True,
162
- "exclude_unset": False,
163
- }
164
- dict_dump = deep_union_pydantic_dicts(
165
- super().model_dump(**kwargs_with_defaults_exclude_unset), # type: ignore # Pydantic v2
166
- super().model_dump(**kwargs_with_defaults_exclude_none), # type: ignore # Pydantic v2
167
- )
98
+ _fields_set = self.__fields_set__
168
99
 
169
- else:
170
- _fields_set = self.__fields_set__.copy()
171
-
172
- fields = _get_model_fields(self.__class__)
173
- for name, field in fields.items():
174
- if name not in _fields_set:
175
- default = _get_field_default(field)
176
-
177
- # If the default values are non-null act like they've been set
178
- # This effectively allows exclude_unset to work like exclude_none where
179
- # the latter passes through intentionally set none values.
180
- if default is not None or (
181
- "exclude_unset" in kwargs and not kwargs["exclude_unset"]
182
- ):
183
- _fields_set.add(name)
184
-
185
- if default is not None:
186
- self.__fields_set__.add(name)
187
-
188
- kwargs_with_defaults_exclude_unset_include_fields: typing.Any = {
189
- "by_alias": True,
190
- "exclude_unset": True,
191
- "include": _fields_set,
192
- **kwargs,
193
- }
194
-
195
- dict_dump = super().dict(
196
- **kwargs_with_defaults_exclude_unset_include_fields
197
- )
198
-
199
- return convert_and_respect_annotation_metadata(
200
- object_=dict_dump, annotation=self.__class__, direction="write"
201
- )
202
-
203
-
204
- def _union_list_of_pydantic_dicts(
205
- source: typing.List[typing.Any], destination: typing.List[typing.Any]
206
- ) -> typing.List[typing.Any]:
207
- converted_list: typing.List[typing.Any] = []
208
- for i, item in enumerate(source):
209
- destination_value = destination[i] # type: ignore
210
- if isinstance(item, dict):
211
- converted_list.append(deep_union_pydantic_dicts(item, destination_value))
212
- elif isinstance(item, list):
213
- converted_list.append(
214
- _union_list_of_pydantic_dicts(item, destination_value)
215
- )
216
- else:
217
- converted_list.append(item)
218
- return converted_list
219
-
220
-
221
- def deep_union_pydantic_dicts(
222
- source: typing.Dict[str, typing.Any], destination: typing.Dict[str, typing.Any]
223
- ) -> typing.Dict[str, typing.Any]:
224
- for key, value in source.items():
225
- node = destination.setdefault(key, {})
226
- if isinstance(value, dict):
227
- deep_union_pydantic_dicts(value, node)
228
- # Note: we do not do this same processing for sets given we do not have sets of models
229
- # and given the sets are unordered, the processing of the set and matching objects would
230
- # be non-trivial.
231
- elif isinstance(value, list):
232
- destination[key] = _union_list_of_pydantic_dicts(value, node)
233
- else:
234
- destination[key] = value
100
+ fields = _get_model_fields(self.__class__)
101
+ for name, field in fields.items():
102
+ if name not in _fields_set:
103
+ default = _get_field_default(field)
104
+
105
+ # If the default values are non-null act like they've been set
106
+ # This effectively allows exclude_unset to work like exclude_none where
107
+ # the latter passes through intentionally set none values.
108
+ if default != None:
109
+ _fields_set.add(name)
235
110
 
236
- return destination
111
+ kwargs_with_defaults_exclude_unset: typing.Any = {
112
+ "by_alias": True,
113
+ "exclude_unset": True,
114
+ "include": _fields_set,
115
+ **kwargs,
116
+ }
117
+
118
+ if IS_PYDANTIC_V2:
119
+ return super().model_dump(**kwargs_with_defaults_exclude_unset) # type: ignore # Pydantic v2
120
+ else:
121
+ return super().dict(**kwargs_with_defaults_exclude_unset)
237
122
 
238
123
 
239
124
  if IS_PYDANTIC_V2:
@@ -260,11 +145,11 @@ def encode_by_type(o: typing.Any) -> typing.Any:
260
145
  return encoder(o)
261
146
 
262
147
 
263
- def update_forward_refs(model: typing.Type["Model"], **localns: typing.Any) -> None:
148
+ def update_forward_refs(model: typing.Type["Model"]) -> None:
264
149
  if IS_PYDANTIC_V2:
265
150
  model.model_rebuild(raise_errors=False) # type: ignore # Pydantic v2
266
151
  else:
267
- model.update_forward_refs(**localns)
152
+ model.update_forward_refs()
268
153
 
269
154
 
270
155
  # Mirrors Pydantic's internal typing
@@ -23,8 +23,6 @@ class RequestOptions(typing.TypedDict, total=False):
23
23
  - additional_query_parameters: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's query parameters dict
24
24
 
25
25
  - additional_body_parameters: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's body parameters dict
26
-
27
- - chunk_size: int. The size, in bytes, to process each chunk of data being streamed back within the response. This equates to leveraging `chunk_size` within `requests` or `httpx`, and is only leveraged for file downloads.
28
26
  """
29
27
 
30
28
  timeout_in_seconds: NotRequired[int]
@@ -32,4 +30,3 @@ class RequestOptions(typing.TypedDict, total=False):
32
30
  additional_headers: NotRequired[typing.Dict[str, typing.Any]]
33
31
  additional_query_parameters: NotRequired[typing.Dict[str, typing.Any]]
34
32
  additional_body_parameters: NotRequired[typing.Dict[str, typing.Any]]
35
- chunk_size: NotRequired[int]
@@ -1,13 +1,10 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  import collections
4
- import inspect
5
4
  import typing
6
5
 
7
6
  import typing_extensions
8
7
 
9
- import pydantic
10
-
11
8
 
12
9
  class FieldMetadata:
13
10
  """
@@ -32,7 +29,6 @@ def convert_and_respect_annotation_metadata(
32
29
  object_: typing.Any,
33
30
  annotation: typing.Any,
34
31
  inner_type: typing.Optional[typing.Any] = None,
35
- direction: typing.Literal["read", "write"],
36
32
  ) -> typing.Any:
37
33
  """
38
34
  Respect the metadata annotations on a field, such as aliasing. This function effectively
@@ -60,79 +56,49 @@ def convert_and_respect_annotation_metadata(
60
56
  inner_type = annotation
61
57
 
62
58
  clean_type = _remove_annotations(inner_type)
63
- # Pydantic models
64
- if (
65
- inspect.isclass(clean_type)
66
- and issubclass(clean_type, pydantic.BaseModel)
67
- and isinstance(object_, typing.Mapping)
68
- ):
69
- return _convert_mapping(object_, clean_type, direction)
70
- # TypedDicts
71
59
  if typing_extensions.is_typeddict(clean_type) and isinstance(
72
60
  object_, typing.Mapping
73
61
  ):
74
- return _convert_mapping(object_, clean_type, direction)
62
+ return _convert_typeddict(object_, clean_type)
75
63
 
76
64
  if (
77
- typing_extensions.get_origin(clean_type) == typing.Dict
78
- or typing_extensions.get_origin(clean_type) == dict
79
- or clean_type == typing.Dict
80
- ) and isinstance(object_, typing.Dict):
81
- key_type = typing_extensions.get_args(clean_type)[0]
82
- value_type = typing_extensions.get_args(clean_type)[1]
83
-
84
- return {
85
- key: convert_and_respect_annotation_metadata(
86
- object_=value,
87
- annotation=annotation,
88
- inner_type=value_type,
89
- direction=direction,
90
- )
91
- for key, value in object_.items()
92
- }
93
-
94
- # If you're iterating on a string, do not bother to coerce it to a sequence.
95
- if not isinstance(object_, str):
96
- if (
97
- typing_extensions.get_origin(clean_type) == typing.Set
98
- or typing_extensions.get_origin(clean_type) == set
99
- or clean_type == typing.Set
100
- ) and isinstance(object_, typing.Set):
101
- inner_type = typing_extensions.get_args(clean_type)[0]
102
- return {
103
- convert_and_respect_annotation_metadata(
104
- object_=item,
105
- annotation=annotation,
106
- inner_type=inner_type,
107
- direction=direction,
108
- )
109
- for item in object_
110
- }
111
- elif (
65
+ # If you're iterating on a string, do not bother to coerce it to a sequence.
66
+ (not isinstance(object_, str))
67
+ and (
112
68
  (
113
- typing_extensions.get_origin(clean_type) == typing.List
114
- or typing_extensions.get_origin(clean_type) == list
115
- or clean_type == typing.List
69
+ (
70
+ typing_extensions.get_origin(clean_type) == typing.List
71
+ or typing_extensions.get_origin(clean_type) == list
72
+ or clean_type == typing.List
73
+ )
74
+ and isinstance(object_, typing.List)
116
75
  )
117
- and isinstance(object_, typing.List)
118
- ) or (
119
- (
120
- typing_extensions.get_origin(clean_type) == typing.Sequence
121
- or typing_extensions.get_origin(clean_type) == collections.abc.Sequence
122
- or clean_type == typing.Sequence
76
+ or (
77
+ (
78
+ typing_extensions.get_origin(clean_type) == typing.Set
79
+ or typing_extensions.get_origin(clean_type) == set
80
+ or clean_type == typing.Set
81
+ )
82
+ and isinstance(object_, typing.Set)
123
83
  )
124
- and isinstance(object_, typing.Sequence)
125
- ):
126
- inner_type = typing_extensions.get_args(clean_type)[0]
127
- return [
128
- convert_and_respect_annotation_metadata(
129
- object_=item,
130
- annotation=annotation,
131
- inner_type=inner_type,
132
- direction=direction,
84
+ or (
85
+ (
86
+ typing_extensions.get_origin(clean_type) == typing.Sequence
87
+ or typing_extensions.get_origin(clean_type)
88
+ == collections.abc.Sequence
89
+ or clean_type == typing.Sequence
133
90
  )
134
- for item in object_
135
- ]
91
+ and isinstance(object_, typing.Sequence)
92
+ )
93
+ )
94
+ ):
95
+ inner_type = typing_extensions.get_args(clean_type)[0]
96
+ return [
97
+ convert_and_respect_annotation_metadata(
98
+ object_=item, annotation=annotation, inner_type=inner_type
99
+ )
100
+ for item in object_
101
+ ]
136
102
 
137
103
  if typing_extensions.get_origin(clean_type) == typing.Union:
138
104
  # We should be able to ~relatively~ safely try to convert keys against all
@@ -141,10 +107,7 @@ def convert_and_respect_annotation_metadata(
141
107
  # Or if another member aliases a field of the same name that another member does not.
142
108
  for member in typing_extensions.get_args(clean_type):
143
109
  object_ = convert_and_respect_annotation_metadata(
144
- object_=object_,
145
- annotation=annotation,
146
- inner_type=member,
147
- direction=direction,
110
+ object_=object_, annotation=annotation, inner_type=member
148
111
  )
149
112
  return object_
150
113
 
@@ -157,37 +120,19 @@ def convert_and_respect_annotation_metadata(
157
120
  return object_
158
121
 
159
122
 
160
- def _convert_mapping(
161
- object_: typing.Mapping[str, object],
162
- expected_type: typing.Any,
163
- direction: typing.Literal["read", "write"],
123
+ def _convert_typeddict(
124
+ object_: typing.Mapping[str, object], expected_type: typing.Any
164
125
  ) -> typing.Mapping[str, object]:
165
126
  converted_object: typing.Dict[str, object] = {}
166
127
  annotations = typing_extensions.get_type_hints(expected_type, include_extras=True)
167
- aliases_to_field_names = _get_alias_to_field_name(annotations)
168
128
  for key, value in object_.items():
169
- if direction == "read" and key in aliases_to_field_names:
170
- dealiased_key = aliases_to_field_names.get(key)
171
- if dealiased_key is not None:
172
- type_ = annotations.get(dealiased_key)
173
- else:
174
- type_ = annotations.get(key)
175
- # Note you can't get the annotation by the field name if you're in read mode, so you must check the aliases map
176
- #
177
- # So this is effectively saying if we're in write mode, and we don't have a type, or if we're in read mode and we don't have an alias
178
- # then we can just pass the value through as is
129
+ type_ = annotations.get(key)
179
130
  if type_ is None:
180
131
  converted_object[key] = value
181
- elif direction == "read" and key not in aliases_to_field_names:
182
- converted_object[key] = convert_and_respect_annotation_metadata(
183
- object_=value, annotation=type_, direction=direction
184
- )
185
132
  else:
186
133
  converted_object[
187
- _alias_key(key, type_, direction, aliases_to_field_names)
188
- ] = convert_and_respect_annotation_metadata(
189
- object_=value, annotation=type_, direction=direction
190
- )
134
+ _alias_key(key, type_)
135
+ ] = convert_and_respect_annotation_metadata(object_=value, annotation=type_)
191
136
  return converted_object
192
137
 
193
138
 
@@ -220,39 +165,7 @@ def _remove_annotations(type_: typing.Any) -> typing.Any:
220
165
  return type_
221
166
 
222
167
 
223
- def get_alias_to_field_mapping(type_: typing.Any) -> typing.Dict[str, str]:
224
- annotations = typing_extensions.get_type_hints(type_, include_extras=True)
225
- return _get_alias_to_field_name(annotations)
226
-
227
-
228
- def get_field_to_alias_mapping(type_: typing.Any) -> typing.Dict[str, str]:
229
- annotations = typing_extensions.get_type_hints(type_, include_extras=True)
230
- return _get_field_to_alias_name(annotations)
231
-
232
-
233
- def _get_alias_to_field_name(
234
- field_to_hint: typing.Dict[str, typing.Any],
235
- ) -> typing.Dict[str, str]:
236
- aliases = {}
237
- for field, hint in field_to_hint.items():
238
- maybe_alias = _get_alias_from_type(hint)
239
- if maybe_alias is not None:
240
- aliases[maybe_alias] = field
241
- return aliases
242
-
243
-
244
- def _get_field_to_alias_name(
245
- field_to_hint: typing.Dict[str, typing.Any],
246
- ) -> typing.Dict[str, str]:
247
- aliases = {}
248
- for field, hint in field_to_hint.items():
249
- maybe_alias = _get_alias_from_type(hint)
250
- if maybe_alias is not None:
251
- aliases[field] = maybe_alias
252
- return aliases
253
-
254
-
255
- def _get_alias_from_type(type_: typing.Any) -> typing.Optional[str]:
168
+ def _alias_key(key: str, type_: typing.Any) -> str:
256
169
  maybe_annotated_type = _get_annotation(type_)
257
170
 
258
171
  if maybe_annotated_type is not None:
@@ -262,15 +175,5 @@ def _get_alias_from_type(type_: typing.Any) -> typing.Optional[str]:
262
175
  for annotation in annotations:
263
176
  if isinstance(annotation, FieldMetadata) and annotation.alias is not None:
264
177
  return annotation.alias
265
- return None
266
-
267
178
 
268
- def _alias_key(
269
- key: str,
270
- type_: typing.Any,
271
- direction: typing.Literal["read", "write"],
272
- aliases_to_field_names: typing.Dict[str, str],
273
- ) -> str:
274
- if direction == "read":
275
- return aliases_to_field_names.get(key, key)
276
- return _get_alias_from_type(type_=type_) or key
179
+ return key
@@ -10,7 +10,6 @@ from json.decoder import JSONDecodeError
10
10
  from ..core.api_error import ApiError
11
11
  from ..types.evaluation import Evaluation
12
12
  from ..types.llm_run_rate_limit import LlmRunRateLimit
13
- from ..core.serialization import convert_and_respect_annotation_metadata
14
13
  from ..core.jsonable_encoder import jsonable_encoder
15
14
  from ..types.evaluation_scenario import EvaluationScenario
16
15
  from ..core.client_wrapper import AsyncClientWrapper
@@ -250,9 +249,7 @@ class EvaluationsClient:
250
249
  "variant_ids": variant_ids,
251
250
  "evaluators_configs": evaluators_configs,
252
251
  "testset_id": testset_id,
253
- "rate_limit": convert_and_respect_annotation_metadata(
254
- object_=rate_limit, annotation=LlmRunRateLimit, direction="write"
255
- ),
252
+ "rate_limit": rate_limit,
256
253
  "lm_providers_keys": lm_providers_keys,
257
254
  "correct_answer_column": correct_answer_column,
258
255
  },
@@ -962,9 +959,7 @@ class AsyncEvaluationsClient:
962
959
  "variant_ids": variant_ids,
963
960
  "evaluators_configs": evaluators_configs,
964
961
  "testset_id": testset_id,
965
- "rate_limit": convert_and_respect_annotation_metadata(
966
- object_=rate_limit, annotation=LlmRunRateLimit, direction="write"
967
- ),
962
+ "rate_limit": rate_limit,
968
963
  "lm_providers_keys": lm_providers_keys,
969
964
  "correct_answer_column": correct_answer_column,
970
965
  },