vellum-ai 0.8.15__py3-none-any.whl → 0.8.17__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 (46) hide show
  1. vellum/__init__.py +50 -0
  2. vellum/client.py +223 -6
  3. vellum/core/client_wrapper.py +3 -3
  4. vellum/core/http_client.py +22 -16
  5. vellum/core/pydantic_utilities.py +26 -3
  6. vellum/resources/__init__.py +2 -0
  7. vellum/resources/metric_definitions/__init__.py +2 -0
  8. vellum/resources/metric_definitions/client.py +178 -0
  9. vellum/resources/test_suites/client.py +8 -8
  10. vellum/types/__init__.py +52 -0
  11. vellum/types/array_input_request.py +36 -0
  12. vellum/types/code_execution_package_request.py +20 -0
  13. vellum/types/code_execution_runtime.py +5 -0
  14. vellum/types/code_executor_input_request.py +22 -0
  15. vellum/types/code_executor_response.py +27 -0
  16. vellum/types/condition_combinator.py +5 -0
  17. vellum/types/error_input_request.py +30 -0
  18. vellum/types/function_call_input_request.py +30 -0
  19. vellum/types/google_vertex_ai_vectorizer_config.py +20 -0
  20. vellum/types/google_vertex_ai_vectorizer_config_request.py +20 -0
  21. vellum/types/google_vertex_ai_vectorizer_text_embedding_004.py +21 -0
  22. vellum/types/google_vertex_ai_vectorizer_text_embedding_004_request.py +21 -0
  23. vellum/types/google_vertex_ai_vectorizer_text_multilingual_embedding_002.py +21 -0
  24. vellum/types/google_vertex_ai_vectorizer_text_multilingual_embedding_002_request.py +21 -0
  25. vellum/types/indexing_config_vectorizer.py +6 -0
  26. vellum/types/indexing_config_vectorizer_request.py +6 -0
  27. vellum/types/json_input_request.py +1 -1
  28. vellum/types/logical_operator.py +2 -0
  29. vellum/types/metadata_filter_config_request.py +4 -0
  30. vellum/types/metadata_filters_request.py +7 -0
  31. vellum/types/metric_definition_execution.py +20 -0
  32. vellum/types/metric_definition_input_request.py +11 -0
  33. vellum/types/number_input_request.py +29 -0
  34. vellum/types/search_filters_request.py +6 -2
  35. vellum/types/search_request_options_request.py +4 -0
  36. vellum/types/search_results_input_request.py +30 -0
  37. vellum/types/string_input_request.py +1 -1
  38. vellum/types/vellum_value.py +24 -0
  39. vellum/types/vellum_value_logical_condition_group_request.py +38 -0
  40. vellum/types/vellum_value_logical_condition_request.py +34 -0
  41. vellum/types/vellum_value_logical_expression_request.py +12 -0
  42. vellum/types/vellum_value_request.py +24 -0
  43. {vellum_ai-0.8.15.dist-info → vellum_ai-0.8.17.dist-info}/METADATA +1 -1
  44. {vellum_ai-0.8.15.dist-info → vellum_ai-0.8.17.dist-info}/RECORD +46 -20
  45. {vellum_ai-0.8.15.dist-info → vellum_ai-0.8.17.dist-info}/LICENSE +0 -0
  46. {vellum_ai-0.8.15.dist-info → vellum_ai-0.8.17.dist-info}/WHEEL +0 -0
