vellum-ai 0.8.9__py3-none-any.whl → 0.8.10__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.
vellum/client.py CHANGED
@@ -892,7 +892,9 @@ class Vellum:
892
892
  ChatMessageRequest(
893
893
  text="string",
894
894
  role="SYSTEM",
895
- content=StringChatMessageContentRequest(),
895
+ content=StringChatMessageContentRequest(
896
+ value="string",
897
+ ),
896
898
  source="string",
897
899
  )
898
900
  ],
@@ -2116,7 +2118,9 @@ class AsyncVellum:
2116
2118
  ChatMessageRequest(
2117
2119
  text="string",
2118
2120
  role="SYSTEM",
2119
- content=StringChatMessageContentRequest(),
2121
+ content=StringChatMessageContentRequest(
2122
+ value="string",
2123
+ ),
2120
2124
  source="string",
2121
2125
  )
2122
2126
  ],
@@ -17,7 +17,7 @@ class BaseClientWrapper:
17
17
  headers: typing.Dict[str, str] = {
18
18
  "X-Fern-Language": "Python",
19
19
  "X-Fern-SDK-Name": "vellum-ai",
20
- "X-Fern-SDK-Version": "0.8.9",
20
+ "X-Fern-SDK-Version": "0.8.10",
21
21
  }
22
22
  headers["X_API_KEY"] = self.api_key
23
23
  return headers
@@ -80,6 +80,8 @@ class UniversalBaseModel(pydantic.BaseModel):
80
80
  smart_union = True
81
81
  allow_population_by_field_name = True
82
82
  json_encoders = {dt.datetime: serialize_datetime}
83
+ # Allow fields begining with `model_` to be used in the model
84
+ protected_namespaces = ()
83
85
 
84
86
  def json(self, **kwargs: typing.Any) -> str:
