vellum-ai 1.0.0__py3-none-any.whl → 1.0.2__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 (34) hide show
  1. vellum/__init__.py +6 -0
  2. vellum/client/core/client_wrapper.py +2 -2
  3. vellum/client/types/__init__.py +6 -0
  4. vellum/client/types/organization_limit_config.py +24 -0
  5. vellum/client/types/organization_read.py +2 -0
  6. vellum/client/types/quota.py +21 -0
  7. vellum/client/types/vembda_service_tier_enum.py +5 -0
  8. vellum/client/types/workflow_execution_actual.py +1 -1
  9. vellum/types/organization_limit_config.py +3 -0
  10. vellum/types/quota.py +3 -0
  11. vellum/types/vembda_service_tier_enum.py +3 -0
  12. vellum/workflows/nodes/displayable/api_node/node.py +1 -0
  13. vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py +30 -0
  14. vellum/workflows/nodes/displayable/bases/api_node/node.py +27 -10
  15. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +1 -1
  16. vellum/workflows/nodes/displayable/tool_calling_node/node.py +5 -0
  17. vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py +3 -0
  18. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +3 -0
  19. {vellum_ai-1.0.0.dist-info → vellum_ai-1.0.2.dist-info}/METADATA +1 -1
  20. {vellum_ai-1.0.0.dist-info → vellum_ai-1.0.2.dist-info}/RECORD +34 -27
  21. vellum_cli/tests/test_ping.py +1 -0
  22. vellum_ee/workflows/display/nodes/base_node_display.py +24 -0
  23. vellum_ee/workflows/display/nodes/vellum/api_node.py +20 -1
  24. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +0 -26
  25. vellum_ee/workflows/display/nodes/vellum/tests/test_api_node.py +31 -0
  26. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +10 -0
  27. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +21 -0
  28. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +21 -0
  29. vellum_ee/workflows/display/workflows/base_workflow_display.py +15 -2
  30. vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +127 -0
  31. /vellum/{workflows/nodes/displayable/bases/inline_prompt_node → prompts}/constants.py +0 -0
  32. {vellum_ai-1.0.0.dist-info → vellum_ai-1.0.2.dist-info}/LICENSE +0 -0
  33. {vellum_ai-1.0.0.dist-info → vellum_ai-1.0.2.dist-info}/WHEEL +0 -0
  34. {vellum_ai-1.0.0.dist-info → vellum_ai-1.0.2.dist-info}/entry_points.txt +0 -0
