vellum-ai 0.12.15__py3-none-any.whl → 0.12.16__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/prompts/blocks/compilation.py +43 -0
  3. vellum/workflows/nodes/core/inline_subworkflow_node/node.py +10 -2
  4. vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py +16 -0
  5. {vellum_ai-0.12.15.dist-info → vellum_ai-0.12.16.dist-info}/METADATA +10 -8
  6. {vellum_ai-0.12.15.dist-info → vellum_ai-0.12.16.dist-info}/RECORD +39 -36
  7. vellum_cli/__init__.py +14 -0
  8. vellum_cli/push.py +26 -4
  9. vellum_cli/tests/test_push.py +63 -0
  10. vellum_ee/workflows/display/nodes/vellum/api_node.py +3 -3
  11. vellum_ee/workflows/display/nodes/vellum/base_node.py +17 -0
  12. vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +2 -2
  13. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +2 -2
  14. vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +20 -6
  15. vellum_ee/workflows/display/nodes/vellum/map_node.py +1 -0
  16. vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +2 -2
  17. vellum_ee/workflows/display/nodes/vellum/search_node.py +4 -2
  18. vellum_ee/workflows/display/nodes/vellum/templating_node.py +1 -1
  19. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +3 -3
  20. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py +0 -0
  21. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py +28 -0
  22. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py +123 -0
  23. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +2 -11
  24. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py +2 -14
  25. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py +1 -7
  26. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +17 -1
  27. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +17 -1
  28. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +1 -9
  29. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +1 -1
  30. vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +1 -4
  31. vellum_ee/workflows/display/types.py +5 -1
  32. vellum_ee/workflows/display/utils/vellum.py +3 -3
  33. vellum_ee/workflows/display/vellum.py +4 -0
  34. vellum_ee/workflows/display/workflows/base_workflow_display.py +44 -16
  35. vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py +3 -0
  36. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +7 -8
  37. {vellum_ai-0.12.15.dist-info → vellum_ai-0.12.16.dist-info}/LICENSE +0 -0
  38. {vellum_ai-0.12.15.dist-info → vellum_ai-0.12.16.dist-info}/WHEEL +0 -0
  39. {vellum_ai-0.12.15.dist-info → vellum_ai-0.12.16.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@ class BaseClientWrapper:
18
18
  headers: typing.Dict[str, str] = {
19
19
  "X-Fern-Language": "Python",
20
20
  "X-Fern-SDK-Name": "vellum-ai",
21
- "X-Fern-SDK-Version": "0.12.15",
21
+ "X-Fern-SDK-Version": "0.12.16",
22
22
  }
23
23
  headers["X_API_KEY"] = self.api_key
24
24
  return headers
@@ -10,6 +10,12 @@ from vellum import (
10
10
  StringVellumValue,
11
11
  VellumVariable,
12
12
  )
13
+ from vellum.client.types.audio_vellum_value import AudioVellumValue
14
+ from vellum.client.types.function_call import FunctionCall
15
+ from vellum.client.types.function_call_vellum_value import FunctionCallVellumValue
16
+ from vellum.client.types.image_vellum_value import ImageVellumValue
17
+ from vellum.client.types.vellum_audio import VellumAudio
18
+ from vellum.client.types.vellum_image import VellumImage
13
19
  from vellum.prompts.blocks.exceptions import PromptCompilationError
14
20
  from vellum.prompts.blocks.types import CompiledChatMessagePromptBlock, CompiledPromptBlock, CompiledValuePromptBlock
15
21
  from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS
@@ -112,6 +118,43 @@ def compile_prompt_blocks(
112
118
 
113
119
  elif block.block_type == "FUNCTION_DEFINITION":
114
120
  raise PromptCompilationError("Function definitions shouldn't go through compilation process")
121
+
122
+ elif block.block_type == "FUNCTION_CALL":
123
+ function_call_block = CompiledValuePromptBlock(
124
+ content=FunctionCallVellumValue(
125
+ value=FunctionCall(
126
+ id=block.id,
127
+ name=block.name,
128
+ arguments=block.arguments,
129
+ ),
130
+ ),
131
+ cache_config=block.cache_config,
132
+ )
133
+ compiled_blocks.append(function_call_block)
134
+
135
+ elif block.block_type == "IMAGE":
136
+ image_block = CompiledValuePromptBlock(
137
+ content=ImageVellumValue(
138
+ value=VellumImage(
139
+ src=block.src,
140
+ metadata=block.metadata,
141
+ ),
142
+ ),
143
+ cache_config=block.cache_config,
144
+ )
145
+ compiled_blocks.append(image_block)
146
+
147
+ elif block.block_type == "AUDIO":
148
+ audio_block = CompiledValuePromptBlock(
149
+ content=AudioVellumValue(
150
+ value=VellumAudio(
151
+ src=block.src,
152
+ metadata=block.metadata,
153
+ ),
154
+ ),
155
+ cache_config=block.cache_config,
156
+ )
157
+ compiled_blocks.append(audio_block)
115
158
  else:
116
159
  raise PromptCompilationError(f"Unknown block_type: {block.block_type}")
117
160
 
@@ -1,5 +1,6 @@
1
1
  from typing import TYPE_CHECKING, ClassVar, Generic, Iterator, Optional, Set, Type, TypeVar, Union
2
2
 
3
+ from vellum.workflows.constants import UNDEF
3
4
  from vellum.workflows.context import execution_context, get_parent_context
4
5
  from vellum.workflows.errors.types import WorkflowErrorCode
5
6
  from vellum.workflows.exceptions import NodeException
@@ -27,7 +28,7 @@ class InlineSubworkflowNode(BaseNode[StateType], Generic[StateType, WorkflowInpu
27
28
  """
28
29
 
29
30
  subworkflow: Type["BaseWorkflow[WorkflowInputsType, InnerStateType]"]
30
- subworkflow_inputs: ClassVar[Union[EntityInputsInterface, BaseInputs]] = {}
31
+ subworkflow_inputs: ClassVar[Union[EntityInputsInterface, BaseInputs, Type[UNDEF]]] = UNDEF
31
32
 
32
33
  def run(self) -> Iterator[BaseOutput]:
33
34
  with execution_context(parent_context=get_parent_context() or self._context.parent_context):
@@ -71,7 +72,14 @@ class InlineSubworkflowNode(BaseNode[StateType], Generic[StateType, WorkflowInpu
71
72
 
72
73
  def _compile_subworkflow_inputs(self) -> WorkflowInputsType:
73
74
  inputs_class = self.subworkflow.get_inputs_class()
74
- if isinstance(self.subworkflow_inputs, dict):
75
+ if self.subworkflow_inputs is UNDEF:
76
+ inputs_dict = {}
77
+ for descriptor in inputs_class:
78
+ if hasattr(self, descriptor.name):
79
+ inputs_dict[descriptor.name] = getattr(self, descriptor.name)
80
+
81
+ return inputs_class(**inputs_dict)
82
+ elif isinstance(self.subworkflow_inputs, dict):
75
83
  return inputs_class(**self.subworkflow_inputs)
76
84
  elif isinstance(self.subworkflow_inputs, inputs_class):
77
85
  return self.subworkflow_inputs
@@ -39,3 +39,19 @@ def test_inline_subworkflow_node__inputs(inputs):
39
39
  assert events == [
40
40
  BaseOutput(name="out", value="bar"),
41
41
  ]
42
+
43
+
44
+ def test_inline_subworkflow_node__support_inputs_as_attributes():
45
+ # GIVEN a node setup with subworkflow inputs
46
+ class MyNode(InlineSubworkflowNode):
47
+ subworkflow = MySubworkflow
48
+ foo = "bar"
49
+
50
+ # WHEN the node is run
51
+ node = MyNode()
52
+ events = list(node.run())
53
+
54
+ # THEN the output is as expected
55
+ assert events == [
56
+ BaseOutput(name="out", value="bar"),
57
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.12.15
3
+ Version: 0.12.16
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -40,9 +40,11 @@ Requires-Dist: typing_extensions (>=4.0.0)
40
40
  Description-Content-Type: text/markdown
41
41
 
42
42
  <p align="center">
43
- <h1 align="center">
44
- Vellum
45
- </h1>
43
+ <a href="https://vellum.ai">
44
+ <picture>
45
+ <img alt="Vellum README banner" src="https://storage.googleapis.com/vellum-public/assets/github-readme-banner.png" height="128">
46
+ </picture>
47
+ </a>
46
48
  <p align="center">
47
49
  <a href="https://vellum.ai">Learn more</a>
48
50
  ·
@@ -64,13 +66,13 @@ Description-Content-Type: text/markdown
64
66
 
65
67
  # Introduction
66
68
 
67
- [Vellum](https://www.vellum.ai/) is the end-to-end development platform for building production-grade AI applications
69
+ [Vellum](https://www.vellum.ai/) is the end-to-end development platform for building production-grade AI applications.
68
70
 
69
71
  ### Core Features
70
72
 
71
73
  - **Orchestration:** A powerful SDK and IDE for defining and debugging the control flow of your AI applications
72
74
  - **Prompting:** A best-in-class prompt playground for iterating on and refining prompts between models from any provider
73
- - **Evaluations**: An evaluations framework that makes it easy to measure the quality of your AI systems at scale.
75
+ - **Evaluations**: An evaluations framework that makes it easy to measure the quality of your AI systems at scale
74
76
  - **Retrieval:** A ready-to-go service for turning unstructured content into intelligent, context-aware solutions
75
77
  optimized for AI systems
76
78
  - **Deployment:** Decouple updates to your AI systems from your application code with an easy integration +
@@ -87,7 +89,7 @@ Description-Content-Type: text/markdown
87
89
 
88
90
  ## Get Started
89
91
 
90
- Most functionality within the SDKs here requires a Vellum account and API key. To sign up, [talk to us](https://www.vellum.ai/landing-pages/request-demo)
92
+ Most functionality within the SDK requires a Vellum account and API key. To sign up, [talk to us](https://www.vellum.ai/landing-pages/request-demo)
91
93
  or visit our [pricing page](https://www.vellum.ai/pricing).
92
94
 
93
95
  Even without a Vellum account, you can use the Workflows SDK to define the control flow of your AI systems. [Learn
@@ -101,7 +103,7 @@ Learn more and get started by visiting the [Vellum Client SDK README](/src/vellu
101
103
  ## Workflows SDK
102
104
 
103
105
  The Vellum Workflows SDK is a high-level framework for defining and debugging the control flow of AI systems. At
104
- it's core, it's a powerful workflow engine with syntactic sugar for intuitively defining graphs, the nodes within,
106
+ it's core, it's a powerful workflow engine with syntactic sugar for declaratively defining graphs, the nodes within,
105
107
  and the relationships between them.
106
108
 
107
109
  The Workflows SDK can be used with or without a Vellum account, but a Vellum account is required to use certain
@@ -1,18 +1,18 @@
1
1
  vellum_cli/CONTRIBUTING.md,sha256=FtDC7BGxSeMnwCXAUssFsAIElXtmJE-O5Z7BpolcgvI,2935
2
2
  vellum_cli/README.md,sha256=2NudRoLzWxNKqnuVy1JuQ7DerIaxWGYkrH8kMd-asIE,90
3
- vellum_cli/__init__.py,sha256=iims87aL6HbwggCAh8JfLBNf3C7tN3TGDmlg7V5W9Lg,8506
3
+ vellum_cli/__init__.py,sha256=7liY2AX5t51Vd_usohIU6QSLjAsF6MaHD30L6ng9SSg,8926
4
4
  vellum_cli/aliased_group.py,sha256=ugW498j0yv4ALJ8vS9MsO7ctDW7Jlir9j6nE_uHAP8c,3363
5
5
  vellum_cli/config.py,sha256=998IZbvkrw2avjbvs8bw6NrbEgGz5UBKRbvKAcastJg,5493
6
6
  vellum_cli/image_push.py,sha256=SJwhwWJsLjwGNezNVd_oCVpFMfPsAB3dfLWmriZZUtw,4419
7
7
  vellum_cli/logger.py,sha256=PuRFa0WCh4sAGFS5aqWB0QIYpS6nBWwPJrIXpWxugV4,1022
8
8
  vellum_cli/pull.py,sha256=hYQBe2_-Y4Ieh_Jo54EwBUpqPYq6UYitUBPgqyOVba0,7499
9
- vellum_cli/push.py,sha256=00VHNlUc41UdO59gwIhSuk3AFL3kDITNQdWCdnYAtxc,5633
9
+ vellum_cli/push.py,sha256=iQ2H-vY8njqiYgIifGooqopqkb1BUUA3I7IN7VIHKv8,6149
10
10
  vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  vellum_cli/tests/conftest.py,sha256=eFGwBxib3Nki830lIFintB0b6r4x8T_KMnmzhlTY5x0,1337
12
12
  vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
13
13
  vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
14
14
  vellum_cli/tests/test_pull.py,sha256=6gbASF6ASy5YcdWjOCt6b5K0u2VWsFegdrTWu6sEVKs,19613
15
- vellum_cli/tests/test_push.py,sha256=NpwGXuZSzrR7B6hBO1UF9O8im13_LlpSqncVSdzYDiQ,5812
15
+ vellum_cli/tests/test_push.py,sha256=sqPy1N9TOa0Wwk4tfEZm18BnfcwRSoQboTWW_PHQA-E,8145
16
16
  vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -27,53 +27,56 @@ vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=QqR3Ly0
27
27
  vellum_ee/workflows/display/nodes/types.py,sha256=St1BB6no528OyELGiyRabWao0GGw6mLhstQAvEACbGk,247
28
28
  vellum_ee/workflows/display/nodes/utils.py,sha256=sloya5TpXsnot1HURc9L51INwflRqUzHxRVnCS9Cd-4,973
29
29
  vellum_ee/workflows/display/nodes/vellum/__init__.py,sha256=_raKY9eKi_OvIFn6nGvf9xKSboKtYLHCWaWCwDQFbOc,1567
30
- vellum_ee/workflows/display/nodes/vellum/api_node.py,sha256=4SSQGecKWHuoGy5YIGJeOZVHGKwTs_8Y-gf3GvsHb0M,8506
31
- vellum_ee/workflows/display/nodes/vellum/base_node.py,sha256=CBE-4tgQhk5zEcQqGQ0R6ZqZbtNuxAaJ5tDD8jDLOfY,672
32
- vellum_ee/workflows/display/nodes/vellum/code_execution_node.py,sha256=qrf2Ne8n2aaoa2xgK3ExCEGI9BA-2g1zmvjSHyzCWmQ,4230
30
+ vellum_ee/workflows/display/nodes/vellum/api_node.py,sha256=zucBb2neqTig5Q3HCiMrksRdg-WISnR2prFxYzk3WL0,8527
31
+ vellum_ee/workflows/display/nodes/vellum/base_node.py,sha256=M59-Kwz6bQ_j8yWLAtJikye-iOl5WtMI8eMnTtvb8SQ,1508
32
+ vellum_ee/workflows/display/nodes/vellum/code_execution_node.py,sha256=Kp-0YRZoy_Pi7HdwUgBxV57a6BzyoxotsvFsfoSGg40,4244
33
33
  vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=EtdqJfhYw03PuT2iyJ6mSAZK4RsQqDie_2AnJAtMelk,13625
34
34
  vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=ygTjSjYDI4DtkxADWub5rhBnRWItMKWF6fezBrgpOKA,1979
35
35
  vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=t5iJQVoRT5g-v2IiUb4kFYdvUVKch0zn27016pzDZoo,2761
36
36
  vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=3TJvHX_Uuf_gr94VkYc_zmNH8I5p71ChIeoAbJZ3ddY,2158
37
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=DYhxHgFT06CNCpovO4Z-wFPqCjFKxyl89ygFs8AucRQ,7189
38
- vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=IqPQdlxLdaMirgDbOSxq17d8bolqqjjRPy4t3YCBhmc,5028
39
- vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=AqUlItgSZij12qRKguKVmDbbaLuDy3Cdom5uOlJPqrc,3640
37
+ vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=dcrCIIWeL5RDHEmc9eyHEdDvxrzQddm71TUtLVcVH8I,7203
38
+ vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=_cdCzwbwB3gvcLz3UOgvmpz_AZwhXaU8CsOj9nuHB0M,5566
39
+ vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=y05CB-Pa5-H22YYSjqKnwGyUnuFqjiawbmjVPoElIQw,3692
40
40
  vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=jzO63B9KiEAncnBqmz2ZTcxjmEHozMEe7WnfpcpsQYg,3195
41
41
  vellum_ee/workflows/display/nodes/vellum/note_node.py,sha256=9VpC3h0RYOxJuRbjDwidBYlLKakkmlEnDMBh2C7lHcY,1107
42
- vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py,sha256=gLRkizwyw21-Z12IyDbdOJpXayiZZd4HWd6qgZQg8sc,3106
43
- vellum_ee/workflows/display/nodes/vellum/search_node.py,sha256=laNWcDt62VRM5hLfcOi-ouAyNhYiFRsD0PWbVGLwlLI,9035
42
+ vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py,sha256=3uvSVvNNwVhqxsEh4moW_gIQss1bIuw9Do8XPWr9XLA,3120
43
+ vellum_ee/workflows/display/nodes/vellum/search_node.py,sha256=sSO7n-UXoIdolRAqyKy6MdpdC-hrrt83ntSWe_qLKEM,9071
44
44
  vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py,sha256=zOp4voBSgB3MR1R93wTOrsiiara_hxEAYFupLl_SvTA,2657
45
- vellum_ee/workflows/display/nodes/vellum/templating_node.py,sha256=IHumtFFZSanRizU3-0ATFgUnDuSFZMScZce8YTDJiGU,3373
45
+ vellum_ee/workflows/display/nodes/vellum/templating_node.py,sha256=l_QDDTxHxmnwGKr6IwZZvwUMXAjSHJPNE8hf5tY75b4,3380
46
46
  vellum_ee/workflows/display/nodes/vellum/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py,sha256=aJfQnIvlrRHVKgQid_gg6VQKkJyPgFnzbvWt9_t0Vz0,3860
47
+ vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py,sha256=JPZKf7irQ38Dus5bWV_ysKkG97z0oeqP57lOptA-dPk,3881
48
48
  vellum_ee/workflows/display/nodes/vellum/try_node.py,sha256=hB8dcGMGkuC95kk9hmZUgHsCLwEA37fHTFXj0JzbRjM,4692
49
49
  vellum_ee/workflows/display/nodes/vellum/utils.py,sha256=6mPg9QilJfLw9Sgk_h9LRSyKZpKgRu06mr3X1AmmDCA,4691
50
50
  vellum_ee/workflows/display/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  vellum_ee/workflows/display/tests/test_vellum_workflow_display.py,sha256=TEg3QbdE7rLbEhml9pMWmay--phsekGlfGVhTblxCGE,1727
52
52
  vellum_ee/workflows/display/tests/workflow_serialization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py,sha256=5UTzBUKC1H5ve9MJGJMMLGhQ-1ZV4NPn6wYYEdreNxM,1172
55
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=nhqi4D_6R9WtQG2WYyPy9RdoollwriWc-72BgOBY9BM,4035
53
56
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=e__ae2yepB5vlgVT08sr1DDB8pYjax6VQLo5FtRk-nA,17934
54
57
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py,sha256=F822H2tM3Fvmc2PvunrVCRhtSKQLLpi5y2L1gyJKa78,31576
55
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py,sha256=T8gYYFd4jxOnrNp3Qhz4KH7ifvDPgyZxJJE7G9xt03U,52569
56
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py,sha256=zQ0MYjHeXR7sx4vGWEH6761DEEZ8RYMNr6ocRmLEAG0,6460
57
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py,sha256=YkgtdubGOl00kusqkADQ-YoTk6dCW83ShoV3DG9Pvuo,6182
58
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py,sha256=88z_dRc2sARwH73KqyZy6KXJCFPULdPKCeTJ2QJAODY,52192
59
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py,sha256=KNcZR9PhkXYUl-OFKc2XK9qG-C_28K01Le7ecpwPUfU,6143
60
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py,sha256=ZcKpGLZ-RyqfWzvVEsFywSYEqLHrIjFjx5RJmxJT_u4,6091
58
61
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py,sha256=vA8cd7PJYhf949OUGeYP_moKtMogSyfHN2Z-qzNQLwM,8294
59
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py,sha256=6z7WJ0GLhG7dhilenw7JTq1O8XUVeYmjJHHvgHBtQeU,21725
60
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py,sha256=iFbqXQr-4VyaqAYbldzRS4jt6G8f1Eoa1lTlMgJQO-Y,15599
61
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py,sha256=7f9sr8nv4pCqdic8E7RHDrbaOiExelIh7CZYAJ8QNus,9649
62
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py,sha256=7XaPhlX4TU7Ehq62opb_1vGHvynjxJLP_pYqyMt6IOI,22621
63
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py,sha256=lukNCF0w45X2i5SCT5KDMGFn0C0acBNY8t78sC4mBXQ,16485
64
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py,sha256=qXEVZ_OZUUvHZvQyXgVrjvhmvFp5As3DrHZWIvlhGsc,9345
62
65
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py,sha256=NkpgaTbu6nLr3iwgsSNtiHyiNDCUaFakd1JaoW6CC6Y,9489
63
66
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_serialization.py,sha256=9R6ELHBn9tsp3cy15q1qp1OByyCxFOVdrM67EwCYY50,12984
64
67
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py,sha256=8bz0vm_EyQKSjnwS5vqqgnjE9ygvm-CaPKcwCfeOrlo,12704
65
68
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py,sha256=6LrGPS7e9CWpjFq2hpliSzP9kDpZ9KqvBNlNO3sq8cs,8063
66
69
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py,sha256=xG8nKA1iKXxUe1fnD2X6qm7cUGW14iq2P-L16zhcKC8,4271
67
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=Y_-JNnPI9nAK6cLWxGaxz9ngo0_Dr0j2VNqreFk4CtE,2659
68
- vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=jvjQju7DYUFQ3FffVVA7RXUO0UB7-Fhq_qH7MiT0XcI,8522
69
- vellum_ee/workflows/display/types.py,sha256=FSPg3TO8iNE2gnl1vn-nsMfit2V6yeBXW0Igh089A9w,2011
70
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=cE6dmre7LRfUV2sZReDhES1zHpYcNH07cDZCrXQsRDw,2638
71
+ vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=stOOF7n7oZvZby9Zyk0vr7dK3OG6bx9TEaIXFEZjX0o,8478
72
+ vellum_ee/workflows/display/types.py,sha256=-ninso8Yf2EBn_RkFhpOEOjRhX2bYgCeMWssHoEgPRg,2248
70
73
  vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
- vellum_ee/workflows/display/utils/vellum.py,sha256=-cz3xB-_-r1O9TBdLQPBvlpptg9CrZVNQ50QimmJFnA,5032
72
- vellum_ee/workflows/display/vellum.py,sha256=OSv0ZS50h1zJbunJ9TH7VEWFw-exXdK_ZsdzPxP9ROs,8814
74
+ vellum_ee/workflows/display/utils/vellum.py,sha256=72wyR_ngYjirPYT8kFDxVPtRdHT7FpzBpsjoGMh1q0c,5053
75
+ vellum_ee/workflows/display/vellum.py,sha256=FHf2GXJ-KNXstMgRg5Prp7BL_dbUt8BSrPxg_QgJmxM,8945
73
76
  vellum_ee/workflows/display/workflows/__init__.py,sha256=kapXsC67VJcgSuiBMa86FdePG5A9kMB5Pi4Uy1O2ob4,207
74
- vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=ydAbFMzcY2LURINZbXYm9BAXZdIa3-7rQ86Kupo7qcA,12804
75
- vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=AMxNnTm2z3LIR5rqxoCAfuy37F2FTuSRDVtKUoezO8M,1184
76
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=GhIviEMDWNw1p8z20ta08T5PeNCVJs5p2hrOX1uyNxg,17066
77
+ vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=u5u_KnDp_ktLBlfkT5wiGHIloodSlUT3D3_DQXijtMA,13735
78
+ vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=kp0u8LN_2IwshLrhMImhpZx1hRyAcD5gXY-kDuuaGMQ,1269
79
+ vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=sUQVEP2te48G97t-au_utKfMhePi4U5nmotzMln7Ga4,16943
77
80
  vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
81
  vellum_ee/workflows/server/virtual_file_loader.py,sha256=sQQFqn7xI0GfUlypWkVFl-X5ShXTh9bXq8N6qlQvSoE,1452
79
82
  vellum/__init__.py,sha256=wO2rKMEtIjNEb53CstEj-0qkUDiKKmGb_uxXEl-jS8c,35776
@@ -81,7 +84,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
81
84
  vellum/client/__init__.py,sha256=7yb5YnhvHQUJusa1WyUZcAKGol3z-Lfu07EfD03eEW4,111291
82
85
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
83
86
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
84
- vellum/client/core/client_wrapper.py,sha256=_Cf6x5JgwTAjYASLdfDJqsyFst0nGh8_6WqQT-DbLkk,1869
87
+ vellum/client/core/client_wrapper.py,sha256=2N1VoBiQAederYuBKuAwXoDAkbTGPnkciOAPvOv1Xyk,1869
85
88
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
86
89
  vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
87
90
  vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
@@ -668,7 +671,7 @@ vellum/plugins/utils.py,sha256=U9ZY9KdE3RRvbcG01hXxu9CvfJD6Fo7nJDgcHjQn0FI,606
668
671
  vellum/plugins/vellum_mypy.py,sha256=VC15EzjTsXOb9uF1bky4rcxePP-0epMVmCsLB2z4Dh8,24816
669
672
  vellum/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
670
673
  vellum/prompts/blocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
671
- vellum/prompts/blocks/compilation.py,sha256=GVxV0iaVp72RCNMlLtUasfg25jBjbeEu3u97QUSbrQo,7506
674
+ vellum/prompts/blocks/compilation.py,sha256=ISuvDHaeVCPb1L7l4umORCECkDn0-rvE49hopz6c2gM,9222
672
675
  vellum/prompts/blocks/exceptions.py,sha256=vmk5PV6Vyw9nKjZYQDUDW0LH8MfQNIgFvFb_mFWdIRI,50
673
676
  vellum/prompts/blocks/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
674
677
  vellum/prompts/blocks/tests/test_compilation.py,sha256=0DhMoc4huHR6YnNL-0aBLmWSyUfw2BpRq_gEdKsQmAc,3693
@@ -1291,9 +1294,9 @@ vellum/workflows/nodes/core/__init__.py,sha256=5zDMCmyt1v0HTJzlUBwq3U9L825yZGZhT
1291
1294
  vellum/workflows/nodes/core/error_node/__init__.py,sha256=g7RRnlHhqu4qByfLjBwCunmgGA8dI5gNsjS3h6TwlSI,60
1292
1295
  vellum/workflows/nodes/core/error_node/node.py,sha256=MFHU5vITYSK-L9CuMZ49In2ZeNLWnhZD0f8r5dWvb5Y,1270
1293
1296
  vellum/workflows/nodes/core/inline_subworkflow_node/__init__.py,sha256=nKNEH1QTl-1PcvmYoqSWEl0-t6gAur8GLTXHzklRQfM,84
1294
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py,sha256=zyKvpeNoD2D7vtGbNuvqXUxVgtkmSbk1XQExwX9KUf8,3602
1297
+ vellum/workflows/nodes/core/inline_subworkflow_node/node.py,sha256=XJLz7Kkk4OwrM-OcPjiLfF3XC49jDwsVKFPTNXkenvQ,3964
1295
1298
  vellum/workflows/nodes/core/inline_subworkflow_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1296
- vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py,sha256=99LLPgHMqohGL-G4KqOSjeVlDR_FH8Rv1gtRii85MC4,1143
1299
+ vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py,sha256=n0-821Ov9ZfRFX_lbzLy5o2rX8fEw2qoxz0aFWCOxVg,1547
1297
1300
  vellum/workflows/nodes/core/map_node/__init__.py,sha256=MXpZYmGfhsMJHqqlpd64WiJRtbAtAMQz-_3fCU_cLV0,56
1298
1301
  vellum/workflows/nodes/core/map_node/node.py,sha256=DTMoGqtR8MyfZ8jy8apNoN-4KFFFHywo87pfpqyBVEw,7322
1299
1302
  vellum/workflows/nodes/core/map_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1412,8 +1415,8 @@ vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528
1412
1415
  vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
1413
1416
  vellum/workflows/workflows/base.py,sha256=qdZYQq-jjdr0fYT0FCfmFuI5ypE3pANupgYcOqqML0o,18884
1414
1417
  vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1415
- vellum_ai-0.12.15.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1416
- vellum_ai-0.12.15.dist-info/METADATA,sha256=vXfKfASRTSAbS23j4YTI7V_hDRYglGisCWULazWGJfo,5168
1417
- vellum_ai-0.12.15.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1418
- vellum_ai-0.12.15.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1419
- vellum_ai-0.12.15.dist-info/RECORD,,
1418
+ vellum_ai-0.12.16.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1419
+ vellum_ai-0.12.16.dist-info/METADATA,sha256=dSVFM4nOL_e1hiNJX-uVrRBdO4-1wDtqhA3MZKwMLTM,5328
1420
+ vellum_ai-0.12.16.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1421
+ vellum_ai-0.12.16.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1422
+ vellum_ai-0.12.16.dist-info/RECORD,,
vellum_cli/__init__.py CHANGED
@@ -49,6 +49,11 @@ def workflows():
49
49
  @click.option("--deployment-name", type=str, help="Unique name for the Deployment")
50
50
  @click.option("--deployment-description", type=str, help="Description for the Deployment")
51
51
  @click.option("--release-tag", type=list, help="Release Tag for the Deployment", multiple=True)
52
+ @click.option(
53
+ "--dry-run",
54
+ is_flag=True,
55
+ help="Check the Workflow for errors and expected changes, without updating its state in Vellum.",
56
+ )
52
57
  def workflows_push(
53
58
  module: Optional[str],
54
59
  deploy: Optional[bool],
@@ -56,6 +61,7 @@ def workflows_push(
56
61
  deployment_name: Optional[str],
57
62
  deployment_description: Optional[str],
58
63
  release_tag: Optional[List[str]],
64
+ dry_run: Optional[bool],
59
65
  ) -> None:
60
66
  """
61
67
  Push Workflows to Vellum. If a module is provided, only the Workflow for that module will be pushed.
@@ -69,6 +75,7 @@ def workflows_push(
69
75
  deployment_name=deployment_name,
70
76
  deployment_description=deployment_description,
71
77
  release_tags=release_tag,
78
+ dry_run=dry_run,
72
79
  )
73
80
 
74
81
 
@@ -79,6 +86,11 @@ def workflows_push(
79
86
  @click.option("--deployment-name", type=str, help="Unique name for the Deployment")
80
87
  @click.option("--deployment-description", type=str, help="Description for the Deployment")
81
88
  @click.option("--release-tag", type=list, help="Release Tag for the Deployment", multiple=True)
89
+ @click.option(
90
+ "--dry-run",
91
+ is_flag=True,
92
+ help="Check the Workflow for errors and expected changes, without updating its state in Vellum.",
93
+ )
82
94
  def push_module(
83
95
  ctx: click.Context,
84
96
  deploy: Optional[bool],
@@ -86,6 +98,7 @@ def push_module(
86
98
  deployment_name: Optional[str],
87
99
  deployment_description: Optional[str],
88
100
  release_tag: Optional[List[str]],
101
+ dry_run: Optional[bool],
89
102
  ) -> None:
90
103
  """Push a specific module to Vellum"""
91
104
 
@@ -97,6 +110,7 @@ def push_module(
97
110
  deployment_name=deployment_name,
98
111
  deployment_description=deployment_description,
99
112
  release_tags=release_tag,
113
+ dry_run=dry_run,
100
114
  )
101
115
 
102
116
 
vellum_cli/push.py CHANGED
@@ -27,6 +27,7 @@ def push_command(
27
27
  deployment_name: Optional[str] = None,
28
28
  deployment_description: Optional[str] = None,
29
29
  release_tags: Optional[List[str]] = None,
30
+ dry_run: Optional[bool] = None,
30
31
  ) -> None:
31
32
  load_dotenv()
32
33
  logger = load_cli_logger()
@@ -49,7 +50,11 @@ def push_command(
49
50
  # Remove this once we could serialize using the artifact in Vembda
50
51
  # https://app.shortcut.com/vellum/story/5585
51
52
  workflow = BaseWorkflow.load_from_module(workflow_config.module)
52
- workflow_display = get_workflow_display(base_display_class=VellumWorkflowDisplay, workflow_class=workflow)
53
+ workflow_display = get_workflow_display(
54
+ base_display_class=VellumWorkflowDisplay,
55
+ workflow_class=workflow,
56
+ dry_run=dry_run or False,
57
+ )
53
58
  exec_config = workflow_display.serialize()
54
59
 
55
60
  container_tag = workflow_config.container_image_tag
@@ -114,11 +119,28 @@ def push_command(
114
119
  # We should check with fern if we could auto-serialize typed object fields for us
115
120
  # https://app.shortcut.com/vellum/story/5568
116
121
  deployment_config=deployment_config_serialized, # type: ignore[arg-type]
122
+ dry_run=dry_run,
117
123
  )
118
- logger.info(
119
- f"""Successfully pushed {label} to Vellum!
124
+
125
+ if dry_run:
126
+ error_messages = [str(e) for e in workflow_display.errors]
127
+ error_message = "\n".join(error_messages) if error_messages else "No errors found."
128
+ logger.info(
129
+ f"""\
130
+ # Workflow Push Report
131
+
132
+ ## Errors
133
+ {error_message}
134
+
135
+ ## Proposed Diffs
136
+ {json.dumps(response.proposed_diffs, indent=2)}
137
+ """
138
+ ) # type: ignore[attr-defined]
139
+ else:
140
+ logger.info(
141
+ f"""Successfully pushed {label} to Vellum!
120
142
  Visit at: https://app.vellum.ai/workflow-sandboxes/{response.workflow_sandbox_id}"""
121
- )
143
+ )
122
144
 
123
145
  requires_save = False
124
146
  if not workflow_config.workflow_sandbox_id:
@@ -171,3 +171,66 @@ class ExampleWorkflow(BaseWorkflow):
171
171
 
172
172
  extracted_files = _extract_tar_gz(call_args["artifact"].read())
173
173
  assert extracted_files["workflow.py"] == workflow_py_file_content
174
+
175
+
176
+ def test_push__dry_run_option_returns_report(mock_module, vellum_client):
177
+ # GIVEN a single workflow configured
178
+ temp_dir = mock_module.temp_dir
179
+ module = mock_module.module
180
+
181
+ # AND a workflow exists in the module successfully
182
+ base_dir = os.path.join(temp_dir, *module.split("."))
183
+ os.makedirs(base_dir, exist_ok=True)
184
+ workflow_py_file_content = """\
185
+ from typing import Dict
186
+ from vellum.workflows import BaseWorkflow
187
+ from vellum.workflows.nodes import BaseNode
188
+ from vellum_ee.workflows.display.nodes import BaseNodeDisplay
189
+
190
+ class NotSupportedNode(BaseNode):
191
+ pass
192
+
193
+ class NotSupportedNodeDisplay(BaseNodeDisplay[NotSupportedNode]):
194
+ def serialize(self, display_context, **kwargs) -> Dict:
195
+ raise NotImplementedError(f"Serialization is not supported.")
196
+
197
+ class ExampleWorkflow(BaseWorkflow):
198
+ graph = NotSupportedNode
199
+ """
200
+ with open(os.path.join(temp_dir, *module.split("."), "workflow.py"), "w") as f:
201
+ f.write(workflow_py_file_content)
202
+
203
+ # AND the push API call returns successfully
204
+ vellum_client.workflows.push.return_value = WorkflowPushResponse(
205
+ workflow_sandbox_id=str(uuid4()),
206
+ proposed_diffs={
207
+ "iterable_item_added": {
208
+ "root['raw_data']['nodes'][0]": {
209
+ "id": str(uuid4()),
210
+ "type": "GENERIC",
211
+ "definition": None,
212
+ "display_data": None,
213
+ "trigger": {"id": str(uuid4()), "merge_behavior": "AWAIT_ATTRIBUTES"},
214
+ "ports": [{"id": str(uuid4()), "name": "default", "type": "DEFAULT"}],
215
+ },
216
+ },
217
+ },
218
+ )
219
+
220
+ # WHEN calling `vellum push`
221
+ runner = CliRunner(mix_stderr=True)
222
+ result = runner.invoke(cli_main, ["push", module, "--dry-run"])
223
+
224
+ # THEN it should succeed
225
+ assert result.exit_code == 0
226
+
227
+ # AND we should have called the push API with the dry-run option
228
+ vellum_client.workflows.push.assert_called_once()
229
+ call_args = vellum_client.workflows.push.call_args.kwargs
230
+ assert call_args["dry_run"] is True
231
+
232
+ # AND the report should be in the output
233
+ assert "## Errors" in result.output
234
+ # assert "Serialization is not supported." in result.output
235
+ assert "## Proposed Diffs" in result.output
236
+ assert "iterable_item_added" in result.output
@@ -161,9 +161,9 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
161
161
  ]
162
162
  inputs.extend(additional_header_inputs)
163
163
 
164
- _, text_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.text)]
165
- _, json_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.json)]
166
- _, status_code_output_display = display_context.node_output_displays[
164
+ _, text_output_display = display_context.global_node_output_displays[cast(OutputReference, node.Outputs.text)]
165
+ _, json_output_display = display_context.global_node_output_displays[cast(OutputReference, node.Outputs.json)]
166
+ _, status_code_output_display = display_context.global_node_output_displays[
167
167
  cast(OutputReference, node.Outputs.status_code)
168
168
  ]
169
169
 
@@ -2,17 +2,34 @@ from typing import Any, Generic, TypeVar
2
2
 
3
3
  from vellum.workflows.nodes.bases.base import BaseNode
4
4
  from vellum.workflows.types.core import JsonObject
5
+ from vellum.workflows.utils.uuids import uuid4_from_hash
5
6
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
6
7
  from vellum_ee.workflows.display.types import WorkflowDisplayContext
8
+ from vellum_ee.workflows.display.vellum import GenericNodeDisplayData
7
9
 
8
10
  _BaseNodeType = TypeVar("_BaseNodeType", bound=BaseNode)
9
11
 
10
12
 
11
13
  class BaseNodeDisplay(BaseNodeVellumDisplay[_BaseNodeType], Generic[_BaseNodeType]):
12
14
  def serialize(self, display_context: WorkflowDisplayContext, **kwargs: Any) -> JsonObject:
15
+ node = self._node
13
16
  node_id = self.node_id
14
17
 
15
18
  return {
16
19
  "id": str(node_id),
20
+ "label": node.__qualname__,
17
21
  "type": "GENERIC",
22
+ "display_data": self.get_generic_node_display_data().dict(),
23
+ "definition": self.get_definition().dict(),
24
+ "trigger": {
25
+ "id": str(uuid4_from_hash(f"{node_id}|trigger")),
26
+ "merge_behavior": node.Trigger.merge_behavior.value,
27
+ },
28
+ "ports": [],
29
+ "adornments": None,
30
+ "attributes": [],
18
31
  }
32
+
33
+ def get_generic_node_display_data(self) -> GenericNodeDisplayData:
34
+ explicit_value = self._get_explicit_node_display_attr("display_data", GenericNodeDisplayData)
35
+ return explicit_value if explicit_value else GenericNodeDisplayData()
@@ -70,8 +70,8 @@ class BaseCodeExecutionNodeDisplay(BaseNodeVellumDisplay[_CodeExecutionNodeType]
70
70
 
71
71
  packages = raise_if_descriptor(node.packages)
72
72
 
73
- _, output_display = display_context.node_output_displays[node.Outputs.result]
74
- _, log_output_display = display_context.node_output_displays[node.Outputs.log]
73
+ _, output_display = display_context.global_node_output_displays[node.Outputs.result]
74
+ _, log_output_display = display_context.global_node_output_displays[node.Outputs.log]
75
75
 
76
76
  output_type = primitive_type_to_vellum_variable_type(node.get_output_type())
77
77
 
@@ -29,8 +29,8 @@ class BaseInlinePromptNodeDisplay(BaseNodeVellumDisplay[_InlinePromptNodeType],
29
29
  node_inputs, prompt_inputs = self._generate_node_and_prompt_inputs(node_id, node, display_context)
30
30
  input_variable_id_by_name = {prompt_input.key: prompt_input.id for prompt_input in prompt_inputs}
31
31
 
32
- _, output_display = display_context.node_output_displays[node.Outputs.text]
33
- _, array_display = display_context.node_output_displays[node.Outputs.results]
32
+ _, output_display = display_context.global_node_output_displays[node.Outputs.text]
33
+ _, array_display = display_context.global_node_output_displays[node.Outputs.results]
34
34
  node_blocks = raise_if_descriptor(node.blocks)
35
35
 
36
36
  return {
@@ -2,6 +2,7 @@ from uuid import UUID
2
2
  from typing import ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar, cast
3
3
 
4
4
  from vellum import VellumVariable
5
+ from vellum.workflows.inputs.base import BaseInputs
5
6
  from vellum.workflows.nodes import InlineSubworkflowNode
6
7
  from vellum.workflows.types.core import JsonObject
7
8
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
@@ -60,12 +61,25 @@ class BaseInlineSubworkflowNodeDisplay(
60
61
  node: Type[InlineSubworkflowNode],
61
62
  display_context: WorkflowDisplayContext,
62
63
  ) -> Tuple[List[NodeInput], List[VellumVariable]]:
64
+ subworkflow = raise_if_descriptor(node.subworkflow)
65
+ subworkflow_inputs_class = subworkflow.get_inputs_class()
63
66
  subworkflow_inputs = raise_if_descriptor(node.subworkflow_inputs)
64
- subworkflow_entries = (
65
- [(variable_name, variable_value) for variable_name, variable_value in subworkflow_inputs.items()]
66
- if isinstance(subworkflow_inputs, dict)
67
- else [(variable_ref.name, variable_value) for variable_ref, variable_value in subworkflow_inputs]
68
- )
67
+
68
+ if isinstance(subworkflow_inputs, BaseInputs):
69
+ subworkflow_entries = [
70
+ (variable_ref.name, variable_value) for variable_ref, variable_value in subworkflow_inputs
71
+ ]
72
+ elif isinstance(subworkflow_inputs, dict):
73
+ subworkflow_entries = [
74
+ (variable_name, variable_value) for variable_name, variable_value in subworkflow_inputs.items()
75
+ ]
76
+ else:
77
+ subworkflow_entries = [
78
+ (descriptor.name, getattr(subworkflow_inputs_class, descriptor.name))
79
+ for descriptor in subworkflow_inputs_class
80
+ if hasattr(subworkflow_inputs_class, descriptor.name)
81
+ ]
82
+
69
83
  node_inputs = [
70
84
  create_node_input(
71
85
  node_id=node_id,
@@ -83,7 +97,7 @@ class BaseInlineSubworkflowNodeDisplay(
83
97
  key=descriptor.name,
84
98
  type=infer_vellum_variable_type(descriptor),
85
99
  )
86
- for descriptor in raise_if_descriptor(node.subworkflow).get_inputs_class()
100
+ for descriptor in subworkflow_inputs_class
87
101
  ]
88
102
 
89
103
  return node_inputs, workflow_inputs
@@ -33,6 +33,7 @@ class BaseMapNodeDisplay(BaseNodeVellumDisplay[_MapNodeType], Generic[_MapNodeTy
33
33
  subworkflow_display = get_workflow_display(
34
34
  base_display_class=display_context.workflow_display_class,
35
35
  workflow_class=subworkflow,
36
+ parent_display_context=display_context,
36
37
  )
37
38
  serialized_subworkflow = subworkflow_display.serialize()
38
39