vellum-ai 0.13.27__py3-none-any.whl → 0.14.0__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 (57) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/workflows/constants.py +8 -3
  3. vellum/workflows/descriptors/exceptions.py +2 -0
  4. vellum/workflows/descriptors/tests/test_utils.py +21 -0
  5. vellum/workflows/descriptors/utils.py +3 -3
  6. vellum/workflows/errors/types.py +4 -1
  7. vellum/workflows/expressions/accessor.py +4 -3
  8. vellum/workflows/expressions/begins_with.py +3 -2
  9. vellum/workflows/expressions/between.py +4 -3
  10. vellum/workflows/expressions/coalesce_expression.py +2 -2
  11. vellum/workflows/expressions/contains.py +10 -2
  12. vellum/workflows/expressions/does_not_begin_with.py +3 -2
  13. vellum/workflows/expressions/does_not_contain.py +6 -2
  14. vellum/workflows/expressions/does_not_end_with.py +3 -2
  15. vellum/workflows/expressions/ends_with.py +3 -2
  16. vellum/workflows/expressions/greater_than.py +3 -2
  17. vellum/workflows/expressions/greater_than_or_equal_to.py +3 -2
  18. vellum/workflows/expressions/in_.py +2 -1
  19. vellum/workflows/expressions/is_blank.py +2 -1
  20. vellum/workflows/expressions/is_nil.py +2 -2
  21. vellum/workflows/expressions/is_not_blank.py +2 -1
  22. vellum/workflows/expressions/is_not_nil.py +2 -2
  23. vellum/workflows/expressions/is_not_undefined.py +2 -2
  24. vellum/workflows/expressions/is_undefined.py +2 -2
  25. vellum/workflows/expressions/less_than.py +3 -2
  26. vellum/workflows/expressions/less_than_or_equal_to.py +3 -2
  27. vellum/workflows/expressions/not_between.py +4 -3
  28. vellum/workflows/expressions/not_in.py +2 -1
  29. vellum/workflows/nodes/bases/base.py +21 -7
  30. vellum/workflows/nodes/bases/tests/test_base_node.py +84 -0
  31. vellum/workflows/nodes/core/inline_subworkflow_node/node.py +3 -3
  32. vellum/workflows/nodes/core/map_node/node.py +5 -0
  33. vellum/workflows/nodes/core/map_node/tests/test_node.py +22 -0
  34. vellum/workflows/nodes/displayable/bases/api_node/node.py +8 -3
  35. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +19 -9
  36. vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +68 -2
  37. vellum/workflows/nodes/displayable/code_execution_node/utils.py +30 -7
  38. vellum/workflows/outputs/base.py +21 -19
  39. vellum/workflows/ports/port.py +14 -5
  40. vellum/workflows/references/external_input.py +2 -2
  41. vellum/workflows/references/lazy.py +2 -2
  42. vellum/workflows/references/output.py +7 -7
  43. vellum/workflows/runner/runner.py +20 -15
  44. vellum/workflows/state/base.py +2 -2
  45. vellum/workflows/state/tests/test_state.py +7 -11
  46. vellum/workflows/utils/vellum_variables.py +3 -0
  47. vellum/workflows/workflows/base.py +20 -0
  48. vellum/workflows/workflows/tests/__init__.py +0 -0
  49. vellum/workflows/workflows/tests/test_base_workflow.py +80 -0
  50. {vellum_ai-0.13.27.dist-info → vellum_ai-0.14.0.dist-info}/METADATA +2 -1
  51. {vellum_ai-0.13.27.dist-info → vellum_ai-0.14.0.dist-info}/RECORD +57 -54
  52. vellum_cli/push.py +15 -1
  53. vellum_cli/tests/test_push.py +44 -0
  54. vellum_ee/workflows/display/nodes/base_node_display.py +2 -2
  55. {vellum_ai-0.13.27.dist-info → vellum_ai-0.14.0.dist-info}/LICENSE +0 -0
  56. {vellum_ai-0.13.27.dist-info → vellum_ai-0.14.0.dist-info}/WHEEL +0 -0
  57. {vellum_ai-0.13.27.dist-info → vellum_ai-0.14.0.dist-info}/entry_points.txt +0 -0
@@ -6,7 +6,7 @@ from threading import Event as ThreadingEvent, Thread
6
6
  from uuid import UUID
7
7
  from typing import TYPE_CHECKING, Any, Dict, Generic, Iterable, Iterator, Optional, Sequence, Set, Tuple, Type, Union
8
8
 
9
- from vellum.workflows.constants import UNDEF
9
+ from vellum.workflows.constants import undefined
10
10
  from vellum.workflows.context import execution_context, get_parent_context
11
11
  from vellum.workflows.descriptors.base import BaseDescriptor
12
12
  from vellum.workflows.edges.edge import Edge
@@ -267,7 +267,7 @@ class WorkflowRunner(Generic[StateType]):
267
267
  )
268
268
  elif output.is_fulfilled:
269
269
  if output.name in streaming_output_queues:
270
- streaming_output_queues[output.name].put(UNDEF)
270
+ streaming_output_queues[output.name].put(undefined)
271
271
 
272
272
  setattr(outputs, output.name, output.value)