vellum/__init__.py CHANGED
@@ -14,6 +14,7 @@ from .types import (
14
14
  ArrayChatMessageContentItem,
15
15
  ArrayChatMessageContentItemRequest,
16
16
  ArrayChatMessageContentRequest,
17
+ ArrayInputRequest,
17
18
  ArrayVariableValue,
18
19
  ArrayVariableValueItem,
19
20
  ArrayVellumValue,
@@ -48,10 +49,15 @@ from .types import (
48
49
  CodeExecutionNodeResultOutput,
49
50
  CodeExecutionNodeSearchResultsResult,
50
51
  CodeExecutionNodeStringResult,
52
+ CodeExecutionPackageRequest,
53
+ CodeExecutionRuntime,
54
+ CodeExecutorInputRequest,
55
+ CodeExecutorResponse,
51
56
  CompilePromptDeploymentExpandMetaRequest,
52
57
  CompilePromptMeta,
53
58
  ComponentsSchemasPdfSearchResultMetaSource,
54
59
  ComponentsSchemasPdfSearchResultMetaSourceRequest,
60
+ ConditionCombinator,
55
61
  ConditionalNodeResult,
56
62
  ConditionalNodeResultData,
57
63
  CreateTestSuiteTestCaseRequest,
@@ -73,6 +79,7 @@ from .types import (
73
79
  EnvironmentEnum,
74
80
  EphemeralPromptCacheConfigRequest,
75
81
  EphemeralPromptCacheConfigTypeEnum,
82
+ ErrorInputRequest,
76
83
  ErrorVariableValue,
77
84
  ErrorVellumValue,
78
85
  ErrorVellumValueRequest,
@@ -104,6 +111,7 @@ from .types import (
104
111
  FunctionCallChatMessageContentRequest,
105
112
  FunctionCallChatMessageContentValue,
106
113
  FunctionCallChatMessageContentValueRequest,
114
+ FunctionCallInputRequest,
107
115
  FunctionCallRequest,
108
116
  FunctionCallVariableValue,
109
117
  FunctionCallVellumValue,
@@ -119,6 +127,12 @@ from .types import (
119
127
  GenerateStreamResponse,
120
128
  GenerateStreamResult,
121
129
  GenerateStreamResultData,
130
+ GoogleVertexAiVectorizerConfig,
131
+ GoogleVertexAiVectorizerConfigRequest,
132
+ GoogleVertexAiVectorizerTextEmbedding004,
133
+ GoogleVertexAiVectorizerTextEmbedding004Request,
134
+ GoogleVertexAiVectorizerTextMultilingualEmbedding002,
135
+ GoogleVertexAiVectorizerTextMultilingualEmbedding002Request,
122
136
  HkunlpInstructorXlVectorizer,
123
137
  HkunlpInstructorXlVectorizerRequest,
124
138
  ImageChatMessageContent,
@@ -151,6 +165,9 @@ from .types import (
151
165
  MetadataFilterConfigRequest,
152
166
  MetadataFilterRuleCombinator,
153
167
  MetadataFilterRuleRequest,
168
+ MetadataFiltersRequest,
169
+ MetricDefinitionExecution,
170
+ MetricDefinitionInputRequest,
154
171
  MetricNodeResult,
155
172
  MlModelUsage,
156
173
  NamedScenarioInputChatHistoryVariableValueRequest,
@@ -195,6 +212,7 @@ from .types import (
195
212
  NodeOutputCompiledValue,
196
213
  NormalizedLogProbs,
197
214
  NormalizedTokenLogProbs,
215
+ NumberInputRequest,
198
216
  NumberVariableValue,
199
217
  NumberVellumValue,
200
218
  NumberVellumValueRequest,
@@ -264,6 +282,7 @@ from .types import (
264
282
  SearchResultMeta,
265
283
  SearchResultMetaRequest,
266
284
  SearchResultRequest,
285
+ SearchResultsInputRequest,
267
286
  SearchResultsVariableValue,
268
287
  SearchResultsVellumValue,
269
288
  SearchResultsVellumValueRequest,
@@ -382,6 +401,11 @@ from .types import (
382
401
  VellumErrorRequest,
383
402
  VellumImage,
384
403
  VellumImageRequest,
404
+ VellumValue,
405
+ VellumValueLogicalConditionGroupRequest,
406
+ VellumValueLogicalConditionRequest,
407
+ VellumValueLogicalExpressionRequest,
408
+ VellumValueRequest,
385
409
  VellumVariable,
386
410
  VellumVariableRequest,
387
411
  VellumVariableType,
@@ -437,6 +461,7 @@ from .resources import (
437
461
  document_indexes,
438
462
  documents,
439
463
  folder_entities,
464
+ metric_definitions,
440
465
  sandboxes,
441
466
  test_suite_runs,
442
467
  test_suites,
@@ -461,6 +486,7 @@ __all__ = [
461
486
  "ArrayChatMessageContentItem",
462
487
  "ArrayChatMessageContentItemRequest",
463
488
  "ArrayChatMessageContentRequest",
489
+ "ArrayInputRequest",
464
490
  "ArrayVariableValue",
465
491
  "ArrayVariableValueItem",
466
492
  "ArrayVellumValue",
@@ -497,10 +523,15 @@ __all__ = [
497
523
  "CodeExecutionNodeResultOutput",
498
524
  "CodeExecutionNodeSearchResultsResult",
499
525
  "CodeExecutionNodeStringResult",
526
+ "CodeExecutionPackageRequest",
527
+ "CodeExecutionRuntime",
528
+ "CodeExecutorInputRequest",
529
+ "CodeExecutorResponse",
500
530
  "CompilePromptDeploymentExpandMetaRequest",
501
531
  "CompilePromptMeta",
502
532
  "ComponentsSchemasPdfSearchResultMetaSource",
503
533
  "ComponentsSchemasPdfSearchResultMetaSourceRequest",
534
+ "ConditionCombinator",
504
535
  "ConditionalNodeResult",
505
536
  "ConditionalNodeResultData",
506
537
  "CreateTestSuiteTestCaseRequest",
@@ -524,6 +555,7 @@ __all__ = [
524
555
  "EnvironmentEnum",
525
556
  "EphemeralPromptCacheConfigRequest",
526
557
  "EphemeralPromptCacheConfigTypeEnum",
558
+ "ErrorInputRequest",
527
559
  "ErrorVariableValue",
528
560
  "ErrorVellumValue",
529
561
  "ErrorVellumValueRequest",
@@ -556,6 +588,7 @@ __all__ = [
556
588
  "FunctionCallChatMessageContentRequest",
557
589
  "FunctionCallChatMessageContentValue",
558
590
  "FunctionCallChatMessageContentValueRequest",
591
+ "FunctionCallInputRequest",
559
592
  "FunctionCallRequest",
560
593
  "FunctionCallVariableValue",
561
594
  "FunctionCallVellumValue",
@@ -571,6 +604,12 @@ __all__ = [
571
604
  "GenerateStreamResponse",
572
605
  "GenerateStreamResult",
573
606
  "GenerateStreamResultData",
607
+ "GoogleVertexAiVectorizerConfig",
608
+ "GoogleVertexAiVectorizerConfigRequest",
609
+ "GoogleVertexAiVectorizerTextEmbedding004",
610
+ "GoogleVertexAiVectorizerTextEmbedding004Request",
611
+ "GoogleVertexAiVectorizerTextMultilingualEmbedding002",
612
+ "GoogleVertexAiVectorizerTextMultilingualEmbedding002Request",
574
613
  "HkunlpInstructorXlVectorizer",
575
614
  "HkunlpInstructorXlVectorizerRequest",
576
615
  "ImageChatMessageContent",
@@ -604,6 +643,9 @@ __all__ = [
604
643
  "MetadataFilterConfigRequest",
605
644
  "MetadataFilterRuleCombinator",
606
645
  "MetadataFilterRuleRequest",
646
+ "MetadataFiltersRequest",
647
+ "MetricDefinitionExecution",
648
+ "MetricDefinitionInputRequest",
607
649
  "MetricNodeResult",
608
650
  "MlModelUsage",
609
651
  "NamedScenarioInputChatHistoryVariableValueRequest",
@@ -649,6 +691,7 @@ __all__ = [
649
691
  "NormalizedLogProbs",
650
692
  "NormalizedTokenLogProbs",
651
693
  "NotFoundError",
694
+ "NumberInputRequest",
652
695
  "NumberVariableValue",
653
696
  "NumberVellumValue",
654
697
  "NumberVellumValueRequest",
@@ -718,6 +761,7 @@ __all__ = [
718
761
  "SearchResultMeta",
719
762
  "SearchResultMetaRequest",
720
763
  "SearchResultRequest",
764
+ "SearchResultsInputRequest",
721
765
  "SearchResultsVariableValue",
722
766
  "SearchResultsVellumValue",
723
767
  "SearchResultsVellumValueRequest",
@@ -838,6 +882,11 @@ __all__ = [
838
882
  "VellumErrorRequest",
839
883
  "VellumImage",
840
884
  "VellumImageRequest",
885
+ "VellumValue",
886
+ "VellumValueLogicalConditionGroupRequest",
887
+ "VellumValueLogicalConditionRequest",
888
+ "VellumValueLogicalExpressionRequest",
889
+ "VellumValueRequest",
841
890
  "VellumVariable",
842
891
  "VellumVariableRequest",
843
892
  "VellumVariableType",
@@ -889,6 +938,7 @@ __all__ = [
889
938
  "document_indexes",
890
939
  "documents",
891
940
  "folder_entities",
941
+ "metric_definitions",
892
942
  "sandboxes",
893
943
  "test_suite_runs",
894
944
  "test_suites",
vellum/client.py CHANGED
@@ -9,24 +9,30 @@ from .resources.deployments.client import DeploymentsClient
9
9
  from .resources.document_indexes.client import DocumentIndexesClient
10
10
  from .resources.documents.client import DocumentsClient
11
11
  from .resources.folder_entities.client import FolderEntitiesClient
12
+ from .resources.metric_definitions.client import MetricDefinitionsClient
12
13
  from .resources.sandboxes.client import SandboxesClient
13
14
  from .resources.test_suite_runs.client import TestSuiteRunsClient
14
15
  from .resources.test_suites.client import TestSuitesClient
15
16
  from .resources.workflow_deployments.client import WorkflowDeploymentsClient
16
17
  from .resources.workflow_sandboxes.client import WorkflowSandboxesClient
17
- from .types.prompt_deployment_input_request import PromptDeploymentInputRequest
18
- from .types.prompt_deployment_expand_meta_request import PromptDeploymentExpandMetaRequest
19
- from .types.raw_prompt_execution_overrides_request import RawPromptExecutionOverridesRequest
18
+ from .types.code_execution_runtime import CodeExecutionRuntime
19
+ from .types.code_executor_input_request import CodeExecutorInputRequest
20
+ from .types.code_execution_package_request import CodeExecutionPackageRequest
21
+ from .types.vellum_variable_type import VellumVariableType
20
22
  from .core.request_options import RequestOptions
21
- from .types.execute_prompt_response import ExecutePromptResponse
23
+ from .types.code_executor_response import CodeExecutorResponse
22
24
  from .core.serialization import convert_and_respect_annotation_metadata
23
25
  from .core.pydantic_utilities import parse_obj_as
24
26
  from .errors.bad_request_error import BadRequestError
27
+ from json.decoder import JSONDecodeError
28
+ from .core.api_error import ApiError
29
+ from .types.prompt_deployment_input_request import PromptDeploymentInputRequest
30
+ from .types.prompt_deployment_expand_meta_request import PromptDeploymentExpandMetaRequest
31
+ from .types.raw_prompt_execution_overrides_request import RawPromptExecutionOverridesRequest
32
+ from .types.execute_prompt_response import ExecutePromptResponse
25
33
  from .errors.forbidden_error import ForbiddenError
26
34
  from .errors.not_found_error import NotFoundError
27
35
  from .errors.internal_server_error import InternalServerError
28
- from json.decoder import JSONDecodeError
29
- from .core.api_error import ApiError
30
36
  from .types.execute_prompt_event import ExecutePromptEvent
31
37
  import json
32
38
  from .types.workflow_request_input_request import WorkflowRequestInputRequest
@@ -48,6 +54,7 @@ from .resources.deployments.client import AsyncDeploymentsClient
48
54
  from .resources.document_indexes.client import AsyncDocumentIndexesClient
49
55
  from .resources.documents.client import AsyncDocumentsClient
50
56
  from .resources.folder_entities.client import AsyncFolderEntitiesClient
57
+ from .resources.metric_definitions.client import AsyncMetricDefinitionsClient
51
58
  from .resources.sandboxes.client import AsyncSandboxesClient
52
59
  from .resources.test_suite_runs.client import AsyncTestSuiteRunsClient
53
60
  from .resources.test_suites.client import AsyncTestSuitesClient
@@ -117,12 +124,113 @@ class Vellum:
117
124
  self.document_indexes = DocumentIndexesClient(client_wrapper=self._client_wrapper)
118
125
  self.documents = DocumentsClient(client_wrapper=self._client_wrapper)
119
126
  self.folder_entities = FolderEntitiesClient(client_wrapper=self._client_wrapper)
127
+ self.metric_definitions = MetricDefinitionsClient(client_wrapper=self._client_wrapper)
120
128
  self.sandboxes = SandboxesClient(client_wrapper=self._client_wrapper)
121
129
  self.test_suite_runs = TestSuiteRunsClient(client_wrapper=self._client_wrapper)
122
130
  self.test_suites = TestSuitesClient(client_wrapper=self._client_wrapper)
123
131
  self.workflow_deployments = WorkflowDeploymentsClient(client_wrapper=self._client_wrapper)
124
132
  self.workflow_sandboxes = WorkflowSandboxesClient(client_wrapper=self._client_wrapper)
125
133
 
134
+ def execute_code(
135
+ self,
136
+ *,
137
+ code: str,
138
+ runtime: CodeExecutionRuntime,
139
+ input_values: typing.Sequence[CodeExecutorInputRequest],
140
+ packages: typing.Sequence[CodeExecutionPackageRequest],
141
+ output_type: VellumVariableType,
142
+ request_options: typing.Optional[RequestOptions] = None,
143
+ ) -> CodeExecutorResponse:
144
+ """
145
+ An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
146
+
147
+ Parameters
148
+ ----------
149
+ code : str
150
+
151
+ runtime : CodeExecutionRuntime
152
+
153
+ input_values : typing.Sequence[CodeExecutorInputRequest]
154
+
155
+ packages : typing.Sequence[CodeExecutionPackageRequest]
156
+
157
+ output_type : VellumVariableType
158
+
159
+ request_options : typing.Optional[RequestOptions]
160
+ Request-specific configuration.
161
+
162
+ Returns
163
+ -------
164
+ CodeExecutorResponse
165
+
166
+
167
+ Examples
168
+ --------
169
+ from vellum import CodeExecutionPackageRequest, StringInputRequest, Vellum
170
+
171
+ client = Vellum(
172
+ api_key="YOUR_API_KEY",
173
+ )
174
+ client.execute_code(
175
+ code="code",
176
+ runtime="PYTHON_3_11_6",
177
+ input_values=[
178
+ StringInputRequest(
179
+ name="name",
180
+ value="value",
181
+ )
182
+ ],
183
+ packages=[
184
+ CodeExecutionPackageRequest(
185
+ version="version",
186
+ name="name",
187
+ )
188
+ ],
189
+ output_type="STRING",
190
+ )
191
+ """
192
+ _response = self._client_wrapper.httpx_client.request(
193
+ "v1/execute-code",
194
+ base_url=self._client_wrapper.get_environment().default,
195
+ method="POST",
196
+ json={
197
+ "code": code,
198
+ "runtime": runtime,
199
+ "input_values": convert_and_respect_annotation_metadata(
200
+ object_=input_values, annotation=typing.Sequence[CodeExecutorInputRequest], direction="write"
201
+ ),
202
+ "packages": convert_and_respect_annotation_metadata(
203
+ object_=packages, annotation=typing.Sequence[CodeExecutionPackageRequest], direction="write"
204
+ ),
205
+ "output_type": output_type,
206
+ },
207
+ request_options=request_options,
208
+ omit=OMIT,
209
+ )
210
+ try:
211
+ if 200 <= _response.status_code < 300:
212
+ return typing.cast(
213
+ CodeExecutorResponse,
214
+ parse_obj_as(
215
+ type_=CodeExecutorResponse, # type: ignore
216
+ object_=_response.json(),
217
+ ),
218
+ )
219
+ if _response.status_code == 400:
220
+ raise BadRequestError(
221
+ typing.cast(
222
+ typing.Optional[typing.Any],
223
+ parse_obj_as(
224
+ type_=typing.Optional[typing.Any], # type: ignore
225
+ object_=_response.json(),
226
+ ),
227
+ )
228
+ )
229
+ _response_json = _response.json()
230
+ except JSONDecodeError:
231
+ raise ApiError(status_code=_response.status_code, body=_response.text)
232
+ raise ApiError(status_code=_response.status_code, body=_response_json)
233
+
126
234
  def execute_prompt(
127
235
  self,
128
236
  *,
@@ -1332,12 +1440,121 @@ class AsyncVellum:
1332
1440
  self.document_indexes = AsyncDocumentIndexesClient(client_wrapper=self._client_wrapper)
1333
1441
  self.documents = AsyncDocumentsClient(client_wrapper=self._client_wrapper)
1334
1442
  self.folder_entities = AsyncFolderEntitiesClient(client_wrapper=self._client_wrapper)
1443
+ self.metric_definitions = AsyncMetricDefinitionsClient(client_wrapper=self._client_wrapper)
1335
1444
  self.sandboxes = AsyncSandboxesClient(client_wrapper=self._client_wrapper)
1336
1445
  self.test_suite_runs = AsyncTestSuiteRunsClient(client_wrapper=self._client_wrapper)
1337
1446
  self.test_suites = AsyncTestSuitesClient(client_wrapper=self._client_wrapper)
1338
1447
  self.workflow_deployments = AsyncWorkflowDeploymentsClient(client_wrapper=self._client_wrapper)
1339
1448
  self.workflow_sandboxes = AsyncWorkflowSandboxesClient(client_wrapper=self._client_wrapper)
1340
1449
 
1450
+ async def execute_code(
1451
+ self,
1452
+ *,
1453
+ code: str,
1454
+ runtime: CodeExecutionRuntime,
1455
+ input_values: typing.Sequence[CodeExecutorInputRequest],
1456
+ packages: typing.Sequence[CodeExecutionPackageRequest],
1457
+ output_type: VellumVariableType,
1458
+ request_options: typing.Optional[RequestOptions] = None,
1459
+ ) -> CodeExecutorResponse:
1460
+ """
1461
+ An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
1462
+
1463
+ Parameters
1464
+ ----------
1465
+ code : str
1466
+
1467
+ runtime : CodeExecutionRuntime
1468
+
1469
+ input_values : typing.Sequence[CodeExecutorInputRequest]
1470
+
1471
+ packages : typing.Sequence[CodeExecutionPackageRequest]
1472
+
1473
+ output_type : VellumVariableType
1474
+
1475
+ request_options : typing.Optional[RequestOptions]
1476
+ Request-specific configuration.
1477
+
1478
+ Returns
1479
+ -------
1480
+ CodeExecutorResponse
1481
+
1482
+
1483
+ Examples
1484
+ --------
1485
+ import asyncio
1486
+
1487
+ from vellum import AsyncVellum, CodeExecutionPackageRequest, StringInputRequest
1488
+
1489
+ client = AsyncVellum(
1490
+ api_key="YOUR_API_KEY",
1491
+ )
1492
+
1493
+
1494
+ async def main() -> None:
1495
+ await client.execute_code(
1496
+ code="code",
1497
+ runtime="PYTHON_3_11_6",
1498
+ input_values=[
1499
+ StringInputRequest(
1500
+ name="name",
1501
+ value="value",
1502
+ )
1503
+ ],
1504
+ packages=[
1505
+ CodeExecutionPackageRequest(
1506
+ version="version",
1507
+ name="name",
1508
+ )
1509
+ ],
1510
+ output_type="STRING",
1511
+ )
1512
+
1513
+
1514
+ asyncio.run(main())
1515
+ """
1516
+ _response = await self._client_wrapper.httpx_client.request(
1517
+ "v1/execute-code",
1518
+ base_url=self._client_wrapper.get_environment().default,
1519
+ method="POST",
1520
+ json={
1521
+ "code": code,
1522
+ "runtime": runtime,
1523
+ "input_values": convert_and_respect_annotation_metadata(
1524
+ object_=input_values, annotation=typing.Sequence[CodeExecutorInputRequest], direction="write"
1525
+ ),
1526
+ "packages": convert_and_respect_annotation_metadata(
1527
+ object_=packages, annotation=typing.Sequence[CodeExecutionPackageRequest], direction="write"
1528
+ ),
1529
+ "output_type": output_type,
1530
+ },
1531
+ request_options=request_options,
1532
+ omit=OMIT,
1533
+ )
1534
+ try:
1535
+ if 200 <= _response.status_code < 300:
1536
+ return typing.cast(
1537
+ CodeExecutorResponse,
1538
+ parse_obj_as(
1539
+ type_=CodeExecutorResponse, # type: ignore
1540
+ object_=_response.json(),
1541
+ ),
1542
+ )
1543
+ if _response.status_code == 400:
1544
+ raise BadRequestError(
1545
+ typing.cast(
1546
+ typing.Optional[typing.Any],
1547
+ parse_obj_as(
1548
+ type_=typing.Optional[typing.Any], # type: ignore
1549
+ object_=_response.json(),
1550
+ ),
1551
+ )
1552
+ )
1553
+ _response_json = _response.json()
1554
+ except JSONDecodeError:
1555
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1556
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1557
+
1341
1558
  async def execute_prompt(
1342
1559
  self,
1343
1560
  *,
@@ -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.15",
20
+ "X-Fern-SDK-Version": "0.8.17",
21
21
  }
22
22
  headers["X_API_KEY"] = self.api_key
23
23
  return headers
@@ -40,7 +40,7 @@ class SyncClientWrapper(BaseClientWrapper):
40
40
  ):
41
41
  super().__init__(api_key=api_key, environment=environment, timeout=timeout)
42
42
  self.httpx_client = HttpClient(
43
- httpx_client=httpx_client, base_headers=self.get_headers(), base_timeout=self.get_timeout()
43
+ httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout
44
44
  )
45
45
 
46
46
 
@@ -55,5 +55,5 @@ class AsyncClientWrapper(BaseClientWrapper):
55
55
  ):
56
56
  super().__init__(api_key=api_key, environment=environment, timeout=timeout)
57
57
  self.httpx_client = AsyncHttpClient(
58
- httpx_client=httpx_client, base_headers=self.get_headers(), base_timeout=self.get_timeout()
58
+ httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout
59
59
  )
@@ -152,9 +152,9 @@ class HttpClient:
152
152
  self,
153
153
  *,
154
154
  httpx_client: httpx.Client,
155
- base_timeout: typing.Optional[float],
156
- base_headers: typing.Dict[str, str],
157
- base_url: typing.Optional[str] = None,
155
+ base_timeout: typing.Callable[[], typing.Optional[float]],
156
+ base_headers: typing.Callable[[], typing.Dict[str, str]],
157
+ base_url: typing.Optional[typing.Callable[[], str]] = None,
158
158
  ):
159
159
  self.base_url = base_url
160
160
  self.base_timeout = base_timeout
@@ -162,7 +162,10 @@ class HttpClient:
162
162
  self.httpx_client = httpx_client
163
163
 
164
164
  def get_base_url(self, maybe_base_url: typing.Optional[str]) -> str:
165
- base_url = self.base_url if maybe_base_url is None else maybe_base_url
165
+ base_url = maybe_base_url
166
+ if self.base_url is not None and base_url is None:
167
+ base_url = self.base_url()
168
+
166
169
  if base_url is None:
167
170
  raise ValueError("A base_url is required to make this request, please provide one and try again.")
168
171
  return base_url
@@ -187,7 +190,7 @@ class HttpClient:
187
190
  timeout = (
188
191
  request_options.get("timeout_in_seconds")
189
192
  if request_options is not None and request_options.get("timeout_in_seconds") is not None
190
- else self.base_timeout
193
+ else self.base_timeout()
191
194
  )
192
195
 
193
196
  json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
@@ -198,7 +201,7 @@ class HttpClient:
198
201
  headers=jsonable_encoder(
199
202
  remove_none_from_dict(
200
203
  {
201
- **self.base_headers,
204
+ **self.base_headers(),
202
205
  **(headers if headers is not None else {}),
203
206
  **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}),
204
207
  }
@@ -271,7 +274,7 @@ class HttpClient:
271
274
  timeout = (
272
275
  request_options.get("timeout_in_seconds")
273
276
  if request_options is not None and request_options.get("timeout_in_seconds") is not None
274
- else self.base_timeout
277
+ else self.base_timeout()
275
278
  )
276
279
 
277
280
  json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
@@ -282,7 +285,7 @@ class HttpClient:
282
285
  headers=jsonable_encoder(
283
286
  remove_none_from_dict(
284
287
  {
285
- **self.base_headers,
288
+ **self.base_headers(),
286
289
  **(headers if headers is not None else {}),
287
290
  **(request_options.get("additional_headers", {}) if request_options is not None else {}),
288
291
  }
@@ -321,9 +324,9 @@ class AsyncHttpClient:
321
324
  self,
322
325
  *,
323
326
  httpx_client: httpx.AsyncClient,
324
- base_timeout: typing.Optional[float],
325
- base_headers: typing.Dict[str, str],
326
- base_url: typing.Optional[str] = None,
327
+ base_timeout: typing.Callable[[], typing.Optional[float]],
328
+ base_headers: typing.Callable[[], typing.Dict[str, str]],
329
+ base_url: typing.Optional[typing.Callable[[], str]] = None,
327
330
  ):
328
331
  self.base_url = base_url
329
332
  self.base_timeout = base_timeout
@@ -331,7 +334,10 @@ class AsyncHttpClient:
331
334
  self.httpx_client = httpx_client
332
335
 
333
336
  def get_base_url(self, maybe_base_url: typing.Optional[str]) -> str:
334
- base_url = self.base_url if maybe_base_url is None else maybe_base_url
337
+ base_url = maybe_base_url
338
+ if self.base_url is not None and base_url is None:
339
+ base_url = self.base_url()
340
+
335
341
  if base_url is None:
336
342
  raise ValueError("A base_url is required to make this request, please provide one and try again.")
337
343
  return base_url
@@ -356,7 +362,7 @@ class AsyncHttpClient:
356
362
  timeout = (
357
363
  request_options.get("timeout_in_seconds")
358
364
  if request_options is not None and request_options.get("timeout_in_seconds") is not None
359
- else self.base_timeout
365
+ else self.base_timeout()
360
366
  )
361
367
 
362
368
  json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
@@ -368,7 +374,7 @@ class AsyncHttpClient:
368
374
  headers=jsonable_encoder(
369
375
  remove_none_from_dict(
370
376
  {
371
- **self.base_headers,
377
+ **self.base_headers(),
372
378
  **(headers if headers is not None else {}),
373
379
  **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}),
374
380
  }
@@ -438,7 +444,7 @@ class AsyncHttpClient:
438
444
  timeout = (
439
445
  request_options.get("timeout_in_seconds")
440
446
  if request_options is not None and request_options.get("timeout_in_seconds") is not None
441
- else self.base_timeout
447
+ else self.base_timeout()
442
448
  )
443
449
 
444
450
  json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
@@ -449,7 +455,7 @@ class AsyncHttpClient:
449
455
  headers=jsonable_encoder(
450
456
  remove_none_from_dict(
451
457
  {
452
- **self.base_headers,
458
+ **self.base_headers(),
453
459
  **(headers if headers is not None else {}),
454
460
  **(request_options.get("additional_headers", {}) if request_options is not None else {}),
455
461
  }
@@ -152,7 +152,7 @@ class UniversalBaseModel(pydantic.BaseModel):
152
152
  )
153
153
 
154
154
  else:
155
- _fields_set = self.__fields_set__
155
+ _fields_set = self.__fields_set__.copy()
156
156
 
157
157
  fields = _get_model_fields(self.__class__)
158
158
  for name, field in fields.items():
@@ -162,9 +162,12 @@ class UniversalBaseModel(pydantic.BaseModel):
162
162
  # If the default values are non-null act like they've been set
163
163
  # This effectively allows exclude_unset to work like exclude_none where
164
164
  # the latter passes through intentionally set none values.
165
- if default != None:
165
+ if default is not None or ("exclude_unset" in kwargs and not kwargs["exclude_unset"]):
166
166
  _fields_set.add(name)
167
167
 
168
+ if default is not None:
169
+ self.__fields_set__.add(name)
170
+
168
171
  kwargs_with_defaults_exclude_unset_include_fields: typing.Any = {
169
172
  "by_alias": True,
170
173
  "exclude_unset": True,
@@ -177,13 +180,33 @@ class UniversalBaseModel(pydantic.BaseModel):
177
180
  return convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write")
178
181
 
179
182
 
183
+ def _union_list_of_pydantic_dicts(
184
+ source: typing.List[typing.Any], destination: typing.List[typing.Any]
185
+ ) -> typing.List[typing.Any]:
186
+ converted_list: typing.List[typing.Any] = []
187
+ for i, item in enumerate(source):
188
+ destination_value = destination[i] # type: ignore
189
+ if isinstance(item, dict):
190
+ converted_list.append(deep_union_pydantic_dicts(item, destination_value))
191
+ elif isinstance(item, list):
192
+ converted_list.append(_union_list_of_pydantic_dicts(item, destination_value))
193
+ else:
194
+ converted_list.append(item)
195
+ return converted_list
196
+
197
+
180
198
  def deep_union_pydantic_dicts(
181
199
  source: typing.Dict[str, typing.Any], destination: typing.Dict[str, typing.Any]
182
200
  ) -> typing.Dict[str, typing.Any]:
183
201
  for key, value in source.items():
202
+ node = destination.setdefault(key, {})
184
203
  if isinstance(value, dict):
185
- node = destination.setdefault(key, {})
186
204
  deep_union_pydantic_dicts(value, node)
205
+ # Note: we do not do this same processing for sets given we do not have sets of models
206
+ # and given the sets are unordered, the processing of the set and matching objects would
207
+ # be non-trivial.
208
+ elif isinstance(value, list):
209
+ destination[key] = _union_list_of_pydantic_dicts(value, node)
187
210
  else:
188
211
  destination[key] = value
189
212
 
@@ -6,6 +6,7 @@ from . import (
6
6
  document_indexes,
7
7
  documents,
8
8
  folder_entities,
9
+ metric_definitions,
9
10
  sandboxes,
10
11
  test_suite_runs,
11
12
  test_suites,
@@ -25,6 +26,7 @@ __all__ = [
25
26
  "document_indexes",
26
27
  "documents",
27
28
  "folder_entities",
29
+ "metric_definitions",
28
30
  "sandboxes",
29
31
  "test_suite_runs",
30
32
  "test_suites",