vellum-ai 1.1.5__py3-none-any.whl → 1.2.1__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 (61) hide show
  1. vellum/__init__.py +18 -1
  2. vellum/client/__init__.py +3 -0
  3. vellum/client/core/client_wrapper.py +2 -2
  4. vellum/client/errors/__init__.py +10 -1
  5. vellum/client/errors/too_many_requests_error.py +11 -0
  6. vellum/client/errors/unauthorized_error.py +11 -0
  7. vellum/client/reference.md +94 -0
  8. vellum/client/resources/__init__.py +2 -0
  9. vellum/client/resources/events/__init__.py +4 -0
  10. vellum/client/resources/events/client.py +165 -0
  11. vellum/client/resources/events/raw_client.py +207 -0
  12. vellum/client/types/__init__.py +6 -0
  13. vellum/client/types/error_detail_response.py +22 -0
  14. vellum/client/types/event_create_response.py +26 -0
  15. vellum/client/types/execution_thinking_vellum_value.py +1 -1
  16. vellum/client/types/thinking_vellum_value.py +1 -1
  17. vellum/client/types/thinking_vellum_value_request.py +1 -1
  18. vellum/client/types/workflow_event.py +33 -0
  19. vellum/errors/too_many_requests_error.py +3 -0
  20. vellum/errors/unauthorized_error.py +3 -0
  21. vellum/resources/events/__init__.py +3 -0
  22. vellum/resources/events/client.py +3 -0
  23. vellum/resources/events/raw_client.py +3 -0
  24. vellum/types/error_detail_response.py +3 -0
  25. vellum/types/event_create_response.py +3 -0
  26. vellum/types/workflow_event.py +3 -0
  27. vellum/workflows/nodes/displayable/bases/api_node/node.py +4 -0
  28. vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py +26 -0
  29. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +6 -1
  30. vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +22 -0
  31. vellum/workflows/sandbox.py +28 -8
  32. vellum/workflows/state/encoder.py +19 -1
  33. vellum/workflows/utils/hmac.py +44 -0
  34. {vellum_ai-1.1.5.dist-info → vellum_ai-1.2.1.dist-info}/METADATA +1 -1
  35. {vellum_ai-1.1.5.dist-info → vellum_ai-1.2.1.dist-info}/RECORD +61 -43
  36. vellum_ee/workflows/display/nodes/base_node_display.py +2 -2
  37. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +37 -7
  38. vellum_ee/workflows/display/nodes/vellum/retry_node.py +1 -1
  39. vellum_ee/workflows/display/nodes/vellum/tests/test_retry_node.py +1 -1
  40. vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +314 -2
  41. vellum_ee/workflows/display/nodes/vellum/try_node.py +1 -1
  42. vellum_ee/workflows/display/tests/test_base_workflow_display.py +53 -1
  43. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +9 -9
  44. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +9 -9
  45. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py +3 -3
  46. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py +14 -15
  47. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py +58 -3
  48. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +1 -1
  49. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py +4 -0
  50. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +1 -1
  51. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +2 -2
  52. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +1 -1
  53. vellum_ee/workflows/display/utils/expressions.py +9 -1
  54. vellum_ee/workflows/display/utils/registry.py +46 -0
  55. vellum_ee/workflows/display/workflows/base_workflow_display.py +21 -1
  56. vellum_ee/workflows/tests/test_registry.py +169 -0
  57. vellum_ee/workflows/tests/test_serialize_module.py +31 -0
  58. vellum_ee/workflows/tests/test_server.py +72 -0
  59. {vellum_ai-1.1.5.dist-info → vellum_ai-1.2.1.dist-info}/LICENSE +0 -0
  60. {vellum_ai-1.1.5.dist-info → vellum_ai-1.2.1.dist-info}/WHEEL +0 -0
  61. {vellum_ai-1.1.5.dist-info → vellum_ai-1.2.1.dist-info}/entry_points.txt +0 -0