273
273
  self._workflow_event_inner_queue.put(
@@ -286,7 +286,7 @@ class WorkflowRunner(Generic[StateType]):
286
286
  node.state.meta.node_execution_cache.fulfill_node_execution(node.__class__, span_id)
287
287
 
288
288
  for descriptor, output_value in outputs:
289
- if output_value is UNDEF:
289
+ if output_value is undefined:
290
290
  if descriptor in node.state.meta.node_outputs:
291
291
  del node.state.meta.node_outputs[descriptor]
292
292
  continue
@@ -386,8 +386,8 @@ class WorkflowRunner(Generic[StateType]):
386
386
  if not isinstance(descriptor, ExternalInputReference):
387
387
  continue
388
388
 
389
- if state.meta.external_inputs.get(descriptor, UNDEF) is UNDEF:
390
- state.meta.external_inputs[descriptor] = UNDEF
389
+ if state.meta.external_inputs.get(descriptor, undefined) is undefined:
390
+ state.meta.external_inputs[descriptor] = undefined
391
391
  return
392
392
 
393
393
  all_deps = self._dependencies[node_class]
@@ -577,7 +577,7 @@ class WorkflowRunner(Generic[StateType]):
577
577
  unresolved_external_inputs = {
578
578
  descriptor
579
579
  for descriptor, node_input_value in final_state.meta.external_inputs.items()
580
- if node_input_value is UNDEF
580
+ if node_input_value is undefined
581
581
  }
582
582
  if unresolved_external_inputs:
583
583
  self._workflow_event_outer_queue.put(
@@ -616,19 +616,21 @@ class WorkflowRunner(Generic[StateType]):
616
616
  for emitter in self.workflow.emitters:
617
617
  emitter.emit_event(item)
618
618
 
619
- def _run_cancel_thread(self) -> None:
619
+ def _run_cancel_thread(self, kill_switch: ThreadingEvent) -> None:
620
620
  if not self._cancel_signal:
621
621
  return
622
622
 
623
- self._cancel_signal.wait()
624
- self._workflow_event_outer_queue.put(
625
- self._reject_workflow_event(
626
- WorkflowError(
627
- code=WorkflowErrorCode.WORKFLOW_CANCELLED,
628
- message="Workflow run cancelled",
623
+ while not kill_switch.wait(timeout=0.1):
624
+ if self._cancel_signal.is_set():
625
+ self._workflow_event_outer_queue.put(
626
+ self._reject_workflow_event(
627
+ WorkflowError(
628
+ code=WorkflowErrorCode.WORKFLOW_CANCELLED,
629
+ message="Workflow run cancelled",
630
+ )
631
+ )
629
632
  )
630
- )
631
- )
633
+ return
632
634
 
633
635
  def _is_terminal_event(self, event: WorkflowEvent) -> bool:
634
636
  if (
@@ -646,10 +648,12 @@ class WorkflowRunner(Generic[StateType]):
646
648
  )
647
649
  background_thread.start()
648
650
 
651
+ cancel_thread_kill_switch = ThreadingEvent()
649
652
  if self._cancel_signal:
650
653
  cancel_thread = Thread(
651
654
  target=self._run_cancel_thread,
652
655
  name=f"{self.workflow.__class__.__name__}.cancel_thread",
656
+ kwargs={"kill_switch": cancel_thread_kill_switch},
653
657
  )
654
658
  cancel_thread.start()
655
659
 
@@ -694,3 +698,4 @@ class WorkflowRunner(Generic[StateType]):
694
698
  )
695
699
 
696
700
  self._background_thread_queue.put(None)
701
+ cancel_thread_kill_switch.set()
@@ -12,7 +12,7 @@ from pydantic import GetCoreSchemaHandler, field_serializer
12
12
  from pydantic_core import core_schema
13
13
 
14
14
  from vellum.core.pydantic_utilities import UniversalBaseModel
15
- from vellum.workflows.constants import UNDEF
15
+ from vellum.workflows.constants import undefined
16
16
  from vellum.workflows.edges.edge import Edge
17
17
  from vellum.workflows.inputs.base import BaseInputs
18
18
  from vellum.workflows.references import ExternalInputReference, OutputReference, StateValueReference
@@ -347,7 +347,7 @@ class BaseState(metaclass=_BaseStateMeta):
347
347
  if key.startswith("_"):
348
348
  continue
349
349
 
350
- if getattr(latest_state, key, UNDEF) == UNDEF:
350
+ if getattr(latest_state, key, undefined) == undefined:
351
351
  setattr(latest_state, key, value)
352
352
 
353
353
  return cast(StateType, latest_state)
@@ -23,6 +23,9 @@ class MockState(BaseState):
23
23
 
24
24
 
25
25
  class MockNode(BaseNode):
26
+ class ExternalInputs(BaseNode.ExternalInputs):
27
+ message: str
28
+
26
29
  class Outputs(BaseOutputs):
27
30
  baz: str
28
31
 
@@ -70,11 +73,7 @@ def test_state_snapshot__external_input_edit():
70
73
  assert snapshot_count[id(state)] == 0
71
74
 
72
75
  # WHEN we add an external input to state
73
- class MockExternalInputs(BaseNode.ExternalInputs):
74
- message: str
75
-
76
- # WHEN we edit external inputs dictionary
77
- state.meta.external_inputs[MockExternalInputs.message] = "hello"
76
+ state.meta.external_inputs[MockNode.ExternalInputs.message] = "hello"
78
77
 
79
78
  # THEN the snapshot is emitted
80
79
  assert snapshot_count[id(state)] == 1
@@ -137,19 +136,16 @@ def test_state_deepcopy__with_external_input_updates():
137
136
  state = MockState(foo="bar")
138
137
 
139
138
  # AND we add an external input to state
140
- class MockExternalInputs(BaseNode.ExternalInputs):
141
- message: str
142
-
143
- state.meta.external_inputs[MockExternalInputs.message] = "hello"
139
+ state.meta.external_inputs[MockNode.ExternalInputs.message] = "hello"
144
140
 
145
141
  # AND we deepcopy the state
146
142
  deepcopied_state = deepcopy(state)
147
143
 
148
144
  # AND we update the original state
149
- state.meta.external_inputs[MockExternalInputs.message] = "world"
145
+ state.meta.external_inputs[MockNode.ExternalInputs.message] = "world"
150
146
 
151
147
  # THEN the copied state is not updated
152
- assert deepcopied_state.meta.external_inputs[MockExternalInputs.message] == "hello"
148
+ assert deepcopied_state.meta.external_inputs[MockNode.ExternalInputs.message] == "hello"
153
149
 
154
150
  # AND the original state has had the correct number of snapshots
155
151
  assert snapshot_count[id(state)] == 2
@@ -45,6 +45,9 @@ def primitive_type_to_vellum_variable_type(type_: Union[Type, BaseDescriptor]) -
45
45
  ]
46
46
  if types == actual_types_with_explicit_ref:
47
47
  return "JSON"
48
+ # Number now supports float and int
49
+ elif types == [float, int]:
50
+ return "NUMBER"
48
51
  raise ValueError(f"Expected Descriptor to only have one type, got {types}")
49
52
 
50
53
  type_ = type_.types[0]
@@ -80,6 +80,26 @@ class _BaseWorkflowMeta(type):
80
80
  if "graph" not in dct:
81
81
  dct["graph"] = set()
82
82
 
83
+ if "Outputs" in dct:
84
+ outputs_class = dct["Outputs"]
85
+
86
+ if not any(issubclass(base, BaseOutputs) for base in outputs_class.__bases__):
87
+ parent_outputs_class = next(
88
+ (base.Outputs for base in bases if hasattr(base, "Outputs")),
89
+ BaseOutputs, # Default to BaseOutputs only if no parent has Outputs
90
+ )
91
+
92
+ filtered_bases = tuple(base for base in outputs_class.__bases__ if base is not object)
93
+
94
+ new_dct = {key: value for key, value in outputs_class.__dict__.items() if not key.startswith("__")}
95
+ new_dct["__module__"] = dct["__module__"]
96
+
97
+ dct["Outputs"] = type(
98
+ f"{name}.Outputs",
99
+ (parent_outputs_class,) + filtered_bases,
100
+ new_dct,
101
+ )
102
+
83
103
  cls = super().__new__(mcs, name, bases, dct)
84
104
  workflow_class = cast(Type["BaseWorkflow"], cls)
85
105
  workflow_class.__id__ = uuid4_from_hash(workflow_class.__qualname__)
File without changes
@@ -0,0 +1,80 @@
1
+ from vellum.workflows.inputs.base import BaseInputs
2
+ from vellum.workflows.nodes.bases.base import BaseNode
3
+ from vellum.workflows.nodes.core.inline_subworkflow_node.node import InlineSubworkflowNode
4
+ from vellum.workflows.outputs.base import BaseOutputs
5
+ from vellum.workflows.state.base import BaseState
6
+ from vellum.workflows.workflows.base import BaseWorkflow
7
+
8
+
9
+ def test_base_workflow__inherit_base_outputs():
10
+ class MyNode(BaseNode):
11
+ class Outputs(BaseNode.Outputs):
12
+ foo: str
13
+
14
+ def run(self):
15
+ return self.Outputs(foo="bar")
16
+
17
+ class MyWorkflow(BaseWorkflow[BaseInputs, BaseState]):
18
+ graph = MyNode
19
+
20
+ class Outputs:
21
+ output = MyNode.Outputs.foo
22
+
23
+ # TEST that the Outputs class is a subclass of BaseOutputs
24
+ assert issubclass(MyWorkflow.Outputs, BaseOutputs)
25
+
26
+ # TEST that the Outputs class does not inherit from object
27
+ assert object not in MyWorkflow.Outputs.__bases__
28
+
29
+ workflow = MyWorkflow()
30
+ terminal_event = workflow.run()
31
+
32
+ # TEST that the Outputs class has the correct attributes
33
+ assert hasattr(MyWorkflow.Outputs, "output")
34
+
35
+ # TEST that the outputs should be correct
36
+ assert terminal_event.name == "workflow.execution.fulfilled", terminal_event
37
+ assert terminal_event.outputs == {"output": "bar"}
38
+
39
+
40
+ def test_subworkflow__inherit_base_outputs():
41
+ class StartNode(BaseNode):
42
+ class Outputs(BaseNode.Outputs):
43
+ foo: str
44
+
45
+ def run(self):
46
+ return self.Outputs(foo="bar")
47
+
48
+ class SubWorkflow(BaseWorkflow[BaseInputs, BaseState]):
49
+ graph = StartNode
50
+
51
+ class Outputs:
52
+ output = StartNode.Outputs.foo
53
+
54
+ class SubworkflowNode(InlineSubworkflowNode):
55
+ subworkflow = SubWorkflow
56
+
57
+ class MainWorkflow(BaseWorkflow[BaseInputs, BaseState]):
58
+ graph = SubworkflowNode
59
+
60
+ class Outputs:
61
+ output = SubworkflowNode.Outputs.output
62
+
63
+ # TEST that the Outputs classes are subclasses of BaseOutputs
64
+ assert issubclass(MainWorkflow.Outputs, BaseOutputs)
65
+ assert issubclass(SubWorkflow.Outputs, BaseOutputs)
66
+
67
+ # TEST that the Outputs classes do not inherit from object
68
+ assert object not in MainWorkflow.Outputs.__bases__
69
+ assert object not in SubWorkflow.Outputs.__bases__
70
+
71
+ # TEST execution
72
+ workflow = MainWorkflow()
73
+ terminal_event = workflow.run()
74
+
75
+ # TEST that the Outputs class has the correct attributes
76
+ assert hasattr(MainWorkflow.Outputs, "output")
77
+
78
+ # TEST that the outputs are correct
79
+ assert terminal_event.name == "workflow.execution.fulfilled", terminal_event
80
+ assert terminal_event.outputs == {"output": "bar"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.13.27
3
+ Version: 0.14.0
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -37,6 +37,7 @@ Requires-Dist: pyyaml (==6.0.1)
37
37
  Requires-Dist: requests (==2.32.3)
38
38
  Requires-Dist: tomli (==2.0.2)
39
39
  Requires-Dist: typing_extensions (>=4.0.0)
40
+ Project-URL: Repository, https://github.com/vellum-ai/vellum-python-sdks
40
41
  Description-Content-Type: text/markdown
41
42
 
42
43
  <p align="center">
@@ -7,21 +7,21 @@ 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
9
  vellum_cli/pull.py,sha256=7yvg4oBOgsbBEsgXtCpYlNR4AOR8hPICamY-4HI-3kM,9031
10
- vellum_cli/push.py,sha256=j4XLSircGX3aHz35i3HyJ4jynWiEH6xVm1uspavPeLM,9101
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
13
13
  vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
14
14
  vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
15
15
  vellum_cli/tests/test_ping.py,sha256=QtbhYKMYn1DFnDyBij2mkQO32j9KOpZ5Pf0yek7k_Ao,1284
16
16
  vellum_cli/tests/test_pull.py,sha256=JURmgGs5lSnpzefSx4K13eF2swv7O8OF86-4df81Zjo,25241
17
- vellum_cli/tests/test_push.py,sha256=e0nJlyRQjfRPjXlHm9uh5Z5eGZMzu1lnpEhO35nGlsc,21330
17
+ vellum_cli/tests/test_push.py,sha256=zDZfSQCHCdKqSfGVHGRgX9VPm-H7EW5gwMf55dm_PFg,23438
18
18
  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
22
  vellum_ee/workflows/display/base.py,sha256=3ZFUYRNKL24fBqXhKpa_Dq2W1a-a86J20dmJYA3H2eY,1755
23
23
  vellum_ee/workflows/display/nodes/__init__.py,sha256=5XOcZJXYUgaLS55QgRJzyQ_W1tpeprjnYAeYVezqoGw,160
24
- vellum_ee/workflows/display/nodes/base_node_display.py,sha256=7RuZkNJxbyOD2w3qPr-5S11mc-iN-NydyUT4FppS62o,16849
24
+ vellum_ee/workflows/display/nodes/base_node_display.py,sha256=j5AoStKNjSmSdxKNqJsi_de4Lhi1WmK0IjdXLQFf2oE,16857
25
25
  vellum_ee/workflows/display/nodes/base_node_vellum_display.py,sha256=pLO0dORfRu--Ne9NgoyFT_CNjfpr5fGCsgbsMkUF5GM,2845
26
26
  vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=0S6ksPp53WXWh1RQVH71nj2bkCWBj4ZaFYhTxW3N2F4,1230
27
27
  vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -116,7 +116,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
116
116
  vellum/client/__init__.py,sha256=j6zi0NZ4BMC6JrwckvzMWuG5x8KoOvO4KqsLhvVCa68,117624
117
117
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
118
118
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
119
- vellum/client/core/client_wrapper.py,sha256=ov-BIscDOkAsVlrwx5oFTC_b2ka0l1D__GsoKPKFG5w,1869
119
+ vellum/client/core/client_wrapper.py,sha256=16qoykymtSsNTtgTE4q07vaJfALO7E-GbQ6P8GVl1Mw,1868
120
120
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
121
121
  vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
122
122
  vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
@@ -1265,12 +1265,13 @@ vellum/utils/uuid.py,sha256=Ch6wWRgwICxLxJCTl5iE3EdRlZj2zADR-zUMUtjcMWM,214
1265
1265
  vellum/version.py,sha256=jq-1PlAYxN9AXuaZqbYk9ak27SgE2lw9Ia5gx1b1gVI,76
1266
1266
  vellum/workflows/README.md,sha256=MLNm-ihc0ao6I8gwwOhXQQBf0jOf-EsA9C519ALYI1o,3610
1267
1267
  vellum/workflows/__init__.py,sha256=CssPsbNvN6rDhoLuqpEv7MMKGa51vE6dvAh6U31Pcio,71
1268
- vellum/workflows/constants.py,sha256=Z0W4YlqfSlSgWC11PrVUPs6ZOBeIaQ78E_90J1hohiw,789
1268
+ vellum/workflows/constants.py,sha256=iPhVhkLfNyFXIUufIR7_9aNFfVOfoDAC8e7jWW02GsQ,949
1269
1269
  vellum/workflows/context.py,sha256=R8qdsFbD_0p7B6PWnyvSrZ_aOgMtGw-_uk0P0UAmwLA,1230
1270
1270
  vellum/workflows/descriptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1271
1271
  vellum/workflows/descriptors/base.py,sha256=gSib3vJpcI_UC8y8jhdp-hOK3_TGTF-SuwdhxF6x5iQ,14332
1272
- vellum/workflows/descriptors/tests/test_utils.py,sha256=63w1P6PELNhWzpg1BqL8y2XQZ8XRt0RUkHgLcsXyOQE,4592
1273
- vellum/workflows/descriptors/utils.py,sha256=nE51MR0KMy3SVHPBg0wjJ3CSJBTLM3tZnVUC_enQEIw,3826
1272
+ vellum/workflows/descriptors/exceptions.py,sha256=gUy4UD9JFUKSeQnQpeuDSLiRqWjWiIsxLahB7p_q3JY,54
1273
+ vellum/workflows/descriptors/tests/test_utils.py,sha256=yrXgu6J6pwqCxJKY3w-i-9t9KKzAkMR7SIICzdcII4k,5266
1274
+ vellum/workflows/descriptors/utils.py,sha256=gmVXJjf2yWmvlYey41J2FZHeSou0JuCHKb3826K_Jok,3838
1274
1275
  vellum/workflows/edges/__init__.py,sha256=wSkmAnz9xyi4vZwtDbKxwlplt2skD7n3NsxkvR_pUus,50
1275
1276
  vellum/workflows/edges/edge.py,sha256=N0SnY3gKVuxImPAdCbPMPlHJIXbkQ3fwq_LbJRvVMFc,677
1276
1277
  vellum/workflows/emitters/__init__.py,sha256=YyOgaoLtVW8eFNEWODzCYb0HzL0PoSeNRf4diJ1Y0dk,80
@@ -1278,7 +1279,7 @@ vellum/workflows/emitters/base.py,sha256=D5SADKIvnbgKwIBgYm77jaqvpo1o0rz4MmuX_mu
1278
1279
  vellum/workflows/environment/__init__.py,sha256=wGHslgSEZ7Octe4C-hNtl84EFelNimgmWQoi7px4-uw,71
1279
1280
  vellum/workflows/environment/environment.py,sha256=0XhJPBs8YASWmvPx8bkSdCvcbDmzpe9stfs2kgtNDRU,296
1280
1281
  vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
1281
- vellum/workflows/errors/types.py,sha256=-Ls41oM4HN28b78Ou13FoZnaWRuaxBgTarKgSoBlCKc,3413
1282
+ vellum/workflows/errors/types.py,sha256=85tmSBt4d9OjUA4AdM5MvIy1vwVLpEu2MhkJhFF1q9k,3502
1282
1283
  vellum/workflows/events/__init__.py,sha256=6pxxceJo2dcaRkWtkDAYlUQZ-PHBQSZytIoyuUK48Qw,759
1283
1284
  vellum/workflows/events/node.py,sha256=uHT6If0esgZ3nLjrjmUPTKf3qbjGhoV_x5YKpjDBDcU,5280
1284
1285
  vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1287,33 +1288,33 @@ vellum/workflows/events/types.py,sha256=cjRE8WL8tYCFradd9NOGl_H0mN3LiWWnA1uHmyT2
1287
1288
  vellum/workflows/events/workflow.py,sha256=lveoWXtVRLjdO_nu0z6VlKeTqlGimogamiFR-jYihlE,5184
1288
1289
  vellum/workflows/exceptions.py,sha256=l-FLGvXywxg6ivolCts71b8pcsYAWoB1cmUR4Jx7N8g,614
1289
1290
  vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1290
- vellum/workflows/expressions/accessor.py,sha256=daIkEudAdyiqCOzO9x_3cy-Y9ilYgNWSEeqcFelkjI0,1743
1291
+ vellum/workflows/expressions/accessor.py,sha256=ItZF7fMLzVTqsdAiaXb5SiDupXmX0X9xbIus1W6hRds,1870
1291
1292
  vellum/workflows/expressions/and_.py,sha256=I7lNqrUM3-m_5hmjjiMhaHhJtKcLj39kEFVWPDOqwfo,916
1292
- vellum/workflows/expressions/begins_with.py,sha256=Ae-RBz_0Xr1WiX1EP0mSgCOOUo-ji1A85aAGd-4BscY,1012
1293
- vellum/workflows/expressions/between.py,sha256=xjc_-TLDN-25tVQ9k9aZciH0wOfqrXV8qNmyGOhimd8,1365
1294
- vellum/workflows/expressions/coalesce_expression.py,sha256=Fyx2cvi715hPhi2OEfH3D0gD_smQIa2aDwnjr7q2Ngs,1186
1295
- vellum/workflows/expressions/contains.py,sha256=j8iKPxytSC0Ig0e-Ie_1vTZ9kFG-4mS1SZ4L0fUP3K4,1045
1296
- vellum/workflows/expressions/does_not_begin_with.py,sha256=CERIru9CGJWGXWmT5QyVC7wbZBJiZu3qNR-cyrJzzec,1026
1297
- vellum/workflows/expressions/does_not_contain.py,sha256=Z7_v_j9VlUFiZo8nFfqaSj7eAYy7EHiIILceS8F2ioE,1067
1298
- vellum/workflows/expressions/does_not_end_with.py,sha256=WB34F0mEtCtKBQ0hliNVj56vdD_ucWxgjyJSH-pKMkI,1020
1293
+ vellum/workflows/expressions/begins_with.py,sha256=FnWsQXbENm0ZwkfEP7dR8Qx4_MMrzj6C1yqAV2KaNHw,1123
1294
+ vellum/workflows/expressions/between.py,sha256=dVeddT6YA91eOAlE1Utg7C7gnCiYE7WP-dg17yXUeAY,1492
1295
+ vellum/workflows/expressions/coalesce_expression.py,sha256=s4pcfu8KkUaUlQkB6BoQUKitGmV1FIQfV4agHHZtd98,1194
1296
+ vellum/workflows/expressions/contains.py,sha256=B1Ub63119QmwPKvBt8vDqQbuiaJWh-_2k5ZUnUNZZak,1392
1297
+ vellum/workflows/expressions/does_not_begin_with.py,sha256=qcnIJsxg4Jt82i2L-PW6ZhKP3C-OlEiXbiIgwHQc5RE,1137
1298
+ vellum/workflows/expressions/does_not_contain.py,sha256=ZdHVewTe_pbPGB0cGv_gIq_4jKkv_oG2tX3RBdEGWoA,1266
1299
+ vellum/workflows/expressions/does_not_end_with.py,sha256=idw2OSuIk02XwBM5CXYOESf655mRrdBREjeinZ5tmVQ,1131
1299
1300
  vellum/workflows/expressions/does_not_equal.py,sha256=LNiCibRZZIxaIrwotjW3SIsKYHWR7BpOItFI-x5KuKU,764
1300
- vellum/workflows/expressions/ends_with.py,sha256=qrnCOfBl-66Hgdz0d_EEej_Md9EMzIYP9NeZBpIP3y0,1006
1301
+ vellum/workflows/expressions/ends_with.py,sha256=FkWZjAudc_DFM-fK-A3_tr6WXavfs_Qi7F6JtVgMglw,1117
1301
1302
  vellum/workflows/expressions/equals.py,sha256=gbI6BKQR7cLQih226-ge_BFSLprgEjqbdiIxo7WFg_E,758
1302
- vellum/workflows/expressions/greater_than.py,sha256=nMi6iAo0vi2hM3JeKfQSCy7DnXbdoyueGEZpGCRImH8,1152
1303
- vellum/workflows/expressions/greater_than_or_equal_to.py,sha256=xUDjfsOrJdoWm9K7OafGDGsuyvYS3xbMjyV4umvA50Q,1164
1304
- vellum/workflows/expressions/in_.py,sha256=tdDTvePdG4WyRkwmSaA4hsUdFJNiIMlrEG6oRrUskjI,1028
1305
- vellum/workflows/expressions/is_blank.py,sha256=u8mGreoZb5t_q2mhhmpD7ytAfFCFUAW9APsDapqUsDY,809
1306
- vellum/workflows/expressions/is_nil.py,sha256=dtgY9Czm3slk45weARspwtfhQmVh0BIUsPOECrATLrA,740
1307
- vellum/workflows/expressions/is_not_blank.py,sha256=npXK9KSUm0nWeT6WJ5LLKB3owgBXHr7SpH8j4W0WapI,816
1308
- vellum/workflows/expressions/is_not_nil.py,sha256=M5Qhtp_H07PORjFN2WapwA1Njp_KaANmLWbfckSSscM,761
1303
+ vellum/workflows/expressions/greater_than.py,sha256=fTM2YF3FY_eOkRtGpgVWcv8qNt4K3lazONUIqcD8oe8,1263
1304
+ vellum/workflows/expressions/greater_than_or_equal_to.py,sha256=sazL_-Jsgjo4jcQeE-6EC0BFHZACriaYMQH4rn0dqEo,1275
1305
+ vellum/workflows/expressions/in_.py,sha256=RgiAIFntXGN4eWoOVBj1gqLymnBxSiw5hYD3TngF3dk,1123
1306
+ vellum/workflows/expressions/is_blank.py,sha256=vOOmK5poXmiNRVH7MR0feIFnL4rwKn7vmmTkJ9TcfVU,904
1307
+ vellum/workflows/expressions/is_nil.py,sha256=xCHwhKlm2UnfC-bVedmGgENCrzNtcn4ZeCYwNflVWbU,748
1308
+ vellum/workflows/expressions/is_not_blank.py,sha256=GJNTe8TKIbh4RwWPFuPwEQw0hbxg2MobHg8bcal4xWU,911
1309
+ vellum/workflows/expressions/is_not_nil.py,sha256=sVNWq_7GKExujpCB_bXEmRxm1tnj0GRDbFY4BtTV1Ew,769
1309
1310
  vellum/workflows/expressions/is_not_null.py,sha256=EoHXFgZScKP_BM2a5Z7YFQN6l7RMEtzs5x5nlvaSST8,671
1310
- vellum/workflows/expressions/is_not_undefined.py,sha256=8NGwA0wZP_aHRy5qJOtaNhRCJyXKekwBNJalSk6Rdmo,727
1311
+ vellum/workflows/expressions/is_not_undefined.py,sha256=9s-RUQBqM17-_nIRvwsHuarLdHVtrxVuwnqBNJEtmh0,735
1311
1312
  vellum/workflows/expressions/is_null.py,sha256=C75ALGlG_sTGcxI46tm9HtgPVfJ7DwTIyKzX8qtEiDU,660
1312
- vellum/workflows/expressions/is_undefined.py,sha256=c9Oc1fdp911fQQ8WMG2L-TeUSqz1wF8cOTuLutJKbe8,716
1313
- vellum/workflows/expressions/less_than.py,sha256=DTWjbhaegnsCWnFSLNldTQr94Dqg3rqWOgMWI7IVsII,1149
1314
- vellum/workflows/expressions/less_than_or_equal_to.py,sha256=IxP1VeXAzXrccdIWT2hm6Fj3Sr-7rPW-DKOHl6MrHjo,1161
1315
- vellum/workflows/expressions/not_between.py,sha256=H2huRR95D9Qb7lCHmK7BcK-Ug-E1gA3sMWz9PGcAVZs,1379
1316
- vellum/workflows/expressions/not_in.py,sha256=OQkN5G1E6VoTDpoLvx7X3GbohLlqEAYHV0rVVUV7ow4,1049
1313
+ vellum/workflows/expressions/is_undefined.py,sha256=uUBK3rxYbwoeRq36AGFc7d61hXzTp8UacQAi-1JbaW0,724
1314
+ vellum/workflows/expressions/less_than.py,sha256=BcfkUH6Bb2inwR8jILn1hebUiyC74foVijBA-JymwT0,1260
1315
+ vellum/workflows/expressions/less_than_or_equal_to.py,sha256=4i1FR6FzlKam29cZPPnXUqACslO242Ww-wZZY4CEK6A,1272
1316
+ vellum/workflows/expressions/not_between.py,sha256=ZtRJeJDSSlOvajL8YoBoh5o_khjIn9xSSeQCnXYbHFE,1506
1317
+ vellum/workflows/expressions/not_in.py,sha256=pFvwkFPsn3WJw61ssFgM2U1dqWEeglfz4FVT4xwm5Mc,1144
1317
1318
  vellum/workflows/expressions/or_.py,sha256=s-8YdMSSCDS2yijR38kguwok3iqmDMMgDYKV93b4O4s,914
1318
1319
  vellum/workflows/graph/__init__.py,sha256=3sHlay5d_-uD7j3QJXiGl0WHFZZ_QScRvgyDhN2GhHY,74
1319
1320
  vellum/workflows/graph/graph.py,sha256=GGR8cGpSuNWPIiTWNWsj6l70upb5nIxAyFcn7VdaJIs,5506
@@ -1324,21 +1325,21 @@ vellum/workflows/inputs/base.py,sha256=1kMgr0WqCYdWUqgFvgSoAMw2067FAlgwhGXLgbIOr
1324
1325
  vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
1325
1326
  vellum/workflows/nodes/__init__.py,sha256=aVdQVv7Y3Ro3JlqXGpxwaU2zrI06plDHD2aumH5WUIs,1157
1326
1327
  vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
1327
- vellum/workflows/nodes/bases/base.py,sha256=v6Y38xRTTKQxfvDpnx7X37EQN6Mrxu2vKtMDQiR2g8A,14186
1328
+ vellum/workflows/nodes/bases/base.py,sha256=O_O4pVZy0_H-4t2umBMumh_a9TCpmQsBGLcLjlS0vtE,14928
1328
1329
  vellum/workflows/nodes/bases/base_adornment_node.py,sha256=eFTgsPCYb3eyGS0-kw7C6crFnwFx437R5wh9-8bWYts,2905
1329
1330
  vellum/workflows/nodes/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1330
- vellum/workflows/nodes/bases/tests/test_base_node.py,sha256=51CueFVty9XYASC0rKr1cXWejho5WElmhfhp6cCONy0,3811
1331
+ vellum/workflows/nodes/bases/tests/test_base_node.py,sha256=4SOdZzvugVtN8CIuo5RrapAxSYGXnxUwQ77dXJ64oTU,6295
1331
1332
  vellum/workflows/nodes/core/__init__.py,sha256=5zDMCmyt1v0HTJzlUBwq3U9L825yZGZhT9JL18-mRR4,455
1332
1333
  vellum/workflows/nodes/core/error_node/__init__.py,sha256=g7RRnlHhqu4qByfLjBwCunmgGA8dI5gNsjS3h6TwlSI,60
1333
1334
  vellum/workflows/nodes/core/error_node/node.py,sha256=MFHU5vITYSK-L9CuMZ49In2ZeNLWnhZD0f8r5dWvb5Y,1270
1334
1335
  vellum/workflows/nodes/core/inline_subworkflow_node/__init__.py,sha256=nKNEH1QTl-1PcvmYoqSWEl0-t6gAur8GLTXHzklRQfM,84
1335
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py,sha256=q0uuS1Coen5_GgAUlZFKeYmCExjBbKxC74Ove-piTGI,5969
1336
+ vellum/workflows/nodes/core/inline_subworkflow_node/node.py,sha256=I7mDUiVoFj-l-JkrvE0L9MS0TDNPVIpu06Q2fvtsHns,5985
1336
1337
  vellum/workflows/nodes/core/inline_subworkflow_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1337
1338
  vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py,sha256=n0-821Ov9ZfRFX_lbzLy5o2rX8fEw2qoxz0aFWCOxVg,1547
1338
1339
  vellum/workflows/nodes/core/map_node/__init__.py,sha256=MXpZYmGfhsMJHqqlpd64WiJRtbAtAMQz-_3fCU_cLV0,56
1339
- vellum/workflows/nodes/core/map_node/node.py,sha256=zL0mN0CAJ8NL-Uaqn4o2kSiw3jYgxrwJraQdMdrz848,8159
1340
+ vellum/workflows/nodes/core/map_node/node.py,sha256=8-vVR5GywLD9vpayfXmC5_CL2oQJyHhpbG4znFoUkY0,8342
1340
1341
  vellum/workflows/nodes/core/map_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1341
- vellum/workflows/nodes/core/map_node/tests/test_node.py,sha256=P7ImQyeLcK-aEJUYCX1gPQyuOxdxnSPpI3mNPpKQ62Y,1919
1342
+ vellum/workflows/nodes/core/map_node/tests/test_node.py,sha256=8ZXs4IIYrXpa4pZz4BSx9t0fx_Usgk3_KF6r3kcy9tE,2547
1342
1343
  vellum/workflows/nodes/core/retry_node/__init__.py,sha256=lN2bIy5a3Uzhs_FYCrooADyYU6ZGShtvLKFWpelwPvo,60
1343
1344
  vellum/workflows/nodes/core/retry_node/node.py,sha256=loIZJUcCsN0y3mr4pw7f23l4eDY69IoTwA2TMnxJlxA,4292
1344
1345
  vellum/workflows/nodes/core/retry_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1357,9 +1358,9 @@ vellum/workflows/nodes/displayable/api_node/tests/__init__.py,sha256=47DEQpj8HBS
1357
1358
  vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py,sha256=yo3zTMRxgpSdWmJ68X610A5rrtCchyfqhcDd2X-GJiU,1249
1358
1359
  vellum/workflows/nodes/displayable/bases/__init__.py,sha256=0mWIx3qUrzllV7jqt7wN03vWGMuI1WrrLZeMLT2Cl2c,304
1359
1360
  vellum/workflows/nodes/displayable/bases/api_node/__init__.py,sha256=1jwx4WC358CLA1jgzl_UD-rZmdMm2v9Mps39ndwCD7U,64
1360
- vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=nIFkP7eeXXSzOVUoQgjPPCzy3_P083X_F5fCm2OAjdU,3798
1361
+ vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=TeVsAhUPEx_lbiyhGcWarqBKZeJJZAJx8mwym9qhwVs,3994
1361
1362
  vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
1362
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=r_gOmeGFQQfzhAc1_bmzcwUvH-Xllc93gE7miTV4rQE,2824
1363
+ vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=cKsNziwWJ9jUjS578I5dIka-zmsXz94hYZR3Cofm8aE,3140
1363
1364
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
1364
1365
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/constants.py,sha256=fnjiRWLoRlC4Puo5oQcpZD5Hd-EesxsAo9l5tGAkpZQ,270
1365
1366
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=UrmI8NkNJFGq9f59gD12S1e8D_R3ROHc934JmtfQk9I,6841
@@ -1374,8 +1375,8 @@ vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=wgtqPljUqa
1374
1375
  vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1375
1376
  vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1376
1377
  vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py,sha256=5QsbmkzSlSbcbWTG_JmIqcP-JNJzOPTKxGzdHos19W4,79
1377
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=y_j4PieOpRYFmTqIEg1IPg-x-y_ezOcjcWCWPXYp1hI,14582
1378
- vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=hF9tdCpta7WN1ANz467Q9LNlISOSmp79jDIkR5d2iQM,3542
1378
+ vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=1i48vpyFZ-zR5DD9wCu4Ekd-aq4gLOsSWnn0BMdJIAs,16810
1379
+ vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=m5y6_sRX5P9icmneNhT_DkXYDNz7l_8Q_Aa8-U5dWsQ,4529
1379
1380
  vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU1F9t8aLmbZU-rLh9ry6LCJ0uj0D8F0L5Uw,72
1380
1381
  vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=Qjfl33gZ3JEgxBA1EgzSUebboGvsARthIxxcQyvx5Gg,1152
1381
1382
  vellum/workflows/nodes/displayable/final_output_node/__init__.py,sha256=G7VXM4OWpubvSJtVkGmMNeqgb9GkM7qZT838eL18XU4,72
@@ -1413,35 +1414,35 @@ vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py,sha256=1
1413
1414
  vellum/workflows/nodes/mocks.py,sha256=gvM2tyoe-V84jFbFdhQsyGAPyQBzmjn_CkhT_yxccgY,499
1414
1415
  vellum/workflows/nodes/utils.py,sha256=T7krLipDSI007JkkH2zsfyQ-tfOBH4hyFzQ0YJKYpuw,4025
1415
1416
  vellum/workflows/outputs/__init__.py,sha256=AyZ4pRh_ACQIGvkf0byJO46EDnSix1ZCAXfvh-ms1QE,94
1416
- vellum/workflows/outputs/base.py,sha256=Wu48tqyQoxpflBUcwzKeZjSVp1LPKrBwuIvnx__9H90,8459
1417
+ vellum/workflows/outputs/base.py,sha256=RPlkKwVml6Ln8-K7kcpRl8-T-0OmB6css_UaKJdjAA8,8581
1417
1418
  vellum/workflows/ports/__init__.py,sha256=bZuMt-R7z5bKwpu4uPW7LlJeePOQWmCcDSXe5frUY5g,101
1418
1419
  vellum/workflows/ports/node_ports.py,sha256=g4A-8iUAvEJSkaWppbvzAR8XU02R9U-qLN4rP2Kq4Aw,2743
1419
- vellum/workflows/ports/port.py,sha256=rc3GB7dDQCUs0IbY08a92-31YzJHQgBeww13brSJ2Js,3172
1420
+ vellum/workflows/ports/port.py,sha256=eI2SOZPZ5rsC3jMsxW6Rbn0NpaYQsrR7AapiIbbiy8Q,3635
1420
1421
  vellum/workflows/ports/utils.py,sha256=pEjVNJKw9LhD_cFN-o0MWBOW2ejno7jv26qqzjLxwS4,1662
1421
1422
  vellum/workflows/references/__init__.py,sha256=glHFC1VfXmcbNvH5VzFbkT03d8_D7MMcvEcsUBrzLIs,591
1422
1423
  vellum/workflows/references/constant.py,sha256=6yUT4q1sMj1hkI_tzzQ9AYcmeeDYFUNCqUq_W2DN0S8,540
1423
1424
  vellum/workflows/references/environment_variable.py,sha256=-gfOcdYwVp9ztSUYz6h2WI2Cg95zqxq5hhFf3Yr7aQg,791
1424
1425
  vellum/workflows/references/execution_count.py,sha256=JILHqt8ELdc9ct-WsVCA5X-rKiP1rmJODw-XTf4kpHI,722
1425
- vellum/workflows/references/external_input.py,sha256=WyBC6uMDu77431YVSU_WvTt-nGLC_bW65tIsplUJXa4,2056
1426
+ vellum/workflows/references/external_input.py,sha256=c_4SojTpykCSbGS1Pjmx9FfquyYGMPksoj0AbrWv7Go,2064
1426
1427
  vellum/workflows/references/input.py,sha256=3INu-TLTi4dziWmva6LO3WvgDlPzsjayUx61cVvqLJA,325
1427
- vellum/workflows/references/lazy.py,sha256=HUQRXQMsCwu0JPVPCDUvQm28q8VlJQ-N8SfFyx2Tap8,2901
1428
+ vellum/workflows/references/lazy.py,sha256=gSOsRwH_V4Jt8aJrwn-8hp3V0jU7GlvoIUDnsMKxvHk,2909
1428
1429
  vellum/workflows/references/node.py,sha256=LP854wDVs-9I_aZ7-nkbwXqL2H7W2_3LED2e9FixNS8,1418
1429
- vellum/workflows/references/output.py,sha256=6F4zIrGykDxBsR6qEXxEKncQV5zV4yHafnHRNkxvklc,2780
1430
+ vellum/workflows/references/output.py,sha256=-g97wkZDf-6_l_-NM4C_8v1VBt2c7NCPhtrG2lBLKSc,2808
1430
1431
  vellum/workflows/references/state_value.py,sha256=bInUF0A3Pt4-zhA0f6LdSuyv8tz7n5QRkHAEn4gsmqI,711
1431
1432
  vellum/workflows/references/vellum_secret.py,sha256=Od4d19a5yletWMqNfJR5d_mZQUkVcFzj29mE-T9J7yE,480
1432
1433
  vellum/workflows/references/workflow_input.py,sha256=86IuhlBz-9cGxeUzizyjdp482ajcl7h8MnX1soNFMII,1415
1433
1434
  vellum/workflows/resolvers/__init__.py,sha256=eH6hTvZO4IciDaf_cf7aM2vs-DkBDyJPycOQevJxQnI,82
1434
1435
  vellum/workflows/resolvers/base.py,sha256=WHra9LRtlTuB1jmuNqkfVE2JUgB61Cyntn8f0b0WZg4,411
1435
1436
  vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
1436
- vellum/workflows/runner/runner.py,sha256=kgfNtVGMdx3nLM0K4upflz-k5iJMKQuwm9MkKDygSuE,28845
1437
+ vellum/workflows/runner/runner.py,sha256=eY4axSyxotT_NHB3CYFA1hDSoM-eY4k3Gq5NEe7dpQw,29208
1437
1438
  vellum/workflows/sandbox.py,sha256=GVJzVjMuYzOBnSrboB0_6MMRZWBluAyQ2o7syeaeBd0,2235
1438
1439
  vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
1439
- vellum/workflows/state/base.py,sha256=IIl76sJtn0GfbFWBqMnpGuvtZyVyQMEXv0QKDfLy8Wg,14763
1440
+ vellum/workflows/state/base.py,sha256=O8BZpXTGsMVEltTs70iIms2PtZ3Qd0imf_OyoB1pKaI,14775
1440
1441
  vellum/workflows/state/context.py,sha256=80b7j11AuG6engdur-AH0dUPnbwu8QyzF_-crWmvUvI,2588
1441
1442
  vellum/workflows/state/encoder.py,sha256=WdUidpOaBDx5lilJl8V8McFDHQYiCLCJR9dmktdzdZY,1836
1442
1443
  vellum/workflows/state/store.py,sha256=VYGBQgN1bpd1as5eGiouV_7scg8QsRs4_1aqZAGIsRQ,793
1443
1444
  vellum/workflows/state/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1444
- vellum/workflows/state/tests/test_state.py,sha256=ucy7U8886J3CinIKQhOqv4dvkKWQk0fyK3JjTSiKZC4,5266
1445
+ vellum/workflows/state/tests/test_state.py,sha256=jBynFR4m74Vn51DdmKBLkxb1loTy1CnJPtzPmdAFQUo,5159
1445
1446
  vellum/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1446
1447
  vellum/workflows/tests/test_sandbox.py,sha256=JKwaluI-lODQo7Ek9sjDstjL_WTdSqUlVik6ZVTfVOA,1826
1447
1448
  vellum/workflows/types/__init__.py,sha256=KxUTMBGzuRCfiMqzzsykOeVvrrkaZmTTo1a7SLu8gRM,68
@@ -1460,13 +1461,15 @@ vellum/workflows/utils/tests/test_names.py,sha256=aOqpyvMsOEK_9mg_-yaNxQDW7QQfwq
1460
1461
  vellum/workflows/utils/tests/test_uuids.py,sha256=i77ABQ0M3S-aFLzDXHJq_yr5FPkJEWCMBn1HJ3DObrE,437
1461
1462
  vellum/workflows/utils/tests/test_vellum_variables.py,sha256=6H-BpmbIEmVRO75QQ3Rfy4bEUMMP2qwGzx2Gp1uXbfw,879
1462
1463
  vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrgTY,739
1463
- vellum/workflows/utils/vellum_variables.py,sha256=g5xHYB8etfHE32ek19nP6Anf8NyjhmUtOwO2KmQ5xZU,3111
1464
+ vellum/workflows/utils/vellum_variables.py,sha256=fC2aSLvlS31D15dOWu43LBRR0QsgUKNXBiCUvvaLXSs,3231
1464
1465
  vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528t75s,683
1465
1466
  vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
1466
- vellum/workflows/workflows/base.py,sha256=uYT0TQnEDtVaH3pErq785FhxxEEmk7C5ZGfuSO3QK8c,18537
1467
+ vellum/workflows/workflows/base.py,sha256=tBivLLLPtMyMi2Bd5WjbwQ2_zZFpG8rNfEidfQ1x2YI,19403
1467
1468
  vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1468
- vellum_ai-0.13.27.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1469
- vellum_ai-0.13.27.dist-info/METADATA,sha256=vsSAQXzNF0pgVlHW2s8G6S4tfzSjLEOplZ9JR0BIR9I,5335
1470
- vellum_ai-0.13.27.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1471
- vellum_ai-0.13.27.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1472
- vellum_ai-0.13.27.dist-info/RECORD,,
1469
+ vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1470
+ vellum/workflows/workflows/tests/test_base_workflow.py,sha256=dz5F3DuGOk9qUMjmNd-GdEE3320G5ko5nJ6J0QJyVcY,2659
1471
+ vellum_ai-0.14.0.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1472
+ vellum_ai-0.14.0.dist-info/METADATA,sha256=whh5Vpg1kDk2eaO-spcwQdR3inmlyl2YWrPoGWgVbYg,5407
1473
+ vellum_ai-0.14.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1474
+ vellum_ai-0.14.0.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1475
+ vellum_ai-0.14.0.dist-info/RECORD,,
vellum_cli/push.py CHANGED
@@ -53,7 +53,16 @@ def push_command(
53
53
  workflow_configs = [w for w in workflow_configs if w.workspace == workspace]
54
54
 
55
55
  if len(workflow_configs) == 0:
56
- raise ValueError(f"No workflow config for '{module}' found in project to push.")
56
+ if module and module_exists(module):
57
+ new_config = WorkflowConfig(
58
+ module=module,
59
+ workflow_sandbox_id=workflow_sandbox_id,
60
+ workspace=workspace or DEFAULT_WORKSPACE_CONFIG.name,
61
+ )
62
+ config.workflows.append(new_config)
63
+ workflow_configs = [new_config]
64
+ else:
65
+ raise ValueError(f"No workflow config for '{module}' found in project to push.")
57
66
 
58
67
  if len(workflow_configs) > 1:
59
68
  raise ValueError("Multiple workflows found in project to push. Pushing only a single workflow is supported.")
@@ -241,3 +250,8 @@ Visit at: https://app.vellum.ai/workflow-sandboxes/{response.workflow_sandbox_id
241
250
 
242
251
  config.save()
243
252
  logger.info("Updated vellum.lock.json file.")
253
+
254
+
255
+ def module_exists(module_name: str) -> bool:
256
+ module_path = os.path.join(os.getcwd(), *module_name.split("."))
257
+ return os.path.exists(module_path) and os.path.isdir(module_path)
@@ -589,3 +589,47 @@ MY_OTHER_VELLUM_API_KEY=aaabbbcccddd
589
589
  assert lock_file_content["workflows"][1]["module"] == module
590
590
  assert lock_file_content["workflows"][1]["workflow_sandbox_id"] == second_workflow_sandbox_id
591
591
  assert lock_file_content["workflows"][1]["workspace"] == "my_other_workspace"
592
+
593
+
594
+ def test_push__create_new_config_for_existing_module(mock_module, vellum_client):
595
+ # GIVEN an empty config (no workflows configured)
596
+ temp_dir = mock_module.temp_dir
597
+ module = mock_module.module
598
+ # GIVEN multiple workflows configured
599
+ mock_module.set_pyproject_toml({"workflows": [{"module": "examples.mock"}, {"module": "examples.mock2"}]})
600
+
601
+ # AND a workflow exists in the module successfully
602
+ workflow_py_file_content = _ensure_workflow_py(temp_dir, module)
603
+
604
+ # AND the push API call returns successfully
605
+ new_workflow_sandbox_id = str(uuid4())
606
+ vellum_client.workflows.push.return_value = WorkflowPushResponse(
607
+ workflow_sandbox_id=new_workflow_sandbox_id,
608
+ )
609
+
610
+ # WHEN calling `vellum push` with a module that exists but isn't in config
611
+ runner = CliRunner()
612
+ result = runner.invoke(cli_main, ["workflows", "push", module])
613
+
614
+ # THEN it should succeed
615
+ assert result.exit_code == 0, result.output
616
+
617
+ # AND we should have called the push API with the correct args
618
+ vellum_client.workflows.push.assert_called_once()
619
+ call_args = vellum_client.workflows.push.call_args.kwargs
620
+ assert json.loads(call_args["exec_config"])["workflow_raw_data"]["definition"]["name"] == "ExampleWorkflow"
621
+ assert call_args["workflow_sandbox_id"] is None # Should be None since it's a new config
622
+ assert call_args["artifact"].name == f"{module.replace('.', '__')}.tar.gz"
623
+
624
+ # AND the files in the artifact should be correct
625
+ extracted_files = _extract_tar_gz(call_args["artifact"].read())
626
+ assert extracted_files["workflow.py"] == workflow_py_file_content
627
+
628
+ # AND check that lockfile was updated with new config
629
+ with open(os.path.join(temp_dir, "vellum.lock.json")) as f:
630
+ lock_file_content = json.load(f)
631
+ new_configs = [w for w in lock_file_content["workflows"] if w["module"] == module]
632
+ assert len(new_configs) == 1 # Should only create one config
633
+ new_config = new_configs[0]
634
+ assert new_config["workflow_sandbox_id"] == new_workflow_sandbox_id
635
+ assert new_config["workspace"] == "default"