vellum-ai 0.12.8__py3-none-any.whl → 0.12.11__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/__init__.py +2 -2
- vellum/client/__init__.py +14 -4
- vellum/client/core/client_wrapper.py +1 -1
- vellum/client/types/__init__.py +2 -2
- vellum/client/types/function_call.py +0 -2
- vellum/client/types/function_call_request.py +0 -2
- vellum/client/types/metric_definition_execution.py +6 -0
- vellum/client/types/test_suite_run_execution_metric_result.py +6 -0
- vellum/client/types/test_suite_run_metric_array_output.py +32 -0
- vellum/client/types/test_suite_run_metric_output.py +2 -0
- vellum/evaluations/resources.py +1 -1
- vellum/prompts/blocks/compilation.py +4 -4
- vellum/types/{fulfilled_enum.py → test_suite_run_metric_array_output.py} +1 -1
- vellum/workflows/nodes/bases/__init__.py +0 -2
- vellum/workflows/nodes/bases/base.py +2 -6
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +13 -7
- vellum/workflows/nodes/core/inline_subworkflow_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py +41 -0
- vellum/workflows/nodes/core/map_node/node.py +1 -1
- vellum/workflows/nodes/core/templating_node/node.py +8 -1
- vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +66 -0
- vellum/workflows/nodes/core/try_node/node.py +1 -3
- vellum/workflows/nodes/core/try_node/tests/test_node.py +1 -1
- vellum/workflows/nodes/displayable/bases/api_node/node.py +2 -2
- vellum/workflows/nodes/displayable/bases/search_node.py +1 -2
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +17 -10
- vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py +13 -3
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +4 -2
- vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py +1 -2
- vellum/workflows/sandbox.py +4 -5
- vellum/workflows/state/context.py +5 -4
- vellum/workflows/state/encoder.py +4 -0
- vellum/workflows/state/tests/test_state.py +19 -0
- vellum/workflows/tests/test_sandbox.py +2 -2
- vellum/workflows/utils/tests/test_vellum_variables.py +3 -0
- vellum/workflows/utils/vellum_variables.py +5 -4
- vellum/workflows/workflows/base.py +5 -2
- {vellum_ai-0.12.8.dist-info → vellum_ai-0.12.11.dist-info}/METADATA +1 -1
- {vellum_ai-0.12.8.dist-info → vellum_ai-0.12.11.dist-info}/RECORD +46 -45
- vellum_cli/tests/test_push.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +6 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py +207 -0
- vellum/client/types/fulfilled_enum.py +0 -5
- vellum/workflows/nodes/bases/base_subworkflow_node/__init__.py +0 -5
- vellum/workflows/nodes/bases/base_subworkflow_node/node.py +0 -10
- /vellum/{evaluations/utils → utils}/uuid.py +0 -0
- {vellum_ai-0.12.8.dist-info → vellum_ai-0.12.11.dist-info}/LICENSE +0 -0
- {vellum_ai-0.12.8.dist-info → vellum_ai-0.12.11.dist-info}/WHEEL +0 -0
- {vellum_ai-0.12.8.dist-info → vellum_ai-0.12.11.dist-info}/entry_points.txt +0 -0
vellum/__init__.py
CHANGED
@@ -120,7 +120,6 @@ from .types import (
|
|
120
120
|
FolderEntityWorkflowSandbox,
|
121
121
|
FolderEntityWorkflowSandboxData,
|
122
122
|
FulfilledAdHocExecutePromptEvent,
|
123
|
-
FulfilledEnum,
|
124
123
|
FulfilledExecutePromptEvent,
|
125
124
|
FulfilledExecutePromptResponse,
|
126
125
|
FulfilledExecuteWorkflowWorkflowResultEvent,
|
@@ -389,6 +388,7 @@ from .types import (
|
|
389
388
|
TestSuiteRunExternalExecConfigData,
|
390
389
|
TestSuiteRunExternalExecConfigDataRequest,
|
391
390
|
TestSuiteRunExternalExecConfigRequest,
|
391
|
+
TestSuiteRunMetricArrayOutput,
|
392
392
|
TestSuiteRunMetricErrorOutput,
|
393
393
|
TestSuiteRunMetricJsonOutput,
|
394
394
|
TestSuiteRunMetricNumberOutput,
|
@@ -649,7 +649,6 @@ __all__ = [
|
|
649
649
|
"FolderEntityWorkflowSandboxData",
|
650
650
|
"ForbiddenError",
|
651
651
|
"FulfilledAdHocExecutePromptEvent",
|
652
|
-
"FulfilledEnum",
|
653
652
|
"FulfilledExecutePromptEvent",
|
654
653
|
"FulfilledExecutePromptResponse",
|
655
654
|
"FulfilledExecuteWorkflowWorkflowResultEvent",
|
@@ -922,6 +921,7 @@ __all__ = [
|
|
922
921
|
"TestSuiteRunExternalExecConfigData",
|
923
922
|
"TestSuiteRunExternalExecConfigDataRequest",
|
924
923
|
"TestSuiteRunExternalExecConfigRequest",
|
924
|
+
"TestSuiteRunMetricArrayOutput",
|
925
925
|
"TestSuiteRunMetricErrorOutput",
|
926
926
|
"TestSuiteRunMetricJsonOutput",
|
927
927
|
"TestSuiteRunMetricNumberOutput",
|
vellum/client/__init__.py
CHANGED
@@ -1079,6 +1079,7 @@ class Vellum:
|
|
1079
1079
|
index_id: typing.Optional[str] = OMIT,
|
1080
1080
|
index_name: typing.Optional[str] = OMIT,
|
1081
1081
|
options: typing.Optional[SearchRequestOptionsRequest] = OMIT,
|
1082
|
+
document_index: typing.Optional[str] = OMIT,
|
1082
1083
|
request_options: typing.Optional[RequestOptions] = None,
|
1083
1084
|
) -> SearchResponse:
|
1084
1085
|
"""
|
@@ -1090,14 +1091,17 @@ class Vellum:
|
|
1090
1091
|
The query to search for.
|
1091
1092
|
|
1092
1093
|
index_id : typing.Optional[str]
|
1093
|
-
The ID of the index to search against. Must provide either this or
|
1094
|
+
The ID of the index to search against. Must provide either this, index_name or document_index.
|
1094
1095
|
|
1095
1096
|
index_name : typing.Optional[str]
|
1096
|
-
The name of the index to search against. Must provide either this or
|
1097
|
+
The name of the index to search against. Must provide either this, index_id or document_index.
|
1097
1098
|
|
1098
1099
|
options : typing.Optional[SearchRequestOptionsRequest]
|
1099
1100
|
Configuration options for the search.
|
1100
1101
|
|
1102
|
+
document_index : typing.Optional[str]
|
1103
|
+
Either the index name or index ID to search against. Must provide either this, index_id or index_name.
|
1104
|
+
|
1101
1105
|
request_options : typing.Optional[RequestOptions]
|
1102
1106
|
Request-specific configuration.
|
1103
1107
|
|
@@ -1128,6 +1132,7 @@ class Vellum:
|
|
1128
1132
|
"options": convert_and_respect_annotation_metadata(
|
1129
1133
|
object_=options, annotation=SearchRequestOptionsRequest, direction="write"
|
1130
1134
|
),
|
1135
|
+
"document_index": document_index,
|
1131
1136
|
},
|
1132
1137
|
request_options=request_options,
|
1133
1138
|
omit=OMIT,
|
@@ -2395,6 +2400,7 @@ class AsyncVellum:
|
|
2395
2400
|
index_id: typing.Optional[str] = OMIT,
|
2396
2401
|
index_name: typing.Optional[str] = OMIT,
|
2397
2402
|
options: typing.Optional[SearchRequestOptionsRequest] = OMIT,
|
2403
|
+
document_index: typing.Optional[str] = OMIT,
|
2398
2404
|
request_options: typing.Optional[RequestOptions] = None,
|
2399
2405
|
) -> SearchResponse:
|
2400
2406
|
"""
|
@@ -2406,14 +2412,17 @@ class AsyncVellum:
|
|
2406
2412
|
The query to search for.
|
2407
2413
|
|
2408
2414
|
index_id : typing.Optional[str]
|
2409
|
-
The ID of the index to search against. Must provide either this or
|
2415
|
+
The ID of the index to search against. Must provide either this, index_name or document_index.
|
2410
2416
|
|
2411
2417
|
index_name : typing.Optional[str]
|
2412
|
-
The name of the index to search against. Must provide either this or
|
2418
|
+
The name of the index to search against. Must provide either this, index_id or document_index.
|
2413
2419
|
|
2414
2420
|
options : typing.Optional[SearchRequestOptionsRequest]
|
2415
2421
|
Configuration options for the search.
|
2416
2422
|
|
2423
|
+
document_index : typing.Optional[str]
|
2424
|
+
Either the index name or index ID to search against. Must provide either this, index_id or index_name.
|
2425
|
+
|
2417
2426
|
request_options : typing.Optional[RequestOptions]
|
2418
2427
|
Request-specific configuration.
|
2419
2428
|
|
@@ -2452,6 +2461,7 @@ class AsyncVellum:
|
|
2452
2461
|
"options": convert_and_respect_annotation_metadata(
|
2453
2462
|
object_=options, annotation=SearchRequestOptionsRequest, direction="write"
|
2454
2463
|
),
|
2464
|
+
"document_index": document_index,
|
2455
2465
|
},
|
2456
2466
|
request_options=request_options,
|
2457
2467
|
omit=OMIT,
|
@@ -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.12.
|
21
|
+
"X-Fern-SDK-Version": "0.12.11",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
vellum/client/types/__init__.py
CHANGED
@@ -127,7 +127,6 @@ from .folder_entity_test_suite_data import FolderEntityTestSuiteData
|
|
127
127
|
from .folder_entity_workflow_sandbox import FolderEntityWorkflowSandbox
|
128
128
|
from .folder_entity_workflow_sandbox_data import FolderEntityWorkflowSandboxData
|
129
129
|
from .fulfilled_ad_hoc_execute_prompt_event import FulfilledAdHocExecutePromptEvent
|
130
|
-
from .fulfilled_enum import FulfilledEnum
|
131
130
|
from .fulfilled_execute_prompt_event import FulfilledExecutePromptEvent
|
132
131
|
from .fulfilled_execute_prompt_response import FulfilledExecutePromptResponse
|
133
132
|
from .fulfilled_execute_workflow_workflow_result_event import FulfilledExecuteWorkflowWorkflowResultEvent
|
@@ -402,6 +401,7 @@ from .test_suite_run_external_exec_config import TestSuiteRunExternalExecConfig
|
|
402
401
|
from .test_suite_run_external_exec_config_data import TestSuiteRunExternalExecConfigData
|
403
402
|
from .test_suite_run_external_exec_config_data_request import TestSuiteRunExternalExecConfigDataRequest
|
404
403
|
from .test_suite_run_external_exec_config_request import TestSuiteRunExternalExecConfigRequest
|
404
|
+
from .test_suite_run_metric_array_output import TestSuiteRunMetricArrayOutput
|
405
405
|
from .test_suite_run_metric_error_output import TestSuiteRunMetricErrorOutput
|
406
406
|
from .test_suite_run_metric_json_output import TestSuiteRunMetricJsonOutput
|
407
407
|
from .test_suite_run_metric_number_output import TestSuiteRunMetricNumberOutput
|
@@ -641,7 +641,6 @@ __all__ = [
|
|
641
641
|
"FolderEntityWorkflowSandbox",
|
642
642
|
"FolderEntityWorkflowSandboxData",
|
643
643
|
"FulfilledAdHocExecutePromptEvent",
|
644
|
-
"FulfilledEnum",
|
645
644
|
"FulfilledExecutePromptEvent",
|
646
645
|
"FulfilledExecutePromptResponse",
|
647
646
|
"FulfilledExecuteWorkflowWorkflowResultEvent",
|
@@ -910,6 +909,7 @@ __all__ = [
|
|
910
909
|
"TestSuiteRunExternalExecConfigData",
|
911
910
|
"TestSuiteRunExternalExecConfigDataRequest",
|
912
911
|
"TestSuiteRunExternalExecConfigRequest",
|
912
|
+
"TestSuiteRunMetricArrayOutput",
|
913
913
|
"TestSuiteRunMetricErrorOutput",
|
914
914
|
"TestSuiteRunMetricJsonOutput",
|
915
915
|
"TestSuiteRunMetricNumberOutput",
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
from ..core.pydantic_utilities import UniversalBaseModel
|
4
4
|
import typing
|
5
|
-
from .fulfilled_enum import FulfilledEnum
|
6
5
|
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
7
6
|
import pydantic
|
8
7
|
|
@@ -15,7 +14,6 @@ class FunctionCall(UniversalBaseModel):
|
|
15
14
|
arguments: typing.Dict[str, typing.Optional[typing.Any]]
|
16
15
|
id: typing.Optional[str] = None
|
17
16
|
name: str
|
18
|
-
state: typing.Optional[FulfilledEnum] = None
|
19
17
|
|
20
18
|
if IS_PYDANTIC_V2:
|
21
19
|
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
from ..core.pydantic_utilities import UniversalBaseModel
|
4
4
|
import typing
|
5
|
-
from .fulfilled_enum import FulfilledEnum
|
6
5
|
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
7
6
|
import pydantic
|
8
7
|
|
@@ -15,7 +14,6 @@ class FunctionCallRequest(UniversalBaseModel):
|
|
15
14
|
arguments: typing.Dict[str, typing.Optional[typing.Any]]
|
16
15
|
id: typing.Optional[str] = None
|
17
16
|
name: str
|
18
|
-
state: typing.Optional[FulfilledEnum] = None
|
19
17
|
|
20
18
|
if IS_PYDANTIC_V2:
|
21
19
|
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
@@ -1,10 +1,13 @@
|
|
1
1
|
# This file was auto-generated by Fern from our API Definition.
|
2
2
|
|
3
|
+
from __future__ import annotations
|
3
4
|
from ..core.pydantic_utilities import UniversalBaseModel
|
5
|
+
from .array_vellum_value import ArrayVellumValue
|
4
6
|
import typing
|
5
7
|
from .test_suite_run_metric_output import TestSuiteRunMetricOutput
|
6
8
|
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
7
9
|
import pydantic
|
10
|
+
from ..core.pydantic_utilities import update_forward_refs
|
8
11
|
|
9
12
|
|
10
13
|
class MetricDefinitionExecution(UniversalBaseModel):
|
@@ -18,3 +21,6 @@ class MetricDefinitionExecution(UniversalBaseModel):
|
|
18
21
|
frozen = True
|
19
22
|
smart_union = True
|
20
23
|
extra = pydantic.Extra.allow
|
24
|
+
|
25
|
+
|
26
|
+
update_forward_refs(ArrayVellumValue, MetricDefinitionExecution=MetricDefinitionExecution)
|
@@ -1,11 +1,14 @@
|
|
1
1
|
# This file was auto-generated by Fern from our API Definition.
|
2
2
|
|
3
|
+
from __future__ import annotations
|
3
4
|
from ..core.pydantic_utilities import UniversalBaseModel
|
5
|
+
from .array_vellum_value import ArrayVellumValue
|
4
6
|
import typing
|
5
7
|
from .test_suite_run_metric_output import TestSuiteRunMetricOutput
|
6
8
|
from .test_suite_run_execution_metric_definition import TestSuiteRunExecutionMetricDefinition
|
7
9
|
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
8
10
|
import pydantic
|
11
|
+
from ..core.pydantic_utilities import update_forward_refs
|
9
12
|
|
10
13
|
|
11
14
|
class TestSuiteRunExecutionMetricResult(UniversalBaseModel):
|
@@ -22,3 +25,6 @@ class TestSuiteRunExecutionMetricResult(UniversalBaseModel):
|
|
22
25
|
frozen = True
|
23
26
|
smart_union = True
|
24
27
|
extra = pydantic.Extra.allow
|
28
|
+
|
29
|
+
|
30
|
+
update_forward_refs(ArrayVellumValue, TestSuiteRunExecutionMetricResult=TestSuiteRunExecutionMetricResult)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
from ..core.pydantic_utilities import UniversalBaseModel
|
5
|
+
from .array_vellum_value import ArrayVellumValue
|
6
|
+
import typing
|
7
|
+
from .vellum_value import VellumValue
|
8
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
9
|
+
import pydantic
|
10
|
+
from ..core.pydantic_utilities import update_forward_refs
|
11
|
+
|
12
|
+
|
13
|
+
class TestSuiteRunMetricArrayOutput(UniversalBaseModel):
|
14
|
+
"""
|
15
|
+
Output for a test suite run metric that is of type ARRAY
|
16
|
+
"""
|
17
|
+
|
18
|
+
value: typing.Optional[typing.List[VellumValue]] = None
|
19
|
+
type: typing.Literal["ARRAY"] = "ARRAY"
|
20
|
+
name: str
|
21
|
+
|
22
|
+
if IS_PYDANTIC_V2:
|
23
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
24
|
+
else:
|
25
|
+
|
26
|
+
class Config:
|
27
|
+
frozen = True
|
28
|
+
smart_union = True
|
29
|
+
extra = pydantic.Extra.allow
|
30
|
+
|
31
|
+
|
32
|
+
update_forward_refs(ArrayVellumValue, TestSuiteRunMetricArrayOutput=TestSuiteRunMetricArrayOutput)
|
@@ -5,10 +5,12 @@ from .test_suite_run_metric_string_output import TestSuiteRunMetricStringOutput
|
|
5
5
|
from .test_suite_run_metric_number_output import TestSuiteRunMetricNumberOutput
|
6
6
|
from .test_suite_run_metric_json_output import TestSuiteRunMetricJsonOutput
|
7
7
|
from .test_suite_run_metric_error_output import TestSuiteRunMetricErrorOutput
|
8
|
+
from .test_suite_run_metric_array_output import TestSuiteRunMetricArrayOutput
|
8
9
|
|
9
10
|
TestSuiteRunMetricOutput = typing.Union[
|
10
11
|
TestSuiteRunMetricStringOutput,
|
11
12
|
TestSuiteRunMetricNumberOutput,
|
12
13
|
TestSuiteRunMetricJsonOutput,
|
13
14
|
TestSuiteRunMetricErrorOutput,
|
15
|
+
TestSuiteRunMetricArrayOutput,
|
14
16
|
]
|
vellum/evaluations/resources.py
CHANGED
@@ -12,7 +12,6 @@ from vellum.evaluations.constants import DEFAULT_MAX_POLLING_DURATION_MS, DEFAUL
|
|
12
12
|
from vellum.evaluations.exceptions import TestSuiteRunResultsException
|
13
13
|
from vellum.evaluations.utils.env import get_api_key
|
14
14
|
from vellum.evaluations.utils.paginator import PaginatedResults, get_all_results
|
15
|
-
from vellum.evaluations.utils.uuid import is_valid_uuid
|
16
15
|
from vellum.types import (
|
17
16
|
ExternalTestCaseExecutionRequest,
|
18
17
|
NamedTestCaseVariableValueRequest,
|
@@ -24,6 +23,7 @@ from vellum.types import (
|
|
24
23
|
TestSuiteRunState,
|
25
24
|
)
|
26
25
|
from vellum.utils.typing import cast_not_optional
|
26
|
+
from vellum.utils.uuid import is_valid_uuid
|
27
27
|
|
28
28
|
logger = logging.getLogger(__name__)
|
29
29
|
|
@@ -104,16 +104,16 @@ def compile_prompt_blocks(
|
|
104
104
|
chat_message_blocks = _compile_chat_messages_as_prompt_blocks(compiled_input.value)
|
105
105
|
compiled_blocks.extend(chat_message_blocks)
|
106
106
|
else:
|
107
|
-
raise
|
107
|
+
raise PromptCompilationError(f"Invalid input type for variable block: {compiled_input.type}")
|
108
108
|
|
109
109
|
elif block.block_type == "RICH_TEXT":
|
110
110
|
value_block = _compile_rich_text_block_as_value_block(block=block, inputs=sanitized_inputs)
|
111
111
|
compiled_blocks.append(value_block)
|
112
112
|
|
113
113
|
elif block.block_type == "FUNCTION_DEFINITION":
|
114
|
-
raise
|
114
|
+
raise PromptCompilationError("Function definitions shouldn't go through compilation process")
|
115
115
|
else:
|
116
|
-
raise
|
116
|
+
raise PromptCompilationError(f"Unknown block_type: {block.block_type}")
|
117
117
|
|
118
118
|
return compiled_blocks
|
119
119
|
|
@@ -172,7 +172,7 @@ def _compile_rich_text_block_as_value_block(
|
|
172
172
|
f"Input variable '{child_block.input_variable}' must be of type STRING or JSON"
|
173
173
|
)
|
174
174
|
else:
|
175
|
-
raise
|
175
|
+
raise PromptCompilationError(f"Invalid child block_type for RICH_TEXT: {child_block.block_type}")
|
176
176
|
|
177
177
|
return CompiledValuePromptBlock(content=StringVellumValue(value=value), cache_config=block.cache_config)
|
178
178
|
|
@@ -344,8 +344,8 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
|
|
344
344
|
all_inputs = {}
|
345
345
|
for key, value in inputs.items():
|
346
346
|
path_parts = key.split(".")
|
347
|
-
|
348
|
-
inputs_key = reduce(lambda acc, part: acc[part], path_parts[1:],
|
347
|
+
node_attribute_descriptor = getattr(self.__class__, path_parts[0])
|
348
|
+
inputs_key = reduce(lambda acc, part: acc[part], path_parts[1:], node_attribute_descriptor)
|
349
349
|
all_inputs[inputs_key] = value
|
350
350
|
|
351
351
|
self._inputs = MappingProxyType(all_inputs)
|
@@ -355,7 +355,3 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
|
|
355
355
|
|
356
356
|
def __repr__(self) -> str:
|
357
357
|
return str(self.__class__)
|
358
|
-
|
359
|
-
|
360
|
-
class MyNode2(BaseNode):
|
361
|
-
pass
|
@@ -1,12 +1,14 @@
|
|
1
|
-
from typing import TYPE_CHECKING, Generic, Iterator, Optional, Set, Type, TypeVar
|
1
|
+
from typing import TYPE_CHECKING, ClassVar, Generic, Iterator, Optional, Set, Type, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.context import execution_context, get_parent_context
|
4
4
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
5
5
|
from vellum.workflows.exceptions import NodeException
|
6
|
-
from vellum.workflows.
|
6
|
+
from vellum.workflows.inputs.base import BaseInputs
|
7
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
7
8
|
from vellum.workflows.outputs.base import BaseOutput, BaseOutputs
|
8
9
|
from vellum.workflows.state.base import BaseState
|
9
10
|
from vellum.workflows.state.context import WorkflowContext
|
11
|
+
from vellum.workflows.types.core import EntityInputsInterface
|
10
12
|
from vellum.workflows.types.generics import StateType, WorkflowInputsType
|
11
13
|
|
12
14
|
if TYPE_CHECKING:
|
@@ -15,7 +17,7 @@ if TYPE_CHECKING:
|
|
15
17
|
InnerStateType = TypeVar("InnerStateType", bound=BaseState)
|
16
18
|
|
17
19
|
|
18
|
-
class InlineSubworkflowNode(
|
20
|
+
class InlineSubworkflowNode(BaseNode[StateType], Generic[StateType, WorkflowInputsType, InnerStateType]):
|
19
21
|
"""
|
20
22
|
Used to execute a Subworkflow defined inline.
|
21
23
|
|
@@ -24,14 +26,13 @@ class InlineSubworkflowNode(BaseSubworkflowNode[StateType], Generic[StateType, W
|
|
24
26
|
"""
|
25
27
|
|
26
28
|
subworkflow: Type["BaseWorkflow[WorkflowInputsType, InnerStateType]"]
|
29
|
+
subworkflow_inputs: ClassVar[Union[EntityInputsInterface, BaseInputs]] = {}
|
27
30
|
|
28
31
|
def run(self) -> Iterator[BaseOutput]:
|
29
32
|
with execution_context(parent_context=get_parent_context() or self._context.parent_context):
|
30
33
|
subworkflow = self.subworkflow(
|
31
34
|
parent_state=self.state,
|
32
|
-
context=WorkflowContext(
|
33
|
-
_vellum_client=self._context._vellum_client,
|
34
|
-
),
|
35
|
+
context=WorkflowContext(vellum_client=self._context.vellum_client),
|
35
36
|
)
|
36
37
|
subworkflow_stream = subworkflow.stream(
|
37
38
|
inputs=self._compile_subworkflow_inputs(),
|
@@ -68,4 +69,9 @@ class InlineSubworkflowNode(BaseSubworkflowNode[StateType], Generic[StateType, W
|
|
68
69
|
|
69
70
|
def _compile_subworkflow_inputs(self) -> WorkflowInputsType:
|
70
71
|
inputs_class = self.subworkflow.get_inputs_class()
|
71
|
-
|
72
|
+
if isinstance(self.subworkflow_inputs, dict):
|
73
|
+
return inputs_class(**self.subworkflow_inputs)
|
74
|
+
elif isinstance(self.subworkflow_inputs, inputs_class):
|
75
|
+
return self.subworkflow_inputs
|
76
|
+
else:
|
77
|
+
raise ValueError(f"Invalid subworkflow inputs type: {type(self.subworkflow_inputs)}")
|
File without changes
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from vellum.workflows.inputs.base import BaseInputs
|
4
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
5
|
+
from vellum.workflows.nodes.core.inline_subworkflow_node.node import InlineSubworkflowNode
|
6
|
+
from vellum.workflows.outputs.base import BaseOutput
|
7
|
+
from vellum.workflows.state.base import BaseState
|
8
|
+
from vellum.workflows.workflows.base import BaseWorkflow
|
9
|
+
|
10
|
+
|
11
|
+
class Inputs(BaseInputs):
|
12
|
+
foo: str
|
13
|
+
|
14
|
+
|
15
|
+
class MyInnerNode(BaseNode):
|
16
|
+
class Outputs(BaseNode.Outputs):
|
17
|
+
out = Inputs.foo
|
18
|
+
|
19
|
+
|
20
|
+
class MySubworkflow(BaseWorkflow[Inputs, BaseState]):
|
21
|
+
graph = MyInnerNode
|
22
|
+
|
23
|
+
class Outputs(BaseWorkflow.Outputs):
|
24
|
+
out = MyInnerNode.Outputs.out
|
25
|
+
|
26
|
+
|
27
|
+
@pytest.mark.parametrize("inputs", [{"foo": "bar"}, Inputs(foo="bar")])
|
28
|
+
def test_inline_subworkflow_node__inputs(inputs):
|
29
|
+
# GIVEN a node setup with subworkflow inputs
|
30
|
+
class MyNode(InlineSubworkflowNode):
|
31
|
+
subworkflow = MySubworkflow
|
32
|
+
subworkflow_inputs = inputs
|
33
|
+
|
34
|
+
# WHEN the node is run
|
35
|
+
node = MyNode()
|
36
|
+
events = list(node.run())
|
37
|
+
|
38
|
+
# THEN the output is as expected
|
39
|
+
assert events == [
|
40
|
+
BaseOutput(name="out", value="bar"),
|
41
|
+
]
|
@@ -108,7 +108,7 @@ class MapNode(BaseNode, Generic[StateType, MapNodeItemType]):
|
|
108
108
|
self._run_subworkflow(item=item, index=index)
|
109
109
|
|
110
110
|
def _run_subworkflow(self, *, item: MapNodeItemType, index: int) -> None:
|
111
|
-
context = WorkflowContext(
|
111
|
+
context = WorkflowContext(vellum_client=self._context.vellum_client)
|
112
112
|
subworkflow = self.subworkflow(parent_state=self.state, context=context)
|
113
113
|
events = subworkflow.stream(
|
114
114
|
inputs=self.SubworkflowInputs(index=index, item=item, all_items=self.items),
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import json
|
1
2
|
from typing import Any, Callable, ClassVar, Dict, Generic, Mapping, Tuple, Type, TypeVar, Union, get_args
|
2
3
|
|
3
4
|
from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS, DEFAULT_JINJA_GLOBALS
|
@@ -7,7 +8,7 @@ from vellum.workflows.errors import WorkflowErrorCode
|
|
7
8
|
from vellum.workflows.exceptions import NodeException
|
8
9
|
from vellum.workflows.nodes.bases import BaseNode
|
9
10
|
from vellum.workflows.nodes.bases.base import BaseNodeMeta
|
10
|
-
from vellum.workflows.types.core import EntityInputsInterface
|
11
|
+
from vellum.workflows.types.core import EntityInputsInterface, Json
|
11
12
|
from vellum.workflows.types.generics import StateType
|
12
13
|
from vellum.workflows.types.utils import get_original_base
|
13
14
|
|
@@ -87,6 +88,12 @@ class TemplatingNode(BaseNode[StateType], Generic[StateType, _OutputType], metac
|
|
87
88
|
if output_type is bool:
|
88
89
|
return bool(rendered_template)
|
89
90
|
|
91
|
+
if output_type is Json:
|
92
|
+
try:
|
93
|
+
return json.loads(rendered_template)
|
94
|
+
except json.JSONDecodeError:
|
95
|
+
raise ValueError("Invalid JSON format for rendered_template")
|
96
|
+
|
90
97
|
raise ValueError(f"Unsupported output type: {output_type}")
|
91
98
|
|
92
99
|
def run(self) -> Outputs:
|
@@ -2,6 +2,8 @@ import json
|
|
2
2
|
|
3
3
|
from vellum.workflows.nodes.bases.base import BaseNode
|
4
4
|
from vellum.workflows.nodes.core.templating_node.node import TemplatingNode
|
5
|
+
from vellum.workflows.state import BaseState
|
6
|
+
from vellum.workflows.types.core import Json
|
5
7
|
|
6
8
|
|
7
9
|
def test_templating_node__dict_output():
|
@@ -22,6 +24,70 @@ def test_templating_node__dict_output():
|
|
22
24
|
assert json.loads(outputs.result) == {"key": "value"}
|
23
25
|
|
24
26
|
|
27
|
+
def test_templating_node__int_output():
|
28
|
+
# GIVEN a templating node that outputs an integer
|
29
|
+
class IntTemplateNode(TemplatingNode[BaseState, int]):
|
30
|
+
template = "{{ data }}"
|
31
|
+
inputs = {
|
32
|
+
"data": 42,
|
33
|
+
}
|
34
|
+
|
35
|
+
# WHEN the node is run
|
36
|
+
node = IntTemplateNode()
|
37
|
+
outputs = node.run()
|
38
|
+
|
39
|
+
# THEN the output is the expected integer
|
40
|
+
assert outputs.result == 42
|
41
|
+
|
42
|
+
|
43
|
+
def test_templating_node__float_output():
|
44
|
+
# GIVEN a templating node that outputs a float
|
45
|
+
class FloatTemplateNode(TemplatingNode[BaseState, float]):
|
46
|
+
template = "{{ data }}"
|
47
|
+
inputs = {
|
48
|
+
"data": 42.5,
|
49
|
+
}
|
50
|
+
|
51
|
+
# WHEN the node is run
|
52
|
+
node = FloatTemplateNode()
|
53
|
+
outputs = node.run()
|
54
|
+
|
55
|
+
# THEN the output is the expected float
|
56
|
+
assert outputs.result == 42.5
|
57
|
+
|
58
|
+
|
59
|
+
def test_templating_node__bool_output():
|
60
|
+
# GIVEN a templating node that outputs a bool
|
61
|
+
class BoolTemplateNode(TemplatingNode[BaseState, bool]):
|
62
|
+
template = "{{ data }}"
|
63
|
+
inputs = {
|
64
|
+
"data": True,
|
65
|
+
}
|
66
|
+
|
67
|
+
# WHEN the node is run
|
68
|
+
node = BoolTemplateNode()
|
69
|
+
outputs = node.run()
|
70
|
+
|
71
|
+
# THEN the output is the expected bool
|
72
|
+
assert outputs.result is True
|
73
|
+
|
74
|
+
|
75
|
+
def test_templating_node__json_output():
|
76
|
+
# GIVEN a templating node that outputs JSON
|
77
|
+
class JSONTemplateNode(TemplatingNode[BaseState, Json]):
|
78
|
+
template = "{{ data }}"
|
79
|
+
inputs = {
|
80
|
+
"data": {"key": "value"},
|
81
|
+
}
|
82
|
+
|
83
|
+
# WHEN the node is run
|
84
|
+
node = JSONTemplateNode()
|
85
|
+
outputs = node.run()
|
86
|
+
|
87
|
+
# THEN the output is the expected JSON
|
88
|
+
assert outputs.result == {"key": "value"}
|
89
|
+
|
90
|
+
|
25
91
|
def test_templating_node__execution_count_reference():
|
26
92
|
# GIVEN a random node
|
27
93
|
class OtherNode(BaseNode):
|
@@ -73,9 +73,7 @@ class TryNode(BaseNode[StateType], Generic[StateType], metaclass=_TryNodeMeta):
|
|
73
73
|
def run(self) -> Iterator[BaseOutput]:
|
74
74
|
subworkflow = self.subworkflow(
|
75
75
|
parent_state=self.state,
|
76
|
-
context=WorkflowContext(
|
77
|
-
_vellum_client=self._context._vellum_client,
|
78
|
-
),
|
76
|
+
context=WorkflowContext(vellum_client=self._context.vellum_client),
|
79
77
|
)
|
80
78
|
subworkflow_stream = subworkflow.stream(
|
81
79
|
event_filter=all_workflow_event_filter,
|
@@ -103,7 +103,7 @@ def test_try_node__use_parent_execution_context():
|
|
103
103
|
# WHEN the node is run with a custom vellum client
|
104
104
|
node = TestNode(
|
105
105
|
context=WorkflowContext(
|
106
|
-
|
106
|
+
vellum_client=Vellum(api_key="test-key"),
|
107
107
|
)
|
108
108
|
)
|
109
109
|
outputs = list(node.run())
|
@@ -26,11 +26,11 @@ class BaseAPINode(BaseNode, Generic[StateType]):
|
|
26
26
|
url: str
|
27
27
|
method: APIRequestMethod
|
28
28
|
data: Optional[str] = None
|
29
|
-
json: Optional[
|
29
|
+
json: Optional[Json] = None
|
30
30
|
headers: Optional[Dict[str, Union[str, VellumSecret]]] = None
|
31
31
|
|
32
32
|
class Outputs(BaseOutputs):
|
33
|
-
json: Optional[
|
33
|
+
json: Optional[Json]
|
34
34
|
headers: Dict[str, str]
|
35
35
|
status_code: int
|
36
36
|
text: str
|
@@ -76,8 +76,7 @@ class BaseSearchNode(BaseNode[StateType], Generic[StateType]):
|
|
76
76
|
try:
|
77
77
|
return self._context.vellum_client.search(
|
78
78
|
query=self.query,
|
79
|
-
|
80
|
-
index_name=self.document_index if isinstance(self.document_index, str) else None,
|
79
|
+
document_index=str(self.document_index),
|
81
80
|
options=self.options,
|
82
81
|
)
|
83
82
|
except NotFoundError:
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import json
|
1
2
|
from typing import Iterator
|
2
3
|
|
3
4
|
from vellum.workflows.errors import WorkflowErrorCode
|
@@ -37,13 +38,19 @@ class InlinePromptNode(BaseInlinePromptNode[StateType]):
|
|
37
38
|
code=WorkflowErrorCode.INTERNAL_ERROR,
|
38
39
|
)
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
string_outputs = []
|
42
|
+
for output in outputs:
|
43
|
+
if output.value is None:
|
44
|
+
continue
|
45
|
+
|
46
|
+
if output.type == "STRING":
|
47
|
+
string_outputs.append(output.value)
|
48
|
+
elif output.type == "JSON":
|
49
|
+
string_outputs.append(json.dumps(output.value, indent=4))
|
50
|
+
elif output.type == "FUNCTION_CALL":
|
51
|
+
string_outputs.append(output.value.model_dump_json(indent=4))
|
52
|
+
else:
|
53
|
+
string_outputs.append(output.value.message)
|
54
|
+
|
55
|
+
value = "\n".join(string_outputs)
|
56
|
+
yield BaseOutput(name="text", value=value)
|