@@ -1,12 +1,31 @@
1
+ from datetime import datetime
2
+
1
3
  from vellum.client.types.prompt_parameters import PromptParameters
4
+ from vellum.client.types.release_review_reviewer import ReleaseReviewReviewer
5
+ from vellum.client.types.workflow_deployment_release import (
6
+ ReleaseEnvironment,
7
+ ReleaseReleaseTag,
8
+ SlimReleaseReview,
9
+ WorkflowDeploymentRelease,
10
+ WorkflowDeploymentReleaseWorkflowDeployment,
11
+ WorkflowDeploymentReleaseWorkflowVersion,
12
+ )
2
13
  from vellum.workflows import BaseWorkflow
3
14
  from vellum.workflows.inputs import BaseInputs
15
+ from vellum.workflows.nodes.bases import BaseNode
16
+ from vellum.workflows.nodes.displayable.code_execution_node.node import CodeExecutionNode
4
17
  from vellum.workflows.nodes.displayable.inline_prompt_node.node import InlinePromptNode
5
18
  from vellum.workflows.nodes.displayable.tool_calling_node.node import ToolCallingNode
6
19
  from vellum.workflows.nodes.displayable.tool_calling_node.state import ToolCallingState
7
20
  from vellum.workflows.nodes.displayable.tool_calling_node.utils import create_router_node, create_tool_prompt_node
21
+ from vellum.workflows.outputs.base import BaseOutputs
8
22
  from vellum.workflows.state.base import BaseState
9
- from vellum.workflows.types.definition import AuthorizationType, EnvironmentVariableReference, MCPServer
23
+ from vellum.workflows.types.definition import (
24
+ AuthorizationType,
25
+ DeploymentDefinition,
26
+ EnvironmentVariableReference,
27
+ MCPServer,
28
+ )
10
29
  from vellum_ee.workflows.display.nodes.get_node_display_class import get_node_display_class
11
30
  from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
12
31
 
@@ -184,6 +203,58 @@ def test_serialize_node__tool_calling_node__mcp_server_api_key():
184
203
  }
185
204
 
186
205
 
206
+ def test_serialize_node__tool_calling_node__mcp_server_no_authorization():
207
+ # GIVEN a tool calling node with an mcp server
208
+ class MyToolCallingNode(ToolCallingNode):
209
+ functions = [
210
+ MCPServer(
211
+ name="my-mcp-server",
212
+ url="https://my-mcp-server.com",
213
+ )
214
+ ]
215
+
216
+ # AND a workflow with the tool calling node
217
+ class Workflow(BaseWorkflow):
218
+ graph = MyToolCallingNode
219
+
220
+ # WHEN the workflow is serialized
221
+ workflow_display = get_workflow_display(workflow_class=Workflow)
222
+ serialized_workflow: dict = workflow_display.serialize()
223
+
224
+ # THEN the node should properly serialize the mcp server
225
+ my_tool_calling_node = next(
226
+ node
227
+ for node in serialized_workflow["workflow_raw_data"]["nodes"]
228
+ if node["id"] == str(MyToolCallingNode.__id__)
229
+ )
230
+
231
+ functions_attribute = next(
232
+ attribute for attribute in my_tool_calling_node["attributes"] if attribute["name"] == "functions"
233
+ )
234
+
235
+ assert functions_attribute == {
236
+ "id": "c8957551-cb3d-49af-8053-acd256c1d852",
237
+ "name": "functions",
238
+ "value": {
239
+ "type": "CONSTANT_VALUE",
240
+ "value": {
241
+ "type": "JSON",
242
+ "value": [
243
+ {
244
+ "type": "MCP_SERVER",
245
+ "name": "my-mcp-server",
246
+ "url": "https://my-mcp-server.com",
247
+ "authorization_type": None,
248
+ "bearer_token_value": None,
249
+ "api_key_header_key": None,
250
+ "api_key_header_value": None,
251
+ }
252
+ ],
253
+ },
254
+ },
255
+ }
256
+
257
+
187
258
  def test_serialize_tool_router_node():