vellum/__init__.py CHANGED
@@ -287,6 +287,7 @@ from .client.types import (
287
287
  OpenAiVectorizerTextEmbedding3SmallRequest,
288
288
  OpenAiVectorizerTextEmbeddingAda002,
289
289
  OpenAiVectorizerTextEmbeddingAda002Request,
290
+ OrganizationLimitConfig,
290
291
  OrganizationRead,
291
292
  PaginatedContainerImageReadList,
292
293
  PaginatedDeploymentReleaseTagReadList,
@@ -327,6 +328,7 @@ from .client.types import (
327
328
  PromptRequestStringInput,
328
329
  PromptSettings,
329
330
  PromptVersionBuildConfigSandbox,
331
+ Quota,
330
332
  RawPromptExecutionOverridesRequest,
331
333
  ReductoChunkerConfig,
332
334
  ReductoChunkerConfigRequest,
@@ -524,6 +526,7 @@ from .client.types import (
524
526
  VellumVariableExtensions,
525
527
  VellumVariableType,
526
528
  VellumWorkflowExecutionEvent,
529
+ VembdaServiceTierEnum,
527
530
  WorkflowDeploymentEventExecutionsResponse,
528
531
  WorkflowDeploymentHistoryItem,
529
532
  WorkflowDeploymentParentContext,
@@ -932,6 +935,7 @@ __all__ = [
932
935
  "OpenAiVectorizerTextEmbedding3SmallRequest",
933
936
  "OpenAiVectorizerTextEmbeddingAda002",
934
937
  "OpenAiVectorizerTextEmbeddingAda002Request",
938
+ "OrganizationLimitConfig",
935
939
  "OrganizationRead",
936
940
  "PaginatedContainerImageReadList",
937
941
  "PaginatedDeploymentReleaseTagReadList",
@@ -972,6 +976,7 @@ __all__ = [
972
976
  "PromptRequestStringInput",
973
977
  "PromptSettings",
974
978
  "PromptVersionBuildConfigSandbox",
979
+ "Quota",
975
980
  "RawPromptExecutionOverridesRequest",
976
981
  "ReductoChunkerConfig",
977
982
  "ReductoChunkerConfigRequest",
@@ -1171,6 +1176,7 @@ __all__ = [
1171
1176
  "VellumVariableExtensions",
1172
1177
  "VellumVariableType",
1173
1178
  "VellumWorkflowExecutionEvent",
1179
+ "VembdaServiceTierEnum",
1174
1180
  "WorkflowDeploymentEventExecutionsResponse",
1175
1181
  "WorkflowDeploymentHistoryItem",
1176
1182
  "WorkflowDeploymentParentContext",
@@ -25,10 +25,10 @@ class BaseClientWrapper:
25
25
 
26
26
  def get_headers(self) -> typing.Dict[str, str]:
27
27
  headers: typing.Dict[str, str] = {
28
- "User-Agent": "vellum-ai/1.0.0",
28
+ "User-Agent": "vellum-ai/1.0.2",
29
29
  "X-Fern-Language": "Python",
30
30
  "X-Fern-SDK-Name": "vellum-ai",
31
- "X-Fern-SDK-Version": "1.0.0",
31
+ "X-Fern-SDK-Version": "1.0.2",
32
32
  }
33
33
  if self._api_version is not None:
34
34
  headers["X-API-Version"] = self._api_version
@@ -295,6 +295,7 @@ from .open_ai_vectorizer_text_embedding_3_small import OpenAiVectorizerTextEmbed
295
295
  from .open_ai_vectorizer_text_embedding_3_small_request import OpenAiVectorizerTextEmbedding3SmallRequest
296
296
  from .open_ai_vectorizer_text_embedding_ada_002 import OpenAiVectorizerTextEmbeddingAda002
297
297
  from .open_ai_vectorizer_text_embedding_ada_002_request import OpenAiVectorizerTextEmbeddingAda002Request
298
+ from .organization_limit_config import OrganizationLimitConfig
298
299
  from .organization_read import OrganizationRead
299
300
  from .paginated_container_image_read_list import PaginatedContainerImageReadList
300
301
  from .paginated_deployment_release_tag_read_list import PaginatedDeploymentReleaseTagReadList
@@ -335,6 +336,7 @@ from .prompt_request_json_input import PromptRequestJsonInput
335
336
  from .prompt_request_string_input import PromptRequestStringInput
336
337
  from .prompt_settings import PromptSettings
337
338
  from .prompt_version_build_config_sandbox import PromptVersionBuildConfigSandbox
339
+ from .quota import Quota
338
340
  from .raw_prompt_execution_overrides_request import RawPromptExecutionOverridesRequest
339
341
  from .reducto_chunker_config import ReductoChunkerConfig
340
342
  from .reducto_chunker_config_request import ReductoChunkerConfigRequest
@@ -548,6 +550,7 @@ from .vellum_variable import VellumVariable
548
550
  from .vellum_variable_extensions import VellumVariableExtensions
549
551
  from .vellum_variable_type import VellumVariableType
550
552
  from .vellum_workflow_execution_event import VellumWorkflowExecutionEvent
553
+ from .vembda_service_tier_enum import VembdaServiceTierEnum
551
554
  from .workflow_deployment_event_executions_response import WorkflowDeploymentEventExecutionsResponse
552
555
  from .workflow_deployment_history_item import WorkflowDeploymentHistoryItem
553
556
  from .workflow_deployment_parent_context import WorkflowDeploymentParentContext
@@ -912,6 +915,7 @@ __all__ = [
912
915
  "OpenAiVectorizerTextEmbedding3SmallRequest",
913
916
  "OpenAiVectorizerTextEmbeddingAda002",
914
917
  "OpenAiVectorizerTextEmbeddingAda002Request",
918
+ "OrganizationLimitConfig",
915
919
  "OrganizationRead",
916
920
  "PaginatedContainerImageReadList",
917
921
  "PaginatedDeploymentReleaseTagReadList",
@@ -952,6 +956,7 @@ __all__ = [
952
956
  "PromptRequestStringInput",
953
957
  "PromptSettings",
954
958
  "PromptVersionBuildConfigSandbox",
959
+ "Quota",
955
960
  "RawPromptExecutionOverridesRequest",
956
961
  "ReductoChunkerConfig",
957
962
  "ReductoChunkerConfigRequest",
@@ -1149,6 +1154,7 @@ __all__ = [
1149
1154
  "VellumVariableExtensions",
1150
1155
  "VellumVariableType",
1151
1156
  "VellumWorkflowExecutionEvent",
1157
+ "VembdaServiceTierEnum",
1152
1158
  "WorkflowDeploymentEventExecutionsResponse",
1153
1159
  "WorkflowDeploymentHistoryItem",
1154
1160
  "WorkflowDeploymentParentContext",
@@ -0,0 +1,24 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from .vembda_service_tier_enum import VembdaServiceTierEnum
6
+ from .quota import Quota
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
8
+ import pydantic
9
+
10
+
11
+ class OrganizationLimitConfig(UniversalBaseModel):
12
+ vembda_service_tier: typing.Optional[VembdaServiceTierEnum] = None
13
+ prompt_executions_quota: typing.Optional[Quota] = None
14
+ workflow_executions_quota: typing.Optional[Quota] = None
15
+ workflow_runtime_seconds_quota: typing.Optional[Quota] = None
16
+
17
+ if IS_PYDANTIC_V2:
18
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
19
+ else:
20
+
21
+ class Config:
22
+ frozen = True
23
+ smart_union = True
24
+ extra = pydantic.Extra.allow
@@ -3,6 +3,7 @@
3
3
  from ..core.pydantic_utilities import UniversalBaseModel
4
4
  import typing
5
5
  from .new_member_join_behavior_enum import NewMemberJoinBehaviorEnum
6
+ from .organization_limit_config import OrganizationLimitConfig
6
7
  from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
8
  import pydantic
8
9
 
@@ -12,6 +13,7 @@ class OrganizationRead(UniversalBaseModel):
12
13
  name: str
13
14
  allow_staff_access: typing.Optional[bool] = None
14
15
  new_member_join_behavior: NewMemberJoinBehaviorEnum
16
+ limit_config: OrganizationLimitConfig
15
17
 
16
18
  if IS_PYDANTIC_V2:
17
19
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -0,0 +1,21 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
6
+ import pydantic
7
+
8
+
9
+ class Quota(UniversalBaseModel):
10
+ name: str
11
+ value: typing.Optional[int] = None
12
+ period_seconds: typing.Optional[int] = None
13
+
14
+ if IS_PYDANTIC_V2:
15
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
16
+ else:
17
+
18
+ class Config:
19
+ frozen = True
20
+ smart_union = True
21
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ VembdaServiceTierEnum = typing.Union[typing.Literal["FREE", "PAID"], typing.Any]
@@ -12,7 +12,7 @@ import pydantic
12
12
  class WorkflowExecutionActual(UniversalBaseModel):
13
13
  output: ExecutionVellumValue
14
14
  timestamp: dt.datetime
15
- quality: float
15
+ quality: typing.Optional[float] = None
16
16
  metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = None
17
17
 
18
18
  if IS_PYDANTIC_V2:
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.organization_limit_config import *
vellum/types/quota.py ADDED
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.quota import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.vembda_service_tier_enum import *
@@ -65,4 +65,5 @@ class APINode(BaseAPINode):
65
65
  json=self.json,
66
66
  headers=final_headers,
67
67
  bearer_token=bearer_token,
68
+ timeout=self.timeout,
68
69
  )
@@ -233,3 +233,33 @@ def test_api_node_raises_error_for_whitespace_url():
233
233
 
234
234
  assert excinfo.value.code == WorkflowErrorCode.INVALID_INPUTS
235
235
  assert "URL is required and must be a non-empty string" in str(excinfo.value)
236
+
237
+
238
+ def test_api_node_passes_timeout_to_vellum_client(vellum_client):
239
+ """Test that timeout is passed to vellum client as RequestOptions."""
240
+ vellum_client.execute_api.return_value = ExecuteApiResponse(
241
+ status_code=200,
242
+ text='{"result": "success"}',
243
+ json_={"result": "success"},
244
+ headers={"content-type": "application/json"},
245
+ )
246
+
247
+ # GIVEN an API node configured with a timeout value of 25 seconds
248
+ class APINodeWithTimeout(APINode):
249
+ method = APIRequestMethod.GET
250
+ authorization_type = AuthorizationType.BEARER_TOKEN
251
+ url = "https://example.com"
252
+ timeout = 25
253
+ bearer_token_value = VellumSecret(name="secret")
254
+
255
+ # WHEN the API node is executed
256
+ node = APINodeWithTimeout()
257
+ node.run()
258
+
259
+ # THEN the vellum client should be called exactly once
260
+ assert vellum_client.execute_api.call_count == 1
261
+ call_args = vellum_client.execute_api.call_args
262
+ request_options = call_args.kwargs["request_options"]
263
+ # AND the call should include RequestOptions with the correct timeout
264
+ assert request_options is not None
265
+ assert request_options["timeout_in_seconds"] == 25
@@ -4,6 +4,7 @@ from requests import Request, RequestException, Session
4
4
  from requests.exceptions import JSONDecodeError
5
5
 
6
6
  from vellum.client import ApiError
7
+ from vellum.client.core.request_options import RequestOptions
7
8
  from vellum.client.types.vellum_secret import VellumSecret as ClientVellumSecret
8
9
  from vellum.workflows.constants import APIRequestMethod
9
10
  from vellum.workflows.errors.types import WorkflowErrorCode
@@ -23,6 +24,7 @@ class BaseAPINode(BaseNode, Generic[StateType]):
23
24
  data: Optional[str] - The data to send in the request body.
24
25
  json: Optional["JsonObject"] - The JSON data to send in the request body.
25
26
  headers: Optional[Dict[str, Union[str, VellumSecret]]] - The headers to send in the request.
27
+ timeout: Optional[int] - The timeout in seconds for the API request.
26
28
  """
27
29
 
28
30
  class Trigger(BaseNode.Trigger):
@@ -33,6 +35,7 @@ class BaseAPINode(BaseNode, Generic[StateType]):
33
35
  data: Optional[str] = None
34
36
  json: Optional[Json] = None
35
37
  headers: Optional[Dict[str, Union[str, VellumSecret]]] = None
38
+ timeout: Optional[int] = None
36
39
 
37
40
  class Outputs(BaseOutputs):
38
41
  json: Optional[Json]
@@ -45,7 +48,9 @@ class BaseAPINode(BaseNode, Generic[StateType]):
45
48
  raise NodeException("URL is required and must be a non-empty string", code=WorkflowErrorCode.INVALID_INPUTS)
46
49
 
47
50
  def run(self) -> Outputs:
48
- return self._run(method=self.method, url=self.url, data=self.data, json=self.json, headers=self.headers)
51
+ return self._run(
52
+ method=self.method, url=self.url, data=self.data, json=self.json, headers=self.headers, timeout=self.timeout
53
+ )
49
54
 
50
55
  def _run(
51
56
  self,
@@ -55,6 +60,7 @@ class BaseAPINode(BaseNode, Generic[StateType]):
55
60
  json: Any = None,
56
61
  headers: Any = None,
57
62
  bearer_token: Optional[VellumSecret] = None,
63
+ timeout: Optional[int] = None,
58
64
  ) -> Outputs:
59
65
  self._validate()
60
66
 
@@ -63,11 +69,11 @@ class BaseAPINode(BaseNode, Generic[StateType]):
63
69
  if isinstance(headers[header], VellumSecret):
64
70
  vellum_instance = True
65
71
  if vellum_instance or bearer_token:
66
- return self._vellum_execute_api(bearer_token, json, headers, method, url)
72
+ return self._vellum_execute_api(bearer_token, json, headers, method, url, timeout)
67
73
  else:
68
- return self._local_execute_api(data, headers, json, method, url)
74
+ return self._local_execute_api(data, headers, json, method, url, timeout)
69
75
 
70
- def _local_execute_api(self, data, headers, json, method, url):
76
+ def _local_execute_api(self, data, headers, json, method, url, timeout):
71
77
  try:
72
78
  if data is not None:
73
79
  prepped = Request(method=method.value, url=url, data=data, headers=headers).prepare()
@@ -79,25 +85,36 @@ class BaseAPINode(BaseNode, Generic[StateType]):
79
85
  raise NodeException(f"Failed to prepare HTTP request: {e}", code=WorkflowErrorCode.PROVIDER_ERROR)
80
86
  try:
81
87
  with Session() as session:
82
- response = session.send(prepped)
88
+ response = session.send(prepped, timeout=timeout)
83
89
  except RequestException as e:
84
90
  raise NodeException(f"HTTP request failed: {e}", code=WorkflowErrorCode.PROVIDER_ERROR)
85
91
  try:
86
- json = response.json()
92
+ json_response = response.json()
87
93
  except JSONDecodeError:
88
- json = None
94
+ json_response = None
89
95
  return self.Outputs(
90
- json=json,
96
+ json=json_response,
91
97
  headers={header: value for header, value in response.headers.items()},
92
98
  status_code=response.status_code,
93
99
  text=response.text,
94
100
  )
95
101
 
96
- def _vellum_execute_api(self, bearer_token, data, headers, method, url):
102
+ def _vellum_execute_api(self, bearer_token, data, headers, method, url, timeout):
97
103
  client_vellum_secret = ClientVellumSecret(name=bearer_token.name) if bearer_token else None
104
+
105
+ # Create request_options if timeout is specified
106
+ request_options = None
107
+ if timeout is not None:
108
+ request_options = RequestOptions(timeout_in_seconds=timeout)
109
+
98
110
  try:
99
111
  vellum_response = self._context.vellum_client.execute_api(
100
- url=url, method=method.value, body=data, headers=headers, bearer_token=client_vellum_secret
112
+ url=url,
113
+ method=method.value,
114
+ body=data,
115
+ headers=headers,
116
+ bearer_token=client_vellum_secret,
117
+ request_options=request_options,
101
118
  )
102
119
  except ApiError as e:
103
120
  raise NodeException(f"Failed to prepare HTTP request: {e}", code=WorkflowErrorCode.NODE_EXECUTION)
@@ -21,13 +21,13 @@ from vellum.client.types.chat_message_request import ChatMessageRequest
21
21
  from vellum.client.types.prompt_exec_config import PromptExecConfig
22
22
  from vellum.client.types.prompt_settings import PromptSettings
23
23
  from vellum.client.types.rich_text_child_block import RichTextChildBlock
24
+ from vellum.prompts.constants import DEFAULT_PROMPT_PARAMETERS
24
25
  from vellum.workflows.context import get_execution_context
25
26
  from vellum.workflows.errors import WorkflowErrorCode
26
27
  from vellum.workflows.errors.types import vellum_error_to_workflow_error
27
28
  from vellum.workflows.events.types import default_serializer
28
29
  from vellum.workflows.exceptions import NodeException
29
30
  from vellum.workflows.nodes.displayable.bases.base_prompt_node import BasePromptNode
30
- from vellum.workflows.nodes.displayable.bases.inline_prompt_node.constants import DEFAULT_PROMPT_PARAMETERS
31
31
  from vellum.workflows.outputs import BaseOutput
32
32
  from vellum.workflows.types import MergeBehavior
33
33
  from vellum.workflows.types.definition import DeploymentDefinition
@@ -1,6 +1,8 @@
1
1
  from typing import ClassVar, Iterator, List, Optional, Set
2
2
 
3
3
  from vellum import ChatMessage, PromptBlock
4
+ from vellum.client.types.prompt_parameters import PromptParameters
5
+ from vellum.prompts.constants import DEFAULT_PROMPT_PARAMETERS
4
6
  from vellum.workflows.context import execution_context, get_parent_context
5
7
  from vellum.workflows.errors.types import WorkflowErrorCode
6
8
  from vellum.workflows.events.workflow import is_workflow_event
@@ -29,6 +31,7 @@ class ToolCallingNode(BaseNode):
29
31
  blocks: List[PromptBlock] - The prompt blocks to use (same format as InlinePromptNode)
30
32
  functions: List[Tool] - The functions that can be called
31
33
  prompt_inputs: Optional[EntityInputsInterface] - Mapping of input variable names to values
34
+ parameters: PromptParameters - The parameters for the Prompt
32
35
  max_prompt_iterations: Optional[int] - Maximum number of prompt iterations before stopping
33
36
  """
34
37
 
@@ -36,6 +39,7 @@ class ToolCallingNode(BaseNode):
36
39
  blocks: ClassVar[List[PromptBlock]] = []
37
40
  functions: ClassVar[List[Tool]] = []
38
41
  prompt_inputs: ClassVar[Optional[EntityInputsInterface]] = None
42
+ parameters: PromptParameters = DEFAULT_PROMPT_PARAMETERS
39
43
  max_prompt_iterations: ClassVar[Optional[int]] = 5
40
44
 
41
45
  class Outputs(BaseOutputs):
@@ -131,6 +135,7 @@ class ToolCallingNode(BaseNode):
131
135
  blocks=self.blocks,
132
136
  functions=self.functions,
133
137
  prompt_inputs=self.prompt_inputs,
138
+ parameters=self.parameters,
134
139
  max_prompt_iterations=self.max_prompt_iterations,
135
140
  )
136
141
 
@@ -10,6 +10,7 @@ from vellum.client.types.initiated_execute_prompt_event import InitiatedExecuteP
10
10
  from vellum.client.types.string_chat_message_content import StringChatMessageContent
11
11
  from vellum.client.types.string_vellum_value import StringVellumValue
12
12
  from vellum.client.types.variable_prompt_block import VariablePromptBlock
13
+ from vellum.prompts.constants import DEFAULT_PROMPT_PARAMETERS
13
14
  from vellum.workflows import BaseWorkflow
14
15
  from vellum.workflows.inputs.base import BaseInputs
15
16
  from vellum.workflows.nodes.bases import BaseNode
@@ -39,6 +40,7 @@ def test_port_condition_match_function_name():
39
40
  blocks=[],
40
41
  functions=[first_function, second_function],
41
42
  prompt_inputs=None,
43
+ parameters=DEFAULT_PROMPT_PARAMETERS,
42
44
  )
43
45
 
44
46
  # AND a state with a function call to the first function
@@ -96,6 +98,7 @@ def test_tool_calling_node_inline_workflow_context():
96
98
  blocks=[],
97
99
  functions=[MyWorkflow],
98
100
  prompt_inputs=None,
101
+ parameters=DEFAULT_PROMPT_PARAMETERS,
99
102
  )
100
103
 
101
104
  # WHEN we create a function node for the workflow
@@ -7,6 +7,7 @@ from vellum import ChatMessage, PromptBlock
7
7
  from vellum.client.types.function_call_chat_message_content import FunctionCallChatMessageContent
8
8
  from vellum.client.types.function_call_chat_message_content_value import FunctionCallChatMessageContentValue
9
9
  from vellum.client.types.prompt_output import PromptOutput
10
+ from vellum.client.types.prompt_parameters import PromptParameters
10
11
  from vellum.client.types.string_chat_message_content import StringChatMessageContent
11
12
  from vellum.client.types.variable_prompt_block import VariablePromptBlock
12
13
  from vellum.workflows.errors.types import WorkflowErrorCode
@@ -188,6 +189,7 @@ def create_tool_router_node(
188
189
  blocks: List[PromptBlock],
189
190
  functions: List[Tool],
190
191
  prompt_inputs: Optional[EntityInputsInterface],
192
+ parameters: PromptParameters,
191
193
  max_prompt_iterations: Optional[int] = None,
192
194
  ) -> Type[ToolRouterNode]:
193
195
  if functions and len(functions) > 0:
@@ -242,6 +244,7 @@ def create_tool_router_node(
242
244
  "blocks": blocks,
243
245
  "functions": functions,
244
246
  "prompt_inputs": prompt_inputs,
247
+ "parameters": parameters,
245
248
  "max_prompt_iterations": max_prompt_iterations,
246
249
  "Ports": Ports,
247
250
  "__module__": __name__,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -16,7 +16,7 @@ vellum_cli/tests/test_image_push.py,sha256=X0YOPdoaAnWtK9IQTxaN_wWpw08-5G3v76k1W
16
16
  vellum_cli/tests/test_image_push_error_handling.py,sha256=QRH0eYNEEIkD2-EVFQWYexOKlhMB6puh1GouovrE-VU,7647
17
17
  vellum_cli/tests/test_init.py,sha256=8UOc_ThfouR4ja5cCl_URuLk7ohr9JXfCnG4yka1OUQ,18754
18
18
  vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
19
- vellum_cli/tests/test_ping.py,sha256=178EJHxPZtnnPMNXXynsQt8DIFhsrdc2bL17_YsG17M,2580
19
+ vellum_cli/tests/test_ping.py,sha256=b3aQLd-N59_8w2rRiWqwpB1rlHaKEYVbAj1Y3hi7A-g,2605
20
20
  vellum_cli/tests/test_pull.py,sha256=hxMbW_j0weDDrkzVGpvLpFcwNQdn-fxTv4wBHeYizzc,49904
21
21
  vellum_cli/tests/test_push.py,sha256=wk9jQTV565TeukR0Vz-2AUQyJa3VlOJrmWxkSTX_Ptw,37860
22
22
  vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -27,21 +27,21 @@ vellum_ee/workflows/display/base.py,sha256=po1YIXOupglAFi1-_zsgNH-VwIjHfy5GCvii6
27
27
  vellum_ee/workflows/display/editor/__init__.py,sha256=MSAgY91xCEg2neH5d8jXx5wRdR962ftZVa6vO9BGq9k,167
28
28
  vellum_ee/workflows/display/editor/types.py,sha256=x-tOOCJ6CF4HmiKDfCmcc3bOVfc1EBlP5o6u5WEfLoY,567
29
29
  vellum_ee/workflows/display/nodes/__init__.py,sha256=jI1aPBQf8DkmrYoZ4O-wR1duqZByOf5mDFmo_wFJPE4,307
30
- vellum_ee/workflows/display/nodes/base_node_display.py,sha256=8Iio5O2Lu7XA5EfCWhXNZVzEOiaXO4eMdssczGBKXxU,16922
30
+ vellum_ee/workflows/display/nodes/base_node_display.py,sha256=oJJiNmF9na2rS5PMMWZLwbajJkssEeBCESDmmz9jy2s,17933
31
31
  vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=jI_kUi9LnNLDpY63QtlC4TfN8P571VN4LpzH0I1ZtLk,1149
32
32
  vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=Z4Mf7xLCNiblSbpKI0BrV5modQr-ZcFzhfir_OSyTTs,2997
34
34
  vellum_ee/workflows/display/nodes/types.py,sha256=St1BB6no528OyELGiyRabWao0GGw6mLhstQAvEACbGk,247
35
35
  vellum_ee/workflows/display/nodes/utils.py,sha256=sloya5TpXsnot1HURc9L51INwflRqUzHxRVnCS9Cd-4,973
36
36
  vellum_ee/workflows/display/nodes/vellum/__init__.py,sha256=nUIgH2s0-7IbQRNrBhLPyRNe8YIrx3Yo9HeeW-aXXFk,1668
37
- vellum_ee/workflows/display/nodes/vellum/api_node.py,sha256=5Uq8x08F64yrBcqbfsVeuoGnTa9eoOPumYzZZrDPmr0,8847
37
+ vellum_ee/workflows/display/nodes/vellum/api_node.py,sha256=lGS-C9cd-nlYVZuaXmArJUJFdwPUMLNJwf1bpa7Ufys,9400
38
38
  vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py,sha256=FHhPoGmmny4Xcxi2pm12Sk3ZOREanWEVrOWcjRhncH4,6337
39
39
  vellum_ee/workflows/display/nodes/vellum/code_execution_node.py,sha256=6lavdBw297GwAQqyxjnPUtx5pHv6k5V9Vkuq7s2D0TM,4508
40
40
  vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=OEw8QRPliL4P8J6oEZdQH8Oc-0u7aFa_Jqx0RyL6F-M,11656
41
41
  vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=YhMsi2TG1zSR8E7IpxzzSncOyVLcvqTuGa3mr4RqHd8,2364
42
42
  vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=zo-nalsuayMqeb2GwR2OB9SFK3y2U5aG-rtwrsjdasQ,3089
43
43
  vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=IniO5KvO0Rw9zghFg3RFvbXBTv6Zi1iuQhaA1DLazqU,2331
44
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=O4crEYQYJ6XGiN7pEQKxJCGGUQCQKf3rSjKYE4D-iCY,12079
44
+ vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=9zLM81RU2FHNaKcrtZkQ-Wez5IaSJ1HuxCBC_BM4CZI,11094
45
45
  vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=f7MeoxgKrdyb1dSJsvdDtZPlp1J2Pa4njPvN3qHVktA,6028
46
46
  vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=uaZ2wcZR1J9C9iI0QWAsgNK9IlcuCz1808oxXmiYsLY,3908
47
47
  vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=RTP_raQWL8ZKoRKLpxLfpyXzw61TZeTCkTuM1uRLIkI,3274
@@ -52,6 +52,7 @@ vellum_ee/workflows/display/nodes/vellum/search_node.py,sha256=bF07csUFSQlAeOayP
52
52
  vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py,sha256=wr2MaqoGFtkL1o7B-4GXgF1gEEOTWsUEiX8l_g7e1qs,2958
53
53
  vellum_ee/workflows/display/nodes/vellum/templating_node.py,sha256=TdIJWh2l8p4tw7ejRexGOFQKnviirUqie3WYwsrVQ4g,3339
54
54
  vellum_ee/workflows/display/nodes/vellum/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
+ vellum_ee/workflows/display/nodes/vellum/tests/test_api_node.py,sha256=DQAtsabvn6BE6xWwKNHzMOppzoy1-1dssNnrwbHUdRU,1490
55
56
  vellum_ee/workflows/display/nodes/vellum/tests/test_code_execution_node.py,sha256=ZasoqG8FmqnZDj2FfL5BGPq9fafOTJqV_4xjOKLi1gc,5434
56
57
  vellum_ee/workflows/display/nodes/vellum/tests/test_error_node.py,sha256=540FoWMpJ3EN_DPjHsr9ODJWCRVcUa5hZBn-5T2GiHU,1665
57
58
  vellum_ee/workflows/display/nodes/vellum/tests/test_inline_subworkflow_node.py,sha256=SKOYan-dxY4gsO0R4JyQUyWrABHBN8XImKw9Eeo4wGo,3535
@@ -77,7 +78,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attr
77
78
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=s6_mnk0pkztU59wYpSfOFpMhAJaRjmyfxM6WJGtnD4Y,6456
78
79
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=PkSgghJDz0fpDB72HHPjLjo8LkZk-HpUkCQzRLX-iVw,40611
79
80
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=dsJr8I9AdPwMOGszirfNDzZP2Ychd94aAKuPXAzknMk,4632
80
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=Q3QOzzF7KE_9EukJ9yNFgYL7Qio_vTqDVd-6kc40wd4,15834
81
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=a05Uh47ZRyy7P2ffZC3yieplFGqmlnjx1sGwY80ZLVU,16189
81
82
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py,sha256=B4DC2e5nqEk5NZeUwR4vKmBoEyToHkAuq4cCqbsidFo,29708
82
83
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py,sha256=oKO8KGlkl505TSW5v0retJF4FS8TfwxxuAzqY9Adr8k,53608
83
84
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py,sha256=E1ww97BFoGbnRkxf84TScat5NQhP8nLVrdaOlpGnSKU,8615
@@ -93,8 +94,8 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_
93
94
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py,sha256=XWrhHg_acLsRHwjstBAii9Pmes9oXFtAUWSAVF1oSBc,11225
94
95
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py,sha256=V8b6gKghLlO7PJI8xeNdnfn8aII0W_IFQvSQBQM62UQ,7721
95
96
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py,sha256=hDWtKXmGI1CKhTwTNqpu_d5RkE5n7SolMLtgd87KqTI,3856
96
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=Nu5XZeGbqev638Osd9Vu17JE74ZWAHsrhYi9Uk-xLr8,25489
97
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=PR2bLdtl0QuA9WbvZGNBpPeQy1xOV6UeALKpJSRSCEY,8712
97
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=4t1lkN2nsZF6lFqP6QnskUQWJlhasF8C2_f6atzk8ZY,26298
98
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=1hoakUkh5kHZYIfY1moJBZYzXgAafkgWsIf4lmZ12vg,9521
98
99
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py,sha256=mova0sPD3evHiHIN1O0VynxlCp-uOcEIKve5Pd_oCDg,4069
99
100
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
100
101
  vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=J4ouI8KxbMfxQP2Zq_9cWMGYgbjCWmKzjCJEtnSJb0I,5829
@@ -110,9 +111,9 @@ vellum_ee/workflows/display/utils/tests/test_auto_layout.py,sha256=vfXI769418s9v
110
111
  vellum_ee/workflows/display/utils/vellum.py,sha256=mtoXmSYwR7rvrq-d6CzCW_auaJXTct0Mi1F0xpRCiNQ,5627
111
112
  vellum_ee/workflows/display/vellum.py,sha256=J2mdJZ1sdLW535DDUkq_Vm8Z572vhuxHxVZF9deKSdk,391
112
113
  vellum_ee/workflows/display/workflows/__init__.py,sha256=JTB9ObEV3l4gGGdtfBHwVJtTTKC22uj-a-XjTVwXCyA,148
113
- vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=5FApz_OAqdj9ljZ7xqln8zi9Y-GKGP810y2XcZmfC-g,41160
114
+ vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=DNR5LuhC6m2r1XzeFsDuX98lL2ka6tYorInhsNC8O_Y,41535
114
115
  vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=gxz76AeCqgAZ9D2lZeTiZzxY9eMgn3qOSfVgiqYcOh8,2028
115
- vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=L7SKWJ26Ex-XXTNfHYXux7KP6I-dxE1EMQylap4Mhjs,31762
116
+ vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=9CkgKbM_zgq0l2bwst1hLFGyOigpjsBO4ZU6qSMXND4,36027
116
117
  vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
118
  vellum_ee/workflows/server/virtual_file_loader.py,sha256=7JphJcSO3H85qiC2DpFfBWjC3JjrbRmoynBC6KKHVsA,2710
118
119
  vellum_ee/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -138,12 +139,12 @@ vellum_ee/workflows/tests/test_display_meta.py,sha256=PkXJVnMZs9GNooDkd59n4YTBAX
138
139
  vellum_ee/workflows/tests/test_serialize_module.py,sha256=EVrCRAP0lpvd0GIDlg2tnGfJzDNooNDXPfGFPLAqmbI,1870
139
140
  vellum_ee/workflows/tests/test_server.py,sha256=SsOkS6sGO7uGC4mxvk4iv8AtcXs058P9hgFHzTWmpII,14519
140
141
  vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
141
- vellum/__init__.py,sha256=S2zlpYoHKXOAP1vcibHB9BPZ2OST32AwXP8AJA0ErUA,42915
142
+ vellum/__init__.py,sha256=akJ4Be38o5zba0aofaTK90Vpm7LzD2xVWVyfRYi8sco,43055
142
143
  vellum/client/README.md,sha256=Dle5iytCXxP1pNeNd7uZyhFo0rl7tp7vU7s8gmi10OQ,4863
143
144
  vellum/client/__init__.py,sha256=yIMTLkqrMput0mnWPw7OQayz3mW7w478E9RmZsiTtWM,124904
144
145
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
145
146
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
146
- vellum/client/core/client_wrapper.py,sha256=XSSzA5VEGoD2dtUQf284uK6Ujy0yg-FTiuwHz7WdiXk,2383
147
+ vellum/client/core/client_wrapper.py,sha256=mZtpQvxbGA88AaGaNdeIKUV2KCodk0iJqUYs3dXpFR4,2383
147
148
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
148
149
  vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
149
150
  vellum/client/core/http_client.py,sha256=cKs2w0ybDBk1wHQf-fTALm_MmvaMe3cZKcYJxqmCxkE,19539
@@ -211,7 +212,7 @@ vellum/client/resources/workspace_secrets/__init__.py,sha256=FTtvy8EDg9nNNg9WCat
211
212
  vellum/client/resources/workspace_secrets/client.py,sha256=l1FOj0f-IB5_oQ7iWiHopFK3lDXBqiaIc9g10W9PHFU,8381
212
213
  vellum/client/resources/workspaces/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
213
214
  vellum/client/resources/workspaces/client.py,sha256=61eFS8USOtHf4cFoT3dZmAMs6KGAVPbXjAolws2ftsQ,3683
214
- vellum/client/types/__init__.py,sha256=NgEh6I44X4Hwrd4lIswu7QPHzuWoxmej9p4JYsSJJb8,65043
215
+ vellum/client/types/__init__.py,sha256=bhFxraYRqIQtMBuAa4Fichl6Za8bm5W_tD6205B0b8o,65264
215
216
  vellum/client/types/ad_hoc_execute_prompt_event.py,sha256=bCjujA2XsOgyF3bRZbcEqV2rOIymRgsLoIRtZpB14xg,607
216
217
  vellum/client/types/ad_hoc_expand_meta.py,sha256=1gv-NCsy_6xBYupLvZH979yf2VMdxAU-l0y0ynMKZaw,1331
217
218
  vellum/client/types/ad_hoc_fulfilled_prompt_execution_meta.py,sha256=oDG60TpwK1YNSKhRsBbiP2O3ZF9PKR-M9chGIfKw4R4,1004
@@ -495,7 +496,8 @@ vellum/client/types/open_ai_vectorizer_text_embedding_3_small.py,sha256=T_-P7qGj
495
496
  vellum/client/types/open_ai_vectorizer_text_embedding_3_small_request.py,sha256=-lwNeWj7ExP-JLncUp1Uyd20FxweVIDu-aEnenPB98A,841
496
497
  vellum/client/types/open_ai_vectorizer_text_embedding_ada_002.py,sha256=c4vNlR6lRvUjq-67M06sroDMNMG_qC4JUBqwmKEJQ2I,812
497
498
  vellum/client/types/open_ai_vectorizer_text_embedding_ada_002_request.py,sha256=FdpkkNBGgRwfqFjBwpfH4t2zKIM0pIYminX2iZQUzvY,841
498
- vellum/client/types/organization_read.py,sha256=y3btZG8pppO78LoGuIC8JKOr5lhkONLLYvn0pmQRn0U,749
499
+ vellum/client/types/organization_limit_config.py,sha256=-d3xOt5EPqPwqIhPi85Ez70eFi-ClwBn6_IPQhD6b_Y,894
500
+ vellum/client/types/organization_read.py,sha256=c5Wl5KY6plC7DuPJq6zAK_UTH2XVhT7H8OdEtxLqN98,854
499
501
  vellum/client/types/paginated_container_image_read_list.py,sha256=7lwIgs1q7Z0xDYPGWPnjSNC1kU_peu79CotzaaQfRdA,801
500
502
  vellum/client/types/paginated_deployment_release_tag_read_list.py,sha256=hp7D74CxPY14dEPRZ-fnTCwp63upxkYquL1e74oYXh4,826
501
503
  vellum/client/types/paginated_document_index_read_list.py,sha256=bO7pm3KCZi5LDO17YXgr_lUF9SRdAfMu6wOutX91ANw,797
@@ -535,6 +537,7 @@ vellum/client/types/prompt_request_json_input.py,sha256=vLhwvCWL_yjVfDzT4921xK4Q
535
537
  vellum/client/types/prompt_request_string_input.py,sha256=8GSFhtN3HeYssbDRY7B5SCh5Qrp67340D9c3oINpCmw,714
536
538
  vellum/client/types/prompt_settings.py,sha256=gITevU-SWiStXFKLfpwG5dQJ-bic5CxnM0OHsT9KR0s,635
537
539
  vellum/client/types/prompt_version_build_config_sandbox.py,sha256=SXU62bAueVpoWo178bLIMYi8aNVpsBGTtOQxHcg6Dmo,678
540
+ vellum/client/types/quota.py,sha256=e-Y1YHvd6ZDFDvfJdMs5sA9JQh8pl2Ep7bFrzB5LjNI,635
538
541
  vellum/client/types/raw_prompt_execution_overrides_request.py,sha256=x4Chkm_NxXySOEyA6s6J_mhhiM91KCcQbu6pQETB8RI,927
539
542
  vellum/client/types/reducto_chunker_config.py,sha256=by_Dj0hZPkLQAf7l1KAudRB8X2XnlfHiRTsyiR-DTRY,654
540
543
  vellum/client/types/reducto_chunker_config_request.py,sha256=RnulU2a_PUtvRE2qhARQhsCkWI--K_MYkobzLNRGEz4,661
@@ -732,6 +735,7 @@ vellum/client/types/vellum_variable.py,sha256=BDcccISJsycsrW3E5A5RTIOfxS_83ofkle
732
735
  vellum/client/types/vellum_variable_extensions.py,sha256=PsrRo0STOKhxrkSFRrOXCPlf1x5Uxpy3vVMJz02O20E,685
733
736
  vellum/client/types/vellum_variable_type.py,sha256=epYV-PY0NkvUntKzgzqelWMq9Dzmh7Y32c19GB_2mh0,411
734
737
  vellum/client/types/vellum_workflow_execution_event.py,sha256=H8rP3_6a6LTvemoHfsmI2THpTRf8PYrZQcjoeTzf-44,934
738
+ vellum/client/types/vembda_service_tier_enum.py,sha256=zIQq6j0BNu1niKkK_G4a_hE5kqkZ5s43k4g5Zj2qiAI,161
735
739
  vellum/client/types/workflow_deployment_event_executions_response.py,sha256=_X9hfsfpCf7DaQpfg83AAcbadZxEVi1NKNf2PZ7PRY8,1190
736
740
  vellum/client/types/workflow_deployment_history_item.py,sha256=w5yqAtmYWw8kTljYEVBa8-fLxKsrBA8Img7IC3GjZG4,1226
737
741
  vellum/client/types/workflow_deployment_parent_context.py,sha256=QwGpZnSNX6RCfkjbxmfln8QefrP8lFHkZ1DAC-oj9-Q,1699
@@ -742,7 +746,7 @@ vellum/client/types/workflow_deployment_release_workflow_version.py,sha256=V1Eb3
742
746
  vellum/client/types/workflow_error.py,sha256=EQajkEmLS64T0wYm0goHQl0rT7Lguurk8pLwkhjsgAI,282
743
747
  vellum/client/types/workflow_event_error.py,sha256=HIewu_kh3KNPpWegAQArvAGHCp-cBIXqlUAAc_dBZhc,687
744
748
  vellum/client/types/workflow_event_execution_read.py,sha256=a4Nv1UmNlMqDPqGrZLpyy3nNRtc1UqXmzXkeApSfstY,2089
745
- vellum/client/types/workflow_execution_actual.py,sha256=YL5WL4O4CyaZWSrxqpE4chJ28EJlyScj5JeaLttegEg,843
749
+ vellum/client/types/workflow_execution_actual.py,sha256=RC5t5wfnbHJ0jvSV_rk3OK38u1v30T7nFlQNk4IVYs0,867
746
750
  vellum/client/types/workflow_execution_actual_chat_history_request.py,sha256=L6U8tgM7SiU4qGJMZChFzj6HfHgO-YAlTXfbT7ZIaE4,1993
747
751
  vellum/client/types/workflow_execution_actual_json_request.py,sha256=5QYaPCSOwFnjH_kTrB2bTznTMFExSZdBhTkmelf1h4Q,1931
748
752
  vellum/client/types/workflow_execution_actual_string_request.py,sha256=1optEDv090iVev1l0Z9cgZ1NfNrHp2VRiNjmS7f7jtc,1895
@@ -851,6 +855,7 @@ vellum/prompts/blocks/helpers.py,sha256=7G1Qi6N3V1K73iqTypMTcl6Rum7wk449yHStkakL
851
855
  vellum/prompts/blocks/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
852
856
  vellum/prompts/blocks/tests/test_compilation.py,sha256=EOUtdzJDFGbGhoc_y5XTMyO0HOpOM7FYJssPzd_yRVg,5235
853
857
  vellum/prompts/blocks/types.py,sha256=6aSJQco-5kKeadfKVVXF_SrQPlIJgMYVNc-C7so1sY8,975
858
+ vellum/prompts/constants.py,sha256=fnjiRWLoRlC4Puo5oQcpZD5Hd-EesxsAo9l5tGAkpZQ,270
854
859
  vellum/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
855
860
  vellum/resources/__init__.py,sha256=sQWK7g_Z4EM7pa7fy6vy3d_DMdTJ4wVcozBn3Lx4Qpo,141
856
861
  vellum/resources/ad_hoc/__init__.py,sha256=UD01D9nS_M7sRKmMbEg4Tv9SlfFj3cWahVxwUEaSLAY,148
@@ -1187,6 +1192,7 @@ vellum/types/open_ai_vectorizer_text_embedding_3_small.py,sha256=5gsPjLdttszz8Nq
1187
1192
  vellum/types/open_ai_vectorizer_text_embedding_3_small_request.py,sha256=kqph8wL-8Cn6vVoJMEYIkFc4kvERvF3pzHjUQxFZAOM,187
1188
1193
  vellum/types/open_ai_vectorizer_text_embedding_ada_002.py,sha256=VTile8qzbXfjXgALK7Lr58U4sWGcEOWJ830gdHNpJhY,179
1189
1194
  vellum/types/open_ai_vectorizer_text_embedding_ada_002_request.py,sha256=345s9jJCbxvgIWb_ejW2pVWOz51d4NnkiyWB4J0qQpE,187
1195
+ vellum/types/organization_limit_config.py,sha256=wJoKIE_HPe0jbUVQx18QCnNVdAkhK05TAZxu8uSPtQY,163
1190
1196
  vellum/types/organization_read.py,sha256=3VdzuCxr_jNaXSL8P_Imk6vNK6BaJ6b1TX1IHKMiQ_Y,155
1191
1197
  vellum/types/paginated_container_image_read_list.py,sha256=dKnIbX8_sYqWo6tS0W694jojAWKybB8pe9Zw8-hvlo8,173
1192
1198
  vellum/types/paginated_deployment_release_tag_read_list.py,sha256=B-fCqNhU5KiYqIvnrybZr7MZCyOBmihHkrDsEhEzOjg,180
@@ -1227,6 +1233,7 @@ vellum/types/prompt_request_json_input.py,sha256=OlXiUPchxe184SWbmIvbmARpY9YWPi8
1227
1233
  vellum/types/prompt_request_string_input.py,sha256=1V-fTtuyhEw5H4EpqIkCqX7aHGJivUzzc_LMeszPjnc,165
1228
1234
  vellum/types/prompt_settings.py,sha256=6_AzrH73lBHSDxKxidI6zhDjAeWh_nZcaIGlrzJhypU,153
1229
1235
  vellum/types/prompt_version_build_config_sandbox.py,sha256=thz3Ty7FMZr1NWrrtPS1QN32kPpZo9hg9VIN6c6biuc,173
1236
+ vellum/types/quota.py,sha256=hhIYDiHDilEV0FJ7LSD-TTzLaDL0kfuJIA9tReithZg,143
1230
1237
  vellum/types/raw_prompt_execution_overrides_request.py,sha256=NvCoHH8ehO0UortbDuDQvwOdxQzXw0_PMGsJc7DtvoA,176
1231
1238
  vellum/types/reducto_chunker_config.py,sha256=6hu2m_WTavxTfKs46BWZGiuOsLE4HYgoP-VdDGS6KTI,160
1232
1239
  vellum/types/reducto_chunker_config_request.py,sha256=KjIZYQu27OIA--0e6RjgUwWmY3iE8s9rlehdhfZRzhQ,168
@@ -1424,6 +1431,7 @@ vellum/types/vellum_variable.py,sha256=rmjuD8hMydLF480--5tWlHbvu6qNaz0Hs9bSrJ8DP
1424
1431
  vellum/types/vellum_variable_extensions.py,sha256=wwKDv_yxtP7gQmfz5HF3zab-FOLt-0OMUYIsHgvrOC0,164
1425
1432
  vellum/types/vellum_variable_type.py,sha256=d3Zkf0ued1QrO90CMGTUnlyg2xT8nKGM4Nv6-L6W_Pg,158
1426
1433
  vellum/types/vellum_workflow_execution_event.py,sha256=EI7XANl17nOtYskD9b4FmdejkKsK7cFDwe9asr2xGC8,169
1434
+ vellum/types/vembda_service_tier_enum.py,sha256=IMC8Ftntkplp7lt1OIqPZjFP_1C3t0-EbspoyWXgFQ4,162
1427
1435
  vellum/types/workflow_deployment_event_executions_response.py,sha256=375mHiA7sucHeFSr0LlaLcVgV7F2QicMZaQiOrC5yOg,183
1428
1436
  vellum/types/workflow_deployment_history_item.py,sha256=dp5pwzOVO83KPwAbYeO3NXlKKHswGa0MTGX82nIhAIg,170
1429
1437
  vellum/types/workflow_deployment_parent_context.py,sha256=kB0eeRXagHqRnuDVA9B8aDlvBZVOmQ702JYXD8evh24,172
@@ -1614,17 +1622,16 @@ vellum/workflows/nodes/core/try_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW
1614
1622
  vellum/workflows/nodes/core/try_node/tests/test_node.py,sha256=h6eUc3SggvhzBWlOD0PrPUlkoCSQHwjqYn81VkxSIxU,4948
1615
1623
  vellum/workflows/nodes/displayable/__init__.py,sha256=zH7SFotr4i8sO-r5_k53yPipQwDouDmHxTfCE6dXAoU,1093
1616
1624
  vellum/workflows/nodes/displayable/api_node/__init__.py,sha256=MoxdQSnidIj1Nf_d-hTxlOxcZXaZnsWFDbE-PkTK24o,56
1617
- vellum/workflows/nodes/displayable/api_node/node.py,sha256=kGvKPxXj4XcAsNLtvE1RBGI58MiSNTkQcQU2g2JHC3E,2922
1625
+ vellum/workflows/nodes/displayable/api_node/node.py,sha256=F7ucsuEmrVYlTKMIoi60fFJ_ELYgGuc7jEmJCEyQczw,2956
1618
1626
  vellum/workflows/nodes/displayable/api_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1619
- vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py,sha256=kZQz_SOMxW_r_6t7OSCuGFifEBqxnPW3K1sE2TkiPtA,8021
1627
+ vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py,sha256=qp6v-MrgpNVDt16Kp0EOyeQx3LpzflTlaNSL1EYZ1nE,9185
1620
1628
  vellum/workflows/nodes/displayable/bases/__init__.py,sha256=0mWIx3qUrzllV7jqt7wN03vWGMuI1WrrLZeMLT2Cl2c,304
1621
1629
  vellum/workflows/nodes/displayable/bases/api_node/__init__.py,sha256=1jwx4WC358CLA1jgzl_UD-rZmdMm2v9Mps39ndwCD7U,64
1622
- vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=4rRrF8IV9ATMm4i5mxjwArYmvSrlDyDxBMWQTrhY3p8,4606
1630
+ vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=JDYe21Ou8WGkVRxO5RYdW10yld-IYv3Ugt13L8f6-s0,5247
1623
1631
  vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
1624
1632
  vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=EJsGaz8Umss6-JWGGYbJp93ZHx3IlZQWAySlHAdNYtY,4466
1625
1633
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
1626
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/constants.py,sha256=fnjiRWLoRlC4Puo5oQcpZD5Hd-EesxsAo9l5tGAkpZQ,270
1627
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=6zzgeBTUwCiYTLRhrZAqmi-nU2r4q0gX-ytnatY5kwY,12896
1634
+ vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=hy_fy4zImhpnHuPczKtOLhv_uOmvxvJsQA9Zl9DTmSw,12851
1628
1635
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1629
1636
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=H1xEaL3vgEPAGQaF_rt8kLl46qmVJEEhcORXT7oRdPk,22626
1630
1637
  vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=0a40fkkZkFMmZN0CsWf6EP_y1H6x36EGa3WcfVNyOsM,9797
@@ -1678,12 +1685,12 @@ vellum/workflows/nodes/displayable/tests/test_search_node_error_handling.py,sha2
1678
1685
  vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py,sha256=VepO5z1277c1y5N6LLIC31nnWD1aak2m5oPFplfJHHs,6935
1679
1686
  vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py,sha256=dc3EEn1sOICpr3GdS8eyeFtExaGwWWcw9eHSdkRhQJU,2584
1680
1687
  vellum/workflows/nodes/displayable/tool_calling_node/__init__.py,sha256=3n0-ysmFKsr40CVxPthc0rfJgqVJeZuUEsCmYudLVRg,117
1681
- vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=i0RQuhJfrO8g_Cz4hug-rHiW1G-IjJiJI6BNkdxsoYg,6204
1688
+ vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=BRA6YRCEOk0Nw3DCIT13WY7WCZ7Gx30s-egJe_md0FA,6504
1682
1689
  vellum/workflows/nodes/displayable/tool_calling_node/state.py,sha256=oQg_GAtc349nPB5BL_oeDYYD7q1qSDPAqjj8iA8OoAw,215
1683
1690
  vellum/workflows/nodes/displayable/tool_calling_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1684
- vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py,sha256=3cCCIz-quneCVl3w8XnGxzyHx-nn_jGTKCbSH9jkYT0,7824
1691
+ vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py,sha256=raY_E5-EgtYNXEPbO2I-Ythe4YeuFdGsXGZ_BAN98uI,7979
1685
1692
  vellum/workflows/nodes/displayable/tool_calling_node/tests/test_utils.py,sha256=eu6WTyENhGLg9pGp_j69rysZjf_qiQXske1YdZn9PzU,1718
1686
- vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=K4ouSeqMEBr6X9Df-qxlJ6wTmFBsYGwbiRtjaibuVlI,12528
1693
+ vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=cWlQpEyeLwJX3peMxuTNG3uy26JoXuaQPG4zTuonB5Y,12671
1687
1694
  vellum/workflows/nodes/experimental/README.md,sha256=eF6DfIL8t-HbF9-mcofOMymKrraiBHDLKTlnBa51ZiE,284
1688
1695
  vellum/workflows/nodes/experimental/__init__.py,sha256=jCQgvZEknXKfuNhGSOou4XPfrPqZ1_XBj5F0n0fgiWM,106
1689
1696
  vellum/workflows/nodes/experimental/openai_chat_completion_node/__init__.py,sha256=lsyD9laR9p7kx5-BXGH2gUTM242UhKy8SMV0SR6S2iE,90
@@ -1756,8 +1763,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
1756
1763
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1757
1764
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=ptMntHzVyy8ZuzNgeTuk7hREgKQ5UBdgq8VJFSGaW4Y,20832
1758
1765
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1759
- vellum_ai-1.0.0.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1760
- vellum_ai-1.0.0.dist-info/METADATA,sha256=AbpfGbPaocNLUgsmqS-axWjsiIWqYAhiKX7RyA1ZXgo,5554
1761
- vellum_ai-1.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1762
- vellum_ai-1.0.0.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1763
- vellum_ai-1.0.0.dist-info/RECORD,,
1766
+ vellum_ai-1.0.2.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1767
+ vellum_ai-1.0.2.dist-info/METADATA,sha256=Sv-txgzIuaWBix0TomAvHzXE1zda-jYNcFRqfD7Npic,5554
1768
+ vellum_ai-1.0.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1769
+ vellum_ai-1.0.2.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1770
+ vellum_ai-1.0.2.dist-info/RECORD,,
@@ -26,6 +26,7 @@ def test_ping__happy_path(vellum_client):
26
26
  name="Test Organization",
27
27
  new_member_join_behavior="AUTO_ACCEPT_FROM_SHARED_DOMAIN",
28
28
  allow_staff_access=True,
29
+ limit_config={},
29
30
  )
30
31
 
31
32
  # WHEN calling `vellum ping`
@@ -247,6 +247,30 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
247
247
 
248
248
  return ports
249
249
 
250
+ def _serialize_attributes(self, display_context: "WorkflowDisplayContext") -> JsonArray:
251
+ """Serialize node attributes, skipping unserializable ones."""
252
+ attributes: JsonArray = []
253
+ for attribute in self._node:
254
+ if attribute in self.__unserializable_attributes__:
255
+ continue
256
+
257
+ id = (
258
+ str(self.attribute_ids_by_name[attribute.name])
259
+ if self.attribute_ids_by_name.get(attribute.name)
260
+ else str(uuid4_from_hash(f"{self.node_id}|{attribute.name}"))
261
+ )
262
+ try:
263
+ attribute_dict: JsonObject = {
264
+ "id": id,
265
+ "name": attribute.name,
266
+ "value": serialize_value(display_context, attribute.instance),
267
+ }
268
+ attributes.append(attribute_dict)
269
+ except ValueError as e:
270
+ raise ValueError(f"Failed to serialize attribute '{attribute.name}': {e}")
271
+
272
+ return attributes
273
+
250
274
  def get_base(self) -> CodeResourceDefinition:
251
275
  node = self._node
252
276
 
@@ -31,6 +31,19 @@ class BaseAPINodeDisplay(BaseNodeDisplay[_APINodeType], Generic[_APINodeType]):
31
31
  APINode.authorization_type,
32
32
  }
33
33
 
34
+ # TODO: Only serialize attributes not inputs
35
+ __unserializable_attributes__ = {
36
+ APINode.data,
37
+ APINode.url,
38
+ APINode.method,
39
+ APINode.json,
40
+ APINode.headers,
41
+ APINode.api_key_header_key,
42
+ APINode.api_key_header_value,
43
+ APINode.bearer_token_value,
44
+ APINode.authorization_type,
45
+ }
46
+
34
47
  def serialize(
35
48
  self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **_kwargs
36
49
  ) -> JsonObject:
@@ -171,7 +184,7 @@ class BaseAPINodeDisplay(BaseNodeDisplay[_APINodeType], Generic[_APINodeType]):
171
184
  cast(OutputReference, node.Outputs.status_code)
172
185
  ]
173
186
 
174
- return {
187
+ serialized_node: JsonObject = {
175
188
  "id": str(node_id),
176
189
  "type": "API",
177
190
  "inputs": [input.dict() for input in inputs],
@@ -205,3 +218,9 @@ class BaseAPINodeDisplay(BaseNodeDisplay[_APINodeType], Generic[_APINodeType]):
205
218
  "definition": self.get_definition().dict(),
206
219
  "ports": self.serialize_ports(display_context),
207
220
  }
221
+
222
+ attributes = self._serialize_attributes(display_context)
223
+ if attributes:
224
+ serialized_node["attributes"] = attributes
225
+
226
+ return serialized_node
@@ -11,7 +11,6 @@ from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
11
11
  from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
12
12
  from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
13
13
  from vellum_ee.workflows.display.types import WorkflowDisplayContext
14
- from vellum_ee.workflows.display.utils.expressions import serialize_value
15
14
  from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
16
15
  from vellum_ee.workflows.display.vellum import NodeInput
17
16
 
@@ -173,7 +172,6 @@ class BaseInlinePromptNodeDisplay(BaseNodeDisplay[_InlinePromptNodeType], Generi
173
172
  }
174
173
 
175
174
  elif prompt_block.block_type == "CHAT_MESSAGE":
176
-
177
175
  chat_properties: JsonObject = {
178
176
  "chat_role": prompt_block.chat_role,
179
177
  "chat_source": prompt_block.chat_source,
@@ -248,30 +246,6 @@ class BaseInlinePromptNodeDisplay(BaseNodeDisplay[_InlinePromptNodeType], Generi
248
246
 
249
247
  return block
250
248
 
251
- def _serialize_attributes(self, display_context: "WorkflowDisplayContext"):
252
- attributes = []
253
- for attribute in self._node:
254
- if attribute in self.__unserializable_attributes__:
255
- continue
256
-
257
- id = (
258
- str(self.attribute_ids_by_name[attribute.name])
259
- if self.attribute_ids_by_name.get(attribute.name)
260
- else str(uuid4_from_hash(f"{self.node_id}|{attribute.name}"))
261
- )
262
- try:
263
- attributes.append(
264
- {
265
- "id": id,
266
- "name": attribute.name,
267
- "value": serialize_value(display_context, attribute.instance),
268
- }
269
- )
270
- except ValueError as e:
271
- raise ValueError(f"Failed to serialize attribute '{attribute.name}': {e}")
272
-
273
- return attributes
274
-
275
249
  def _serialize_parameters(self, parameters, display_context: "WorkflowDisplayContext") -> JsonObject:
276
250
  """Serialize parameters, returning empty object when nested descriptors are detected."""
277
251
  params = raise_if_descriptor(parameters)
@@ -0,0 +1,31 @@
1
+ from vellum.workflows.constants import APIRequestMethod
2
+ from vellum.workflows.nodes.displayable.api_node.node import APINode
3
+ from vellum.workflows.workflows.base import BaseWorkflow
4
+ from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
5
+
6
+
7
+ def test_serialize_node__api_node_with_timeout():
8
+ # GIVEN an API node with timeout specified
9
+ class MyAPINode(APINode):
10
+ url = "https://api.example.com"
11
+ method = APIRequestMethod.GET
12
+ timeout = 30 # This is the key attribute we're testing
13
+
14
+ # AND a workflow with the API node
15
+ class Workflow(BaseWorkflow):
16
+ graph = MyAPINode
17
+
18
+ # WHEN the workflow is serialized
19
+ workflow_display = get_workflow_display(workflow_class=Workflow)
20
+ serialized_workflow: dict = workflow_display.serialize()
21
+
22
+ # THEN the node should properly serialize the timeout
23
+ my_api_node = next(node for node in serialized_workflow["workflow_raw_data"]["nodes"] if node["type"] == "API")
24
+
25
+ # Assert that timeout is present in the serialized attributes
26
+ timeout_attribute = next((attr for attr in my_api_node.get("attributes", []) if attr["name"] == "timeout"), None)
27
+
28
+ assert timeout_attribute is not None, "timeout attribute should be present in serialized attributes"
29
+ assert timeout_attribute["value"]["type"] == "CONSTANT_VALUE"
30
+ assert timeout_attribute["value"]["value"]["type"] == "NUMBER"
31
+ assert timeout_attribute["value"]["value"]["value"] == 30.0
@@ -162,6 +162,16 @@ def test_serialize_workflow(vellum_client):
162
162
  },
163
163
  },
164
164
  ],
165
+ "attributes": [
166
+ {
167
+ "id": "ad719e65-0032-4012-a0bd-9b5162194bce",
168
+ "name": "timeout",
169
+ "value": {
170
+ "type": "CONSTANT_VALUE",
171
+ "value": {"type": "JSON", "value": None},
172
+ },
173
+ },
174
+ ],
165
175
  "data": {
166
176
  "label": "Simple A P I Node",
167
177
  "error_output_id": None,
@@ -407,6 +407,27 @@ def test_serialize_workflow():
407
407
  ],
408
408
  },
409
409
  },
410
+ {
411
+ "id": "229cd1ca-dc2f-4586-b933-c4d4966f7bd1",
412
+ "name": "parameters",
413
+ "value": {
414
+ "type": "CONSTANT_VALUE",
415
+ "value": {
416
+ "type": "JSON",
417
+ "value": {
418
+ "stop": [],
419
+ "temperature": 0.0,
420
+ "max_tokens": 4096.0,
421
+ "top_p": 1.0,
422
+ "top_k": 0.0,
423
+ "frequency_penalty": 0.0,
424
+ "presence_penalty": 0.0,
425
+ "logit_bias": None,
426
+ "custom_parameters": None,
427
+ },
428
+ },
429
+ },
430
+ },
410
431
  {
411
432
  "id": "1668419e-a193-43a5-8a97-3394e89bf278",
412
433
  "name": "max_prompt_iterations",
@@ -169,6 +169,27 @@ def test_serialize_workflow():
169
169
  ],
170
170
  },
