vellum-ai 0.14.1__py3-none-any.whl → 0.14.3__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.
Files changed (27) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/prompts/blocks/compilation.py +2 -2
  3. vellum/prompts/blocks/tests/test_compilation.py +9 -0
  4. vellum/utils/templating/constants.py +6 -2
  5. vellum/utils/templating/custom_filters.py +22 -1
  6. vellum/utils/templating/render.py +4 -3
  7. vellum/utils/templating/tests/__init__.py +0 -0
  8. vellum/utils/templating/tests/test_custom_filters.py +19 -0
  9. vellum/workflows/errors/types.py +3 -0
  10. vellum/workflows/nodes/core/templating_node/node.py +3 -3
  11. vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +41 -0
  12. vellum/workflows/nodes/displayable/code_execution_node/node.py +5 -4
  13. vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +51 -0
  14. vellum/workflows/nodes/displayable/code_execution_node/utils.py +13 -11
  15. {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.3.dist-info}/METADATA +1 -1
  16. {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.3.dist-info}/RECORD +27 -25
  17. vellum_cli/pull.py +3 -11
  18. vellum_ee/workflows/display/base.py +7 -6
  19. vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +3 -5
  20. vellum_ee/workflows/display/types.py +2 -3
  21. vellum_ee/workflows/display/vellum.py +12 -6
  22. vellum_ee/workflows/display/workflows/base_workflow_display.py +10 -18
  23. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +11 -38
  24. vellum_ee/workflows/tests/local_workflow/display/workflow.py +0 -4
  25. {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.3.dist-info}/LICENSE +0 -0
  26. {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.3.dist-info}/WHEEL +0 -0
  27. {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.3.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.14.1",
21
+ "X-Fern-SDK-Version": "0.14.3",
22
22
  }
23
23
  headers["X_API_KEY"] = self.api_key
24
24
  return headers
@@ -19,7 +19,7 @@ from vellum.client.types.vellum_audio import VellumAudio
19
19
  from vellum.client.types.vellum_image import VellumImage
20
20
  from vellum.prompts.blocks.exceptions import PromptCompilationError
21
21
  from vellum.prompts.blocks.types import CompiledChatMessagePromptBlock, CompiledPromptBlock, CompiledValuePromptBlock
22
- from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS
22
+ from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS, DEFAULT_JINJA_GLOBALS
23
23
  from vellum.utils.templating.render import render_sandboxed_jinja_template
24
24
  from vellum.utils.typing import cast_not_optional
25
25
 
@@ -74,7 +74,7 @@ def compile_prompt_blocks(
74
74
  template=block.template,
75
75
  input_values={name: inp.value for name, inp in inputs_by_name.items()},
76
76
  jinja_custom_filters=DEFAULT_JINJA_CUSTOM_FILTERS,
77
- jinja_globals=DEFAULT_JINJA_CUSTOM_FILTERS,
77
+ jinja_globals=DEFAULT_JINJA_GLOBALS,
78
78
  )
79
79
  jinja_content = StringVellumValue(value=rendered_template)
80
80
 
@@ -37,6 +37,14 @@ from vellum.prompts.blocks.types import CompiledChatMessagePromptBlock, Compiled
37
37
  CompiledValuePromptBlock(content=StringVellumValue(value="Repeat back to me Hello, world!")),
38
38
  ],
39
39
  ),
40
+ (
41
+ [JinjaPromptBlock(template="{{ re.search('test', message).group() }}")],
42
+ [PromptRequestStringInput(key="message", value="testing")],
43
+ [VellumVariable(id="1", type="STRING", key="message")],
44
+ [
45
+ CompiledValuePromptBlock(content=StringVellumValue(value="test")),
46
+ ],
47
+ ),
40
48
  # Rich Text