188
259
  """
189
260
  Test that the tool router node created by create_router_node serializes successfully.
@@ -243,7 +314,7 @@ def test_serialize_tool_router_node():
243
314
  },
244
315
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
245
316
  "id": "690c66e1-1e18-4984-b695-84beb0157541",
246
- "label": "RouterNode",
317
+ "label": "Router Node",
247
318
  "outputs": [],
248
319
  "ports": [
249
320
  {
@@ -332,3 +403,244 @@ def test_serialize_tool_router_node():
332
403
  "trigger": {"id": "73a96f44-c2dd-40cc-96f6-49b9f914b166", "merge_behavior": "AWAIT_ATTRIBUTES"},
333
404
  "type": "GENERIC",
334
405
  }
406
+
407
+
408
+ def test_serialize_node__tool_calling_node__subworkflow_with_parent_input_reference():
409
+ """
410
+ Test that a tool calling node with a subworkflow that references parent inputs serializes correctly
411
+ """
412
+
413
+ # GIVEN a workflow inputs class
414
+ class MyInputs(BaseInputs):
415
+ text: str
416
+ greeting: str
417
+
418
+ # AND a code execution node that references parent inputs
419
+ class CodeExecution(CodeExecutionNode[BaseState, str]):
420
+ code = ""
421
+ code_inputs = {
422
+ "text": MyInputs.text,
423
+ }
424
+ runtime = "PYTHON_3_11_6"
425
+ packages = []
426
+
427
+ # AND a subworkflow that uses the code execution node
428
+ class FunctionSubworkflow(BaseWorkflow):
429
+ graph = CodeExecution
430
+
431
+ class Outputs(BaseWorkflow.Outputs):
432
+ output = CodeExecution.Outputs.result
433
+
434
+ # AND a tool calling node that uses the subworkflow
435
+ class MyToolCallingNode(ToolCallingNode):
436
+ ml_model = "gpt-4.1"
437
+ prompt_inputs = {
438
+ "text": MyInputs.text,
439
+ }
440
+ blocks = []
441
+ parameters = PromptParameters()
442
+ functions = [FunctionSubworkflow]
443
+
444
+ # AND a workflow with the tool calling node
445
+ class Workflow(BaseWorkflow[MyInputs, BaseState]):
446
+ graph = MyToolCallingNode
447
+
448
+ # WHEN the workflow is serialized
449
+ workflow_display = get_workflow_display(workflow_class=Workflow)
450
+ serialized_workflow: dict = workflow_display.serialize()
451
+
452
+ # THEN the node should properly serialize the functions with parent input references
453
+ my_tool_calling_node = next(
454
+ node
455
+ for node in serialized_workflow["workflow_raw_data"]["nodes"]
456
+ if node["id"] == str(MyToolCallingNode.__id__)
457
+ )
458
+
459
+ functions_attribute = next(
460
+ attribute for attribute in my_tool_calling_node["attributes"] if attribute["name"] == "functions"
461
+ )
462
+
463
+ data = functions_attribute["value"]["value"]["value"][0]
464
+ nodes = data["exec_config"]["workflow_raw_data"]["nodes"]
465
+ code_exec_node = next((node for node in nodes if node["type"] == "CODE_EXECUTION"), None)
466
+
467
+ assert code_exec_node is not None
468
+ text_input = next((input for input in code_exec_node["inputs"] if input["key"] == "text"), None)
469
+ assert text_input == {
470
+ "id": "da92a1c4-d37c-4008-a1ab-c0bcc0cd20d0",
471
+ "key": "text",
472
+ "value": {
473
+ "rules": [
474
+ {"type": "INPUT_VARIABLE", "data": {"input_variable_id": "6f0c1889-3f08-4c5c-bb24-f7b94169105c"}}
475
+ ],
476
+ "combinator": "OR",
477
+ },
478
+ }
479
+
480
+
481
+ def test_serialize_tool_prompt_node_with_inline_workflow():
482
+ """
483
+ Test that the tool prompt node created by create_tool_prompt_node serializes successfully with inline workflow.
484
+ """
485
+
486
+ # GIVEN a simple inline workflow for tool calling
487
+ class SimpleWorkflowInputs(BaseInputs):
488
+ message: str
489
+
490
+ class SimpleNode(BaseNode):
491
+ message = SimpleWorkflowInputs.message
492
+
493
+ class Outputs(BaseOutputs):
494
+ result: str
495
+
496
+ def run(self) -> Outputs:
497
+ return self.Outputs(result=f"Processed: {self.message}")
498
+
499
+ class SimpleInlineWorkflow(BaseWorkflow[SimpleWorkflowInputs, BaseState]):
500
+ """A simple workflow for testing inline tool serialization."""
501
+
502
+ graph = SimpleNode
503
+
504
+ class Outputs(BaseOutputs):
505
+ result = SimpleNode.Outputs.result
506
+
507
+ # WHEN we create a tool prompt node using create_tool_prompt_node with inline workflow
508
+ tool_prompt_node = create_tool_prompt_node(
509
+ ml_model="gpt-4o-mini",
510
+ blocks=[],
511
+ functions=[SimpleInlineWorkflow],
512
+ prompt_inputs=None,
513
+ parameters=PromptParameters(),
514
+ )
515
+
516
+ tool_prompt_node_display_class = get_node_display_class(tool_prompt_node)
517
+ tool_prompt_node_display = tool_prompt_node_display_class()
518
+
519
+ # AND we create a workflow that uses this tool prompt node
520
+ class TestWorkflow(BaseWorkflow[BaseInputs, ToolCallingState]):
521
+ graph = tool_prompt_node
522
+
523
+ # WHEN we serialize the entire workflow
524
+ workflow_display = get_workflow_display(workflow_class=TestWorkflow)
525
+ display_context = workflow_display.display_context
526
+ serialized_tool_prompt_node = tool_prompt_node_display.serialize(display_context)
527
+
528
+ # THEN prompt inputs should be serialized correctly
529
+ attributes = serialized_tool_prompt_node["attributes"]
530
+ assert isinstance(attributes, list)
531
+ prompt_inputs_attr = next(
532
+ (attr for attr in attributes if isinstance(attr, dict) and attr["name"] == "prompt_inputs"), None
533
+ )
534
+ assert prompt_inputs_attr == {
535
+ "id": "bc1320a2-23e4-4238-8b00-efbf88e91856",
536
+ "name": "prompt_inputs",
537
+ "value": {
538
+ "type": "DICTIONARY_REFERENCE",
539
+ "entries": [
540
+ {
541
+ "id": "76ceec7b-ec37-474f-ba38-2bfd27cecc5d",
542
+ "key": "chat_history",
543
+ "value": {
544
+ "type": "BINARY_EXPRESSION",
545
+ "lhs": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": []}},
546
+ "operator": "concat",
547
+ "rhs": {
548
+ "type": "WORKFLOW_STATE",
549
+ "state_variable_id": "7a1caaf5-99df-487a-8b2d-6512df2d871a",
550
+ },
551
+ },
552
+ }
553
+ ],
554
+ },
555
+ }
556
+
557
+
558
+ def test_serialize_tool_prompt_node_with_workflow_deployment(vellum_client):
559
+ """
560
+ Test that the tool prompt node serializes successfully with a workflow deployment.
561
+ """
562
+ vellum_client.workflow_deployments.retrieve_workflow_deployment_release.return_value = WorkflowDeploymentRelease(
563
+ id="test-id",
564
+ created=datetime.now(),
565
+ environment=ReleaseEnvironment(
566
+ id="test-id",
567
+ name="test-name",
568
+ label="test-label",
569
+ ),
570
+ created_by=None,
571
+ workflow_version=WorkflowDeploymentReleaseWorkflowVersion(
572
+ id="test-id",
573
+ input_variables=[],
574
+ output_variables=[],
575
+ ),
576
+ deployment=WorkflowDeploymentReleaseWorkflowDeployment(name="test-name"),
577
+ description="test-description",
578
+ release_tags=[
579
+ ReleaseReleaseTag(
580
+ name="test-name",
581
+ source="USER",
582
+ )
583
+ ],
584
+ reviews=[
585
+ SlimReleaseReview(
586
+ id="test-id",
587
+ created=datetime.now(),
588
+ reviewer=ReleaseReviewReviewer(
589
+ id="test-id",
590
+ full_name="test-name",
591
+ ),
592
+ state="APPROVED",
593
+ )
594
+ ],
595
+ )
596
+
597
+ # GIVEN a workflow deployment
598
+ workflow_deployment = DeploymentDefinition(
599
+ deployment="test-deployment",
600
+ release_tag="test-release-tag",
601
+ )
602
+
603
+ # WHEN we create a tool prompt node using create_tool_prompt_node with a workflow deployment
604
+ tool_prompt_node = create_tool_prompt_node(
605
+ ml_model="gpt-4o-mini",
606
+ blocks=[],
607
+ functions=[workflow_deployment],
608
+ prompt_inputs=None,
609
+ parameters=PromptParameters(),
610
+ )
611
+
612
+ tool_prompt_node_display_class = get_node_display_class(tool_prompt_node)
613
+ tool_prompt_node_display = tool_prompt_node_display_class()
614
+
615
+ # AND we create a workflow that uses this tool prompt node
616
+ class TestWorkflow(BaseWorkflow[BaseInputs, ToolCallingState]):
617
+ graph = tool_prompt_node
618
+
619
+ # WHEN we serialize the entire workflow
620
+ workflow_display = get_workflow_display(workflow_class=TestWorkflow)
621
+ display_context = workflow_display.display_context
622
+ serialized_tool_prompt_node = tool_prompt_node_display.serialize(display_context)
623
+
624
+ # THEN functions attribute should be serialized correctly
625
+ attributes = serialized_tool_prompt_node["attributes"]
626
+ assert isinstance(attributes, list)
627
+ functions_attr = next((attr for attr in attributes if isinstance(attr, dict) and attr["name"] == "functions"), None)
628
+ assert functions_attr == {
629
+ "id": "6326ccc4-7cf6-4235-ba3c-a6e860b0c48b",
630
+ "name": "functions",
631
+ "value": {
632
+ "type": "CONSTANT_VALUE",
633
+ "value": {
634
+ "type": "JSON",
635
+ "value": [
636
+ {
637
+ "type": "WORKFLOW_DEPLOYMENT",
638
+ "name": "test-name",
639
+ "description": "test-description",
640
+ "deployment": "test-deployment",
641
+ "release_tag": "test-release-tag",
642
+ }
643
+ ],
644
+ },
645
+ },
646
+ }
@@ -43,7 +43,7 @@ class BaseTryNodeDisplay(BaseAdornmentNodeDisplay[_TryNodeType], Generic[_TryNod
43
43
 
44
44
  adornment: JsonObject = {
45
45
  "id": str(node_id),
46
- "label": node.__qualname__,
46
+ "label": self.label,
47
47
  "base": self.get_base().dict(),
48
48
  "attributes": attributes,
49
49
  }
@@ -2,7 +2,8 @@ from uuid import UUID
2
2
  from typing import Dict
3
3
 
4
4
  from vellum.workflows.inputs import BaseInputs
5
- from vellum.workflows.nodes import BaseNode
5
+ from vellum.workflows.nodes import BaseNode, InlineSubworkflowNode
6
+ from vellum.workflows.outputs.base import BaseOutputs
6
7
  from vellum.workflows.ports.port import Port
7
8
  from vellum.workflows.references.lazy import LazyReference
8
9
  from vellum.workflows.state import BaseState
@@ -327,3 +328,54 @@ def test_serialize__port_with_lazy_reference():
327
328
  },
328
329
  }
329
330
  ]
331
+
332
+
333
+ def test_global_propagation_deep_nested_subworkflows():
334
+ # GIVEN the root workflow, a middle workflow, and an inner workflow
335
+
336
+ class RootInputs(BaseInputs):
337
+ root_param: str
338
+
339
+ class MiddleInputs(BaseInputs):
340
+ middle_param: str
341
+
342
+ class InnerInputs(BaseInputs):
343
+ inner_param: str
344
+
345
+ class InnerNode(BaseNode):
346
+ class Outputs(BaseOutputs):
347
+ done: bool
348
+
349
+ def run(self) -> Outputs:
350
+ return self.Outputs(done=True)
351
+
352
+ class InnerWorkflow(BaseWorkflow[InnerInputs, BaseState]):
353
+ graph = InnerNode
354
+
355
+ class MiddleInlineSubworkflowNode(InlineSubworkflowNode):
356
+ subworkflow_inputs = {"inner_param": "x"}
357
+ subworkflow = InnerWorkflow
358
+
359
+ class MiddleWorkflow(BaseWorkflow[MiddleInputs, BaseState]):
360
+ graph = MiddleInlineSubworkflowNode
361
+
362
+ class OuterInlineSubworkflowNode(InlineSubworkflowNode):
363
+ subworkflow_inputs = {"middle_param": "y"}
364
+ subworkflow = MiddleWorkflow
365
+
366
+ class RootWorkflow(BaseWorkflow[RootInputs, BaseState]):
367
+ graph = OuterInlineSubworkflowNode
368
+
369
+ # WHEN we build the displays
370
+ root_display = get_workflow_display(workflow_class=RootWorkflow)
371
+ middle_display = get_workflow_display(
372
+ workflow_class=MiddleWorkflow, parent_display_context=root_display.display_context
373
+ )
374
+ inner_display = get_workflow_display(
375
+ workflow_class=InnerWorkflow, parent_display_context=middle_display.display_context
376
+ )
377
+
378
+ # THEN the deepest display must include root + middle + inner inputs in its GLOBAL view
379
+ inner_global_names = {ref.name for ref in inner_display.display_context.global_workflow_input_displays.keys()}
380
+
381
+ assert inner_global_names == {"middle_param", "inner_param", "root_param"}
@@ -47,7 +47,7 @@ def test_serialize_node__retry(serialize_node):
47
47
  assert not DeepDiff(
48
48
  {
49
49
  "id": "188b50aa-e518-4b7b-a5e0-e2585fb1d7b5",
50
- "label": "test_serialize_node__retry.<locals>.InnerRetryGenericNode",
50
+ "label": "Inner Retry Generic Node",
51
51
  "type": "GENERIC",
52
52
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
53
53
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -68,7 +68,7 @@ def test_serialize_node__retry(serialize_node):
68
68
  "adornments": [
69
69
  {
70
70
  "id": "5be7d260-74f7-4734-b31b-a46a94539586",
71
- "label": "RetryNode",
71
+ "label": "Retry Node",
72
72
  "base": {
73
73
  "name": "RetryNode",
74
74
  "module": ["vellum", "workflows", "nodes", "core", "retry_node", "node"],
@@ -154,7 +154,7 @@ def test_serialize_node__try(serialize_node):
154
154
  assert not DeepDiff(
155
155
  {
156
156
  "id": str(InnerTryGenericNode.__wrapped_node__.__id__),
157
- "label": "test_serialize_node__try.<locals>.InnerTryGenericNode",
157
+ "label": "Inner Try Generic Node",
158
158
  "type": "GENERIC",
159
159
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
160
160
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -175,7 +175,7 @@ def test_serialize_node__try(serialize_node):
175
175
  "adornments": [
176
176
  {
177
177
  "id": "3344083c-a32c-4a32-920b-0fb5093448fa",
178
- "label": "TryNode",
178
+ "label": "Try Node",
179
179
  "base": {
180
180
  "name": "TryNode",
181
181
  "module": ["vellum", "workflows", "nodes", "core", "try_node", "node"],
@@ -248,7 +248,7 @@ def test_serialize_node__stacked():
248
248
  assert not DeepDiff(
249
249
  {
250
250
  "id": "074833b0-e142-4bbc-8dec-209a35e178a3",
251
- "label": "test_serialize_node__stacked.<locals>.InnerStackedGenericNode",
251
+ "label": "Inner Stacked Generic Node",
252
252
  "type": "GENERIC",
253
253
  "display_data": {"position": {"x": 200.0, "y": -50.0}},
254
254
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -272,7 +272,7 @@ def test_serialize_node__stacked():
272
272
  "adornments": [
273
273
  {
274
274
  "id": "3344083c-a32c-4a32-920b-0fb5093448fa",
275
- "label": "TryNode",
275
+ "label": "Try Node",
276
276
  "base": {
277
277
  "name": "TryNode",
278
278
  "module": ["vellum", "workflows", "nodes", "core", "try_node", "node"],
@@ -287,7 +287,7 @@ def test_serialize_node__stacked():
287
287
  },
288
288
  {
289
289
  "id": "5be7d260-74f7-4734-b31b-a46a94539586",
290
- "label": "RetryNode",
290
+ "label": "Retry Node",
291
291
  "base": {
292
292
  "name": "RetryNode",
293
293
  "module": ["vellum", "workflows", "nodes", "core", "retry_node", "node"],
@@ -351,5 +351,5 @@ def test_serialize_node__adornment_order_matches_decorator_order():
351
351
 
352
352
  adornments = cast(List[Dict[str, Any]], my_node["adornments"])
353
353
  assert len(adornments) == 2
354
- assert adornments[0]["label"] == "TryNode"
355
- assert adornments[1]["label"] == "RetryNode"
354
+ assert adornments[0]["label"] == "Try Node"
355
+ assert adornments[1]["label"] == "Retry Node"
@@ -34,7 +34,7 @@ def test_serialize_node__constant_value(serialize_node):
34
34
  assert not DeepDiff(
35
35
  {
36
36
  "id": "67e07859-7f67-4287-9854-06ab4199e576",
37
- "label": "test_serialize_node__constant_value.<locals>.ConstantValueGenericNode",
37
+ "label": "Constant Value Generic Node",
38
38
  "type": "GENERIC",
39
39
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
40
40
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -104,7 +104,7 @@ def test_serialize_node__constant_value_reference(serialize_node):
104
104
  assert not DeepDiff(
105
105
  {
106
106
  "id": "73643f17-e49e-47d2-bd01-bb9c3eab6ae9",
107
- "label": "test_serialize_node__constant_value_reference.<locals>.ConstantValueReferenceGenericNode",
107
+ "label": "Constant Value Reference Generic Node",
108
108
  "type": "GENERIC",
109
109
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
110
110
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -146,7 +146,7 @@ def test_serialize_node__lazy_reference(serialize_node):
146
146
  assert not DeepDiff(
147
147
  {
148
148
  "id": "3d6bfe3b-263a-40a6-8a05-98288e9559a4",
149
- "label": "test_serialize_node__lazy_reference.<locals>.LazyReferenceGenericNode",
149
+ "label": "Lazy Reference Generic Node",
150
150
  "type": "GENERIC",
151
151
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
152
152
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -229,7 +229,7 @@ def test_serialize_node__workflow_input(serialize_node):
229
229
  assert not DeepDiff(
230
230
  {
231
231
  "id": "30116483-6f38-40e0-baf2-32de0e14e9a3",
232
- "label": "test_serialize_node__workflow_input.<locals>.WorkflowInputGenericNode",
232
+ "label": "Workflow Input Generic Node",
233
233
  "type": "GENERIC",
234
234
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
235
235
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -292,7 +292,7 @@ def test_serialize_node__workflow_input_as_nested_chat_history():
292
292
  assert not DeepDiff(
293
293
  {
294
294
  "id": "11be9d37-0069-4695-a317-14a3b6519d4e",
295
- "label": "test_serialize_node__workflow_input_as_nested_chat_history.<locals>.GenericNode",
295
+ "label": "Generic Node",
296
296
  "type": "GENERIC",
297
297
  "display_data": {"position": {"x": 200.0, "y": -50.0}},
298
298
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -362,7 +362,7 @@ def test_serialize_node__node_output(serialize_node):
362
362
  assert not DeepDiff(
363
363
  {
364
364
  "id": "7210742f-8c3e-4379-9800-8b4b7f5dd7ed",
365
- "label": "test_serialize_node__node_output.<locals>.GenericNodeReferencingOutput",
365
+ "label": "Generic Node Referencing Output",
366
366
  "type": "GENERIC",
367
367
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
368
368
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -412,7 +412,7 @@ def test_serialize_node__vellum_secret(serialize_node):
412
412
  assert not DeepDiff(
413
413
  {
414
414
  "id": "0e75bd8f-882e-4ab7-8348-061319b574f7",
415
- "label": "test_serialize_node__vellum_secret.<locals>.VellumSecretGenericNode",
415
+ "label": "Vellum Secret Generic Node",
416
416
  "type": "GENERIC",
417
417
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
418
418
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -465,7 +465,7 @@ def test_serialize_node__node_execution(serialize_node):
465
465
  assert not DeepDiff(
466
466
  {
467
467
  "id": "f42dda6b-e856-49bd-b203-46c9dd66c08b",
468
- "label": "test_serialize_node__node_execution.<locals>.GenericNodeReferencingExecutions",
468
+ "label": "Generic Node Referencing Executions",
469
469
  "type": "GENERIC",
470
470
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
471
471
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -561,7 +561,7 @@ def test_serialize_node__coalesce(serialize_node):
561
561
  assert not DeepDiff(
562
562
  {
563
563
  "id": "bb99f326-7d2a-4b5e-95f3-6039114798da",
564
- "label": "test_serialize_node__coalesce.<locals>.CoalesceNodeFinal",
564
+ "label": "Coalesce Node Final",
565
565
  "type": "GENERIC",
566
566
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
567
567
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -23,7 +23,7 @@ def test_serialize_node__annotated_output(serialize_node):
23
23
  assert not DeepDiff(
24
24
  {
25
25
  "id": "e33ddf79-f48c-4057-ba17-d41a3a60ac98",
26
- "label": "test_serialize_node__annotated_output.<locals>.AnnotatedOutputGenericNode",
26
+ "label": "Annotated Output Generic Node",
27
27
  "type": "GENERIC",
28
28
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
29
29
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -71,7 +71,7 @@ def test_serialize_node__workflow_input(serialize_node):
71
71
  assert not DeepDiff(
72
72
  {
73
73
  "id": "30116483-6f38-40e0-baf2-32de0e14e9a3",
74
- "label": "test_serialize_node__workflow_input.<locals>.WorkflowInputGenericNode",
74
+ "label": "Workflow Input Generic Node",
75
75
  "type": "GENERIC",
76
76
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
77
77
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -134,7 +134,7 @@ def test_serialize_node__node_output_reference(serialize_node):
134
134
  assert not DeepDiff(
135
135
  {
136
136
  "id": "ac067acc-6a6f-44b1-ae84-428e965ce691",
137
- "label": "test_serialize_node__node_output_reference.<locals>.GenericNodeReferencingOutput",
137
+ "label": "Generic Node Referencing Output",
138
138
  "type": "GENERIC",
139
139
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
140
140
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},