vellum-ai 1.7.5__py3-none-any.whl → 1.7.7__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 (29) hide show
  1. vellum/client/core/client_wrapper.py +2 -2
  2. vellum/workflows/nodes/bases/base.py +28 -9
  3. vellum/workflows/nodes/bases/base_adornment_node.py +53 -1
  4. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +3 -1
  5. vellum/workflows/nodes/displayable/search_node/node.py +2 -1
  6. vellum/workflows/nodes/displayable/search_node/tests/test_node.py +14 -0
  7. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +7 -1
  8. vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py +1 -1
  9. vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py +54 -0
  10. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +26 -24
  11. vellum/workflows/runner/runner.py +42 -52
  12. vellum/workflows/triggers/__init__.py +2 -1
  13. vellum/workflows/triggers/integration.py +62 -0
  14. vellum/workflows/triggers/tests/__init__.py +1 -0
  15. vellum/workflows/triggers/tests/test_integration.py +102 -0
  16. vellum/workflows/workflows/base.py +17 -3
  17. {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/METADATA +1 -1
  18. {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/RECORD +29 -26
  19. vellum_cli/push.py +1 -5
  20. vellum_cli/tests/test_push.py +86 -0
  21. vellum_ee/workflows/display/nodes/base_node_display.py +1 -1
  22. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +16 -0
  23. vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py +16 -19
  24. vellum_ee/workflows/display/utils/expressions.py +11 -11
  25. vellum_ee/workflows/display/workflows/base_workflow_display.py +23 -14
  26. vellum_ee/workflows/tests/test_server.py +40 -1
  27. {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/LICENSE +0 -0
  28. {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/WHEEL +0 -0
  29. {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/entry_points.txt +0 -0
@@ -410,7 +410,7 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
410
410
  self.display_context.add_error(e)
411
411
 
412
412
  # Serialize workflow-level trigger if present
413
- trigger_data: Optional[JsonObject] = self._serialize_workflow_trigger()
413
+ triggers: Optional[JsonArray] = self._serialize_workflow_trigger()
414
414
 
415
415
  workflow_raw_data: JsonObject = {
416
416
  "nodes": cast(JsonArray, nodes_dict_list),
@@ -423,22 +423,25 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
423
423
  "output_values": output_values,
424
424
  }
425
425
 
426
- if trigger_data is not None:
427
- workflow_raw_data["trigger"] = trigger_data
428
-
429
- return {
426
+ result: JsonObject = {
430
427
  "workflow_raw_data": workflow_raw_data,
431
428
  "input_variables": input_variables,
432
429
  "state_variables": state_variables,
433
430
  "output_variables": output_variables,
434
431
  }
435
432
 
436
- def _serialize_workflow_trigger(self) -> Optional[JsonObject]:
433
+ if triggers is not None:
434
+ result["triggers"] = triggers
435
+
436
+ return result
437
+
438
+ def _serialize_workflow_trigger(self) -> Optional[JsonArray]:
437
439
  """
438
440
  Serialize workflow-level trigger information.
439
441
 
440
442
  Returns:
441
- JsonObject with trigger data if a trigger is present, None otherwise
443
+ JsonArray with trigger data if a trigger is present, None otherwise.
444
+ Each trigger in the array has: id (UUID), type (str), attributes (list)
442
445
  """
443
446
  # Get all trigger edges from the workflow's subgraphs
444
447
  trigger_edges = []
@@ -469,13 +472,19 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
469
472
  f"Please add it to the trigger type mapping in get_trigger_type_mapping()."
470
473
  )
471
474
 
472
- return {
473
- "type": trigger_type.value,
474
- "definition": {
475
- "name": trigger_class.__name__,
476
- "module": cast(JsonArray, trigger_class.__module__.split(".")),
477
- },
478
- }
475
+ # Return as a list with a single trigger object matching Django schema
476
+ trigger_id = uuid4_from_hash(f"{trigger_class.__module__} | {trigger_class.__qualname__}")
477
+
478
+ return cast(
479
+ JsonArray,
480
+ [
481
+ {
482
+ "id": str(trigger_id),
483
+ "type": trigger_type.value,
484
+ "attributes": [],
485
+ }
486
+ ],
487
+ )
479
488
 
480
489
  def _serialize_edge_display_data(self, edge_display: EdgeDisplay) -> Optional[JsonObject]:
481
490
  """Serialize edge display data, returning None if no display data is present."""
@@ -536,10 +536,49 @@ class BrokenNode(BaseNode) # Missing colon
536
536
 
537
537
  # AND the error message should be user-friendly
538
538
  error_message = str(exc_info.value)
539
- assert "Failed to load workflow module:" in error_message
539
+ assert "Syntax Error raised while loading Workflow:" in error_message
540
540
  assert "invalid syntax" in error_message or "expected ':'" in error_message
541
541
 
542
542
 
543
+ def test_load_from_module__name_error_in_node_file():
544
+ """
545
+ Tests that a NameError in a node file raises WorkflowInitializationException with user-facing message.
546
+ """
547
+ # GIVEN a workflow module with a node file containing a NameError (undefined class reference)
548
+ files = {
549
+ "__init__.py": "",
550
+ "workflow.py": """\
551
+ from vellum.workflows import BaseWorkflow
552
+ from .nodes.broken_node import BrokenNode
553
+
554
+ class Workflow(BaseWorkflow):
555
+ graph = BrokenNode
556
+ """,
557
+ "nodes/__init__.py": "",
558
+ "nodes/broken_node.py": """\
559
+ from vellum.workflows.nodes import BaseNode
560
+
561
+ class BrokenNode(BaseNode):
562
+ some_attribute = UndefinedClass()
563
+ """,
564
+ }
565
+
566
+ namespace = str(uuid4())
567
+
568
+ # AND the virtual file loader is registered
569
+ sys.meta_path.append(VirtualFileFinder(files, namespace))
570
+
571
+ # WHEN we attempt to load the workflow
572
+ # THEN it should raise WorkflowInitializationException
573
+ with pytest.raises(WorkflowInitializationException) as exc_info:
574
+ BaseWorkflow.load_from_module(namespace)
575
+
576
+ # AND the error message should be user-friendly
577
+ error_message = str(exc_info.value)
578
+ assert "Invalid variable reference:" in error_message
579
+ assert "UndefinedClass" in error_message or "not defined" in error_message
580
+
581
+
543
582
  def test_serialize_module__tool_calling_node_with_single_tool():
544
583
  """Test that serialize_module works with a tool calling node that has a single tool."""
545
584