vellum-ai 0.14.44__py3-none-any.whl → 0.14.46__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 (56) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/client/core/pydantic_utilities.py +7 -1
  3. vellum/workflows/nodes/bases/base.py +1 -0
  4. vellum/workflows/nodes/bases/tests/test_base_node.py +20 -0
  5. vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +8 -14
  6. vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +62 -0
  7. vellum/workflows/nodes/displayable/code_execution_node/utils.py +3 -54
  8. vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +5 -6
  9. vellum/workflows/nodes/utils.py +4 -0
  10. vellum/workflows/ports/port.py +13 -3
  11. vellum/workflows/types/code_execution_node_wrappers.py +64 -0
  12. vellum/workflows/types/tests/test_utils.py +3 -3
  13. vellum/workflows/types/utils.py +31 -10
  14. vellum/workflows/vellum_client.py +19 -7
  15. {vellum_ai-0.14.44.dist-info → vellum_ai-0.14.46.dist-info}/METADATA +1 -1
  16. {vellum_ai-0.14.44.dist-info → vellum_ai-0.14.46.dist-info}/RECORD +56 -53
  17. vellum_cli/config.py +7 -2
  18. vellum_cli/push.py +5 -1
  19. vellum_cli/tests/test_push.py +192 -8
  20. vellum_ee/workflows/display/nodes/base_node_display.py +4 -173
  21. vellum_ee/workflows/display/nodes/vellum/conditional_node.py +1 -1
  22. vellum_ee/workflows/display/nodes/vellum/final_output_node.py +2 -1
  23. vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +5 -6
  24. vellum_ee/workflows/display/nodes/vellum/retry_node.py +3 -3
  25. vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +5 -6
  26. vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_deployment_node.py +106 -0
  27. vellum_ee/workflows/display/nodes/vellum/tests/test_subworkflow_deployment_node.py +109 -0
  28. vellum_ee/workflows/display/nodes/vellum/try_node.py +3 -3
  29. vellum_ee/workflows/display/tests/test_base_workflow_display.py +1 -0
  30. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +73 -111
  31. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +0 -1
  32. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +0 -3
  33. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +0 -4
  34. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py +0 -1
  35. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py +0 -1
  36. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py +0 -1
  37. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py +0 -1
  38. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +18 -2
  39. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +10 -1
  40. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +0 -1
  41. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +2 -3
  42. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_serialization.py +0 -1
  43. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +2 -3
  44. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py +0 -1
  45. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py +1 -2
  46. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +0 -1
  47. vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +5 -55
  48. vellum_ee/workflows/display/types.py +3 -0
  49. vellum_ee/workflows/display/utils/expressions.py +222 -2
  50. vellum_ee/workflows/display/utils/vellum.py +1 -79
  51. vellum_ee/workflows/display/workflows/base_workflow_display.py +59 -37
  52. vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py +3 -0
  53. vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +98 -0
  54. {vellum_ai-0.14.44.dist-info → vellum_ai-0.14.46.dist-info}/LICENSE +0 -0
  55. {vellum_ai-0.14.44.dist-info → vellum_ai-0.14.46.dist-info}/WHEEL +0 -0
  56. {vellum_ai-0.14.44.dist-info → vellum_ai-0.14.46.dist-info}/entry_points.txt +0 -0
@@ -6,6 +6,8 @@ from vellum.workflows.nodes.core.inline_subworkflow_node.node import InlineSubwo
6
6
  from vellum.workflows.nodes.core.retry_node.node import RetryNode
7
7
  from vellum.workflows.nodes.core.templating_node.node import TemplatingNode
8
8
  from vellum.workflows.nodes.core.try_node.node import TryNode
9
+ from vellum.workflows.nodes.displayable.final_output_node.node import FinalOutputNode
10
+ from vellum.workflows.references.lazy import LazyReference
9
11
  from vellum.workflows.workflows.base import BaseWorkflow
10
12
  from vellum_ee.workflows.display.editor.types import NodeDisplayData, NodeDisplayPosition
11
13
  from vellum_ee.workflows.display.nodes import BaseNodeDisplay
@@ -327,3 +329,99 @@ def test_serialize_workflow__inherited_workflow_display_class_not_registered():
327
329
 
328
330
  # THEN it should should succeed
329
331
  assert data is not None