41
49
  (
42
50
  [
@@ -127,6 +135,7 @@ from vellum.prompts.blocks.types import CompiledChatMessagePromptBlock, Compiled
127
135
  "empty",
128
136
  "jinja-no-variables",
129
137
  "jinja-with-variables",
138
+ "jinja-with-custom-global",
130
139
  "rich-text-no-variables",
131
140
  "rich-text-with-variables",
132
141
  "chat-message",
@@ -10,7 +10,7 @@ import pydash
10
10
  import pytz
11
11
  import yaml
12
12
 
13
- from vellum.utils.templating.custom_filters import is_valid_json_string
13
+ from vellum.utils.templating.custom_filters import is_valid_json_string, replace
14
14
 
15
15
  DEFAULT_JINJA_GLOBALS: Dict[str, Any] = {
16
16
  "datetime": datetime,
@@ -23,6 +23,10 @@ DEFAULT_JINJA_GLOBALS: Dict[str, Any] = {
23
23
  "re": re,
24
24
  "yaml": yaml,
25
25
  }
26
- DEFAULT_JINJA_CUSTOM_FILTERS: Dict[str, Callable[[Union[str, bytes]], bool]] = {
26
+
27
+ FilterFunc = Union[Callable[[Union[str, bytes]], bool], Callable[[Any, Any, Any], str]]
28
+
29
+ DEFAULT_JINJA_CUSTOM_FILTERS: Dict[str, FilterFunc] = {
27
30
  "is_valid_json_string": is_valid_json_string,
31
+ "replace": replace,
28
32
  }
@@ -1,5 +1,7 @@
1
1
  import json
2
- from typing import Union
2
+ from typing import Any, Union
3
+
4
+ from vellum.workflows.state.encoder import DefaultStateEncoder
3
5
 
4
6
 
5
7
  def is_valid_json_string(value: Union[str, bytes]) -> bool:
@@ -10,3 +12,22 @@ def is_valid_json_string(value: Union[str, bytes]) -> bool:
10
12
  except ValueError:
11
13
  return False
12
14
  return True
15
+
16
+
17
+ def replace(s: Any, old: Any, new: Any) -> str:
18
+ def encode_to_str(obj: Any) -> str:
19
+ """Encode an object for template rendering using DefaultStateEncoder."""
20
+ try:
21
+ if isinstance(obj, str):
22
+ return obj
23
+ return json.dumps(obj, cls=DefaultStateEncoder)
24
+ except TypeError:
25
+ return str(obj)
26
+
27
+ if old == "":
28
+ return encode_to_str(s)
29
+
30
+ s_str = encode_to_str(s)
31
+ old_str = encode_to_str(old)
32
+ new_str = encode_to_str(new)
33
+ return s_str.replace(old_str, new_str)
@@ -1,14 +1,15 @@
1
1
  import json
2
- from typing import Any, Callable, Dict, Optional, Union
2
+ from typing import Any, Dict, Optional
3
3
 
4
4
  from jinja2.sandbox import SandboxedEnvironment
5
5
 
6
+ from vellum.utils.templating.constants import FilterFunc
6
7
  from vellum.utils.templating.exceptions import JinjaTemplateError
7
8
  from vellum.workflows.state.encoder import DefaultStateEncoder
8
9
 
9
10
 
10
11
  def finalize(obj: Any) -> str:
11
- if isinstance(obj, dict):
12
+ if isinstance(obj, (dict, list)):
12
13
  return json.dumps(obj, cls=DefaultStateEncoder)
13
14
 
14
15
  return str(obj)
@@ -18,7 +19,7 @@ def render_sandboxed_jinja_template(
18
19
  *,
19
20
  template: str,
20
21
  input_values: Dict[str, Any],
21
- jinja_custom_filters: Optional[Dict[str, Callable[[Union[str, bytes]], bool]]] = None,
22
+ jinja_custom_filters: Optional[Dict[str, FilterFunc]] = None,
22
23
  jinja_globals: Optional[Dict[str, Any]] = None,
23
24
  ) -> str:
24
25
  """Render a Jinja template within a sandboxed environment."""
File without changes
@@ -0,0 +1,19 @@
1
+ import pytest
2
+
3
+ from vellum.utils.templating.custom_filters import replace
4
+
5
+
6
+ @pytest.mark.parametrize(
7
+ ["input_str", "old", "new", "expected"],
8
+ [
9
+ ("foo", "foo", "bar", "bar"),
10
+ ({"message": "hello"}, "hello", "world", '{"message": "world"}'),
11
+ ("Value: 123", 123, 456, "Value: 456"),
12
+ (123, 2, 4, "143"),
13
+ ("", "", "", ""),
14
+ ("foo", "", "bar", "foo"),
15
+ ],
16
+ )
17
+ def test_replace(input_str, old, new, expected):
18
+ actual = replace(input_str, old, new)
19
+ assert actual == expected
@@ -13,6 +13,7 @@ class WorkflowErrorCode(Enum):
13
13
  INVALID_INPUTS = "INVALID_INPUTS"
14
14
  INVALID_OUTPUTS = "INVALID_OUTPUTS"
15
15
  INVALID_STATE = "INVALID_STATE"
16
+ INVALID_CODE = "INVALID_CODE"
16
17
  INVALID_TEMPLATE = "INVALID_TEMPLATE"
17
18
  INTERNAL_ERROR = "INTERNAL_ERROR"
18
19
  NODE_EXECUTION = "NODE_EXECUTION"
@@ -54,6 +55,7 @@ _WORKFLOW_EVENT_ERROR_CODE_TO_WORKFLOW_ERROR_CODE: Dict[WorkflowExecutionEventEr
54
55
  "INTERNAL_SERVER_ERROR": WorkflowErrorCode.INTERNAL_ERROR,
55
56
  "NODE_EXECUTION": WorkflowErrorCode.NODE_EXECUTION,
56
57
  "LLM_PROVIDER": WorkflowErrorCode.PROVIDER_ERROR,
58
+ "INVALID_CODE": WorkflowErrorCode.INVALID_CODE,
57
59
  "INVALID_TEMPLATE": WorkflowErrorCode.INVALID_TEMPLATE,
58
60
  "USER_DEFINED_ERROR": WorkflowErrorCode.USER_DEFINED_ERROR,
59
61
  }
@@ -71,6 +73,7 @@ _WORKFLOW_ERROR_CODE_TO_VELLUM_ERROR_CODE: Dict[WorkflowErrorCode, VellumErrorCo
71
73
  WorkflowErrorCode.INVALID_INPUTS: "INVALID_INPUTS",
72
74
  WorkflowErrorCode.INVALID_OUTPUTS: "INVALID_REQUEST",
73
75
  WorkflowErrorCode.INVALID_STATE: "INVALID_REQUEST",
76
+ WorkflowErrorCode.INVALID_CODE: "INVALID_CODE",
74
77
  WorkflowErrorCode.INVALID_TEMPLATE: "INVALID_INPUTS",
75
78
  WorkflowErrorCode.INTERNAL_ERROR: "INTERNAL_SERVER_ERROR",
76
79
  WorkflowErrorCode.NODE_EXECUTION: "USER_DEFINED_ERROR",
@@ -1,6 +1,6 @@
1
- from typing import Any, Callable, ClassVar, Dict, Generic, Mapping, Tuple, Type, TypeVar, Union, get_args
1
+ from typing import Any, ClassVar, Dict, Generic, Mapping, Tuple, Type, TypeVar, get_args
2
2
 
3
- from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS, DEFAULT_JINJA_GLOBALS
3
+ from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS, DEFAULT_JINJA_GLOBALS, FilterFunc
4
4
  from vellum.utils.templating.exceptions import JinjaTemplateError
5
5
  from vellum.utils.templating.render import render_sandboxed_jinja_template
6
6
  from vellum.workflows.errors import WorkflowErrorCode
@@ -54,7 +54,7 @@ class TemplatingNode(BaseNode[StateType], Generic[StateType, _OutputType], metac
54
54
  inputs: ClassVar[EntityInputsInterface]
55
55
 
56
56
  jinja_globals: Dict[str, Any] = DEFAULT_JINJA_GLOBALS
57
- jinja_custom_filters: Mapping[str, Callable[[Union[str, bytes]], bool]] = DEFAULT_JINJA_CUSTOM_FILTERS
57
+ jinja_custom_filters: Mapping[str, FilterFunc] = DEFAULT_JINJA_CUSTOM_FILTERS
58
58
 
59
59
  class Outputs(BaseNode.Outputs):
60
60
  """
@@ -4,6 +4,7 @@ from typing import List, Union
4
4
 
5
5
  from vellum.client.types.chat_message import ChatMessage
6
6
  from vellum.client.types.function_call import FunctionCall
7
+ from vellum.client.types.function_call_vellum_value import FunctionCallVellumValue
7
8
  from vellum.workflows.exceptions import NodeException
8
9
  from vellum.workflows.nodes.bases.base import BaseNode
9
10
  from vellum.workflows.nodes.core.templating_node.node import TemplatingNode
@@ -193,3 +194,43 @@ def test_templating_node__union_float_int_output():
193
194
 
194
195
  # THEN it should correctly parse as a float
195
196
  assert outputs.result == 42.5
197
+
198
+
199
+ def test_templating_node__replace_filter():
200
+ # GIVEN a templating node that outputs a complex object
201
+ class ReplaceFilterTemplateNode(TemplatingNode[BaseState, Json]):
202
+ template = """{{- prompt_outputs | selectattr(\'type\', \'equalto\', \'FUNCTION_CALL\') \
203
+ | list | replace(\"\\n\",\",\") -}}"""
204
+ inputs = {
205
+ "prompt_outputs": [FunctionCallVellumValue(value=FunctionCall(name="test", arguments={"key": "value"}))]
206
+ }
207
+
208
+ # WHEN the node is run
209
+ node = ReplaceFilterTemplateNode()
210
+ outputs = node.run()
211
+
212
+ # THEN the output is the expected JSON
213
+ assert outputs.result == [
214
+ {
215
+ "type": "FUNCTION_CALL",
216
+ "value": {
217
+ "name": "test",
218
+ "arguments": {"key": "value"},
219
+ "id": None,
220
+ },
221
+ }
222
+ ]
223
+
224
+
225
+ def test_templating_node__last_chat_message():
226
+ # GIVEN a templating node that outputs a complex object
227
+ class LastChatMessageTemplateNode(TemplatingNode[BaseState, List[ChatMessage]]):
228
+ template = """{{ chat_history[:-1] }}"""
229
+ inputs = {"chat_history": [ChatMessage(role="USER", text="Hello"), ChatMessage(role="ASSISTANT", text="World")]}
230
+
231
+ # WHEN the node is run
232
+ node = LastChatMessageTemplateNode()
233
+ outputs = node.run()
234
+
235
+ # THEN the output is the expected JSON
236
+ assert outputs.result == [ChatMessage(role="USER", text="Hello")]
@@ -93,13 +93,14 @@ class CodeExecutionNode(BaseNode[StateType], Generic[StateType, _OutputType], me
93
93
  log: str
94
94
 
95
95
  def run(self) -> Outputs:
96
- input_values = self._compile_code_inputs()
97
96
  output_type = self.__class__.get_output_type()
98
97
  code = self._resolve_code()
99
98
  if not self.packages and self.runtime == "PYTHON_3_11_6":
100
- logs, result = run_code_inline(code, input_values, output_type)
99
+ logs, result = run_code_inline(code, self.code_inputs, output_type)
101
100
  return self.Outputs(result=result, log=logs)
101
+
102
102
  else:
103
+ input_values = self._compile_code_inputs()
103
104
  expected_output_type = primitive_type_to_vellum_variable_type(output_type)
104
105
 
105
106
  code_execution_result = self._context.vellum_client.execute_code(
@@ -131,7 +132,7 @@ class CodeExecutionNode(BaseNode[StateType], Generic[StateType, _OutputType], me
131
132
  compiled_inputs.append(
132
133
  StringInput(
133
134
  name=input_name,
134
- value=str(input_value),
135
+ value=input_value,
135
136
  )
136
137
  )
137
138
  elif isinstance(input_value, VellumSecret):
@@ -193,7 +194,7 @@ class CodeExecutionNode(BaseNode[StateType], Generic[StateType, _OutputType], me
193
194
  )
194
195
  else:
195
196
  raise NodeException(
196
- message=f"Unrecognized input type for input '{input_name}'",
197
+ message=f"Unrecognized input type for input '{input_name}': {input_value.__class__.__name__}",
197
198
  code=WorkflowErrorCode.INVALID_INPUTS,
198
199
  )
199
200
 
@@ -7,6 +7,7 @@ from vellum.client.types.code_execution_package import CodeExecutionPackage
7
7
  from vellum.client.types.code_executor_secret_input import CodeExecutorSecretInput
8
8
  from vellum.client.types.function_call import FunctionCall
9
9
  from vellum.client.types.number_input import NumberInput
10
+ from vellum.workflows.errors import WorkflowErrorCode
10
11
  from vellum.workflows.exceptions import NodeException
11
12
  from vellum.workflows.inputs.base import BaseInputs
12
13
  from vellum.workflows.nodes.displayable.code_execution_node import CodeExecutionNode
@@ -559,3 +560,53 @@ def main(arg1: List[Dict]) -> float:
559
560
 
560
561
  # AND we should not have invoked the Code via Vellum since it's running inline
561
562
  vellum_client.execute_code.assert_not_called()
563
+
564
+
565
+ def test_run_node__code_execution_error():
566
+ # GIVEN a node that will raise an error during execution
567
+ class State(BaseState):
568
+ pass
569
+
570
+ class ExampleCodeExecutionNode(CodeExecutionNode[State, int]):
571
+ code = """\
572
+ def main(arg1: int, arg2: int) -> int:
573
+ return arg1 + arg2 + arg3
574
+ """
575
+ runtime = "PYTHON_3_11_6"
576
+ code_inputs = {
577
+ "arg1": 1,
578
+ "arg2": 2,
579
+ }
580
+
581
+ # WHEN we run the node
582
+ node = ExampleCodeExecutionNode(state=State())
583
+
584
+ # THEN it should raise a NodeException with the execution error
585
+ with pytest.raises(NodeException) as exc_info:
586
+ node.run()
587
+
588
+ # AND the error should contain the execution error details
589
+ assert "name 'arg3' is not defined" in str(exc_info.value)
590
+ assert exc_info.value.code == WorkflowErrorCode.INVALID_CODE
591
+
592
+
593
+ def test_run_node__array_of_bools_input():
594
+ # GIVEN a node that will raise an error during execution
595
+ class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, int]):
596
+ code = """\
597
+ def main(arg1: list[bool]) -> int:
598
+ return len(arg1)
599
+ """
600
+ runtime = "PYTHON_3_11_6"
601
+ code_inputs = {
602
+ "arg1": [True, False, True],
603
+ }
604
+
605
+ # WHEN we run the node
606
+ node = ExampleCodeExecutionNode()
607
+
608
+ # THEN it should raise a NodeException with the execution error
609
+ outputs = node.run()
610
+
611
+ # AND the error should contain the execution error details
612
+ assert outputs == {"result": 3, "log": ""}
@@ -1,14 +1,13 @@
1
1
  import io
2
2
  import os
3
3
  import re
4
- from typing import Any, List, Tuple, Union, get_args, get_origin
4
+ from typing import Any, Tuple, Union, get_args, get_origin
5
5
 
6
6
  from pydantic import BaseModel, ValidationError
7
7
 
8
- from vellum import VellumValue
9
- from vellum.client.types.code_executor_input import CodeExecutorInput
10
8
  from vellum.workflows.errors.types import WorkflowErrorCode
11
9
  from vellum.workflows.exceptions import NodeException
10
+ from vellum.workflows.types.core import EntityInputsInterface
12
11
 
13
12
 
14
13
  def read_file_from_path(node_filepath: str, script_filepath: str) -> Union[str, None]:
@@ -70,13 +69,11 @@ def _clean_for_dict_wrapper(obj):
70
69
 
71
70
  def run_code_inline(
72
71
  code: str,
73
- input_values: List[CodeExecutorInput],
72
+ inputs: EntityInputsInterface,
74
73
  output_type: Any,
75
74
  ) -> Tuple[str, Any]:
76
75
  log_buffer = io.StringIO()
77
76
 
78
- VELLUM_TYPES = get_args(VellumValue)
79
-
80
77
  def wrap_value(value):
81
78
  if isinstance(value, list):
82
79
  return ListWrapper(
@@ -84,7 +81,7 @@ def run_code_inline(
84
81
  # Convert VellumValue to dict with its fields
85
82
  (
86
83
  item.model_dump()
87
- if isinstance(item, VELLUM_TYPES)
84
+ if isinstance(item, BaseModel)
88
85
  else _clean_for_dict_wrapper(item) if isinstance(item, (dict, list)) else item
89
86
  )
90
87
  for item in value
@@ -93,18 +90,23 @@ def run_code_inline(
93
90
  return _clean_for_dict_wrapper(value)
94
91
 
95
92
  exec_globals = {
96
- "__arg__inputs": {input_value.name: wrap_value(input_value.value) for input_value in input_values},
93
+ "__arg__inputs": {name: wrap_value(value) for name, value in inputs.items()},
97
94
  "__arg__out": None,
98
95
  "print": lambda *args, **kwargs: log_buffer.write(f"{' '.join(args)}\n"),
99
96
  }
100
- run_args = [f"{input_value.name}=__arg__inputs['{input_value.name}']" for input_value in input_values]
97
+ run_args = [f"{name}=__arg__inputs['{name}']" for name in inputs.keys()]
101
98
  execution_code = f"""\
102
99
  {code}
103
100
 
104
101
  __arg__out = main({", ".join(run_args)})
105
102
  """
106
-
107
- exec(execution_code, exec_globals)
103
+ try:
104
+ exec(execution_code, exec_globals)
105
+ except Exception as e:
106
+ raise NodeException(
107
+ code=WorkflowErrorCode.INVALID_CODE,
108
+ message=str(e),
109
+ )
108
110
 
109
111
  logs = log_buffer.getvalue()
110
112
  result = exec_globals["__arg__out"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.1
3
+ Version: 0.14.3
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -6,7 +6,7 @@ vellum_cli/config.py,sha256=Bsb3mnvKvv3oOTcCuxpgC7lWPMqt6eJhgRA6VEE-vL4,9266
6
6
  vellum_cli/image_push.py,sha256=SJwhwWJsLjwGNezNVd_oCVpFMfPsAB3dfLWmriZZUtw,4419
7
7
  vellum_cli/logger.py,sha256=PuRFa0WCh4sAGFS5aqWB0QIYpS6nBWwPJrIXpWxugV4,1022
8
8
  vellum_cli/ping.py,sha256=lWyJw6sziXjyTopTYRdFF5hV-sYPVDdX0yVbG5fzcY4,585
9
- vellum_cli/pull.py,sha256=7yvg4oBOgsbBEsgXtCpYlNR4AOR8hPICamY-4HI-3kM,9031
9
+ vellum_cli/pull.py,sha256=SA2EOHXbLO_jGKhzUHNrLyxEwaPbeLiU3TeRY5oeX_Y,8877
10
10
  vellum_cli/push.py,sha256=xjTNbLwOVFNU3kpBrm56Bk5QkSRrJ9z86qceghCzfIA,9655
11
11
  vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  vellum_cli/tests/conftest.py,sha256=AFYZryKA2qnUuCPBxBKmHLFoPiE0WhBFFej9tNwSHdc,1526
@@ -19,7 +19,7 @@ vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  vellum_ee/workflows/display/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- vellum_ee/workflows/display/base.py,sha256=i8o7Ex0S9BVub_91s6D2a8kHGcv3ro5XGEwSzeVSz-Y,2083
22
+ vellum_ee/workflows/display/base.py,sha256=ak29FIsawhaFa9_paZUHThlZRFJ1xB486JWKuSt1PYY,1965
23
23
  vellum_ee/workflows/display/nodes/__init__.py,sha256=5XOcZJXYUgaLS55QgRJzyQ_W1tpeprjnYAeYVezqoGw,160
24
24
  vellum_ee/workflows/display/nodes/base_node_display.py,sha256=En8Ir2e1mpExkAi1T8ExOEpZbv5gu6OetaNq35-_WSY,16317
25
25
  vellum_ee/workflows/display/nodes/base_node_vellum_display.py,sha256=pLO0dORfRu--Ne9NgoyFT_CNjfpr5fGCsgbsMkUF5GM,2845
@@ -36,7 +36,7 @@ vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=I1Jkp2htRINJATtv1e
36
36
  vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=p-PvlnxpBQ7IKskZi2A19jKAtKnSxJ8LPbGMA83VkFk,2805
37
37
  vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=aYZSJTxknU4LMiQdWk9LcK6CkhdozeDEMiRxfAyUNEc,2202
38
38
  vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=aNZhjw5CwpUO8IcLJ2nhYrzn96RJ3FWeJXdfDizuPzw,8491
39
- vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=9858pFzuhkAAmLcw4gkt5mPvsqWk5vqcX_vwHOg2xZw,5610
39
+ vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=MU9I8CB1X1TgL1aa1eT6DHWwNJ-2v79t74xl0oy-fBo,5510
40
40
  vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=VlO3UwkspCOdDQ-h3v8k16-7JZwWNSLpOLT4p-eirIs,3740
41
41
  vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=HkNMgdQELiON42jdO-xDLmqrEKdGx1RVqrz2DXNTLS8,3239
42
42
  vellum_ee/workflows/display/nodes/vellum/note_node.py,sha256=TMb8txILu2uWjzoxaghjgjlzeBAgzn4vkP_8zSh2qoE,1151
@@ -80,16 +80,16 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_n
80
80
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py,sha256=NdhE3lm7RMQ8DqkraPSq24IbOxNla9unbs4tsMWRzm4,3781
81
81
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=gHKU8Vg960ooV3uXqM2LMnVS-mGbv3aagGozQuTVTjI,2455
82
82
  vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=huKAOeMJ2MKmp6XtbvMJTUadqynoV40Ypoz9jsBEBEQ,7431
83
- vellum_ee/workflows/display/types.py,sha256=bm355ZcZ-7WaesBvIB8RbWDD7qiFmazfcNb6tEZWx3M,2940
83
+ vellum_ee/workflows/display/types.py,sha256=xDC1zy4rWKNqDtSr-h6MQfWnJ6scZ_Sadxp4t8Q3PY4,2897
84
84
  vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  vellum_ee/workflows/display/utils/expressions.py,sha256=9FpOslDI-RCR5m4TgAu9KCHh4aTVnh7CHR2ykyMUDw0,1151
86
86
  vellum_ee/workflows/display/utils/vellum.py,sha256=UjK_RxnSEmlIu9klGCPWU5RAQBmgZ7cRbRdgxaTbubE,8081
87
- vellum_ee/workflows/display/vellum.py,sha256=PVte2gcp1_4g-8ZaM0XVAaDwf3O-kSHy7-5Q-Co-YG0,8463
87
+ vellum_ee/workflows/display/vellum.py,sha256=0Uwe1NJA_7trwSqqqaYwilqRp6_u2GqOwSNbgTVlgZE,8638
88
88
  vellum_ee/workflows/display/workflows/__init__.py,sha256=kapXsC67VJcgSuiBMa86FdePG5A9kMB5Pi4Uy1O2ob4,207
89
- vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=Amow11LhE-GL3j8bNZ8rK1iYKjkNOhH1ECMQ-dvyLAU,17204
89
+ vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=mqP81wMam8Xl0g0qeBrFiCfpUdKqlwySINK28UU8EzM,16974
90
90
  vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=kp0u8LN_2IwshLrhMImhpZx1hRyAcD5gXY-kDuuaGMQ,1269
91
91
  vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=yl1ytpl9_lijOGeDPWSypWYRJ7aOEVA7NgUg81jTuCs,2229
92
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=12miGvHL9_ZzXaU5r1u1TVTGSBrs8LHBVJU-DKfS0JE,18802
92
+ vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=3UHe61Em1Tj68ZAR4B6Ucas_vc1BuHlqwbicN-aJMys,17828
93
93
  vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
94
  vellum_ee/workflows/server/virtual_file_loader.py,sha256=X_DdNK7MfyOjKWekk6YQpOSCT6klKcdjT6nVJcBH1sM,1481
95
95
  vellum_ee/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -104,7 +104,7 @@ vellum_ee/workflows/tests/local_workflow/display/__init__.py,sha256=xo75Uqb4aErO
104
104
  vellum_ee/workflows/tests/local_workflow/display/nodes/__init__.py,sha256=szW_mgOUriyZ6v1vlnevBgkzNi8g83-ihS98UOLHVcE,155
105
105
  vellum_ee/workflows/tests/local_workflow/display/nodes/final_output.py,sha256=Kv92TCREiZsB9531KZYaBIq83uHn7e_ECw_yAbD1qfk,1017
106
106
  vellum_ee/workflows/tests/local_workflow/display/nodes/templating_node.py,sha256=5cankEe1rDZlXKgILFSPbmN0tUZhIdmcFgz_AguXTJc,1229
107
- vellum_ee/workflows/tests/local_workflow/display/workflow.py,sha256=I0uc9hmeQGMxUJMiOu1btBpUb2aSvIXUSNS05WiPeNA,2336
107
+ vellum_ee/workflows/tests/local_workflow/display/workflow.py,sha256=QV-TyH6FeqOZ53U8kj3m_annpYgRynG_hfrOuoV1cmk,2051
108
108
  vellum_ee/workflows/tests/local_workflow/inputs.py,sha256=4cgsZBoUbIY0Rs8gknC9yqxQ-sSoULclx_SAm1FT2RA,96
109
109
  vellum_ee/workflows/tests/local_workflow/metadata.json,sha256=rdu3h5qkFZiqhCAMxoyoWyMI0O8QALC5-URvSIW6F00,24
110
110
  vellum_ee/workflows/tests/local_workflow/nodes/__init__.py,sha256=1F6jxUpSKfPXPj4ZZKSbnX6Mg-VwF3euLJSZfGn6xkM,127
@@ -119,7 +119,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
119
119
  vellum/client/__init__.py,sha256=j6zi0NZ4BMC6JrwckvzMWuG5x8KoOvO4KqsLhvVCa68,117624
120
120
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
121
121
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
122
- vellum/client/core/client_wrapper.py,sha256=AN4UTP8OvOr6qMSP_VqGlHKGOVsUnQj3CLqFDhB3p5E,1868
122
+ vellum/client/core/client_wrapper.py,sha256=5MqSBkzxbM11wbTg4CUjaavYf5Rv9t5-_lqijxHjmU8,1868
123
123
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
124
124
  vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
125
125
  vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
@@ -709,10 +709,10 @@ vellum/plugins/utils.py,sha256=U9ZY9KdE3RRvbcG01hXxu9CvfJD6Fo7nJDgcHjQn0FI,606
709
709
  vellum/plugins/vellum_mypy.py,sha256=QTuMSq6PiZW1dyTUZ5Bf1d4XkgFj0TKAgZLP8f4UgL4,27914
710
710
  vellum/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
711
711
  vellum/prompts/blocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
712
- vellum/prompts/blocks/compilation.py,sha256=P2gdL4bRR1j0IbvQFzS13cJzGpnaDZFhdV3x5COVvs0,9481
712
+ vellum/prompts/blocks/compilation.py,sha256=lpGVuquFaHnGglON7-S8fIHgUIZyo6TdXOmBtG_Si-0,9497
713
713
  vellum/prompts/blocks/exceptions.py,sha256=vmk5PV6Vyw9nKjZYQDUDW0LH8MfQNIgFvFb_mFWdIRI,50
714
714
  vellum/prompts/blocks/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
715
- vellum/prompts/blocks/tests/test_compilation.py,sha256=WhR8L7AzxssZiizItAbbtQMXZ3An5RMUws0kfCwJBgw,4841
715
+ vellum/prompts/blocks/tests/test_compilation.py,sha256=EOUtdzJDFGbGhoc_y5XTMyO0HOpOM7FYJssPzd_yRVg,5235
716
716
  vellum/prompts/blocks/types.py,sha256=6aSJQco-5kKeadfKVVXF_SrQPlIJgMYVNc-C7so1sY8,975
717
717
  vellum/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
718
718
  vellum/resources/__init__.py,sha256=sQWK7g_Z4EM7pa7fy6vy3d_DMdTJ4wVcozBn3Lx4Qpo,141
@@ -1259,10 +1259,12 @@ vellum/types/workspace_read.py,sha256=9CvgvK8Li8vL6qC5KX7f3-nEHslJ4lw2w07bvXcrjA
1259
1259
  vellum/types/workspace_secret_read.py,sha256=Z6QNXHxVHRdrLXSI31KxngePRwJTVoJYMXVbtPQwrxs,159
1260
1260
  vellum/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1261
1261
  vellum/utils/templating/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1262
- vellum/utils/templating/constants.py,sha256=XTNmDsKa7byjw4GMZmzx2dUeYUTeMLZrPgRHcc80Kvc,613
1263
- vellum/utils/templating/custom_filters.py,sha256=Q0DahYRHP4KfaUXDt9XxN-DFLBrAxlv90yaVqxScoUw,264
1262
+ vellum/utils/templating/constants.py,sha256=8OHMO6WFAEimbIaiHc5gy6s91D7_KvW-vTlEMWwvl_M,711
1263
+ vellum/utils/templating/custom_filters.py,sha256=XVHriwazejRZmxB_eg4xHgCxl7AiQQ2sx-hRLMmylfU,885
1264
1264
  vellum/utils/templating/exceptions.py,sha256=cDp140PP4OnInW4qAvg3KqiSiF70C71UyEAKRBR1Abo,46
1265
- vellum/utils/templating/render.py,sha256=2n6M10p2WtM2_6I10PKOIyH_gTmAo5EkxDYL2DR7F4U,2014
1265
+ vellum/utils/templating/render.py,sha256=5OsD1e9fks1aysYTyPKjYGaloYUbIKWpajcxtjtiFuU,2037
1266
+ vellum/utils/templating/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1267
+ vellum/utils/templating/tests/test_custom_filters.py,sha256=mkJwc7t1gE13SKgPxhF-lN_m2XGCkphCB9Te81dGekI,532
1266
1268
  vellum/utils/typing.py,sha256=wx_daFqD69cYkuJTVnvNrpjhqC3uuhbnyJ9_bIwC9OU,327
1267
1269
  vellum/utils/uuid.py,sha256=Ch6wWRgwICxLxJCTl5iE3EdRlZj2zADR-zUMUtjcMWM,214
1268
1270
  vellum/version.py,sha256=jq-1PlAYxN9AXuaZqbYk9ak27SgE2lw9Ia5gx1b1gVI,76
@@ -1282,7 +1284,7 @@ vellum/workflows/emitters/base.py,sha256=D5SADKIvnbgKwIBgYm77jaqvpo1o0rz4MmuX_mu
1282
1284
  vellum/workflows/environment/__init__.py,sha256=wGHslgSEZ7Octe4C-hNtl84EFelNimgmWQoi7px4-uw,71
1283
1285
  vellum/workflows/environment/environment.py,sha256=0XhJPBs8YASWmvPx8bkSdCvcbDmzpe9stfs2kgtNDRU,296
1284
1286
  vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
1285
- vellum/workflows/errors/types.py,sha256=85tmSBt4d9OjUA4AdM5MvIy1vwVLpEu2MhkJhFF1q9k,3502
1287
+ vellum/workflows/errors/types.py,sha256=tVW7Il9zalnwWzdoDLqYPIvRTOhXIv6FPORZAbU7n5Q,3640
1286
1288
  vellum/workflows/events/__init__.py,sha256=6pxxceJo2dcaRkWtkDAYlUQZ-PHBQSZytIoyuUK48Qw,759
1287
1289
  vellum/workflows/events/node.py,sha256=uHT6If0esgZ3nLjrjmUPTKf3qbjGhoV_x5YKpjDBDcU,5280
1288
1290
  vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1348,8 +1350,8 @@ vellum/workflows/nodes/core/retry_node/node.py,sha256=loIZJUcCsN0y3mr4pw7f23l4eD
1348
1350
  vellum/workflows/nodes/core/retry_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1349
1351
  vellum/workflows/nodes/core/retry_node/tests/test_node.py,sha256=RM_OHwxrHwyxvlQQBJPqVBxpedFuWQ9h2-Xa3kP75sc,4399
1350
1352
  vellum/workflows/nodes/core/templating_node/__init__.py,sha256=GmyuYo81_A1_Bz6id69ozVFS6FKiuDsZTiA3I6MaL2U,70
1351
- vellum/workflows/nodes/core/templating_node/node.py,sha256=zCYhq88qLTvoC9LetVrD9sLXkwHZsaWekxMhru_nV70,3752
1352
- vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py,sha256=j6v3TTD4Fjq-sWcuOZOzX-okFUC18q2VKiPT9ot1bk8,5830
1353
+ vellum/workflows/nodes/core/templating_node/node.py,sha256=Vqlg4L-5XNuIdbZKQe-GEYqTIV7iXNjLO7QIRgz4ujc,3722
1354
+ vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py,sha256=nY2P6r7cW85k7NEKXUFNeDTMWlz8ZEZyMY2Sg-0qO_E,7327
1353
1355
  vellum/workflows/nodes/core/try_node/__init__.py,sha256=JVD4DrldTIqFQQFrubs9KtWCCc0YCAc7Fzol5ZWIWeM,56
1354
1356
  vellum/workflows/nodes/core/try_node/node.py,sha256=bk2uhYUl10yaPJlOBWxiL7igTUrL_7mM9S2nvsdWB68,4242
1355
1357
  vellum/workflows/nodes/core/try_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1374,12 +1376,12 @@ vellum/workflows/nodes/displayable/bases/tests/test_utils.py,sha256=eqdqbKNRWVMD
1374
1376
  vellum/workflows/nodes/displayable/bases/types.py,sha256=C37B2Qh2YP7s7pUjd-EYKc2Zl1TbnCgI_mENuUSb8bo,1706
1375
1377
  vellum/workflows/nodes/displayable/bases/utils.py,sha256=ckMUenSsNkiYmSw6FmjSMHYaCk8Y8_sUjL6lkFFEqts,5412
1376
1378
  vellum/workflows/nodes/displayable/code_execution_node/__init__.py,sha256=0FLWMMktpzSnmBMizQglBpcPrP80fzVsoJwJgf822Cg,76
1377
- vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=wgtqPljUqan9SILMysPCdSmZ0HoCpTTTNNaW0y9nQQI,9082
1379
+ vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=_yrQn_uLwy8zVW1RjFMoeomDEsbpbbKK7ifMGEBfNlk,9120
1378
1380
  vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1379
1381
  vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1380
1382
  vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py,sha256=5QsbmkzSlSbcbWTG_JmIqcP-JNJzOPTKxGzdHos19W4,79
1381
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=1i48vpyFZ-zR5DD9wCu4Ekd-aq4gLOsSWnn0BMdJIAs,16810
1382
- vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=m5y6_sRX5P9icmneNhT_DkXYDNz7l_8Q_Aa8-U5dWsQ,4529
1383
+ vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=5WHsW_uEKDn1ukM9_O2FsGCYELfONz-2h_kYnNRNYHE,18333
1384
+ vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=rdWD1wtxPKHbdHRHEdTeRMSJi9sgAm2t0FqeAWuQHlQ,4534
1383
1385
  vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU1F9t8aLmbZU-rLh9ry6LCJ0uj0D8F0L5Uw,72
1384
1386
  vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=Qjfl33gZ3JEgxBA1EgzSUebboGvsARthIxxcQyvx5Gg,1152
1385
1387
  vellum/workflows/nodes/displayable/final_output_node/__init__.py,sha256=G7VXM4OWpubvSJtVkGmMNeqgb9GkM7qZT838eL18XU4,72
@@ -1471,8 +1473,8 @@ vellum/workflows/workflows/base.py,sha256=tBivLLLPtMyMi2Bd5WjbwQ2_zZFpG8rNfEidfQ
1471
1473
  vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1472
1474
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1473
1475
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=dz5F3DuGOk9qUMjmNd-GdEE3320G5ko5nJ6J0QJyVcY,2659
1474
- vellum_ai-0.14.1.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1475
- vellum_ai-0.14.1.dist-info/METADATA,sha256=TGCti5BkhYzjafUugASpEkqaT-cfB5-0K0zWZQPi3II,5407
1476
- vellum_ai-0.14.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1477
- vellum_ai-0.14.1.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1478
- vellum_ai-0.14.1.dist-info/RECORD,,
1476
+ vellum_ai-0.14.3.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1477
+ vellum_ai-0.14.3.dist-info/METADATA,sha256=4Q0I2ydIobyCxpBPpfRJgFtoGEfWnlteA_j2XUuFvME,5407
1478
+ vellum_ai-0.14.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1479
+ vellum_ai-0.14.3.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1480
+ vellum_ai-0.14.3.dist-info/RECORD,,
vellum_cli/pull.py CHANGED
@@ -2,14 +2,14 @@ import io
2
2
  import json
3
3
  import os
4
4
  from pathlib import Path
5
- from uuid import UUID
6
5
  import zipfile
7
- from typing import Optional, Union
6
+ from typing import Optional
8
7
 
9
8
  from dotenv import load_dotenv
10
9
  from pydash import snake_case
11
10
 
12
11
  from vellum.client.core.pydantic_utilities import UniversalBaseModel
12
+ from vellum.utils.uuid import is_valid_uuid
13
13
  from vellum.workflows.vellum_client import create_vellum_client
14
14
  from vellum_cli.config import VellumCliConfig, WorkflowConfig, load_vellum_cli_config
15
15
  from vellum_cli.logger import load_cli_logger
@@ -18,14 +18,6 @@ ERROR_LOG_FILE_NAME = "error.log"
18
18
  METADATA_FILE_NAME = "metadata.json"
19
19
 
20
20
 
21
- def _is_valid_uuid(val: Union[str, UUID, None]) -> bool:
22
- try:
23
- UUID(str(val))
24
- return True
25
- except (ValueError, TypeError):
26
- return False
27
-
28
-
29
21
  class WorkflowConfigResolutionResult(UniversalBaseModel):
30
22
  workflow_config: Optional[WorkflowConfig] = None
31
23
  pk: Optional[str] = None
@@ -88,7 +80,7 @@ def _resolve_workflow_config(
88
80
  elif workflow_deployment:
89
81
  module = (
90
82
  f"workflow_{workflow_deployment.split('-')[0]}"
91
- if _is_valid_uuid(workflow_deployment)
83
+ if is_valid_uuid(workflow_deployment)
92
84
  else snake_case(workflow_deployment)
93
85
  )
94
86
  workflow_config = WorkflowConfig(
@@ -74,14 +74,15 @@ EntrypointDisplayOverridesType = TypeVar("EntrypointDisplayOverridesType", bound
74
74
 
75
75
 
76
76
  @dataclass
77
- class WorkflowOutputDisplayOverrides:
77
+ class WorkflowOutputDisplay:
78
78
  id: UUID
79
+ name: str
79
80
 
80
81
 
81
82
  @dataclass
82
- class WorkflowOutputDisplay(WorkflowOutputDisplayOverrides):
83
- pass
84
-
83
+ class WorkflowOutputDisplayOverrides(WorkflowOutputDisplay):
84
+ """
85
+ DEPRECATED: Use WorkflowOutputDisplay instead. Will be removed in 0.15.0
86
+ """
85
87
 
86
- WorkflowOutputDisplayType = TypeVar("WorkflowOutputDisplayType", bound=WorkflowOutputDisplay)
87
- WorkflowOutputDisplayOverridesType = TypeVar("WorkflowOutputDisplayOverridesType", bound=WorkflowOutputDisplayOverrides)
88
+ pass
@@ -1,5 +1,5 @@
1
1
  from uuid import UUID
2
- from typing import ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar, cast
2
+ from typing import ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar
3
3
 
4
4
  from vellum import VellumVariable
5
5
  from vellum.workflows.inputs.base import BaseInputs
@@ -10,7 +10,7 @@ from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
10
10
  from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
11
11
  from vellum_ee.workflows.display.types import WorkflowDisplayContext
12
12
  from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
13
- from vellum_ee.workflows.display.vellum import NodeInput, WorkflowOutputVellumDisplay
13
+ from vellum_ee.workflows.display.vellum import NodeInput
14
14
  from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
15
15
 
16
16
  _InlineSubworkflowNodeType = TypeVar("_InlineSubworkflowNodeType", bound=InlineSubworkflowNode)
@@ -110,9 +110,7 @@ class BaseInlineSubworkflowNodeDisplay(
110
110
  ) -> List[VellumVariable]:
111
111
  workflow_outputs: List[VellumVariable] = []
112
112
  for output_descriptor in raise_if_descriptor(node.subworkflow).Outputs: # type: ignore[union-attr]
113
- workflow_output_display = cast(
114
- WorkflowOutputVellumDisplay, display_context.workflow_output_displays[output_descriptor]
115
- )
113
+ workflow_output_display = display_context.workflow_output_displays[output_descriptor]
116
114
  output_type = infer_vellum_variable_type(output_descriptor)
117
115
  workflow_outputs.append(
118
116
  VellumVariable(id=str(workflow_output_display.id), key=workflow_output_display.name, type=output_type)
@@ -13,7 +13,7 @@ from vellum_ee.workflows.display.base import (
13
13
  StateValueDisplayType,
14
14
  WorkflowInputsDisplayType,
15
15
  WorkflowMetaDisplayType,
16
- WorkflowOutputDisplayType,
16
+ WorkflowOutputDisplay,
17
17
  )
18
18
 
19
19
  if TYPE_CHECKING:
@@ -45,7 +45,6 @@ class WorkflowDisplayContext(
45
45
  StateValueDisplayType,
46
46
  NodeDisplayType,
47
47
  EntrypointDisplayType,
48
- WorkflowOutputDisplayType,
49
48
  EdgeDisplayType,
50
49
  ]
51
50
  ):
@@ -63,6 +62,6 @@ class WorkflowDisplayContext(
63
62
  default_factory=dict
64
63
  )
65
64
  entrypoint_displays: Dict[Type[BaseNode], EntrypointDisplayType] = field(default_factory=dict)
66
- workflow_output_displays: Dict[BaseDescriptor, WorkflowOutputDisplayType] = field(default_factory=dict)
65
+ workflow_output_displays: Dict[BaseDescriptor, WorkflowOutputDisplay] = field(default_factory=dict)
67
66
  edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplayType] = field(default_factory=dict)
68
67
  port_displays: Dict[Port, "PortDisplay"] = field(default_factory=dict)
@@ -20,7 +20,6 @@ from vellum_ee.workflows.display.base import (
20
20
  WorkflowInputsDisplayOverrides,
21
21
  WorkflowMetaDisplay,
22
22
  WorkflowMetaDisplayOverrides,
23
- WorkflowOutputDisplay,
24
23
  WorkflowOutputDisplayOverrides,
25
24
  )
26
25
 
@@ -123,16 +122,23 @@ class EntrypointVellumDisplay(EntrypointVellumDisplayOverrides):
123
122
 
124
123
 
125
124
  @dataclass
126
- class WorkflowOutputVellumDisplayOverrides(WorkflowOutputDisplay, WorkflowOutputDisplayOverrides):
127
- name: str
128
- label: str
129
- node_id: UUID
130
- display_data: NodeDisplayData
125
+ class WorkflowOutputVellumDisplayOverrides(WorkflowOutputDisplayOverrides):
126
+ """
127
+ DEPRECATED: Use WorkflowOutputDisplay instead. Will be removed in 0.15.0
128
+ """
129
+
130
+ label: Optional[str] = None
131
+ node_id: Optional[UUID] = None
132
+ display_data: Optional[NodeDisplayData] = None
131
133
  target_handle_id: Optional[UUID] = None
132
134
 
133
135
 
134
136
  @dataclass
135
137
  class WorkflowOutputVellumDisplay(WorkflowOutputVellumDisplayOverrides):
138
+ """
139
+ DEPRECATED: Use WorkflowOutputDisplay instead. Will be removed in 0.15.0
140
+ """
141
+
136
142
  pass
137
143
 
138
144
 
@@ -28,8 +28,7 @@ from vellum_ee.workflows.display.base import (
28
28
  WorkflowInputsDisplayType,
29
29
  WorkflowMetaDisplayOverridesType,
30
30
  WorkflowMetaDisplayType,
31
- WorkflowOutputDisplayOverridesType,
32
- WorkflowOutputDisplayType,
31
+ WorkflowOutputDisplay,
33
32
  )
34
33
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
35
34
  from vellum_ee.workflows.display.nodes.get_node_display_class import get_node_display_class
@@ -58,8 +57,6 @@ class BaseWorkflowDisplay(
58
57
  EntrypointDisplayOverridesType,
59
58
  EdgeDisplayType,
60
59
  EdgeDisplayOverridesType,
61
- WorkflowOutputDisplayType,
62
- WorkflowOutputDisplayOverridesType,
63
60
  ]
64
61
  ):
65
62
  # Used to specify the display data for a workflow.
@@ -75,7 +72,7 @@ class BaseWorkflowDisplay(
75
72
  entrypoint_displays: Dict[Type[BaseNode], EntrypointDisplayOverridesType] = {}
76
73
 
77
74
  # Used to explicitly specify display data for a workflow's outputs.
78
- output_displays: Dict[BaseDescriptor, WorkflowOutputDisplayOverridesType] = {}
75
+ output_displays: Dict[BaseDescriptor, WorkflowOutputDisplay] = {}
79
76
 
80
77
  # Used to explicitly specify display data for a workflow's edges.
81
78
  edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplayOverridesType] = {}
@@ -101,7 +98,6 @@ class BaseWorkflowDisplay(
101
98
  StateValueDisplayType,
102
99
  NodeDisplayType,
103
100
  EntrypointDisplayType,
104
- WorkflowOutputDisplayType,
105
101
  EdgeDisplayType,
106
102
  ]
107
103
  ] = None,
@@ -202,7 +198,6 @@ class BaseWorkflowDisplay(
202
198
  StateValueDisplayType,
203
199
  NodeDisplayType,
204
200
  EntrypointDisplayType,
205
- WorkflowOutputDisplayType,
206
201
  EdgeDisplayType,
207
202
  ]:
208
203
  workflow_display = self._generate_workflow_meta_display()
@@ -285,7 +280,7 @@ class BaseWorkflowDisplay(
285
280
  edge, node_displays, port_displays, overrides=edge_display_overrides
286
281
  )
287
282
 
288
- workflow_output_displays: Dict[BaseDescriptor, WorkflowOutputDisplayType] = {}
283
+ workflow_output_displays: Dict[BaseDescriptor, WorkflowOutputDisplay] = {}
289
284
  for workflow_output in self._workflow.Outputs:
290
285
  if workflow_output in workflow_output_displays:
291
286
  continue
@@ -298,9 +293,9 @@ class BaseWorkflowDisplay(
298
293
  ):
299
294
  raise ValueError("Expected to find a descriptor instance on the workflow output")
300
295
 
301
- workflow_output_display_overrides = self.output_displays.get(workflow_output)
302
- workflow_output_displays[workflow_output] = self._generate_workflow_output_display(
303
- workflow_output, overrides=workflow_output_display_overrides
296
+ workflow_output_display = self.output_displays.get(workflow_output)
297
+ workflow_output_displays[workflow_output] = (
298
+ workflow_output_display or self._generate_workflow_output_display(workflow_output)
304
299
  )
305
300
 
306
301
  return WorkflowDisplayContext(
@@ -345,13 +340,10 @@ class BaseWorkflowDisplay(
345
340
  ) -> EntrypointDisplayType:
346
341
  pass
347
342
 
348
- @abstractmethod
349
- def _generate_workflow_output_display(
350
- self,
351
- output: BaseDescriptor,
352
- overrides: Optional[WorkflowOutputDisplayOverridesType] = None,
353
- ) -> WorkflowOutputDisplayType:
354
- pass
343
+ def _generate_workflow_output_display(self, output: BaseDescriptor) -> WorkflowOutputDisplay:
344
+ output_id = uuid4_from_hash(f"{self.workflow_id}|id|{output.name}")
345
+
346
+ return WorkflowOutputDisplay(id=output_id, name=output.name)
355
347
 
356
348
  @abstractmethod
357
349
  def _generate_edge_display(
@@ -31,8 +31,6 @@ from vellum_ee.workflows.display.vellum import (
31
31
  WorkflowInputsVellumDisplayOverrides,
32
32
  WorkflowMetaVellumDisplay,
33
33
  WorkflowMetaVellumDisplayOverrides,
34
- WorkflowOutputVellumDisplay,
35
- WorkflowOutputVellumDisplayOverrides,
36
34
  )
37
35
  from vellum_ee.workflows.display.workflows.base_workflow_display import BaseWorkflowDisplay
38
36
 
@@ -53,8 +51,6 @@ class VellumWorkflowDisplay(
53
51
  EntrypointVellumDisplayOverrides,
54
52
  EdgeVellumDisplay,
55
53
  EdgeVellumDisplayOverrides,
56
- WorkflowOutputVellumDisplay,
57
- WorkflowOutputVellumDisplayOverrides,
58
54
  ]
59
55
  ):
60
56
  node_display_base_class = BaseNodeDisplay
@@ -144,7 +140,7 @@ class VellumWorkflowDisplay(
144
140
 
145
141
  # Add a synthetic Terminal Node and track the Workflow's output variables for each Workflow output
146
142
  for workflow_output, workflow_output_display in self.display_context.workflow_output_displays.items():
147
- final_output_node_id = workflow_output_display.node_id
143
+ final_output_node_id = uuid4_from_hash(f"{self.workflow_id}|node_id|{workflow_output.name}")
148
144
  inferred_type = infer_vellum_variable_type(workflow_output)
149
145
 
150
146
  # Remove the terminal node output from the unreferenced set
@@ -176,20 +172,25 @@ class VellumWorkflowDisplay(
176
172
  except IndexError:
177
173
  source_node_display = None
178
174
 
175
+ synthetic_target_handle_id = str(
176
+ uuid4_from_hash(f"{self.workflow_id}|target_handle_id|{workflow_output_display.name}")
177
+ )
178
+ synthetic_display_data = NodeDisplayData().dict()
179
+ synthetic_node_label = "Final Output"
179
180
  nodes.append(
180
181
  {
181
182
  "id": str(final_output_node_id),
182
183
  "type": "TERMINAL",
183
184
  "data": {
184
- "label": workflow_output_display.label,
185
+ "label": synthetic_node_label,
185
186
  "name": workflow_output_display.name,
186
- "target_handle_id": str(workflow_output_display.target_handle_id),
187
+ "target_handle_id": synthetic_target_handle_id,
187
188
  "output_id": str(workflow_output_display.id),
188
189
  "output_type": inferred_type,
189
190
  "node_input_id": str(node_input.id),
190
191
  },
191
192
  "inputs": [node_input.dict()],
192
- "display_data": workflow_output_display.display_data.dict(),
193
+ "display_data": synthetic_display_data,
193
194
  "base": final_output_node_base,
194
195
  "definition": None,
195
196
  }
@@ -210,8 +211,8 @@ class VellumWorkflowDisplay(
210
211
  "id": str(uuid4_from_hash(f"{self.workflow_id}|edge_id|{workflow_output_display.name}")),
211
212
  "source_node_id": str(source_node_display.node_id),
212
213
  "source_handle_id": str(source_handle_id),
213
- "target_node_id": str(workflow_output_display.node_id),
214
- "target_handle_id": str(workflow_output_display.target_handle_id),
214
+ "target_node_id": str(final_output_node_id),
215
+ "target_handle_id": synthetic_target_handle_id,
215
216
  "type": "DEFAULT",
216
217
  }
217
218
  )
@@ -355,34 +356,6 @@ class VellumWorkflowDisplay(
355
356
 
356
357
  return EntrypointVellumDisplay(id=entrypoint_id, edge_display=edge_display)
357
358
 
358
- def _generate_workflow_output_display(
359
- self,
360
- output: BaseDescriptor,
361
- overrides: Optional[WorkflowOutputVellumDisplayOverrides] = None,
362
- ) -> WorkflowOutputVellumDisplay:
363
- if overrides:
364
- return WorkflowOutputVellumDisplay(
365
- id=overrides.id,
366
- name=overrides.name,
367
- label=overrides.label,
368
- node_id=overrides.node_id,
369
- target_handle_id=overrides.target_handle_id,
370
- display_data=overrides.display_data,
371
- )
372
-
373
- output_id = uuid4_from_hash(f"{self.workflow_id}|id|{output.name}")
374
- node_id = uuid4_from_hash(f"{self.workflow_id}|node_id|{output.name}")
375
- target_handle_id = uuid4_from_hash(f"{self.workflow_id}|target_handle_id|{output.name}")
376
-
377
- return WorkflowOutputVellumDisplay(
378
- id=output_id,
379
- node_id=node_id,
380
- name=output.name,
381
- label="Final Output",
382
- target_handle_id=target_handle_id,
383
- display_data=NodeDisplayData(),
384
- )
385
-
386
359
  def _generate_edge_display(
387
360
  self,
388
361
  edge: Edge,
@@ -47,10 +47,6 @@ class WorkflowDisplay(VellumWorkflowDisplay[Workflow]):
47
47
  output_displays = {
48
48
  Workflow.Outputs.final_output: WorkflowOutputVellumDisplayOverrides(
49
49
  id=UUID("5469b810-6ea6-4362-9e79-e360d44a1405"),
50
- node_id=UUID("f3ef4b2b-fec9-4026-9cc6-e5eac295307f"),
51
50
  name="final-output",
52
- label="Final Output",
53
- target_handle_id=UUID("3ec34f6e-da48-40d5-a65b-a48fefa75763"),
54
- display_data=NodeDisplayData(position=NodeDisplayPosition(x=2750, y=210), width=459, height=234),
55
51
  )
56
52
  }