171
171
  },
172
+ {
173
+ "id": "229cd1ca-dc2f-4586-b933-c4d4966f7bd1",
174
+ "name": "parameters",
175
+ "value": {
176
+ "type": "CONSTANT_VALUE",
177
+ "value": {
178
+ "type": "JSON",
179
+ "value": {
180
+ "stop": [],
181
+ "temperature": 0.0,
182
+ "max_tokens": 4096.0,
183
+ "top_p": 1.0,
184
+ "top_k": 0.0,
185
+ "frequency_penalty": 0.0,
186
+ "presence_penalty": 0.0,
187
+ "logit_bias": None,
188
+ "custom_parameters": None,
189
+ },
190
+ },
191
+ },
192
+ },
172
193
  {
173
194
  "id": "1668419e-a193-43a5-8a97-3394e89bf278",
174
195
  "name": "max_prompt_iterations",
@@ -136,13 +136,16 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
136
136
  if workflow_input_reference.instance
137
137
  else None
138
138
  )
139
+
140
+ is_required = self._is_reference_required(workflow_input_reference)
141
+
139
142
  input_variables.append(
140
143
  {
141
144
  "id": str(workflow_input_display.id),
142
145
  "key": workflow_input_display.name or workflow_input_reference.name,
143
146
  "type": infer_vellum_variable_type(workflow_input_reference),
144
147
  "default": default.dict() if default else None,
145
- "required": workflow_input_reference.instance is undefined,
148
+ "required": is_required,
146
149
  "extensions": {"color": workflow_input_display.color},
147
150
  }
148
151
  )