85
87
  kwargs_with_defaults: typing.Any = {
@@ -97,30 +99,64 @@ class UniversalBaseModel(pydantic.BaseModel):
97
99
  Override the default dict method to `exclude_unset` by default. This function patches
98
100
  `exclude_unset` to work include fields within non-None default values.
99
101
  """
100
- _fields_set = self.__fields_set__
101
-
102
- fields = _get_model_fields(self.__class__)
103
- for name, field in fields.items():
104
- if name not in _fields_set:
105
- default = _get_field_default(field)
106
-
107
- # If the default values are non-null act like they've been set
108
- # This effectively allows exclude_unset to work like exclude_none where
109
- # the latter passes through intentionally set none values.
110
- if default != None:
111
- _fields_set.add(name)
112
-
113
- kwargs_with_defaults_exclude_unset: typing.Any = {
114
- "by_alias": True,
115
- "exclude_unset": True,
116
- "include": _fields_set,
117
- **kwargs,
118
- }
119
-
102
+ # Note: the logic here is multi-plexed given the levers exposed in Pydantic V1 vs V2
103
+ # Pydantic V1's .dict can be extremely slow, so we do not want to call it twice.
104
+ #
105
+ # We'd ideally do the same for Pydantic V2, but it shells out to a library to serialize models
106
+ # that we have less control over, and this is less intrusive than custom serializers for now.
120
107
  if IS_PYDANTIC_V2:
121
- return super().model_dump(**kwargs_with_defaults_exclude_unset) # type: ignore # Pydantic v2
108
+ kwargs_with_defaults_exclude_unset: typing.Any = {
109
+ **kwargs,
110
+ "by_alias": True,
111
+ "exclude_unset": True,
112
+ "exclude_none": False,
113
+ }
114
+ kwargs_with_defaults_exclude_none: typing.Any = {
115
+ **kwargs,
116
+ "by_alias": True,
117
+ "exclude_none": True,
118
+ "exclude_unset": False,
119
+ }
120
+ return deep_union_pydantic_dicts(
121
+ super().model_dump(**kwargs_with_defaults_exclude_unset), # type: ignore # Pydantic v2
122
+ super().model_dump(**kwargs_with_defaults_exclude_none), # type: ignore # Pydantic v2
123
+ )
124
+
122
125
  else:
123
- return super().dict(**kwargs_with_defaults_exclude_unset)
126
+ _fields_set = self.__fields_set__
127
+
128
+ fields = _get_model_fields(self.__class__)
129
+ for name, field in fields.items():
130
+ if name not in _fields_set:
131
+ default = _get_field_default(field)
132
+
133
+ # If the default values are non-null act like they've been set
134
+ # This effectively allows exclude_unset to work like exclude_none where
135
+ # the latter passes through intentionally set none values.
136
+ if default != None:
137
+ _fields_set.add(name)
138
+
139
+ kwargs_with_defaults_exclude_unset_include_fields: typing.Any = {
140
+ "by_alias": True,
141
+ "exclude_unset": True,
142
+ "include": _fields_set,
143
+ **kwargs,
144
+ }
145
+
146
+ return super().dict(**kwargs_with_defaults_exclude_unset_include_fields)
147
+
148
+
149
+ def deep_union_pydantic_dicts(
150
+ source: typing.Dict[str, typing.Any], destination: typing.Dict[str, typing.Any]
151
+ ) -> typing.Dict[str, typing.Any]:
152
+ for key, value in source.items():
153
+ if isinstance(value, dict):
154
+ node = destination.setdefault(key, {})
155
+ deep_union_pydantic_dicts(value, node)
156
+ else:
157
+ destination[key] = value
158
+
159
+ return destination
124
160
 
125
161
 
126
162
  if IS_PYDANTIC_V2:
@@ -1,10 +1,13 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  import collections
4
+ import inspect
4
5
  import typing
5
6
 
6
7
  import typing_extensions
7
8
 
9
+ import pydantic
10
+
8
11
 
9
12
  class FieldMetadata:
10
13
  """
@@ -29,6 +32,7 @@ def convert_and_respect_annotation_metadata(
29
32
  object_: typing.Any,
30
33
  annotation: typing.Any,
31
34
  inner_type: typing.Optional[typing.Any] = None,
35
+ direction: typing.Literal["read", "write"],
32
36
  ) -> typing.Any:
33
37
  """
34
38
  Respect the metadata annotations on a field, such as aliasing. This function effectively
@@ -56,44 +60,59 @@ def convert_and_respect_annotation_metadata(
56
60
  inner_type = annotation
57
61
 
58
62
  clean_type = _remove_annotations(inner_type)
59
- if typing_extensions.is_typeddict(clean_type) and isinstance(object_, typing.Mapping):
60
- return _convert_typeddict(object_, clean_type)
61
-
63
+ # Pydantic models
62
64
  if (
63
- # If you're iterating on a string, do not bother to coerce it to a sequence.
64
- (not isinstance(object_, str))
65
- and (
66
- (
67
- (
68
- typing_extensions.get_origin(clean_type) == typing.List
69
- or typing_extensions.get_origin(clean_type) == list
70
- or clean_type == typing.List
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
+ if typing_extensions.is_typeddict(clean_type) and isinstance(object_, typing.Mapping):
72
+ return _convert_mapping(object_, clean_type, direction)
73
+
74
+ # If you're iterating on a string, do not bother to coerce it to a sequence.
75
+ if not isinstance(object_, str):
76
+ if (
77
+ typing_extensions.get_origin(clean_type) == typing.Set
78
+ or typing_extensions.get_origin(clean_type) == set
79
+ or clean_type == typing.Set
80
+ ) and isinstance(object_, typing.Set):
81
+ inner_type = typing_extensions.get_args(clean_type)[0]
82
+ return {
83
+ convert_and_respect_annotation_metadata(
84
+ object_=item,
85
+ annotation=annotation,
86
+ inner_type=inner_type,
87
+ direction=direction,
71
88
  )
72
- and isinstance(object_, typing.List)
89
+ for item in object_
90
+ }
91
+ elif (
92
+ (
93
+ typing_extensions.get_origin(clean_type) == typing.List
94
+ or typing_extensions.get_origin(clean_type) == list
95
+ or clean_type == typing.List
73
96
  )
74
- or (
75
- (
76
- typing_extensions.get_origin(clean_type) == typing.Set
77
- or typing_extensions.get_origin(clean_type) == set
78
- or clean_type == typing.Set
79
- )
80
- and isinstance(object_, typing.Set)
97
+ and isinstance(object_, typing.List)
98
+ ) or (
99
+ (
100
+ typing_extensions.get_origin(clean_type) == typing.Sequence
101
+ or typing_extensions.get_origin(clean_type) == collections.abc.Sequence
102
+ or clean_type == typing.Sequence
81
103
  )
82
- or (
83
- (
84
- typing_extensions.get_origin(clean_type) == typing.Sequence
85
- or typing_extensions.get_origin(clean_type) == collections.abc.Sequence
86
- or clean_type == typing.Sequence
104
+ and isinstance(object_, typing.Sequence)
105
+ ):
106
+ inner_type = typing_extensions.get_args(clean_type)[0]
107
+ return [
108
+ convert_and_respect_annotation_metadata(
109
+ object_=item,
110
+ annotation=annotation,
111
+ inner_type=inner_type,
112
+ direction=direction,
87
113
  )
88
- and isinstance(object_, typing.Sequence)
89
- )
90
- )
91
- ):
92
- inner_type = typing_extensions.get_args(clean_type)[0]
93
- return [
94
- convert_and_respect_annotation_metadata(object_=item, annotation=annotation, inner_type=inner_type)
95
- for item in object_
96
- ]
114
+ for item in object_
115
+ ]
97
116
 
98
117
  if typing_extensions.get_origin(clean_type) == typing.Union:
99
118
  # We should be able to ~relatively~ safely try to convert keys against all
@@ -101,7 +120,12 @@ def convert_and_respect_annotation_metadata(
101
120
  # of the same name to a different name from another member
102
121
  # Or if another member aliases a field of the same name that another member does not.
103
122
  for member in typing_extensions.get_args(clean_type):
104
- object_ = convert_and_respect_annotation_metadata(object_=object_, annotation=annotation, inner_type=member)
123
+ object_ = convert_and_respect_annotation_metadata(
124
+ object_=object_,
125
+ annotation=annotation,
126
+ inner_type=member,
127
+ direction=direction,
128
+ )
105
129
  return object_
106
130
 
107
131
  annotated_type = _get_annotation(annotation)
@@ -113,16 +137,34 @@ def convert_and_respect_annotation_metadata(
113
137
  return object_
114
138
 
115
139
 
116
- def _convert_typeddict(object_: typing.Mapping[str, object], expected_type: typing.Any) -> typing.Mapping[str, object]:
140
+ def _convert_mapping(
141
+ object_: typing.Mapping[str, object],
142
+ expected_type: typing.Any,
143
+ direction: typing.Literal["read", "write"],
144
+ ) -> typing.Mapping[str, object]:
117
145
  converted_object: typing.Dict[str, object] = {}
118
146
  annotations = typing_extensions.get_type_hints(expected_type, include_extras=True)
147
+ aliases_to_field_names = _get_alias_to_field_name(annotations)
119
148
  for key, value in object_.items():
120
- type_ = annotations.get(key)
149
+ if direction == "read" and key in aliases_to_field_names:
150
+ dealiased_key = aliases_to_field_names.get(key)
151
+ if dealiased_key is not None:
152
+ type_ = annotations.get(dealiased_key)
153
+ else:
154
+ type_ = annotations.get(key)
155
+ # Note you can't get the annotation by the field name if you're in read mode, so you must check the aliases map
156
+ #
157
+ # 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
158
+ # then we can just pass the value through as is
121
159
  if type_ is None:
122
160
  converted_object[key] = value
161
+ elif direction == "read" and key not in aliases_to_field_names:
162
+ converted_object[key] = convert_and_respect_annotation_metadata(
163
+ object_=value, annotation=type_, direction=direction
164
+ )
123
165
  else:
124
- converted_object[_alias_key(key, type_)] = convert_and_respect_annotation_metadata(
125
- object_=value, annotation=type_
166
+ converted_object[_alias_key(key, type_, direction, aliases_to_field_names)] = (
167
+ convert_and_respect_annotation_metadata(object_=value, annotation=type_, direction=direction)
126
168
  )
127
169
  return converted_object
128
170
 
@@ -156,7 +198,39 @@ def _remove_annotations(type_: typing.Any) -> typing.Any:
156
198
  return type_
157
199
 
158
200
 
159
- def _alias_key(key: str, type_: typing.Any) -> str:
201
+ def get_alias_to_field_mapping(type_: typing.Any) -> typing.Dict[str, str]:
202
+ annotations = typing_extensions.get_type_hints(type_, include_extras=True)
203
+ return _get_alias_to_field_name(annotations)
204
+
205
+
206
+ def get_field_to_alias_mapping(type_: typing.Any) -> typing.Dict[str, str]:
207
+ annotations = typing_extensions.get_type_hints(type_, include_extras=True)
208
+ return _get_field_to_alias_name(annotations)
209
+
210
+
211
+ def _get_alias_to_field_name(
212
+ field_to_hint: typing.Dict[str, typing.Any],
213
+ ) -> typing.Dict[str, str]:
214
+ aliases = {}
215
+ for field, hint in field_to_hint.items():
216
+ maybe_alias = _get_alias_from_type(hint)
217
+ if maybe_alias is not None:
218
+ aliases[maybe_alias] = field
219
+ return aliases
220
+
221
+
222
+ def _get_field_to_alias_name(
223
+ field_to_hint: typing.Dict[str, typing.Any],
224
+ ) -> typing.Dict[str, str]:
225
+ aliases = {}
226
+ for field, hint in field_to_hint.items():
227
+ maybe_alias = _get_alias_from_type(hint)
228
+ if maybe_alias is not None:
229
+ aliases[field] = maybe_alias
230
+ return aliases
231
+
232
+
233
+ def _get_alias_from_type(type_: typing.Any) -> typing.Optional[str]:
160
234
  maybe_annotated_type = _get_annotation(type_)
161
235
 
162
236
  if maybe_annotated_type is not None:
@@ -166,5 +240,15 @@ def _alias_key(key: str, type_: typing.Any) -> str:
166
240
  for annotation in annotations:
167
241
  if isinstance(annotation, FieldMetadata) and annotation.alias is not None:
168
242
  return annotation.alias
243
+ return None
244
+
169
245
 
170
- return key
246
+ def _alias_key(
247
+ key: str,
248
+ type_: typing.Any,
249
+ direction: typing.Literal["read", "write"],
250
+ aliases_to_field_names: typing.Dict[str, str],
251
+ ) -> str:
252
+ if direction == "read":
253
+ return aliases_to_field_names.get(key, key)
254
+ return _get_alias_from_type(type_=type_) or key
@@ -112,7 +112,9 @@ class AdHocClient:
112
112
  ),
113
113
  id="string",
114
114
  state="ENABLED",
115
- cache_config=EphemeralPromptCacheConfigRequest(),
115
+ cache_config=EphemeralPromptCacheConfigRequest(
116
+ type={"key": "value"},
117
+ ),
116
118
  )
117
119
  ],
118
120
  expand_meta=AdHocExpandMetaRequest(
@@ -288,7 +290,9 @@ class AsyncAdHocClient:
288
290
  ),
289
291
  id="string",
290
292
  state="ENABLED",
291
- cache_config=EphemeralPromptCacheConfigRequest(),
293
+ cache_config=EphemeralPromptCacheConfigRequest(
294
+ type={"key": "value"},
295
+ ),
292
296
  )
293
297
  ],
294
298
  expand_meta=AdHocExpandMetaRequest(
@@ -229,8 +229,18 @@ class TestSuitesClient:
229
229
  id="string",
230
230
  data=CreateTestSuiteTestCaseRequest(
231
231
  label="string",
232
- input_values=[NamedTestCaseStringVariableValueRequest()],
233
- evaluation_values=[NamedTestCaseStringVariableValueRequest()],
232
+ input_values=[
233
+ NamedTestCaseStringVariableValueRequest(
234
+ value="string",
235
+ name="string",
236
+ )
237
+ ],
238
+ evaluation_values=[
239
+ NamedTestCaseStringVariableValueRequest(
240
+ value="string",
241
+ name="string",
242
+ )
243
+ ],
234
244
  external_id="string",
235
245
  ),
236
246
  )
@@ -548,9 +558,17 @@ class AsyncTestSuitesClient:
548
558
  id="string",
549
559
  data=CreateTestSuiteTestCaseRequest(
550
560
  label="string",
551
- input_values=[NamedTestCaseStringVariableValueRequest()],
561
+ input_values=[
562
+ NamedTestCaseStringVariableValueRequest(
563
+ value="string",
564
+ name="string",
565
+ )
566
+ ],
552
567
  evaluation_values=[
553
- NamedTestCaseStringVariableValueRequest()
568
+ NamedTestCaseStringVariableValueRequest(
569
+ value="string",
570
+ name="string",
571
+ )
554
572
  ],
555
573
  external_id="string",
556
574
  ),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.8.9
3
+ Version: 0.8.10
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.8,<4.0
@@ -1,17 +1,17 @@
1
1
  vellum/__init__.py,sha256=ZjILSZ1gKX9YUZjjOzr0wngRMV7aYaCvuCXgoxt7n2o,30148
2
- vellum/client.py,sha256=FzaKpt5tvigJpdckmhhtIZemZnt_qM-50WfXENgyA74,101094
2
+ vellum/client.py,sha256=tsLLtZbwPASP8Cdh1RF19pOuNmZbBKFkUiplU9X190Q,101256
3
3
  vellum/core/__init__.py,sha256=FzSvKbXjuM18Hdk3iGK-jsGY_DfouyRS659thZV5c1Y,1394
4
4
  vellum/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
5
- vellum/core/client_wrapper.py,sha256=ufeiagHJMhTy-ivorHYOOgDbHND76t2jMmfgX9VcJN8,1897
5
+ vellum/core/client_wrapper.py,sha256=M-BpiKCvswDs5lRLcJdm1cAw-R1gKHfMTOJcWjskwVk,1898
6
6
  vellum/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
7
7
  vellum/core/file.py,sha256=vliNmlB7PbDfi4EKiVPNq5QaGXJ4zlDBGupv7Qciy7g,1520
8
8
  vellum/core/http_client.py,sha256=rZSidd9LazCjduvdBhZ7GDs4iGfn-OAfRGsDXB1z8f4,18882
9
9
  vellum/core/jsonable_encoder.py,sha256=qaF1gtgH-kQZb4kJskETwcCsOPUof-NnYVdszHkb-dM,3656
10
- vellum/core/pydantic_utilities.py,sha256=F91xFonOmTu3AdWJtQduQoS8Gn_K7y8ln9IT8LU6WPM,7549
10
+ vellum/core/pydantic_utilities.py,sha256=h_XylfOhkKxX6ZxL5CVfXylOzR4oc5AjCVC5yTsR4aU,9138
11
11
  vellum/core/query_encoder.py,sha256=ekulqNd0j8TgD7ox-Qbz7liqX8-KP9blvT9DsRCenYM,2144
12
12
  vellum/core/remove_none_from_dict.py,sha256=EU9SGgYidWq7SexuJbNs4-PZ-5Bl3Vppd864mS6vQZw,342
13
13
  vellum/core/request_options.py,sha256=5cCGt5AEGgtP5xifDl4oVQUmSjlIA8FmRItAlJawM18,1417
14
- vellum/core/serialization.py,sha256=X1W2KRWxKwOL7k4EatJMas1e2CCLfUOI77qrj8AvLGc,5862
14
+ vellum/core/serialization.py,sha256=5evS9ZBT8F0_GUAfzb6FQvdgw4JKuHFBlEoqZ8Y8-DU,8970
15
15
  vellum/environment.py,sha256=bcAFjoE9XXd7tiysYS90Os669IJmUMZS2JZ_ZQn0Dpg,498
16
16
  vellum/errors/__init__.py,sha256=HZB8vVqzDNx0M2uFJ05S5RcGTH95iVDl4v3rQ4xRqSw,343
17
17
  vellum/errors/bad_request_error.py,sha256=_EbO8mWqN9kFZPvIap8qa1lL_EWkRcsZe1HKV9GDWJY,264
@@ -30,7 +30,7 @@ vellum/lib/utils/paginator.py,sha256=yDvgehocYBDclLt5SewZH4hCIyq0yLHdBzkyPCoYPjs
30
30
  vellum/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  vellum/resources/__init__.py,sha256=iaTrngunVag3wUnyP3TlA8lG55RUCYw4qgdlZXzhi2Q,806
32
32
  vellum/resources/ad_hoc/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
33
- vellum/resources/ad_hoc/client.py,sha256=cXVuw1ETy_oQkBtiiU8NVljB-Xp0iVZ6GrpfXv8m5pA,13862
33
+ vellum/resources/ad_hoc/client.py,sha256=7WwFing-VwbfZJbwBRJCkJ3ypXJ7jMSt4kaCVSTW3gk,14006
34
34
  vellum/resources/deployments/__init__.py,sha256=AE0TcFwLrLBljM0ZDX-pPw4Kqt-1f5JDpIok2HS80QI,157
35
35
  vellum/resources/deployments/client.py,sha256=A_x9lFFFNiiwggPcrMfP88vv5F0FuLo39Ek36WEfJpE,28516
36
36
  vellum/resources/deployments/types/__init__.py,sha256=IhwnmoXJ0r_QEhh1b2tBcaAm_x3fWMVuIhYmAapp_ZA,183
@@ -48,7 +48,7 @@ vellum/resources/sandboxes/client.py,sha256=RDFDge2gkI6Kpo3VhlRISKS8wHDp7MYh83XV
48
48
  vellum/resources/test_suite_runs/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
49
49
  vellum/resources/test_suite_runs/client.py,sha256=laE40piDiurzmO1mwStY0ebsxQpTuETgiCAewtSrNk8,14192
50
50
  vellum/resources/test_suites/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
51
- vellum/resources/test_suites/client.py,sha256=NxlaHkupz_i3JqxgqV5LmNl_LVkyFSFSebTPH1hd6SU,23105
51
+ vellum/resources/test_suites/client.py,sha256=Sy_mXyAwObTwRSPH9gOO8gNZRfx4MlQVV3TxaAdnVx0,23795
52
52
  vellum/resources/workflow_deployments/__init__.py,sha256=-5BCA0kSmW6WUh4gqLuQtHv4zFdt9lccuDwMU5YvEu4,173
53
53
  vellum/resources/workflow_deployments/client.py,sha256=ezSg3EDA5UszvrT15jx7-RoSO8pXRwAIDlqMCJXkNOY,17393
54
54
  vellum/resources/workflow_deployments/types/__init__.py,sha256=rmS_4dtbgLHGNQJ_pOloygrjl4sNbKZjTEKBxbMyz6E,208
@@ -484,7 +484,7 @@ vellum/types/workflow_result_event_output_data_search_results.py,sha256=U34IK7Zv
484
484
  vellum/types/workflow_result_event_output_data_string.py,sha256=tM3kgh6tEhD0dFEb_7UU0-UspeN4pUdINCcCrD64W74,1228
485
485
  vellum/types/workflow_stream_event.py,sha256=Wn3Yzuy9MqWAeo8tEaXDTKDEbJoA8DdYdMVq8EKuhu8,361
486
486
  vellum/version.py,sha256=jq-1PlAYxN9AXuaZqbYk9ak27SgE2lw9Ia5gx1b1gVI,76
487
- vellum_ai-0.8.9.dist-info/LICENSE,sha256=CcaljEIoOBaU-wItPH4PmM_mDCGpyuUY0Er1BGu5Ti8,1073
488
- vellum_ai-0.8.9.dist-info/METADATA,sha256=ApCmRTG3GYNsYwkGWltiBbBqNx03p4HsJzr9ikoVJtA,4394
489
- vellum_ai-0.8.9.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
490
- vellum_ai-0.8.9.dist-info/RECORD,,
487
+ vellum_ai-0.8.10.dist-info/LICENSE,sha256=CcaljEIoOBaU-wItPH4PmM_mDCGpyuUY0Er1BGu5Ti8,1073
488
+ vellum_ai-0.8.10.dist-info/METADATA,sha256=QHpzDwJPFH8HiKsH-zgInPuvI39uSU4MtqDrQpIJzwI,4395
489
+ vellum_ai-0.8.10.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
490
+ vellum_ai-0.8.10.dist-info/RECORD,,