vellum-ai 0.9.16rc2__py3-none-any.whl → 0.9.16rc4__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/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.9.16rc4.dist-info}/METADATA +2 -1
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.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.9.16rc4.dist-info}/LICENSE +0 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/WHEEL +0 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.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)}")
|