vellum-ai 0.13.0__py3-none-any.whl → 0.13.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/client/core/pydantic_utilities.py +5 -0
  3. vellum/client/resources/workflows/client.py +8 -0
  4. vellum/client/types/logical_operator.py +2 -0
  5. vellum/workflows/descriptors/base.py +1 -1
  6. vellum/workflows/descriptors/tests/test_utils.py +3 -0
  7. vellum/workflows/expressions/accessor.py +8 -2
  8. vellum/workflows/nodes/core/map_node/node.py +49 -24
  9. vellum/workflows/nodes/core/map_node/tests/test_node.py +4 -4
  10. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +1 -1
  11. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +5 -3
  12. vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +3 -0
  13. vellum/workflows/nodes/displayable/bases/search_node.py +37 -2
  14. vellum/workflows/nodes/displayable/bases/tests/__init__.py +0 -0
  15. vellum/workflows/nodes/displayable/bases/tests/test_utils.py +61 -0
  16. vellum/workflows/nodes/displayable/bases/types.py +42 -0
  17. vellum/workflows/nodes/displayable/bases/utils.py +112 -0
  18. vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py +0 -1
  19. vellum/workflows/nodes/displayable/search_node/tests/__init__.py +0 -0
  20. vellum/workflows/nodes/displayable/search_node/tests/test_node.py +164 -0
  21. vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +2 -3
  22. vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +0 -1
  23. vellum/workflows/runner/runner.py +37 -4
  24. vellum/workflows/types/tests/test_utils.py +5 -2
  25. vellum/workflows/types/utils.py +4 -0
  26. vellum/workflows/workflows/base.py +14 -0
  27. {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.1.dist-info}/METADATA +1 -1
  28. {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.1.dist-info}/RECORD +46 -36
  29. vellum_cli/__init__.py +10 -0
  30. vellum_cli/ping.py +28 -0
  31. vellum_cli/tests/test_ping.py +47 -0
  32. vellum_ee/workflows/display/nodes/vellum/base_node.py +22 -9
  33. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +3 -0
  34. vellum_ee/workflows/display/nodes/vellum/map_node.py +1 -1
  35. vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +14 -10
  36. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +2 -2
  37. vellum_ee/workflows/display/nodes/vellum/utils.py +8 -1
  38. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +67 -0
  39. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +66 -0
  40. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py +660 -0
  41. vellum_ee/workflows/display/utils/vellum.py +4 -42
  42. vellum_ee/workflows/display/vellum.py +7 -36
  43. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +2 -1
  44. {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.1.dist-info}/LICENSE +0 -0
  45. {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.1.dist-info}/WHEEL +0 -0
  46. {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.1.dist-info}/entry_points.txt +0 -0
@@ -5,6 +5,7 @@ from deepdiff import DeepDiff
5
5
  from vellum.workflows.inputs.base import BaseInputs
6
6
  from vellum.workflows.nodes.bases.base import BaseNode
7
7
  from vellum.workflows.ports.port import Port
8
+ from vellum.workflows.references.vellum_secret import VellumSecretReference
8
9
  from vellum_ee.workflows.display.base import WorkflowInputsDisplay
9
10
  from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay
10
11
  from vellum_ee.workflows.display.nodes.vellum.base_node import BaseNodeDisplay
@@ -353,3 +354,662 @@ def test_serialize_node__node_output_reference(serialize_node):
353
354
  serialized_node,
354
355
  ignore_order=True,
355
356
  )
