vellum-ai 0.8.15__py3-none-any.whl → 0.8.17__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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",