332
+
333
+
334
+ def test_serialize_workflow__terminal_node_mismatches_workflow_output_name():
335
+ # GIVEN a node
336
+ class ExitNode(FinalOutputNode):
337
+ class Outputs(FinalOutputNode.Outputs):
338
+ value = "hello"
339
+
340
+ # AND a workflow that uses the node
341
+ class MyWorkflow(BaseWorkflow):
342
+ graph = ExitNode
343
+
344
+ class Outputs(BaseWorkflow.Outputs):
345
+ answer = ExitNode.Outputs.value
346
+
347
+ # WHEN we serialize it
348
+ workflow_display = get_workflow_display(workflow_class=MyWorkflow)
349
+ data = workflow_display.serialize()
350
+
351
+ # THEN it should have an output name that matches the workflow output
352
+ assert isinstance(data["workflow_raw_data"], dict)
353
+ assert isinstance(data["workflow_raw_data"]["nodes"], list)
354
+ terminal_node = [
355
+ node for node in data["workflow_raw_data"]["nodes"] if isinstance(node, dict) and node["type"] == "TERMINAL"
356
+ ][0]
357
+ assert isinstance(terminal_node["data"], dict)
358
+ assert terminal_node["data"]["name"] == "answer"
359
+
360
+ # AND the output variable should have the correct name
361
+ assert isinstance(data["output_variables"], list)
362
+ assert isinstance(data["output_variables"][0], dict)
363
+ assert data["output_variables"][0]["key"] == "answer"
364
+ assert data["output_variables"][0]["type"] == "STRING"
365
+
366
+ # AND the output value should have the correct name
367
+ output_variable_id = data["output_variables"][0]["id"]
368
+ assert isinstance(data["workflow_raw_data"]["output_values"], list)
369
+ assert isinstance(data["workflow_raw_data"]["output_values"][0], dict)
370
+ assert data["workflow_raw_data"]["output_values"][0]["output_variable_id"] == output_variable_id
371
+ assert data["workflow_raw_data"]["output_values"][0]["value"] == {
372
+ "type": "NODE_OUTPUT",
373
+ "node_id": str(ExitNode.__id__),
374
+ "node_output_id": str(ExitNode.__output_ids__["value"]),
375
+ }
376
+
377
+
378
+ def test_serialize_workflow__nested_lazy_reference():
379
+ # GIVEN an inner node that references the output of an outer node
380
+ class InnerNode(BaseNode):
381
+ foo = LazyReference[str]("OuterNode.Outputs.bar")
382
+
383
+ class Outputs(BaseNode.Outputs):
384
+ foo = "foo"
385
+
386
+ # AND a workflow that uses the inner node
387
+ class InnerWorkflow(BaseWorkflow):
388
+ graph = InnerNode
389
+
390
+ class Outputs(BaseWorkflow.Outputs):
391
+ foo = InnerNode.Outputs.foo
392
+
393
+ # AND a subworkflow that uses the inner workflow
394
+ class SubworkflowNode(InlineSubworkflowNode):
395
+ subworkflow = InnerWorkflow
396
+
397
+ # AND the outer node
398
+ class OuterNode(BaseNode):
399
+ class Outputs(BaseNode.Outputs):
400
+ bar: str
401
+
402
+ # AND a workflow that uses the subworkflow node and the outer node
403
+ class MyWorkflow(BaseWorkflow):
404
+ graph = SubworkflowNode >> OuterNode
405
+
406
+ class Outputs(BaseWorkflow.Outputs):
407
+ answer = SubworkflowNode.Outputs.foo
408
+
409
+ # WHEN we serialize it
410
+ workflow_display = get_workflow_display(workflow_class=MyWorkflow)
411
+ data: dict = workflow_display.serialize()
412
+
413
+ # THEN it should have properly serialized the lazy reference
414
+ subworkflow_node = next(
415
+ node for node in data["workflow_raw_data"]["nodes"] if isinstance(node, dict) and node["type"] == "SUBWORKFLOW"
416
+ )
417
+ inner_node = next(
418
+ node
419
+ for node in subworkflow_node["data"]["workflow_raw_data"]["nodes"]
420
+ if isinstance(node, dict) and node["type"] == "GENERIC"
421
+ )
422
+
423
+ assert inner_node["attributes"][0]["value"] == {
424
+ "type": "NODE_OUTPUT",
425
+ "node_id": str(OuterNode.__id__),
426
+ "node_output_id": str(OuterNode.__output_ids__["bar"]),
427
+ }