357
+
358
+
359
+ class GenericNodeReferencingSecret(BaseNode):
360
+ class Outputs(BaseNode.Outputs):
361
+ output = Inputs.input
362
+
363
+ class Ports(BaseNode.Ports):
364
+ if_branch = Port.on_if(VellumSecretReference(name="hello").equals("hello"))
365
+
366
+
367
+ def test_serialize_node__vellum_secret_reference(serialize_node):
368
+ workflow_input_id = uuid4()
369
+ serialized_node = serialize_node(
370
+ node_class=GenericNodeReferencingSecret,
371
+ global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=workflow_input_id)},
372
+ )
373
+
374
+ assert not DeepDiff(
375
+ {
376
+ "id": "88272edd-fc81-403b-bb87-a116ef8f269e",
377
+ "label": "GenericNodeReferencingSecret",
378
+ "type": "GENERIC",
379
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
380
+ "definition": {
381
+ "name": "GenericNodeReferencingSecret",
382
+ "module": [
383
+ "vellum_ee",
384
+ "workflows",
385
+ "display",
386
+ "tests",
387
+ "workflow_serialization",
388
+ "generic_nodes",
389
+ "test_ports_serialization",
390
+ ],
391
+ },
392
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
393
+ "trigger": {"id": "2709539b-352d-455a-bb86-dba070b59aa1", "merge_behavior": "AWAIT_ANY"},
394
+ "ports": [
395
+ {
396
+ "id": "a353d3f6-2a1f-457c-b8d1-13db5b45be8f",
397
+ "type": "IF",
398
+ "expression": {
399
+ "type": "BINARY_EXPRESSION",
400
+ "lhs": {"type": "VELLUM_SECRET", "vellum_secret_name": "hello"},
401
+ "operator": "=",
402
+ "rhs": {
403
+ "type": "CONSTANT_VALUE",
404
+ "value": {
405
+ "type": "STRING",
406
+ "value": "hello",
407
+ },
408
+ },
409
+ },
410
+ }
411
+ ],
412
+ "adornments": None,
413
+ "attributes": [],
414
+ },
415
+ serialized_node,
416
+ ignore_order=True,
417
+ )
418
+
419
+
420
+ class NodeWithExecutions(BaseNode):
421
+ pass
422
+
423
+
424
+ class NodeWithExecutionsDisplay(BaseNodeDisplay[NodeWithExecutions]):
425
+ pass
426
+
427
+
428
+ class GenericNodeReferencingExecutions(BaseNode):
429
+ class Outputs(BaseNode.Outputs):
430
+ output = NodeWithExecutions.Execution.count
431
+
432
+ class Ports(BaseNode.Ports):
433
+ if_branch = Port.on_if(NodeWithExecutions.Execution.count.equals(5))
434
+
435
+
436
+ def test_serialize_node__execution_count_reference(serialize_node):
437
+ workflow_input_id = uuid4()
438
+ serialized_node = serialize_node(
439
+ node_class=GenericNodeReferencingExecutions,
440
+ global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=workflow_input_id)},
441
+ global_node_displays={NodeWithExecutions: NodeWithExecutionsDisplay()},
442
+ )
443
+
444
+ assert not DeepDiff(
445
+ {
446
+ "id": "6e4d2fb7-891e-492e-97a1-adf44693f518",
447
+ "label": "GenericNodeReferencingExecutions",
448
+ "type": "GENERIC",
449
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
450
+ "definition": {
451
+ "name": "GenericNodeReferencingExecutions",
452
+ "module": [
453
+ "vellum_ee",
454
+ "workflows",
455
+ "display",
456
+ "tests",
457
+ "workflow_serialization",
458
+ "generic_nodes",
459
+ "test_ports_serialization",
460
+ ],
461
+ },
462
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
463
+ "trigger": {"id": "68a91426-4c30-4194-a4c0-cff224d3c0f3", "merge_behavior": "AWAIT_ANY"},
464
+ "ports": [
465
+ {
466
+ "id": "1794c2eb-5cab-49fe-9354-dfc29f11b374",
467
+ "type": "IF",
468
+ "expression": {
469
+ "type": "BINARY_EXPRESSION",
470
+ "lhs": {
471
+ "type": "EXECUTION_COUNTER",
472
+ "node_id": "c09bd5a6-dc04-4036-90d4-580acd43c71f",
473
+ },
474
+ "operator": "=",
475
+ "rhs": {
476
+ "type": "CONSTANT_VALUE",
477
+ "value": {
478
+ "type": "NUMBER",
479
+ "value": 5,
480
+ },
481
+ },
482
+ },
483
+ }
484
+ ],
485
+ "adornments": None,
486
+ "attributes": [],
487
+ },
488
+ serialized_node,
489
+ ignore_order=True,
490
+ )
491
+
492
+
493
+ class NullGenericNode(BaseNode):
494
+ class Outputs(BaseNode.Outputs):
495
+ output = Inputs.input
496
+
497
+ class Ports(BaseNode.Ports):
498
+ if_branch = Port.on_if(Inputs.input.is_null())
499
+
500
+
501
+ def test_serialize_node__null(serialize_node):
502
+ input_id = uuid4()
503
+ serialized_node = serialize_node(
504
+ node_class=NullGenericNode, global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)}
505
+ )
506
+
507
+ assert not DeepDiff(
508
+ {
509
+ "id": "d5fe72cd-a2bd-4f91-ae13-44e4c617815e",
510
+ "label": "NullGenericNode",
511
+ "type": "GENERIC",
512
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
513
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
514
+ "definition": {
515
+ "name": "NullGenericNode",
516
+ "module": [
517
+ "vellum_ee",
518
+ "workflows",
519
+ "display",
520
+ "tests",
521
+ "workflow_serialization",
522
+ "generic_nodes",
523
+ "test_ports_serialization",
524
+ ],
525
+ },
526
+ "trigger": {"id": "26b257ed-6a7d-4ca3-a5c8-d17ba1e776ba", "merge_behavior": "AWAIT_ANY"},
527
+ "ports": [
528
+ {
529
+ "id": "51932d23-492e-4b3b-8b03-6ad7303a80c9",
530
+ "type": "IF",
531
+ "expression": {
532
+ "type": "UNARY_EXPRESSION",
533
+ "lhs": {
534
+ "type": "WORKFLOW_INPUT",
535
+ "input_variable_id": str(input_id),
536
+ },
537
+ "operator": "null",
538
+ },
539
+ }
540
+ ],
541
+ "adornments": None,
542
+ "attributes": [],
543
+ },
544
+ serialized_node,
545
+ ignore_order=True,
546
+ )
547
+
548
+
549
+ class IntegerInputs(BaseInputs):
550
+ input: int
551
+
552
+
553
+ class BetweenGenericNode(BaseNode):
554
+ class Outputs(BaseNode.Outputs):
555
+ output = IntegerInputs.input
556
+
557
+ class Ports(BaseNode.Ports):
558
+ if_branch = Port.on_if(IntegerInputs.input.between(1, 10))
559
+
560
+
561
+ def test_serialize_node__between(serialize_node):
562
+ input_id = uuid4()
563
+ serialized_node = serialize_node(
564
+ node_class=BetweenGenericNode,
565
+ global_workflow_input_displays={IntegerInputs.input: WorkflowInputsDisplay(id=input_id)},
566
+ )
567
+
568
+ assert not DeepDiff(
569
+ {
570
+ "id": "3ef33a2a-6ad5-415c-be75-f38cc1403dfc",
571
+ "label": "BetweenGenericNode",
572
+ "type": "GENERIC",
573
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
574
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
575
+ "definition": {
576
+ "name": "BetweenGenericNode",
577
+ "module": [
578
+ "vellum_ee",
579
+ "workflows",
580
+ "display",
581
+ "tests",
582
+ "workflow_serialization",
583
+ "generic_nodes",
584
+ "test_ports_serialization",
585
+ ],
586
+ },
587
+ "trigger": {"id": "086a355e-d9ef-4039-af35-9f1211497b32", "merge_behavior": "AWAIT_ANY"},
588
+ "ports": [
589
+ {
590
+ "id": "a86bd19f-a9f7-45c3-80ff-73330b1b75af",
591
+ "type": "IF",
592
+ "expression": {
593
+ "type": "TERNARY_EXPRESSION",
594
+ "base": {
595
+ "type": "WORKFLOW_INPUT",
596
+ "input_variable_id": str(input_id),
597
+ },
598
+ "operator": "between",
599
+ "lhs": {
600
+ "type": "CONSTANT_VALUE",
601
+ "value": {
602
+ "type": "NUMBER",
603
+ "value": 1,
604
+ },
605
+ },
606
+ "rhs": {
607
+ "type": "CONSTANT_VALUE",
608
+ "value": {
609
+ "type": "NUMBER",
610
+ "value": 10,
611
+ },
612
+ },
613
+ },
614
+ }
615
+ ],
616
+ "adornments": None,
617
+ "attributes": [],
618
+ },
619
+ serialized_node,
620
+ ignore_order=True,
621
+ )
622
+
623
+
624
+ class OrGenericNode(BaseNode):
625
+ class Outputs(BaseNode.Outputs):
626
+ output = Inputs.input
627
+
628
+ class Ports(BaseNode.Ports):
629
+ if_branch = Port.on_if(Inputs.input.equals("hello") | Inputs.input.equals("world"))
630
+
631
+
632
+ def test_serialize_node__or(serialize_node):
633
+ input_id = uuid4()
634
+ serialized_node = serialize_node(
635
+ node_class=OrGenericNode, global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)}
636
+ )
637
+
638
+ assert not DeepDiff(
639
+ {
640
+ "id": "63900268-b9d0-4285-8ea4-7c478f4abf88",
641
+ "label": "OrGenericNode",
642
+ "type": "GENERIC",
643
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
644
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
645
+ "definition": {
646
+ "name": "OrGenericNode",
647
+ "module": [
648
+ "vellum_ee",
649
+ "workflows",
650
+ "display",
651
+ "tests",
652
+ "workflow_serialization",
653
+ "generic_nodes",
654
+ "test_ports_serialization",
655
+ ],
656
+ },
657
+ "trigger": {"id": "dc245f37-9be7-4097-a50a-4f7196e24313", "merge_behavior": "AWAIT_ANY"},
658
+ "ports": [
659
+ {
660
+ "id": "652a42f9-f4e7-4791-8167-8903ff839520",
661
+ "type": "IF",
662
+ "expression": {
663
+ "type": "BINARY_EXPRESSION",
664
+ "lhs": {
665
+ "type": "BINARY_EXPRESSION",
666
+ "lhs": {
667
+ "type": "WORKFLOW_INPUT",
668
+ "input_variable_id": str(input_id),
669
+ },
670
+ "operator": "=",
671
+ "rhs": {
672
+ "type": "CONSTANT_VALUE",
673
+ "value": {
674
+ "type": "STRING",
675
+ "value": "hello",
676
+ },
677
+ },
678
+ },
679
+ "operator": "or",
680
+ "rhs": {
681
+ "type": "BINARY_EXPRESSION",
682
+ "lhs": {
683
+ "type": "WORKFLOW_INPUT",
684
+ "input_variable_id": str(input_id),
685
+ },
686
+ "operator": "=",
687
+ "rhs": {
688
+ "type": "CONSTANT_VALUE",
689
+ "value": {
690
+ "type": "STRING",
691
+ "value": "world",
692
+ },
693
+ },
694
+ },
695
+ },
696
+ }
697
+ ],
698
+ "adornments": None,
699
+ "attributes": [],
700
+ },
701
+ serialized_node,
702
+ ignore_order=True,
703
+ )
704
+
705
+
706
+ class AndThenOrGenericNode(BaseNode):
707
+ class Outputs(BaseNode.Outputs):
708
+ output = Inputs.input
709
+
710
+ class Ports(BaseNode.Ports):
711
+ if_branch = Port.on_if(
712
+ Inputs.input.equals("hello") & Inputs.input.equals("then") | Inputs.input.equals("world")
713
+ )
714
+
715
+
716
+ def test_serialize_node__and_then_or(serialize_node):
717
+ input_id = uuid4()
718
+ serialized_node = serialize_node(
719
+ node_class=AndThenOrGenericNode,
720
+ global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)},
721
+ )
722
+
723
+ assert not DeepDiff(
724
+ {
725
+ "id": "b3908206-e540-4dac-9c64-a2e12b847b15",
726
+ "label": "AndThenOrGenericNode",
727
+ "type": "GENERIC",
728
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
729
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
730
+ "definition": {
731
+ "name": "AndThenOrGenericNode",
732
+ "module": [
733
+ "vellum_ee",
734
+ "workflows",
735
+ "display",
736
+ "tests",
737
+ "workflow_serialization",
738
+ "generic_nodes",
739
+ "test_ports_serialization",
740
+ ],
741
+ },
742
+ "trigger": {"id": "33cfa8f4-bfc5-40b3-8df8-ab86371c26e0", "merge_behavior": "AWAIT_ANY"},
743
+ "ports": [
744
+ {
745
+ "id": "42c89e95-6bbf-4e85-8f26-d4b6fc55d99c",
746
+ "type": "IF",
747
+ "expression": {
748
+ "type": "BINARY_EXPRESSION",
749
+ "lhs": {
750
+ "type": "BINARY_EXPRESSION",
751
+ "lhs": {
752
+ "type": "BINARY_EXPRESSION",
753
+ "lhs": {
754
+ "type": "WORKFLOW_INPUT",
755
+ "input_variable_id": str(input_id),
756
+ },
757
+ "operator": "=",
758
+ "rhs": {
759
+ "type": "CONSTANT_VALUE",
760
+ "value": {
761
+ "type": "STRING",
762
+ "value": "hello",
763
+ },
764
+ },
765
+ },
766
+ "operator": "and",
767
+ "rhs": {
768
+ "type": "BINARY_EXPRESSION",
769
+ "lhs": {
770
+ "type": "WORKFLOW_INPUT",
771
+ "input_variable_id": str(input_id),
772
+ },
773
+ "operator": "=",
774
+ "rhs": {
775
+ "type": "CONSTANT_VALUE",
776
+ "value": {
777
+ "type": "STRING",
778
+ "value": "then",
779
+ },
780
+ },
781
+ },
782
+ },
783
+ "operator": "or",
784
+ "rhs": {
785
+ "type": "BINARY_EXPRESSION",
786
+ "lhs": {
787
+ "type": "WORKFLOW_INPUT",
788
+ "input_variable_id": str(input_id),
789
+ },
790
+ "operator": "=",
791
+ "rhs": {
792
+ "type": "CONSTANT_VALUE",
793
+ "value": {
794
+ "type": "STRING",
795
+ "value": "world",
796
+ },
797
+ },
798
+ },
799
+ },
800
+ }
801
+ ],
802
+ "adornments": None,
803
+ "attributes": [],
804
+ },
805
+ serialized_node,
806
+ ignore_order=True,
807
+ )
808
+
809
+
810
+ class ParenthesizedAndThenOrGenericNode(BaseNode):
811
+ class Outputs(BaseNode.Outputs):
812
+ output = Inputs.input
813
+
814
+ class Ports(BaseNode.Ports):
815
+ if_branch = Port.on_if(
816
+ Inputs.input.equals("hello") & (Inputs.input.equals("then") | Inputs.input.equals("world"))
817
+ )
818
+
819
+
820
+ def test_serialize_node__parenthesized_and_then_or(serialize_node):
821
+ input_id = uuid4()
822
+ serialized_node = serialize_node(
823
+ node_class=ParenthesizedAndThenOrGenericNode,
824
+ global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)},
825
+ )
826
+
827
+ assert not DeepDiff(
828
+ {
829
+ "id": "6ed0373a-13b1-4edb-b0c4-31642cf312f8",
830
+ "label": "ParenthesizedAndThenOrGenericNode",
831
+ "type": "GENERIC",
832
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
833
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
834
+ "definition": {
835
+ "name": "ParenthesizedAndThenOrGenericNode",
836
+ "module": [
837
+ "vellum_ee",
838
+ "workflows",
839
+ "display",
840
+ "tests",
841
+ "workflow_serialization",
842
+ "generic_nodes",
843
+ "test_ports_serialization",
844
+ ],
845
+ },
846
+ "trigger": {"id": "91ac3b05-c931-4a4c-bb48-c2ba0e883867", "merge_behavior": "AWAIT_ANY"},
847
+ "ports": [
848
+ {
849
+ "id": "cc07394b-f20b-4370-8a5b-af90e847a73f",
850
+ "type": "IF",
851
+ "expression": {
852
+ "type": "BINARY_EXPRESSION",
853
+ "lhs": {
854
+ "type": "BINARY_EXPRESSION",
855
+ "lhs": {
856
+ "type": "WORKFLOW_INPUT",
857
+ "input_variable_id": str(input_id),
858
+ },
859
+ "operator": "=",
860
+ "rhs": {
861
+ "type": "CONSTANT_VALUE",
862
+ "value": {
863
+ "type": "STRING",
864
+ "value": "hello",
865
+ },
866
+ },
867
+ },
868
+ "operator": "and",
869
+ "rhs": {
870
+ "type": "BINARY_EXPRESSION",
871
+ "lhs": {
872
+ "type": "BINARY_EXPRESSION",
873
+ "lhs": {
874
+ "type": "WORKFLOW_INPUT",
875
+ "input_variable_id": str(input_id),
876
+ },
877
+ "operator": "=",
878
+ "rhs": {
879
+ "type": "CONSTANT_VALUE",
880
+ "value": {
881
+ "type": "STRING",
882
+ "value": "then",
883
+ },
884
+ },
885
+ },
886
+ "operator": "or",
887
+ "rhs": {
888
+ "type": "BINARY_EXPRESSION",
889
+ "lhs": {
890
+ "type": "WORKFLOW_INPUT",
891
+ "input_variable_id": str(input_id),
892
+ },
893
+ "operator": "=",
894
+ "rhs": {
895
+ "type": "CONSTANT_VALUE",
896
+ "value": {
897
+ "type": "STRING",
898
+ "value": "world",
899
+ },
900
+ },
901
+ },
902
+ },
903
+ },
904
+ }
905
+ ],
906
+ "adornments": None,
907
+ "attributes": [],
908
+ },
909
+ serialized_node,
910
+ ignore_order=True,
911
+ )
912
+
913
+
914
+ class OrThenAndGenericNode(BaseNode):
915
+ class Outputs(BaseNode.Outputs):
916
+ output = Inputs.input
917
+
918
+ class Ports(BaseNode.Ports):
919
+ if_branch = Port.on_if(
920
+ Inputs.input.equals("hello") | Inputs.input.equals("then") & Inputs.input.equals("world")
921
+ )
922
+
923
+
924
+ def test_serialize_node__or_then_and(serialize_node):
925
+ input_id = uuid4()
926
+ serialized_node = serialize_node(
927
+ node_class=OrThenAndGenericNode,
928
+ global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)},
929
+ )
930
+
931
+ assert not DeepDiff(
932
+ {
933
+ "id": "a0e0a35b-132e-4168-ad7d-ceb04f3203f2",
934
+ "label": "OrThenAndGenericNode",
935
+ "type": "GENERIC",
936
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
937
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
938
+ "definition": {
939
+ "name": "OrThenAndGenericNode",
940
+ "module": [
941
+ "vellum_ee",
942
+ "workflows",
943
+ "display",
944
+ "tests",
945
+ "workflow_serialization",
946
+ "generic_nodes",
947
+ "test_ports_serialization",
948
+ ],
949
+ },
950
+ "trigger": {"id": "dfa53d32-36cc-4b1d-adad-d4de21ac1e5a", "merge_behavior": "AWAIT_ANY"},
951
+ "ports": [
952
+ {
953
+ "id": "daaff604-da1e-45e6-b3df-5bc8de8d55fe",
954
+ "type": "IF",
955
+ "expression": {
956
+ "type": "BINARY_EXPRESSION",
957
+ "lhs": {
958
+ "type": "BINARY_EXPRESSION",
959
+ "lhs": {
960
+ "type": "WORKFLOW_INPUT",
961
+ "input_variable_id": str(input_id),
962
+ },
963
+ "operator": "=",
964
+ "rhs": {
965
+ "type": "CONSTANT_VALUE",
966
+ "value": {
967
+ "type": "STRING",
968
+ "value": "hello",
969
+ },
970
+ },
971
+ },
972
+ "operator": "or",
973
+ "rhs": {
974
+ "type": "BINARY_EXPRESSION",
975
+ "lhs": {
976
+ "type": "BINARY_EXPRESSION",
977
+ "lhs": {
978
+ "type": "WORKFLOW_INPUT",
979
+ "input_variable_id": str(input_id),
980
+ },
981
+ "operator": "=",
982
+ "rhs": {
983
+ "type": "CONSTANT_VALUE",
984
+ "value": {
985
+ "type": "STRING",
986
+ "value": "then",
987
+ },
988
+ },
989
+ },
990
+ "operator": "and",
991
+ "rhs": {
992
+ "type": "BINARY_EXPRESSION",
993
+ "lhs": {
994
+ "type": "WORKFLOW_INPUT",
995
+ "input_variable_id": str(input_id),
996
+ },
997
+ "operator": "=",
998
+ "rhs": {
999
+ "type": "CONSTANT_VALUE",
1000
+ "value": {
1001
+ "type": "STRING",
1002
+ "value": "world",
1003
+ },
1004
+ },
1005
+ },
1006
+ },
1007
+ },
1008
+ }
1009
+ ],
1010
+ "adornments": None,
1011
+ "attributes": [],
1012
+ },
1013
+ serialized_node,
1014
+ ignore_order=True,
1015
+ )