@@ -152,13 +155,16 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
152
155
  default = (
153
156
  primitive_to_vellum_value(state_value_reference.instance) if state_value_reference.instance else None
154
157
  )
158
+
159
+ is_required = self._is_reference_required(state_value_reference)
160
+
155
161
  state_variables.append(
156
162
  {
157
163
  "id": str(state_value_display.id),
158
164
  "key": state_value_display.name or state_value_reference.name,
159
165
  "type": infer_vellum_variable_type(state_value_reference),
160
166
  "default": default.dict() if default else None,
161
- "required": state_value_reference.instance is undefined,
167
+ "required": is_required,
162
168
  "extensions": {"color": state_value_display.color},
163
169
  }
164
170
  )
@@ -938,5 +944,12 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
938
944
 
939
945
  return additional_files
940
946
 
947
+ @staticmethod
948
+ def _is_reference_required(reference: BaseDescriptor) -> bool:
949
+ has_default = reference.instance is not undefined
950
+ is_optional = type(None) in reference.types
951
+ is_required = not has_default and not is_optional
952
+ return is_required
953
+
941
954
 
942
955
  register_workflow_display_class(workflow_class=BaseWorkflow, workflow_display_class=BaseWorkflowDisplay)
@@ -1,6 +1,8 @@
1
1
  import pytest
