vellum-ai 0.12.8__py3-none-any.whl → 0.12.11__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|