vellum-ai 0.14.3__py3-none-any.whl → 0.14.5__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/core/client_wrapper.py +1 -1
- vellum/client/resources/document_indexes/client.py +4 -4
- vellum/client/resources/documents/client.py +0 -2
- vellum/client/resources/folder_entities/client.py +4 -8
- vellum/client/resources/test_suite_runs/client.py +0 -2
- vellum/client/types/deployment_read.py +5 -5
- vellum/client/types/deployment_release_tag_read.py +2 -2
- vellum/client/types/document_document_to_document_index.py +5 -5
- vellum/client/types/document_index_read.py +5 -5
- vellum/client/types/document_read.py +1 -1
- vellum/client/types/enriched_normalized_completion.py +3 -3
- vellum/client/types/generate_options_request.py +2 -2
- vellum/client/types/slim_deployment_read.py +5 -5
- vellum/client/types/slim_document.py +3 -3
- vellum/client/types/slim_document_document_to_document_index.py +5 -5
- vellum/client/types/slim_workflow_deployment.py +5 -5
- vellum/client/types/test_suite_run_read.py +5 -5
- vellum/client/types/workflow_deployment_read.py +5 -5
- vellum/client/types/workflow_release_tag_read.py +2 -2
- vellum/workflows/constants.py +9 -0
- vellum/workflows/context.py +8 -3
- vellum/workflows/nodes/core/map_node/node.py +1 -1
- vellum/workflows/nodes/core/retry_node/node.py +4 -3
- vellum/workflows/nodes/core/try_node/node.py +1 -1
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +5 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +81 -1
- vellum/workflows/nodes/displayable/code_execution_node/utils.py +44 -20
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +17 -10
- vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +1 -0
- vellum/workflows/tests/test_undefined.py +12 -0
- vellum/workflows/workflows/base.py +76 -0
- vellum/workflows/workflows/tests/test_base_workflow.py +135 -0
- vellum/workflows/workflows/tests/test_context.py +60 -0
- {vellum_ai-0.14.3.dist-info → vellum_ai-0.14.5.dist-info}/METADATA +1 -1
- {vellum_ai-0.14.3.dist-info → vellum_ai-0.14.5.dist-info}/RECORD +47 -44
- vellum_ee/workflows/display/nodes/__init__.py +4 -0
- vellum_ee/workflows/display/nodes/vellum/__init__.py +2 -0
- vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py +39 -0
- vellum_ee/workflows/display/nodes/vellum/map_node.py +2 -2
- vellum_ee/workflows/display/nodes/vellum/retry_node.py +36 -4
- vellum_ee/workflows/display/nodes/vellum/try_node.py +43 -29
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +25 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +14 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +19 -1
- {vellum_ai-0.14.3.dist-info → vellum_ai-0.14.5.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.3.dist-info → vellum_ai-0.14.5.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.3.dist-info → vellum_ai-0.14.5.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@ class BaseClientWrapper:
|
|
18
18
|
headers: typing.Dict[str, str] = {
|
19
19
|
"X-Fern-Language": "Python",
|
20
20
|
"X-Fern-SDK-Name": "vellum-ai",
|
21
|
-
"X-Fern-SDK-Version": "0.14.
|
21
|
+
"X-Fern-SDK-Version": "0.14.5",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
@@ -54,8 +54,8 @@ class DocumentIndexesClient:
|
|
54
54
|
status : typing.Optional[DocumentIndexesListRequestStatus]
|
55
55
|
Filter down to only document indices that have a status matching the status specified
|
56
56
|
|
57
|
-
|
58
|
-
|
57
|
+
* `ACTIVE` - Active
|
58
|
+
* `ARCHIVED` - Archived
|
59
59
|
|
60
60
|
request_options : typing.Optional[RequestOptions]
|
61
61
|
Request-specific configuration.
|
@@ -589,8 +589,8 @@ class AsyncDocumentIndexesClient:
|
|
589
589
|
status : typing.Optional[DocumentIndexesListRequestStatus]
|
590
590
|
Filter down to only document indices that have a status matching the status specified
|
591
591
|
|
592
|
-
|
593
|
-
|
592
|
+
* `ACTIVE` - Active
|
593
|
+
* `ARCHIVED` - Archived
|
594
594
|
|
595
595
|
request_options : typing.Optional[RequestOptions]
|
596
596
|
Request-specific configuration.
|
@@ -278,7 +278,6 @@ class DocumentsClient:
|
|
278
278
|
**Note:** Uses a base url of `https://documents.vellum.ai`.
|
279
279
|
|
280
280
|
This is a multipart/form-data request. The `contents` field should be a file upload. It also expects a JSON body with the following fields:
|
281
|
-
|
282
281
|
- `add_to_index_names: list[str]` - Optionally include the names of all indexes that you'd like this document to be included in
|
283
282
|
- `external_id: str | None` - Optionally include an external ID for this document. This is useful if you want to re-upload the same document later when its contents change and would like it to be re-indexed.
|
284
283
|
- `label: str` - A human-friendly name for this document. Typically the filename.
|
@@ -675,7 +674,6 @@ class AsyncDocumentsClient:
|
|
675
674
|
**Note:** Uses a base url of `https://documents.vellum.ai`.
|
676
675
|
|
677
676
|
This is a multipart/form-data request. The `contents` field should be a file upload. It also expects a JSON body with the following fields:
|
678
|
-
|
679
677
|
- `add_to_index_names: list[str]` - Optionally include the names of all indexes that you'd like this document to be included in
|
680
678
|
- `external_id: str | None` - Optionally include an external ID for this document. This is useful if you want to re-upload the same document later when its contents change and would like it to be re-indexed.
|
681
679
|
- `label: str` - A human-friendly name for this document. Typically the filename.
|
@@ -39,7 +39,6 @@ class FolderEntitiesClient:
|
|
39
39
|
|
40
40
|
To filter by an entity's parent folder, provide the ID of the parent folder. To filter by the root directory, provide
|
41
41
|
a string representing the entity type of the root directory. Supported root directories include:
|
42
|
-
|
43
42
|
- PROMPT_SANDBOX
|
44
43
|
- WORKFLOW_SANDBOX
|
45
44
|
- DOCUMENT_INDEX
|
@@ -48,8 +47,8 @@ class FolderEntitiesClient:
|
|
48
47
|
entity_status : typing.Optional[FolderEntitiesListRequestEntityStatus]
|
49
48
|
Filter down to only those objects whose entities have a status matching the status specified.
|
50
49
|
|
51
|
-
|
52
|
-
|
50
|
+
* `ACTIVE` - Active
|
51
|
+
* `ARCHIVED` - Archived
|
53
52
|
|
54
53
|
limit : typing.Optional[int]
|
55
54
|
Number of results to return per page.
|
@@ -119,7 +118,6 @@ class FolderEntitiesClient:
|
|
119
118
|
folder_id : str
|
120
119
|
The ID of the folder to which the entity should be added. This can be a UUID of a folder, or the name of a root
|
121
120
|
directory. Supported root directories include:
|
122
|
-
|
123
121
|
- PROMPT_SANDBOX
|
124
122
|
- WORKFLOW_SANDBOX
|
125
123
|
- DOCUMENT_INDEX
|
@@ -190,7 +188,6 @@ class AsyncFolderEntitiesClient:
|
|
190
188
|
|
191
189
|
To filter by an entity's parent folder, provide the ID of the parent folder. To filter by the root directory, provide
|
192
190
|
a string representing the entity type of the root directory. Supported root directories include:
|
193
|
-
|
194
191
|
- PROMPT_SANDBOX
|
195
192
|
- WORKFLOW_SANDBOX
|
196
193
|
- DOCUMENT_INDEX
|
@@ -199,8 +196,8 @@ class AsyncFolderEntitiesClient:
|
|
199
196
|
entity_status : typing.Optional[FolderEntitiesListRequestEntityStatus]
|
200
197
|
Filter down to only those objects whose entities have a status matching the status specified.
|
201
198
|
|
202
|
-
|
203
|
-
|
199
|
+
* `ACTIVE` - Active
|
200
|
+
* `ARCHIVED` - Archived
|
204
201
|
|
205
202
|
limit : typing.Optional[int]
|
206
203
|
Number of results to return per page.
|
@@ -278,7 +275,6 @@ class AsyncFolderEntitiesClient:
|
|
278
275
|
folder_id : str
|
279
276
|
The ID of the folder to which the entity should be added. This can be a UUID of a folder, or the name of a root
|
280
277
|
directory. Supported root directories include:
|
281
|
-
|
282
278
|
- PROMPT_SANDBOX
|
283
279
|
- WORKFLOW_SANDBOX
|
284
280
|
- DOCUMENT_INDEX
|
@@ -163,7 +163,6 @@ class TestSuiteRunsClient:
|
|
163
163
|
|
164
164
|
expand : typing.Optional[typing.Union[str, typing.Sequence[str]]]
|
165
165
|
The response fields to expand for more information.
|
166
|
-
|
167
166
|
- 'results.metric_results.metric_label' expands the metric label for each metric result.
|
168
167
|
- 'results.metric_results.metric_definition' expands the metric definition for each metric result.
|
169
168
|
- 'results.metric_results.metric_definition.name' expands the metric definition name for each metric result.
|
@@ -381,7 +380,6 @@ class AsyncTestSuiteRunsClient:
|
|
381
380
|
|
382
381
|
expand : typing.Optional[typing.Union[str, typing.Sequence[str]]]
|
383
382
|
The response fields to expand for more information.
|
384
|
-
|
385
383
|
- 'results.metric_results.metric_label' expands the metric label for each metric result.
|
386
384
|
- 'results.metric_results.metric_definition' expands the metric definition for each metric result.
|
387
385
|
- 'results.metric_results.metric_definition.name' expands the metric definition name for each metric result.
|
@@ -30,17 +30,17 @@ class DeploymentRead(UniversalBaseModel):
|
|
30
30
|
"""
|
31
31
|
The current status of the deployment
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
* `ACTIVE` - Active
|
34
|
+
* `ARCHIVED` - Archived
|
35
35
|
"""
|
36
36
|
|
37
37
|
environment: typing.Optional[EnvironmentEnum] = pydantic.Field(default=None)
|
38
38
|
"""
|
39
39
|
The environment this deployment is used in
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
* `DEVELOPMENT` - Development
|
42
|
+
* `STAGING` - Staging
|
43
|
+
* `PRODUCTION` - Production
|
44
44
|
"""
|
45
45
|
|
46
46
|
last_deployed_on: dt.datetime
|
@@ -18,8 +18,8 @@ class DeploymentReleaseTagRead(UniversalBaseModel):
|
|
18
18
|
"""
|
19
19
|
The source of how the Release Tag was originally created
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
* `SYSTEM` - System
|
22
|
+
* `USER` - User
|
23
23
|
"""
|
24
24
|
|
25
25
|
history_item: DeploymentReleaseTagDeploymentHistoryItem = pydantic.Field()
|
@@ -26,11 +26,11 @@ class DocumentDocumentToDocumentIndex(UniversalBaseModel):
|
|
26
26
|
"""
|
27
27
|
An enum value representing where this document is along its indexing lifecycle for this index.
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
* `AWAITING_PROCESSING` - Awaiting Processing
|
30
|
+
* `QUEUED` - Queued
|
31
|
+
* `INDEXING` - Indexing
|
32
|
+
* `INDEXED` - Indexed
|
33
|
+
* `FAILED` - Failed
|
34
34
|
"""
|
35
35
|
|
36
36
|
extracted_text_file_url: typing.Optional[str] = None
|
@@ -27,17 +27,17 @@ class DocumentIndexRead(UniversalBaseModel):
|
|
27
27
|
"""
|
28
28
|
The current status of the document index
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
* `ACTIVE` - Active
|
31
|
+
* `ARCHIVED` - Archived
|
32
32
|
"""
|
33
33
|
|
34
34
|
environment: typing.Optional[EnvironmentEnum] = pydantic.Field(default=None)
|
35
35
|
"""
|
36
36
|
The environment this document index is used in
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
* `DEVELOPMENT` - Development
|
39
|
+
* `STAGING` - Staging
|
40
|
+
* `PRODUCTION` - Production
|
41
41
|
"""
|
42
42
|
|
43
43
|
indexing_config: DocumentIndexIndexingConfig
|
@@ -29,9 +29,9 @@ class EnrichedNormalizedCompletion(UniversalBaseModel):
|
|
29
29
|
"""
|
30
30
|
The reason the generation finished.
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
* `LENGTH` - LENGTH
|
33
|
+
* `STOP` - STOP
|
34
|
+
* `UNKNOWN` - UNKNOWN
|
35
35
|
"""
|
36
36
|
|
37
37
|
logprobs: typing.Optional[NormalizedLogProbs] = pydantic.Field(default=None)
|
@@ -30,17 +30,17 @@ class SlimDeploymentRead(UniversalBaseModel):
|
|
30
30
|
"""
|
31
31
|
The current status of the deployment
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
* `ACTIVE` - Active
|
34
|
+
* `ARCHIVED` - Archived
|
35
35
|
"""
|
36
36
|
|
37
37
|
environment: typing.Optional[EnvironmentEnum] = pydantic.Field(default=None)
|
38
38
|
"""
|
39
39
|
The environment this deployment is used in
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
* `DEVELOPMENT` - Development
|
42
|
+
* `STAGING` - Staging
|
43
|
+
* `PRODUCTION` - Production
|
44
44
|
"""
|
45
45
|
|
46
46
|
last_deployed_on: dt.datetime
|
@@ -37,15 +37,15 @@ class SlimDocument(UniversalBaseModel):
|
|
37
37
|
"""
|
38
38
|
An enum value representing why the document could not be processed. Is null unless processing_state is FAILED.
|
39
39
|
|
40
|
-
|
41
|
-
|
40
|
+
* `EXCEEDED_CHARACTER_LIMIT` - Exceeded Character Limit
|
41
|
+
* `INVALID_FILE` - Invalid File
|
42
42
|
"""
|
43
43
|
|
44
44
|
status: typing.Optional[DocumentStatus] = pydantic.Field(default=None)
|
45
45
|
"""
|
46
46
|
The document's current status.
|
47
47
|
|
48
|
-
|
48
|
+
* `ACTIVE` - Active
|
49
49
|
"""
|
50
50
|
|
51
51
|
keywords: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
|
@@ -26,11 +26,11 @@ class SlimDocumentDocumentToDocumentIndex(UniversalBaseModel):
|
|
26
26
|
"""
|
27
27
|
An enum value representing where this document is along its indexing lifecycle for this index.
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
* `AWAITING_PROCESSING` - Awaiting Processing
|
30
|
+
* `QUEUED` - Queued
|
31
|
+
* `INDEXING` - Indexing
|
32
|
+
* `INDEXED` - Indexed
|
33
|
+
* `FAILED` - Failed
|
34
34
|
"""
|
35
35
|
|
36
36
|
if IS_PYDANTIC_V2:
|
@@ -29,17 +29,17 @@ class SlimWorkflowDeployment(UniversalBaseModel):
|
|
29
29
|
"""
|
30
30
|
The current status of the workflow deployment
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
* `ACTIVE` - Active
|
33
|
+
* `ARCHIVED` - Archived
|
34
34
|
"""
|
35
35
|
|
36
36
|
environment: typing.Optional[EnvironmentEnum] = pydantic.Field(default=None)
|
37
37
|
"""
|
38
38
|
The environment this workflow deployment is used in
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
* `DEVELOPMENT` - Development
|
41
|
+
* `STAGING` - Staging
|
42
|
+
* `PRODUCTION` - Production
|
43
43
|
"""
|
44
44
|
|
45
45
|
created: dt.datetime
|
@@ -21,11 +21,11 @@ class TestSuiteRunRead(UniversalBaseModel):
|
|
21
21
|
"""
|
22
22
|
The current state of this run
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
* `QUEUED` - Queued
|
25
|
+
* `RUNNING` - Running
|
26
|
+
* `COMPLETE` - Complete
|
27
|
+
* `FAILED` - Failed
|
28
|
+
* `CANCELLED` - Cancelled
|
29
29
|
"""
|
30
30
|
|
31
31
|
exec_config: typing.Optional[TestSuiteRunExecConfig] = pydantic.Field(default=None)
|
@@ -29,17 +29,17 @@ class WorkflowDeploymentRead(UniversalBaseModel):
|
|
29
29
|
"""
|
30
30
|
The current status of the workflow deployment
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
* `ACTIVE` - Active
|
33
|
+
* `ARCHIVED` - Archived
|
34
34
|
"""
|
35
35
|
|
36
36
|
environment: typing.Optional[EnvironmentEnum] = pydantic.Field(default=None)
|
37
37
|
"""
|
38
38
|
The environment this workflow deployment is used in
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
* `DEVELOPMENT` - Development
|
41
|
+
* `STAGING` - Staging
|
42
|
+
* `PRODUCTION` - Production
|
43
43
|
"""
|
44
44
|
|
45
45
|
created: dt.datetime
|
@@ -18,8 +18,8 @@ class WorkflowReleaseTagRead(UniversalBaseModel):
|
|
18
18
|
"""
|
19
19
|
The source of how the Release Tag was originally created
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
* `SYSTEM` - System
|
22
|
+
* `USER` - User
|
23
23
|
"""
|
24
24
|
|
25
25
|
history_item: WorkflowReleaseTagWorkflowDeploymentHistoryItem = pydantic.Field()
|
vellum/workflows/constants.py
CHANGED
@@ -3,6 +3,15 @@ from typing import Any, cast
|
|
3
3
|
|
4
4
|
|
5
5
|
class _UndefMeta(type):
|
6
|
+
def __new__(cls, name: str, bases: tuple[type, ...], attrs: dict[str, Any]) -> type:
|
7
|
+
cls.__name__ = "undefined"
|
8
|
+
cls.__qualname__ = "undefined"
|
9
|
+
|
10
|
+
undefined_class = super().__new__(cls, name, bases, attrs)
|
11
|
+
undefined_class.__name__ = "undefined"
|
12
|
+
undefined_class.__qualname__ = "undefined"
|
13
|
+
return undefined_class
|
14
|
+
|
6
15
|
def __repr__(cls) -> str:
|
7
16
|
return "undefined"
|
8
17
|
|
vellum/workflows/context.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from contextlib import contextmanager
|
2
2
|
import threading
|
3
|
+
from uuid import UUID
|
3
4
|
from typing import Iterator, Optional, cast
|
4
5
|
|
5
6
|
from vellum.client.core import UniversalBaseModel
|
@@ -8,6 +9,7 @@ from vellum.workflows.events.types import ParentContext
|
|
8
9
|
|
9
10
|
class ExecutionContext(UniversalBaseModel):
|
10
11
|
parent_context: Optional[ParentContext] = None
|
12
|
+
trace_id: Optional[UUID] = None
|
11
13
|
|
12
14
|
|
13
15
|
_CONTEXT_KEY = "_execution_context"
|
@@ -30,11 +32,14 @@ def get_parent_context() -> ParentContext:
|
|
30
32
|
|
31
33
|
|
32
34
|
@contextmanager
|
33
|
-
def execution_context(
|
35
|
+
def execution_context(
|
36
|
+
parent_context: Optional[ParentContext] = None, trace_id: Optional[UUID] = None
|
37
|
+
) -> Iterator[None]:
|
34
38
|
"""Context manager for handling execution context."""
|
35
39
|
prev_context = get_execution_context()
|
36
|
-
|
37
|
-
|
40
|
+
set_trace_id = prev_context.trace_id or trace_id
|
41
|
+
set_parent_context = parent_context or prev_context.parent_context
|
42
|
+
set_context = ExecutionContext(parent_context=set_parent_context, trace_id=set_trace_id)
|
38
43
|
try:
|
39
44
|
set_execution_context(set_context)
|
40
45
|
yield
|
@@ -42,8 +42,8 @@ class MapNode(BaseAdornmentNode[StateType], Generic[StateType, MapNodeItemType])
|
|
42
42
|
Used to map over a list of items and execute a Subworkflow on each iteration.
|
43
43
|
|
44
44
|
items: List[MapNodeItemType] - The items to map over
|
45
|
-
subworkflow: Type["BaseWorkflow[SubworkflowInputs, BaseState]"] - The Subworkflow to execute on each iteration
|
46
45
|
max_concurrency: Optional[int] = None - The maximum number of concurrent subworkflow executions
|
46
|
+
subworkflow: Type["BaseWorkflow"] - The Subworkflow to execute
|
47
47
|
"""
|
48
48
|
|
49
49
|
items: List[MapNodeItemType]
|
@@ -18,9 +18,10 @@ class RetryNode(BaseAdornmentNode[StateType], Generic[StateType]):
|
|
18
18
|
Used to retry a Subworkflow a specified number of times.
|
19
19
|
|
20
20
|
max_attempts: int - The maximum number of attempts to retry the Subworkflow
|
21
|
-
delay: float - The number of seconds to wait between retries
|
22
|
-
retry_on_error_code: Optional[
|
23
|
-
|
21
|
+
delay: float = None - The number of seconds to wait between retries
|
22
|
+
retry_on_error_code: Optional[WorkflowErrorCode] = None - The error code to retry on
|
23
|
+
retry_on_condition: Optional[BaseDescriptor] = None - The condition to retry on
|
24
|
+
subworkflow: Type["BaseWorkflow"] - The Subworkflow to execute
|
24
25
|
"""
|
25
26
|
|
26
27
|
max_attempts: int
|
@@ -17,7 +17,7 @@ class TryNode(BaseAdornmentNode[StateType], Generic[StateType]):
|
|
17
17
|
"""
|
18
18
|
Used to execute a Subworkflow and handle errors.
|
19
19
|
|
20
|
-
on_error_code: Optional[
|
20
|
+
on_error_code: Optional[WorkflowErrorCode] = None - The error code to handle
|
21
21
|
subworkflow: Type["BaseWorkflow"] - The Subworkflow to execute
|
22
22
|
"""
|
23
23
|
|
@@ -17,6 +17,7 @@ from vellum import (
|
|
17
17
|
)
|
18
18
|
from vellum.client import RequestOptions
|
19
19
|
from vellum.client.types.chat_message_request import ChatMessageRequest
|
20
|
+
from vellum.client.types.prompt_settings import PromptSettings
|
20
21
|
from vellum.workflows.constants import OMIT
|
21
22
|
from vellum.workflows.context import get_parent_context
|
22
23
|
from vellum.workflows.errors import WorkflowErrorCode
|
@@ -53,6 +54,8 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
53
54
|
parameters: PromptParameters = DEFAULT_PROMPT_PARAMETERS
|
54
55
|
expand_meta: Optional[AdHocExpandMeta] = OMIT
|
55
56
|
|
57
|
+
settings: Optional[PromptSettings] = None
|
58
|
+
|
56
59
|
class Trigger(BasePromptNode.Trigger):
|
57
60
|
merge_behavior = MergeBehavior.AWAIT_ANY
|
58
61
|
|
@@ -60,6 +63,7 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
60
63
|
input_variables, input_values = self._compile_prompt_inputs()
|
61
64
|
parent_context = get_parent_context()
|
62
65
|
request_options = self.request_options or RequestOptions()
|
66
|
+
|
63
67
|
request_options["additional_body_parameters"] = {
|
64
68
|
"execution_context": {"parent_context": parent_context},
|
65
69
|
**request_options.get("additional_body_parameters", {}),
|
@@ -79,6 +83,7 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
79
83
|
input_variables=input_variables,
|
80
84
|
parameters=self.parameters,
|
81
85
|
blocks=self.blocks,
|
86
|
+
settings=self.settings,
|
82
87
|
functions=normalized_functions,
|
83
88
|
expand_meta=self.expand_meta,
|
84
89
|
request_options=request_options,
|
@@ -1,12 +1,16 @@
|
|
1
1
|
import pytest
|
2
2
|
import os
|
3
|
-
from typing import Any, Union
|
3
|
+
from typing import Any, List, Union
|
4
|
+
|
5
|
+
from pydantic import BaseModel
|
4
6
|
|
5
7
|
from vellum import CodeExecutorResponse, NumberVellumValue, StringInput, StringVellumValue
|
8
|
+
from vellum.client.types.chat_message import ChatMessage
|
6
9
|
from vellum.client.types.code_execution_package import CodeExecutionPackage
|
7
10
|
from vellum.client.types.code_executor_secret_input import CodeExecutorSecretInput
|
8
11
|
from vellum.client.types.function_call import FunctionCall
|
9
12
|
from vellum.client.types.number_input import NumberInput
|
13
|
+
from vellum.client.types.string_chat_message_content import StringChatMessageContent
|
10
14
|
from vellum.workflows.errors import WorkflowErrorCode
|
11
15
|
from vellum.workflows.exceptions import NodeException
|
12
16
|
from vellum.workflows.inputs.base import BaseInputs
|
@@ -610,3 +614,79 @@ def main(arg1: list[bool]) -> int:
|
|
610
614
|
|
611
615
|
# AND the error should contain the execution error details
|
612
616
|
assert outputs == {"result": 3, "log": ""}
|
617
|
+
|
618
|
+
|
619
|
+
def test_run_node__union_output_type__pydantic_children():
|
620
|
+
# GIVEN a node that is a union type with a pydantic child
|
621
|
+
class OptionOne(BaseModel):
|
622
|
+
foo: str
|
623
|
+
|
624
|
+
class OptionTwo(BaseModel):
|
625
|
+
bar: int
|
626
|
+
|
627
|
+
class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, Union[OptionOne, OptionTwo]]):
|
628
|
+
code = """\
|
629
|
+
def main():
|
630
|
+
return { "foo": "hello" }
|
631
|
+
"""
|
632
|
+
runtime = "PYTHON_3_11_6"
|
633
|
+
code_inputs = {}
|
634
|
+
|
635
|
+
# WHEN we run the node
|
636
|
+
node = ExampleCodeExecutionNode()
|
637
|
+
|
638
|
+
# THEN it should run successfully
|
639
|
+
outputs = node.run()
|
640
|
+
|
641
|
+
# AND the result should be the correct type
|
642
|
+
assert outputs == {"result": OptionOne(foo="hello"), "log": ""}
|
643
|
+
|
644
|
+
|
645
|
+
def test_run_node__union_output_type__miss():
|
646
|
+
# GIVEN a node that is a union type
|
647
|
+
class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, Union[int, float]]):
|
648
|
+
code = """\
|
649
|
+
def main():
|
650
|
+
return "hello"
|
651
|
+
"""
|
652
|
+
runtime = "PYTHON_3_11_6"
|
653
|
+
code_inputs = {}
|
654
|
+
|
655
|
+
# WHEN we run the node
|
656
|
+
node = ExampleCodeExecutionNode()
|
657
|
+
|
658
|
+
# THEN it should raise a NodeException with the execution error
|
659
|
+
with pytest.raises(NodeException) as exc_info:
|
660
|
+
node.run()
|
661
|
+
|
662
|
+
# AND the error should contain the execution error details
|
663
|
+
assert exc_info.value.message == "Expected an output of type 'int | float', but received 'str'"
|
664
|
+
|
665
|
+
|
666
|
+
def test_run_node__chat_history_output_type():
|
667
|
+
# GIVEN a node that that has a chat history return type
|
668
|
+
class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, List[ChatMessage]]):
|
669
|
+
code = """\
|
670
|
+
def main():
|
671
|
+
return [
|
672
|
+
{
|
673
|
+
"role": "USER",
|
674
|
+
"content": {
|
675
|
+
"type": "STRING",
|
676
|
+
"value": "Hello, world!",
|
677
|
+
}
|
678
|
+
}
|
679
|
+
]
|
680
|
+
"""
|
681
|
+
code_inputs = {}
|
682
|
+
runtime = "PYTHON_3_11_6"
|
683
|
+
|
684
|
+
# WHEN we run the node
|
685
|
+
node = ExampleCodeExecutionNode()
|
686
|
+
outputs = node.run()
|
687
|
+
|
688
|
+
# AND the error should contain the execution error details
|
689
|
+
assert outputs == {
|
690
|
+
"result": [ChatMessage(role="USER", content=StringChatMessageContent(value="Hello, world!"))],
|
691
|
+
"log": "",
|
692
|
+
}
|