2
2
  from uuid import uuid4
3
+ from typing import Optional
3
4
 
5
+ from vellum.workflows.inputs import BaseInputs
4
6
  from vellum.workflows.nodes.bases.base import BaseNode
5
7
  from vellum.workflows.nodes.core.inline_subworkflow_node.node import InlineSubworkflowNode
6
8
  from vellum.workflows.nodes.core.retry_node.node import RetryNode
@@ -8,6 +10,7 @@ from vellum.workflows.nodes.core.templating_node.node import TemplatingNode
8
10
  from vellum.workflows.nodes.core.try_node.node import TryNode
9
11
  from vellum.workflows.nodes.displayable.final_output_node.node import FinalOutputNode
10
12
  from vellum.workflows.references.lazy import LazyReference
13
+ from vellum.workflows.state.base import BaseState
11
14
  from vellum.workflows.workflows.base import BaseWorkflow
12
15
  from vellum_ee.workflows.display.editor.types import NodeDisplayData, NodeDisplayPosition
13
16
  from vellum_ee.workflows.display.nodes import BaseNodeDisplay
@@ -828,3 +831,127 @@ def test_serialize_workflow__empty_rules_indexerror():
828
831
  terminal_nodes = [node for node in nodes if node.get("type") == "TERMINAL"]
