vellum-ai 0.9.16rc2__py3-none-any.whl → 0.10.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- vellum/plugins/__init__.py +0 -0
- vellum/plugins/pydantic.py +74 -0
- vellum/plugins/utils.py +19 -0
- vellum/plugins/vellum_mypy.py +639 -3
- vellum/workflows/README.md +90 -0
- vellum/workflows/__init__.py +5 -0
- vellum/workflows/constants.py +43 -0
- vellum/workflows/descriptors/__init__.py +0 -0
- vellum/workflows/descriptors/base.py +339 -0
- vellum/workflows/descriptors/tests/test_utils.py +83 -0
- vellum/workflows/descriptors/utils.py +90 -0
- vellum/workflows/edges/__init__.py +5 -0
- vellum/workflows/edges/edge.py +23 -0
- vellum/workflows/emitters/__init__.py +5 -0
- vellum/workflows/emitters/base.py +14 -0
- vellum/workflows/environment/__init__.py +5 -0
- vellum/workflows/environment/environment.py +7 -0
- vellum/workflows/errors/__init__.py +6 -0
- vellum/workflows/errors/types.py +20 -0
- vellum/workflows/events/__init__.py +31 -0
- vellum/workflows/events/node.py +125 -0
- vellum/workflows/events/tests/__init__.py +0 -0
- vellum/workflows/events/tests/test_event.py +216 -0
- vellum/workflows/events/types.py +52 -0
- vellum/workflows/events/utils.py +5 -0
- vellum/workflows/events/workflow.py +139 -0
- vellum/workflows/exceptions.py +15 -0
- vellum/workflows/expressions/__init__.py +0 -0
- vellum/workflows/expressions/accessor.py +52 -0
- vellum/workflows/expressions/and_.py +32 -0
- vellum/workflows/expressions/begins_with.py +31 -0
- vellum/workflows/expressions/between.py +38 -0
- vellum/workflows/expressions/coalesce_expression.py +41 -0
- vellum/workflows/expressions/contains.py +30 -0
- vellum/workflows/expressions/does_not_begin_with.py +31 -0
- vellum/workflows/expressions/does_not_contain.py +30 -0
- vellum/workflows/expressions/does_not_end_with.py +31 -0
- vellum/workflows/expressions/does_not_equal.py +25 -0
- vellum/workflows/expressions/ends_with.py +31 -0
- vellum/workflows/expressions/equals.py +25 -0
- vellum/workflows/expressions/greater_than.py +33 -0
- vellum/workflows/expressions/greater_than_or_equal_to.py +33 -0
- vellum/workflows/expressions/in_.py +31 -0
- vellum/workflows/expressions/is_blank.py +24 -0
- vellum/workflows/expressions/is_not_blank.py +24 -0
- vellum/workflows/expressions/is_not_null.py +21 -0
- vellum/workflows/expressions/is_not_undefined.py +22 -0
- vellum/workflows/expressions/is_null.py +21 -0
- vellum/workflows/expressions/is_undefined.py +22 -0
- vellum/workflows/expressions/less_than.py +33 -0
- vellum/workflows/expressions/less_than_or_equal_to.py +33 -0
- vellum/workflows/expressions/not_between.py +38 -0
- vellum/workflows/expressions/not_in.py +31 -0
- vellum/workflows/expressions/or_.py +32 -0
- vellum/workflows/graph/__init__.py +3 -0
- vellum/workflows/graph/graph.py +131 -0
- vellum/workflows/graph/tests/__init__.py +0 -0
- vellum/workflows/graph/tests/test_graph.py +437 -0
- vellum/workflows/inputs/__init__.py +5 -0
- vellum/workflows/inputs/base.py +55 -0
- vellum/workflows/logging.py +14 -0
- vellum/workflows/nodes/__init__.py +46 -0
- vellum/workflows/nodes/bases/__init__.py +7 -0
- vellum/workflows/nodes/bases/base.py +332 -0
- vellum/workflows/nodes/bases/base_subworkflow_node/__init__.py +5 -0
- vellum/workflows/nodes/bases/base_subworkflow_node/node.py +10 -0
- vellum/workflows/nodes/bases/tests/__init__.py +0 -0
- vellum/workflows/nodes/bases/tests/test_base_node.py +125 -0
- vellum/workflows/nodes/core/__init__.py +16 -0
- vellum/workflows/nodes/core/error_node/__init__.py +5 -0
- vellum/workflows/nodes/core/error_node/node.py +26 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/__init__.py +5 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +73 -0
- vellum/workflows/nodes/core/map_node/__init__.py +5 -0
- vellum/workflows/nodes/core/map_node/node.py +147 -0
- vellum/workflows/nodes/core/map_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/core/map_node/tests/test_node.py +65 -0
- vellum/workflows/nodes/core/retry_node/__init__.py +5 -0
- vellum/workflows/nodes/core/retry_node/node.py +106 -0
- vellum/workflows/nodes/core/retry_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/core/retry_node/tests/test_node.py +93 -0
- vellum/workflows/nodes/core/templating_node/__init__.py +5 -0
- vellum/workflows/nodes/core/templating_node/custom_filters.py +12 -0
- vellum/workflows/nodes/core/templating_node/exceptions.py +2 -0
- vellum/workflows/nodes/core/templating_node/node.py +123 -0
- vellum/workflows/nodes/core/templating_node/render.py +55 -0
- vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +21 -0
- vellum/workflows/nodes/core/try_node/__init__.py +5 -0
- vellum/workflows/nodes/core/try_node/node.py +110 -0
- vellum/workflows/nodes/core/try_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/core/try_node/tests/test_node.py +82 -0
- vellum/workflows/nodes/displayable/__init__.py +31 -0
- vellum/workflows/nodes/displayable/api_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/api_node/node.py +44 -0
- vellum/workflows/nodes/displayable/bases/__init__.py +11 -0
- vellum/workflows/nodes/displayable/bases/api_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/bases/api_node/node.py +70 -0
- vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +60 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/constants.py +13 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +118 -0
- vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +98 -0
- vellum/workflows/nodes/displayable/bases/search_node.py +90 -0
- vellum/workflows/nodes/displayable/code_execution_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/code_execution_node/node.py +197 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py +0 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py +3 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +111 -0
- vellum/workflows/nodes/displayable/code_execution_node/utils.py +10 -0
- vellum/workflows/nodes/displayable/conditional_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/conditional_node/node.py +25 -0
- vellum/workflows/nodes/displayable/final_output_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/final_output_node/node.py +43 -0
- vellum/workflows/nodes/displayable/guardrail_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/guardrail_node/node.py +97 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +41 -0
- vellum/workflows/nodes/displayable/merge_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/merge_node/node.py +10 -0
- vellum/workflows/nodes/displayable/prompt_deployment_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +45 -0
- vellum/workflows/nodes/displayable/search_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/search_node/node.py +26 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +156 -0
- vellum/workflows/nodes/displayable/tests/__init__.py +0 -0
- vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +148 -0
- vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py +134 -0
- vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +80 -0
- vellum/workflows/nodes/utils.py +27 -0
- vellum/workflows/outputs/__init__.py +6 -0
- vellum/workflows/outputs/base.py +196 -0
- vellum/workflows/ports/__init__.py +7 -0
- vellum/workflows/ports/node_ports.py +75 -0
- vellum/workflows/ports/port.py +75 -0
- vellum/workflows/ports/utils.py +40 -0
- vellum/workflows/references/__init__.py +17 -0
- vellum/workflows/references/environment_variable.py +20 -0
- vellum/workflows/references/execution_count.py +20 -0
- vellum/workflows/references/external_input.py +49 -0
- vellum/workflows/references/input.py +7 -0
- vellum/workflows/references/lazy.py +55 -0
- vellum/workflows/references/node.py +43 -0
- vellum/workflows/references/output.py +78 -0
- vellum/workflows/references/state_value.py +23 -0
- vellum/workflows/references/vellum_secret.py +15 -0
- vellum/workflows/references/workflow_input.py +41 -0
- vellum/workflows/resolvers/__init__.py +5 -0
- vellum/workflows/resolvers/base.py +15 -0
- vellum/workflows/runner/__init__.py +5 -0
- vellum/workflows/runner/runner.py +588 -0
- vellum/workflows/runner/types.py +18 -0
- vellum/workflows/state/__init__.py +5 -0
- vellum/workflows/state/base.py +327 -0
- vellum/workflows/state/context.py +18 -0
- vellum/workflows/state/encoder.py +57 -0
- vellum/workflows/state/store.py +28 -0
- vellum/workflows/state/tests/__init__.py +0 -0
- vellum/workflows/state/tests/test_state.py +113 -0
- vellum/workflows/types/__init__.py +0 -0
- vellum/workflows/types/core.py +91 -0
- vellum/workflows/types/generics.py +14 -0
- vellum/workflows/types/stack.py +39 -0
- vellum/workflows/types/tests/__init__.py +0 -0
- vellum/workflows/types/tests/test_utils.py +76 -0
- vellum/workflows/types/utils.py +164 -0
- vellum/workflows/utils/__init__.py +0 -0
- vellum/workflows/utils/names.py +13 -0
- vellum/workflows/utils/tests/__init__.py +0 -0
- vellum/workflows/utils/tests/test_names.py +15 -0
- vellum/workflows/utils/tests/test_vellum_variables.py +25 -0
- vellum/workflows/utils/vellum_variables.py +81 -0
- vellum/workflows/vellum_client.py +18 -0
- vellum/workflows/workflows/__init__.py +5 -0
- vellum/workflows/workflows/base.py +365 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.10.0.dist-info}/METADATA +2 -1
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.10.0.dist-info}/RECORD +245 -7
- vellum_cli/__init__.py +72 -0
- vellum_cli/aliased_group.py +103 -0
- vellum_cli/config.py +96 -0
- vellum_cli/image_push.py +112 -0
- vellum_cli/logger.py +36 -0
- vellum_cli/pull.py +73 -0
- vellum_cli/push.py +121 -0
- vellum_cli/tests/test_config.py +100 -0
- vellum_cli/tests/test_pull.py +152 -0
- vellum_ee/workflows/__init__.py +0 -0
- vellum_ee/workflows/display/__init__.py +0 -0
- vellum_ee/workflows/display/base.py +73 -0
- vellum_ee/workflows/display/nodes/__init__.py +4 -0
- vellum_ee/workflows/display/nodes/base_node_display.py +116 -0
- vellum_ee/workflows/display/nodes/base_node_vellum_display.py +36 -0
- vellum_ee/workflows/display/nodes/get_node_display_class.py +25 -0
- vellum_ee/workflows/display/nodes/tests/__init__.py +0 -0
- vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +47 -0
- vellum_ee/workflows/display/nodes/types.py +18 -0
- vellum_ee/workflows/display/nodes/utils.py +33 -0
- vellum_ee/workflows/display/nodes/vellum/__init__.py +32 -0
- vellum_ee/workflows/display/nodes/vellum/api_node.py +205 -0
- vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +71 -0
- vellum_ee/workflows/display/nodes/vellum/conditional_node.py +217 -0
- vellum_ee/workflows/display/nodes/vellum/final_output_node.py +61 -0
- vellum_ee/workflows/display/nodes/vellum/guardrail_node.py +49 -0
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +170 -0
- vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +99 -0
- vellum_ee/workflows/display/nodes/vellum/map_node.py +100 -0
- vellum_ee/workflows/display/nodes/vellum/merge_node.py +48 -0
- vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +68 -0
- vellum_ee/workflows/display/nodes/vellum/search_node.py +193 -0
- vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +58 -0
- vellum_ee/workflows/display/nodes/vellum/templating_node.py +67 -0
- vellum_ee/workflows/display/nodes/vellum/tests/__init__.py +0 -0
- vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +106 -0
- vellum_ee/workflows/display/nodes/vellum/try_node.py +38 -0
- vellum_ee/workflows/display/nodes/vellum/utils.py +76 -0
- vellum_ee/workflows/display/tests/__init__.py +0 -0
- vellum_ee/workflows/display/tests/workflow_serialization/__init__.py +0 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +426 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +607 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +1175 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py +235 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +511 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +372 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +272 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +289 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +354 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py +123 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +84 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +233 -0
- vellum_ee/workflows/display/types.py +46 -0
- vellum_ee/workflows/display/utils/__init__.py +0 -0
- vellum_ee/workflows/display/utils/tests/__init__.py +0 -0
- vellum_ee/workflows/display/utils/tests/test_uuids.py +16 -0
- vellum_ee/workflows/display/utils/uuids.py +24 -0
- vellum_ee/workflows/display/utils/vellum.py +121 -0
- vellum_ee/workflows/display/vellum.py +357 -0
- vellum_ee/workflows/display/workflows/__init__.py +5 -0
- vellum_ee/workflows/display/workflows/base_workflow_display.py +302 -0
- vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py +32 -0
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +386 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.10.0.dist-info}/LICENSE +0 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.10.0.dist-info}/WHEEL +0 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.10.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,170 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
from typing import Any, ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union, cast
|
3
|
+
|
4
|
+
from vellum import PromptBlock, RichTextChildBlock, VellumVariable
|
5
|
+
|
6
|
+
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
7
|
+
from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
|
8
|
+
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
9
|
+
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
10
|
+
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
11
|
+
from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
|
12
|
+
from vellum_ee.workflows.display.vellum import NodeInput
|
13
|
+
from vellum.workflows.nodes import InlinePromptNode
|
14
|
+
from vellum.workflows.references import OutputReference
|
15
|
+
from vellum.workflows.types.core import JsonObject
|
16
|
+
|
17
|
+
_InlinePromptNodeType = TypeVar("_InlinePromptNodeType", bound=InlinePromptNode)
|
18
|
+
|
19
|
+
|
20
|
+
class BaseInlinePromptNodeDisplay(BaseNodeVellumDisplay[_InlinePromptNodeType], Generic[_InlinePromptNodeType]):
|
21
|
+
output_id: ClassVar[Optional[UUID]] = None
|
22
|
+
array_output_id: ClassVar[Optional[UUID]] = None
|
23
|
+
prompt_input_ids_by_name: ClassVar[Dict[str, UUID]] = {}
|
24
|
+
|
25
|
+
def serialize(
|
26
|
+
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs: Any
|
27
|
+
) -> JsonObject:
|
28
|
+
node = self._node
|
29
|
+
node_id = self.node_id
|
30
|
+
|
31
|
+
node_inputs, prompt_inputs = self._generate_node_and_prompt_inputs(node_id, node, display_context)
|
32
|
+
input_variable_id_by_name = {prompt_input.key: prompt_input.id for prompt_input in prompt_inputs}
|
33
|
+
|
34
|
+
_, output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.text)]
|
35
|
+
_, array_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.results)]
|
36
|
+
node_blocks = raise_if_descriptor(node.blocks)
|
37
|
+
|
38
|
+
return {
|
39
|
+
"id": str(node_id),
|
40
|
+
"type": "PROMPT",
|
41
|
+
"inputs": [node_input.dict() for node_input in node_inputs],
|
42
|
+
"data": {
|
43
|
+
"label": self.label,
|
44
|
+
"output_id": str(output_display.id),
|
45
|
+
"error_output_id": str(error_output_id) if error_output_id else None,
|
46
|
+
"array_output_id": str(array_display.id),
|
47
|
+
"source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
|
48
|
+
"target_handle_id": str(self.get_target_handle_id()),
|
49
|
+
"variant": "INLINE",
|
50
|
+
"exec_config": {
|
51
|
+
"parameters": raise_if_descriptor(node.parameters).dict(),
|
52
|
+
"input_variables": [prompt_input.dict() for prompt_input in prompt_inputs],
|
53
|
+
"prompt_template_block_data": {
|
54
|
+
"version": 1,
|
55
|
+
"blocks": [
|
56
|
+
self._generate_prompt_block(block, input_variable_id_by_name, [i])
|
57
|
+
for i, block in enumerate(node_blocks)
|
58
|
+
],
|
59
|
+
},
|
60
|
+
},
|
61
|
+
"ml_model_name": raise_if_descriptor(node.ml_model),
|
62
|
+
},
|
63
|
+
"display_data": self.get_display_data().dict(),
|
64
|
+
"definition": self.get_definition().dict(),
|
65
|
+
}
|
66
|
+
|
67
|
+
def _generate_node_and_prompt_inputs(
|
68
|
+
self,
|
69
|
+
node_id: UUID,
|
70
|
+
node: Type[InlinePromptNode],
|
71
|
+
display_context: WorkflowDisplayContext,
|
72
|
+
) -> Tuple[List[NodeInput], List[VellumVariable]]:
|
73
|
+
value = raise_if_descriptor(node.prompt_inputs)
|
74
|
+
|
75
|
+
node_inputs: List[NodeInput] = []
|
76
|
+
prompt_inputs: List[VellumVariable] = []
|
77
|
+
|
78
|
+
for variable_name, variable_value in value.items():
|
79
|
+
node_input = create_node_input(
|
80
|
+
node_id=node_id,
|
81
|
+
input_name=variable_name,
|
82
|
+
value=variable_value,
|
83
|
+
display_context=display_context,
|
84
|
+
input_id=self.prompt_input_ids_by_name.get(variable_name),
|
85
|
+
)
|
86
|
+
vellum_variable_type = infer_vellum_variable_type(variable_value)
|
87
|
+
node_inputs.append(node_input)
|
88
|
+
prompt_inputs.append(VellumVariable(id=str(node_input.id), key=variable_name, type=vellum_variable_type))
|
89
|
+
|
90
|
+
return node_inputs, prompt_inputs
|
91
|
+
|
92
|
+
def _generate_prompt_block(
|
93
|
+
self,
|
94
|
+
prompt_block: Union[PromptBlock, RichTextChildBlock],
|
95
|
+
input_variable_id_by_name: Dict[str, str],
|
96
|
+
path: List[int],
|
97
|
+
) -> JsonObject:
|
98
|
+
block: JsonObject
|
99
|
+
if prompt_block.block_type == "JINJA":
|
100
|
+
block = {
|
101
|
+
"block_type": "JINJA",
|
102
|
+
"properties": {"template": prompt_block.template, "template_type": "STRING"},
|
103
|
+
}
|
104
|
+
|
105
|
+
elif prompt_block.block_type == "CHAT_MESSAGE":
|
106
|
+
chat_properties: JsonObject = {
|
107
|
+
"chat_role": prompt_block.chat_role,
|
108
|
+
"chat_source": prompt_block.chat_source,
|
109
|
+
"blocks": [
|
110
|
+
self._generate_prompt_block(block, input_variable_id_by_name, path + [i])
|
111
|
+
for i, block in enumerate(prompt_block.blocks)
|
112
|
+
],
|
113
|
+
}
|
114
|
+
if prompt_block.chat_message_unterminated is not None:
|
115
|
+
chat_properties["chat_message_unterminated"] = prompt_block.chat_message_unterminated
|
116
|
+
|
117
|
+
block = {
|
118
|
+
"block_type": "CHAT_MESSAGE",
|
119
|
+
"properties": chat_properties,
|
120
|
+
}
|
121
|
+
|
122
|
+
elif prompt_block.block_type == "FUNCTION_DEFINITION":
|
123
|
+
block = {
|
124
|
+
"block_type": "FUNCTION_DEFINITION",
|
125
|
+
"properties": {
|
126
|
+
"function_name": prompt_block.function_name,
|
127
|
+
"function_description": prompt_block.function_description,
|
128
|
+
"function_parameters": prompt_block.function_parameters,
|
129
|
+
"function_forced": prompt_block.function_forced,
|
130
|
+
"function_strict": prompt_block.function_strict,
|
131
|
+
},
|
132
|
+
}
|
133
|
+
|
134
|
+
elif prompt_block.block_type == "VARIABLE":
|
135
|
+
block = {
|
136
|
+
"block_type": "VARIABLE",
|
137
|
+
"input_variable_id": input_variable_id_by_name[prompt_block.input_variable],
|
138
|
+
}
|
139
|
+
|
140
|
+
elif prompt_block.block_type == "PLAIN_TEXT":
|
141
|
+
block = {
|
142
|
+
"block_type": "PLAIN_TEXT",
|
143
|
+
"text": prompt_block.text,
|
144
|
+
}
|
145
|
+
|
146
|
+
elif prompt_block.block_type == "RICH_TEXT":
|
147
|
+
block = {
|
148
|
+
"block_type": "RICH_TEXT",
|
149
|
+
"blocks": [
|
150
|
+
self._generate_prompt_block(child, input_variable_id_by_name, path + [i])
|
151
|
+
for i, child in enumerate(prompt_block.blocks)
|
152
|
+
],
|
153
|
+
}
|
154
|
+
else:
|
155
|
+
raise NotImplementedError(f"Serialization for prompt block type {prompt_block.block_type} not implemented")
|
156
|
+
|
157
|
+
block["id"] = str(
|
158
|
+
uuid4_from_hash(f"{self.node_id}-{prompt_block.block_type}-{'-'.join([str(i) for i in path])}")
|
159
|
+
)
|
160
|
+
if prompt_block.cache_config:
|
161
|
+
block["cache_config"] = prompt_block.cache_config.dict()
|
162
|
+
else:
|
163
|
+
block["cache_config"] = None
|
164
|
+
|
165
|
+
if prompt_block.state:
|
166
|
+
block["state"] = prompt_block.state
|
167
|
+
else:
|
168
|
+
block["state"] = "ENABLED"
|
169
|
+
|
170
|
+
return block
|
@@ -0,0 +1,99 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
from typing import Any, ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar
|
3
|
+
|
4
|
+
from vellum import VellumVariable
|
5
|
+
|
6
|
+
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
7
|
+
from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
|
8
|
+
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
9
|
+
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
10
|
+
from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
|
11
|
+
from vellum_ee.workflows.display.vellum import NodeInput
|
12
|
+
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
13
|
+
from vellum.workflows.nodes import InlineSubworkflowNode
|
14
|
+
from vellum.workflows.types.core import JsonObject
|
15
|
+
|
16
|
+
_InlineSubworkflowNodeType = TypeVar("_InlineSubworkflowNodeType", bound=InlineSubworkflowNode)
|
17
|
+
|
18
|
+
|
19
|
+
class BaseInlineSubworkflowNodeDisplay(
|
20
|
+
BaseNodeVellumDisplay[_InlineSubworkflowNodeType], Generic[_InlineSubworkflowNodeType]
|
21
|
+
):
|
22
|
+
workflow_input_ids_by_name: ClassVar[Dict[str, UUID]] = {}
|
23
|
+
|
24
|
+
def serialize(
|
25
|
+
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs: Any
|
26
|
+
) -> JsonObject:
|
27
|
+
node = self._node
|
28
|
+
node_id = self.node_id
|
29
|
+
|
30
|
+
node_inputs, workflow_inputs = self._generate_node_and_workflow_inputs(node_id, node, display_context)
|
31
|
+
workflow_outputs = self._generate_workflow_outputs(node)
|
32
|
+
|
33
|
+
subworkflow_display = get_workflow_display(
|
34
|
+
base_display_class=display_context.workflow_display_class,
|
35
|
+
workflow_class=raise_if_descriptor(node.subworkflow),
|
36
|
+
parent_display_context=display_context,
|
37
|
+
)
|
38
|
+
serialized_subworkflow = subworkflow_display.serialize()
|
39
|
+
|
40
|
+
return {
|
41
|
+
"id": str(node_id),
|
42
|
+
"type": "SUBWORKFLOW",
|
43
|
+
"inputs": [node_input.dict() for node_input in node_inputs],
|
44
|
+
"data": {
|
45
|
+
"label": self.label,
|
46
|
+
"error_output_id": str(error_output_id) if error_output_id else None,
|
47
|
+
"source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
|
48
|
+
"target_handle_id": str(self.get_target_handle_id()),
|
49
|
+
"variant": "INLINE",
|
50
|
+
"workflow_raw_data": serialized_subworkflow["workflow_raw_data"],
|
51
|
+
"input_variables": [workflow_input.dict() for workflow_input in workflow_inputs],
|
52
|
+
"output_variables": [workflow_output.dict() for workflow_output in workflow_outputs],
|
53
|
+
},
|
54
|
+
"display_data": self.get_display_data().dict(),
|
55
|
+
"definition": self.get_definition().dict(),
|
56
|
+
}
|
57
|
+
|
58
|
+
def _generate_node_and_workflow_inputs(
|
59
|
+
self,
|
60
|
+
node_id: UUID,
|
61
|
+
node: Type[InlineSubworkflowNode],
|
62
|
+
display_context: WorkflowDisplayContext,
|
63
|
+
) -> Tuple[List[NodeInput], List[VellumVariable]]:
|
64
|
+
subworkflow_inputs = raise_if_descriptor(node.subworkflow_inputs)
|
65
|
+
node_inputs = [
|
66
|
+
create_node_input(
|
67
|
+
node_id=node_id,
|
68
|
+
input_name=variable_name,
|
69
|
+
value=variable_value,
|
70
|
+
display_context=display_context,
|
71
|
+
input_id=self.workflow_input_ids_by_name.get(variable_name),
|
72
|
+
)
|
73
|
+
for variable_name, variable_value in subworkflow_inputs.items()
|
74
|
+
]
|
75
|
+
node_inputs_by_key = {node_input.key: node_input for node_input in node_inputs}
|
76
|
+
workflow_inputs = [
|
77
|
+
VellumVariable(
|
78
|
+
id=node_inputs_by_key[descriptor.name].id,
|
79
|
+
key=descriptor.name,
|
80
|
+
type=infer_vellum_variable_type(descriptor),
|
81
|
+
)
|
82
|
+
for descriptor in raise_if_descriptor(node.subworkflow).get_inputs_class()
|
83
|
+
]
|
84
|
+
|
85
|
+
return node_inputs, workflow_inputs
|
86
|
+
|
87
|
+
def _generate_workflow_outputs(
|
88
|
+
self,
|
89
|
+
node: Type[InlineSubworkflowNode],
|
90
|
+
) -> List[VellumVariable]:
|
91
|
+
workflow_outputs: List[VellumVariable] = []
|
92
|
+
for output_descriptor in raise_if_descriptor(node.subworkflow).Outputs: # type: ignore[union-attr]
|
93
|
+
node_output_display = self.get_node_output_display(output_descriptor)
|
94
|
+
output_type = infer_vellum_variable_type(output_descriptor)
|
95
|
+
workflow_outputs.append(
|
96
|
+
VellumVariable(id=str(node_output_display.id), key=node_output_display.name, type=output_type)
|
97
|
+
)
|
98
|
+
|
99
|
+
return workflow_outputs
|
@@ -0,0 +1,100 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
from typing import Any, ClassVar, Dict, Generic, List, Optional, Type, TypeVar
|
3
|
+
|
4
|
+
from vellum import VellumVariable
|
5
|
+
|
6
|
+
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
7
|
+
from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
|
8
|
+
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
9
|
+
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
10
|
+
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
11
|
+
from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
|
12
|
+
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
13
|
+
from vellum.workflows.nodes import MapNode
|
14
|
+
from vellum.workflows.types.core import JsonObject
|
15
|
+
|
16
|
+
_MapNodeType = TypeVar("_MapNodeType", bound=MapNode)
|
17
|
+
|
18
|
+
|
19
|
+
class BaseMapNodeDisplay(BaseNodeVellumDisplay[_MapNodeType], Generic[_MapNodeType]):
|
20
|
+
workflow_input_ids_by_name: ClassVar[Dict[str, UUID]] = {}
|
21
|
+
|
22
|
+
def serialize(
|
23
|
+
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs: Any
|
24
|
+
) -> JsonObject:
|
25
|
+
node = self._node
|
26
|
+
node_id = self.node_id
|
27
|
+
|
28
|
+
workflow_inputs: List[VellumVariable] = []
|
29
|
+
subworkflow = raise_if_descriptor(node.subworkflow)
|
30
|
+
for descriptor in subworkflow.get_inputs_class():
|
31
|
+
# In WaC it's always 'all_items'
|
32
|
+
# In Vellum it's always 'items'
|
33
|
+
variable_name = descriptor.name if descriptor.name != "all_items" else "items"
|
34
|
+
variable_id = str(
|
35
|
+
self.workflow_input_ids_by_name.get(variable_name) or uuid4_from_hash(f"{self.node_id}|{variable_name}")
|
36
|
+
)
|
37
|
+
workflow_inputs.append(
|
38
|
+
VellumVariable(
|
39
|
+
id=variable_id,
|
40
|
+
key=variable_name,
|
41
|
+
type=infer_vellum_variable_type(descriptor),
|
42
|
+
)
|
43
|
+
)
|
44
|
+
|
45
|
+
items_workflow_input = next(input for input in workflow_inputs if input.key == "items")
|
46
|
+
item_workflow_input = next(input for input in workflow_inputs if input.key == "item")
|
47
|
+
index_workflow_input = next(input for input in workflow_inputs if input.key == "index")
|
48
|
+
|
49
|
+
workflow_outputs = self._generate_workflow_outputs(node)
|
50
|
+
|
51
|
+
items_node_input = create_node_input(
|
52
|
+
node_id=node_id,
|
53
|
+
input_name="items",
|
54
|
+
value=node.items,
|
55
|
+
display_context=display_context,
|
56
|
+
input_id=UUID(items_workflow_input.id),
|
57
|
+
)
|
58
|
+
node_inputs = [items_node_input]
|
59
|
+
|
60
|
+
subworkflow_display = get_workflow_display(
|
61
|
+
base_display_class=display_context.workflow_display_class,
|
62
|
+
workflow_class=subworkflow,
|
63
|
+
)
|
64
|
+
serialized_subworkflow = subworkflow_display.serialize()
|
65
|
+
|
66
|
+
return {
|
67
|
+
"id": str(node_id),
|
68
|
+
"type": "MAP",
|
69
|
+
"inputs": [node_input.dict() for node_input in node_inputs],
|
70
|
+
"data": {
|
71
|
+
"label": self.label,
|
72
|
+
"error_output_id": str(error_output_id) if error_output_id else None,
|
73
|
+
"source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
|
74
|
+
"target_handle_id": str(self.get_target_handle_id()),
|
75
|
+
"variant": "INLINE",
|
76
|
+
"workflow_raw_data": serialized_subworkflow["workflow_raw_data"],
|
77
|
+
"input_variables": [workflow_input.dict() for workflow_input in workflow_inputs],
|
78
|
+
"output_variables": [workflow_output.dict() for workflow_output in workflow_outputs],
|
79
|
+
"concurrency": raise_if_descriptor(node.concurrency),
|
80
|
+
"items_input_id": str(items_workflow_input.id),
|
81
|
+
"item_input_id": str(item_workflow_input.id),
|
82
|
+
"index_input_id": str(index_workflow_input.id),
|
83
|
+
},
|
84
|
+
"display_data": self.get_display_data().dict(),
|
85
|
+
"definition": self.get_definition().dict(),
|
86
|
+
}
|
87
|
+
|
88
|
+
def _generate_workflow_outputs(
|
89
|
+
self,
|
90
|
+
node: Type[MapNode],
|
91
|
+
) -> List[VellumVariable]:
|
92
|
+
workflow_outputs: List[VellumVariable] = []
|
93
|
+
for output_descriptor in raise_if_descriptor(node.subworkflow).Outputs: # type: ignore[union-attr]
|
94
|
+
node_output_display = self.get_node_output_display(output_descriptor)
|
95
|
+
output_type = infer_vellum_variable_type(output_descriptor)
|
96
|
+
workflow_outputs.append(
|
97
|
+
VellumVariable(id=str(node_output_display.id), key=node_output_display.name, type=output_type)
|
98
|
+
)
|
99
|
+
|
100
|
+
return workflow_outputs
|
@@ -0,0 +1,48 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
from typing import Any, ClassVar, Generic, List, Optional, TypeVar
|
3
|
+
|
4
|
+
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
5
|
+
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
6
|
+
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
7
|
+
from vellum_ee.workflows.display.vellum import EdgeVellumDisplay
|
8
|
+
from vellum.workflows.nodes.displayable import MergeNode
|
9
|
+
from vellum.workflows.types.core import JsonObject
|
10
|
+
|
11
|
+
_MergeNodeType = TypeVar("_MergeNodeType", bound=MergeNode)
|
12
|
+
|
13
|
+
|
14
|
+
class BaseMergeNodeDisplay(BaseNodeVellumDisplay[_MergeNodeType], Generic[_MergeNodeType]):
|
15
|
+
target_handle_ids: ClassVar[List[UUID]]
|
16
|
+
|
17
|
+
def serialize(self, display_context: WorkflowDisplayContext, **kwargs: Any) -> JsonObject:
|
18
|
+
node = self._node
|
19
|
+
node_id = self.node_id
|
20
|
+
|
21
|
+
all_edges: List[EdgeVellumDisplay] = [edge_display for _, edge_display in display_context.edge_displays.items()]
|
22
|
+
merged_edges = [edge for edge in all_edges if edge.target_node_id == self.node_id]
|
23
|
+
|
24
|
+
target_handle_ids = self.get_target_handle_ids()
|
25
|
+
|
26
|
+
if target_handle_ids is None:
|
27
|
+
target_handle_ids = [
|
28
|
+
uuid4_from_hash(f"{node_id}|target_handle|{edge.source_node_id}") for edge in merged_edges
|
29
|
+
]
|
30
|
+
elif len(target_handle_ids) != len(merged_edges):
|
31
|
+
raise ValueError("If you explicitly specify target_handle_ids, you must specify one for each incoming edge")
|
32
|
+
|
33
|
+
return {
|
34
|
+
"id": str(node_id),
|
35
|
+
"type": "MERGE",
|
36
|
+
"inputs": [],
|
37
|
+
"data": {
|
38
|
+
"label": self.label,
|
39
|
+
"merge_strategy": node.Trigger.merge_behavior.value,
|
40
|
+
"target_handles": [{"id": str(target_handle_id)} for target_handle_id in target_handle_ids],
|
41
|
+
"source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
|
42
|
+
},
|
43
|
+
"display_data": self.get_display_data().dict(),
|
44
|
+
"definition": self.get_definition().dict(),
|
45
|
+
}
|
46
|
+
|
47
|
+
def get_target_handle_ids(self) -> Optional[List[UUID]]:
|
48
|
+
return self._get_explicit_node_display_attr("target_handle_ids", List[UUID])
|
@@ -0,0 +1,68 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
from typing import Any, ClassVar, Dict, Generic, Optional, TypeVar, cast
|
3
|
+
|
4
|
+
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
5
|
+
from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
|
6
|
+
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
7
|
+
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
8
|
+
from vellum.workflows.nodes.displayable.prompt_deployment_node import PromptDeploymentNode
|
9
|
+
from vellum.workflows.references import OutputReference
|
10
|
+
from vellum.workflows.types.core import JsonObject
|
11
|
+
from vellum.workflows.vellum_client import create_vellum_client
|
12
|
+
|
13
|
+
_PromptDeploymentNodeType = TypeVar("_PromptDeploymentNodeType", bound=PromptDeploymentNode)
|
14
|
+
|
15
|
+
|
16
|
+
class BasePromptDeploymentNodeDisplay(
|
17
|
+
BaseNodeVellumDisplay[_PromptDeploymentNodeType], Generic[_PromptDeploymentNodeType]
|
18
|
+
):
|
19
|
+
output_id: ClassVar[Optional[UUID]] = None
|
20
|
+
array_output_id: ClassVar[Optional[UUID]] = None
|
21
|
+
prompt_input_ids_by_name: ClassVar[Dict[str, UUID]] = {}
|
22
|
+
|
23
|
+
def serialize(
|
24
|
+
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs: Any
|
25
|
+
) -> JsonObject:
|
26
|
+
node = self._node
|
27
|
+
node_id = self.node_id
|
28
|
+
|
29
|
+
prompt_inputs = raise_if_descriptor(node.prompt_inputs)
|
30
|
+
node_inputs = [
|
31
|
+
create_node_input(
|
32
|
+
node_id=node_id,
|
33
|
+
input_name=variable_name,
|
34
|
+
value=variable_value,
|
35
|
+
display_context=display_context,
|
36
|
+
input_id=self.prompt_input_ids_by_name.get(variable_name),
|
37
|
+
)
|
38
|
+
for variable_name, variable_value in prompt_inputs.items()
|
39
|
+
]
|
40
|
+
|
41
|
+
_, output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.text)]
|
42
|
+
_, array_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.results)]
|
43
|
+
|
44
|
+
# TODO: Pass through the name instead of retrieving the ID
|
45
|
+
# https://app.shortcut.com/vellum/story/4702
|
46
|
+
vellum_client = create_vellum_client()
|
47
|
+
deployment = vellum_client.deployments.retrieve(
|
48
|
+
id=str(raise_if_descriptor(node.deployment)),
|
49
|
+
)
|
50
|
+
|
51
|
+
return {
|
52
|
+
"id": str(node_id),
|
53
|
+
"type": "PROMPT",
|
54
|
+
"inputs": [node_input.dict() for node_input in node_inputs],
|
55
|
+
"data": {
|
56
|
+
"label": self.label,
|
57
|
+
"output_id": str(output_display.id),
|
58
|
+
"error_output_id": str(error_output_id) if error_output_id else None,
|
59
|
+
"array_output_id": str(array_display.id),
|
60
|
+
"source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
|
61
|
+
"target_handle_id": str(self.get_target_handle_id()),
|
62
|
+
"variant": "DEPLOYMENT",
|
63
|
+
"prompt_deployment_id": str(deployment.id),
|
64
|
+
"release_tag": raise_if_descriptor(node.release_tag),
|
65
|
+
},
|
66
|
+
"display_data": self.get_display_data().dict(),
|
67
|
+
"definition": self.get_definition().dict(),
|
68
|
+
}
|
@@ -0,0 +1,193 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from uuid import UUID
|
3
|
+
from typing import Any, Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union, cast
|
4
|
+
|
5
|
+
from vellum import (
|
6
|
+
MetadataFilterConfigRequest,
|
7
|
+
VellumValueLogicalConditionGroupRequest,
|
8
|
+
VellumValueLogicalConditionRequest,
|
9
|
+
)
|
10
|
+
|
11
|
+
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
12
|
+
from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
|
13
|
+
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
14
|
+
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
15
|
+
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
16
|
+
from vellum_ee.workflows.display.vellum import NodeInput
|
17
|
+
from vellum.workflows.nodes.displayable.search_node import SearchNode
|
18
|
+
from vellum.workflows.references import OutputReference
|
19
|
+
from vellum.workflows.types.core import JsonArray, JsonObject
|
20
|
+
|
21
|
+
_SearchNodeType = TypeVar("_SearchNodeType", bound=SearchNode)
|
22
|
+
|
23
|
+
|
24
|
+
@dataclass
|
25
|
+
class VariableIdMap:
|
26
|
+
id: Optional[UUID]
|
27
|
+
lhs: Optional["VariableIdMap"]
|
28
|
+
rhs: Optional["VariableIdMap"]
|
29
|
+
|
30
|
+
|
31
|
+
class BaseSearchNodeDisplay(BaseNodeVellumDisplay[_SearchNodeType], Generic[_SearchNodeType]):
|
32
|
+
variable_ids: Optional[VariableIdMap] = None
|
33
|
+
|
34
|
+
def serialize(
|
35
|
+
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs: Any
|
36
|
+
) -> JsonObject:
|
37
|
+
node = self._node
|
38
|
+
node_id = self.node_id
|
39
|
+
node_inputs = self._generate_search_node_inputs(node_id, node, display_context)
|
40
|
+
|
41
|
+
_, results_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.results)]
|
42
|
+
_, text_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.text)]
|
43
|
+
|
44
|
+
return {
|
45
|
+
"id": str(node_id),
|
46
|
+
"type": "SEARCH",
|
47
|
+
"inputs": [node_input.dict() for node_input in node_inputs.values()],
|
48
|
+
"data": {
|
49
|
+
"label": self.label,
|
50
|
+
"results_output_id": str(results_output_display.id),
|
51
|
+
"text_output_id": str(text_output_display.id),
|
52
|
+
"error_output_id": str(error_output_id) if error_output_id else None,
|
53
|
+
"source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
|
54
|
+
"target_handle_id": str(self.get_target_handle_id()),
|
55
|
+
"query_node_input_id": str(node_inputs["query"].id),
|
56
|
+
"document_index_node_input_id": str(node_inputs["document_index_id"].id),
|
57
|
+
"weights_node_input_id": str(node_inputs["weights"].id),
|
58
|
+
"limit_node_input_id": str(node_inputs["limit"].id),
|
59
|
+
"separator_node_input_id": str(node_inputs["separator"].id),
|
60
|
+
"result_merging_enabled_node_input_id": str(node_inputs["result_merging_enabled"].id),
|
61
|
+
"external_id_filters_node_input_id": str(node_inputs["external_id_filters"].id),
|
62
|
+
"metadata_filters_node_input_id": str(node_inputs["metadata_filters"].id),
|
63
|
+
},
|
64
|
+
"display_data": self.get_display_data().dict(),
|
65
|
+
"definition": self.get_definition().dict(),
|
66
|
+
}
|
67
|
+
|
68
|
+
def _generate_search_node_inputs(
|
69
|
+
self,
|
70
|
+
node_id: UUID,
|
71
|
+
node: Type[SearchNode],
|
72
|
+
display_context: WorkflowDisplayContext,
|
73
|
+
) -> Dict[str, NodeInput]:
|
74
|
+
node_inputs: Dict[str, NodeInput] = {}
|
75
|
+
|
76
|
+
options = raise_if_descriptor(node.options)
|
77
|
+
filters = options.filters if options else None
|
78
|
+
|
79
|
+
if filters and filters.external_ids:
|
80
|
+
# TODO: Add support for serializing external ID filters
|
81
|
+
# https://app.shortcut.com/vellum/story/5563/add-support-for-serializing-external-id-in-text-search-nodes
|
82
|
+
raise NotImplementedError("Serializing External ID filters is not yet supported")
|
83
|
+
|
84
|
+
raw_metadata_filters = filters.metadata if filters else None
|
85
|
+
metadata_filters = None
|
86
|
+
metadata_filters_node_inputs: list[NodeInput] = []
|
87
|
+
if raw_metadata_filters:
|
88
|
+
if isinstance(raw_metadata_filters, MetadataFilterConfigRequest):
|
89
|
+
raise ValueError(
|
90
|
+
"MetadataFilterConfigRequest is deprecated. Please use VellumValueLogicalExpressionRequest instead."
|
91
|
+
)
|
92
|
+
metadata_filters, metadata_filters_node_inputs = self._serialize_logical_expression(
|
93
|
+
raw_metadata_filters, display_context=display_context
|
94
|
+
)
|
95
|
+
|
96
|
+
result_merging = options.result_merging if options else None
|
97
|
+
result_merging_enabled = True if result_merging and result_merging.enabled else False
|
98
|
+
|
99
|
+
weights = options.weights if options else None
|
100
|
+
|
101
|
+
node_input_names_and_values = [
|
102
|
+
("query", node.query),
|
103
|
+
("document_index_id", node.document_index),
|
104
|
+
("weights", weights.dict() if weights else None),
|
105
|
+
("limit", options.limit if options else None),
|
106
|
+
("separator", raise_if_descriptor(node.chunk_separator)),
|
107
|
+
(
|
108
|
+
"result_merging_enabled",
|
109
|
+
("True" if result_merging_enabled else "False"),
|
110
|
+
),
|
111
|
+
("external_id_filters", None),
|
112
|
+
("metadata_filters", metadata_filters),
|
113
|
+
]
|
114
|
+
|
115
|
+
for node_input_name, node_input_value in node_input_names_and_values:
|
116
|
+
node_input = create_node_input(
|
117
|
+
node_id,
|
118
|
+
node_input_name,
|
119
|
+
node_input_value,
|
120
|
+
display_context,
|
121
|
+
input_id=self.node_input_ids_by_name.get(node_input_name),
|
122
|
+
)
|
123
|
+
node_inputs[node_input_name] = node_input
|
124
|
+
|
125
|
+
for node_input in metadata_filters_node_inputs:
|
126
|
+
node_inputs[node_input.key] = node_input
|
127
|
+
|
128
|
+
return node_inputs
|
129
|
+
|
130
|
+
def _serialize_logical_expression(
|
131
|
+
self,
|
132
|
+
logical_expression: Union[VellumValueLogicalConditionGroupRequest, VellumValueLogicalConditionRequest],
|
133
|
+
display_context: WorkflowDisplayContext,
|
134
|
+
path: List[int] = [],
|
135
|
+
variable_id_map: Optional[VariableIdMap] = None,
|
136
|
+
) -> Tuple[JsonObject, List[NodeInput]]:
|
137
|
+
if isinstance(logical_expression, VellumValueLogicalConditionGroupRequest):
|
138
|
+
conditions: JsonArray = []
|
139
|
+
variables = []
|
140
|
+
for idx, condition in enumerate(logical_expression.conditions):
|
141
|
+
serialized_condition, serialized_variables = self._serialize_logical_expression(
|
142
|
+
condition, display_context=display_context, path=path + [idx]
|
143
|
+
)
|
144
|
+
conditions.append(serialized_condition)
|
145
|
+
variables.extend(serialized_variables)
|
146
|
+
|
147
|
+
return (
|
148
|
+
{
|
149
|
+
"type": "LOGICAL_CONDITION_GROUP",
|
150
|
+
"combinator": logical_expression.combinator,
|
151
|
+
"conditions": conditions,
|
152
|
+
"negated": logical_expression.negated,
|
153
|
+
},
|
154
|
+
variables,
|
155
|
+
)
|
156
|
+
elif isinstance(logical_expression, VellumValueLogicalConditionRequest):
|
157
|
+
lhs_variable_id = (
|
158
|
+
variable_id_map.lhs.id
|
159
|
+
if variable_id_map and variable_id_map.lhs and variable_id_map.lhs.id
|
160
|
+
else uuid4_from_hash(f"{self.node_id}|{hash(tuple(path))}|lhs")
|
161
|
+
)
|
162
|
+
rhs_variable_id = (
|
163
|
+
variable_id_map.rhs.id
|
164
|
+
if variable_id_map and variable_id_map.rhs and variable_id_map.rhs.id
|
165
|
+
else uuid4_from_hash(f"{self.node_id}|{hash(tuple(path))}|rhs")
|
166
|
+
)
|
167
|
+
|
168
|
+
return (
|
169
|
+
{
|
170
|
+
"type": "LOGICAL_CONDITION",
|
171
|
+
"lhs": str(lhs_variable_id),
|
172
|
+
"operator": logical_expression.operator,
|
173
|
+
"rhs": str(rhs_variable_id),
|
174
|
+
},
|
175
|
+
[
|
176
|
+
create_node_input(
|
177
|
+
self.node_id,
|
178
|
+
f"vellum-query-builder-variable-{lhs_variable_id}",
|
179
|
+
logical_expression.lhs_variable.value,
|
180
|
+
display_context,
|
181
|
+
input_id=lhs_variable_id,
|
182
|
+
),
|
183
|
+
create_node_input(
|
184
|
+
self.node_id,
|
185
|
+
f"vellum-query-builder-variable-{rhs_variable_id}",
|
186
|
+
logical_expression.rhs_variable.value,
|
187
|
+
display_context,
|
188
|
+
input_id=rhs_variable_id,
|
189
|
+
),
|
190
|
+
],
|
191
|
+
)
|
192
|
+
else:
|
193
|
+
raise ValueError(f"Unsupported logical expression type: {type(logical_expression)}")
|