829
832
  assert len(terminal_nodes) == 1
830
833
  assert terminal_nodes[0]["data"]["name"] == "problematic_output"
834
+
835
+
836
+ def test_serialize_workflow__input_variables():
837
+ # GIVEN a workflow with inputs
838
+ class Inputs(BaseInputs):
839
+ input_1: str
840
+ input_2: Optional[str]
841
+ input_3: int = 1
842
+ input_4: Optional[int] = 2
843
+
844
+ class MyWorkflow(BaseWorkflow[Inputs, BaseState]):
845
+ pass
846
+
847
+ # WHEN we serialize it
848
+ workflow_display = get_workflow_display(workflow_class=MyWorkflow)
849
+ data = workflow_display.serialize()
850
+
851
+ # THEN the inputs should be serialized correctly
852
+ assert "input_variables" in data
853
+ input_variables = data["input_variables"]
854
+ assert isinstance(input_variables, list)
855
+ assert len(input_variables) == 4
856
+
857
+ input_1 = next(var for var in input_variables if isinstance(var, dict) and var["key"] == "input_1")
858
+ assert input_1 == {
859
+ "id": "13bd7980-3fbd-486c-9ebd-a29d84f7bda0",
860
+ "key": "input_1",
861
+ "type": "STRING",
862
+ "default": None,
863
+ "required": True,
864
+ "extensions": {"color": None},
865
+ }
866
+
867
+ input_2 = next(var for var in input_variables if isinstance(var, dict) and var["key"] == "input_2")
868
+ assert input_2 == {
869
+ "id": "13847952-beab-408d-945e-cfa079e6e124",
870
+ "key": "input_2",
871
+ "type": "STRING",
872
+ "default": None,
873
+ "required": False,
874
+ "extensions": {"color": None},
875
+ }
876
+
877
+ input_3 = next(var for var in input_variables if isinstance(var, dict) and var["key"] == "input_3")
878
+ assert input_3 == {
879
+ "id": "2e38e1a4-09ff-4bb8-a12e-9bf54d4f3a5e",
880
+ "key": "input_3",
881
+ "type": "NUMBER",
882
+ "default": {"type": "NUMBER", "value": 1.0},
883
+ "required": False,
884
+ "extensions": {"color": None},
885
+ }
886
+
887
+ input_4 = next(var for var in input_variables if isinstance(var, dict) and var["key"] == "input_4")
888
+ assert input_4 == {
889
+ "id": "d945b6ae-2490-4bfb-9b1c-b1e484dfd4f6",
890
+ "key": "input_4",
891
+ "type": "NUMBER",
892
+ "default": {"type": "NUMBER", "value": 2.0},
893
+ "required": False,
894
+ "extensions": {"color": None},
895
+ }
896
+
897
+
898
+ def test_serialize_workflow__state_variables():
899
+ # GIVEN a workflow with state variables
900
+ class State(BaseState):
901
+ state_1: str = "hello"
902
+ state_2: Optional[str] = None
903
+ state_3: int = 1
904
+ state_4: Optional[int] = 2
905
+
906
+ class MyWorkflow(BaseWorkflow[BaseInputs, State]):
907
+ pass
908
+
909
+ # WHEN we serialize it
910
+ workflow_display = get_workflow_display(workflow_class=MyWorkflow)
911
+ data = workflow_display.serialize()
912
+
913
+ # THEN the state variables should be serialized correctly
914
+ assert "state_variables" in data
915
+ state_variables = data["state_variables"]
916
+ assert isinstance(state_variables, list)
917
+ assert len(state_variables) == 4
918
+
919
+ state_1 = next(var for var in state_variables if isinstance(var, dict) and var["key"] == "state_1")
920
+ assert state_1 == {
921
+ "id": "83c5b71d-56eb-42a5-84df-97e3591370c2",
922
+ "key": "state_1",
923
+ "type": "STRING",
924
+ "default": {"type": "STRING", "value": "hello"},
925
+ "required": False,
926
+ "extensions": {"color": None},
927
+ }
928
+
929
+ state_2 = next(var for var in state_variables if isinstance(var, dict) and var["key"] == "state_2")
930
+ assert state_2 == {
931
+ "id": "9b0cfeec-aa66-42b3-8f31-aa7eb8ac30ea",
932
+ "key": "state_2",
933
+ "type": "STRING",
934
+ "default": None,
935
+ "required": False,
936
+ "extensions": {"color": None},
937
+ }
938
+
939
+ state_3 = next(var for var in state_variables if isinstance(var, dict) and var["key"] == "state_3")
940
+ assert state_3 == {
941
+ "id": "3e19c570-6b46-4eab-ad81-d8d97028496f",
942
+ "key": "state_3",
943
+ "type": "NUMBER",
944
+ "default": {"type": "NUMBER", "value": 1.0},
945
+ "required": False,
946
+ "extensions": {"color": None},
947
+ }
948
+
949
+ state_4 = next(var for var in state_variables if isinstance(var, dict) and var["key"] == "state_4")
950
+ assert state_4 == {
951
+ "id": "50c735de-f269-4d0a-b511-c9a1104451bb",
952
+ "key": "state_4",
953
+ "type": "NUMBER",
954
+ "default": {"type": "NUMBER", "value": 2.0},
955
+ "required": False,
956
+ "extensions": {"color": None},
957
+ }