vellum-ai 0.13.22__py3-none-any.whl → 0.13.24__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.
@@ -18,7 +18,7 @@ class BaseClientWrapper:
18
18
  headers: typing.Dict[str, str] = {
19
19
  "X-Fern-Language": "Python",
20
20
  "X-Fern-SDK-Name": "vellum-ai",
21
- "X-Fern-SDK-Version": "0.13.22",
21
+ "X-Fern-SDK-Version": "0.13.24",
22
22
  }
23
23
  headers["X_API_KEY"] = self.api_key
24
24
  return headers
@@ -11,7 +11,9 @@ import pydantic
11
11
  class ExecuteApiResponse(UniversalBaseModel):
12
12
  status_code: int
13
13
  text: str
14
- json_: typing_extensions.Annotated[typing.Dict[str, typing.Optional[typing.Any]], FieldMetadata(alias="json")]
14
+ json_: typing_extensions.Annotated[
15
+ typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]], FieldMetadata(alias="json")
16
+ ] = None
15
17
  headers: typing.Dict[str, str]
16
18
 
17
19
  if IS_PYDANTIC_V2:
@@ -33,6 +33,7 @@ class APINode(BaseAPINode):
33
33
  def run(self) -> BaseAPINode.Outputs:
34
34
  headers = self.headers or {}
35
35
  header_overrides = {}
36
+ bearer_token = None
36
37
 
37
38
  if (
38
39
  self.authorization_type == AuthorizationType.API_KEY
@@ -40,9 +41,17 @@ class APINode(BaseAPINode):
40
41
  and self.api_key_header_value
41
42
  ):
42
43
  header_overrides[self.api_key_header_key] = self.api_key_header_value
43
- elif self.authorization_type == AuthorizationType.BEARER_TOKEN:
44
+ elif self.authorization_type == AuthorizationType.BEARER_TOKEN and isinstance(self.bearer_token_value, str):
44
45
  header_overrides["Authorization"] = f"Bearer {self.bearer_token_value}"
45
-
46
+ elif self.authorization_type == AuthorizationType.BEARER_TOKEN and isinstance(
47
+ self.bearer_token_value, VellumSecret
48
+ ):
49
+ bearer_token = self.bearer_token_value
46
50
  return self._run(
47
- method=self.method, url=self.url, data=self.data, json=self.json, headers={**headers, **header_overrides}
51
+ method=self.method,
52
+ url=self.url,
53
+ data=self.data or self.json,
54
+ json=self.json,
55
+ headers={**headers, **header_overrides},
56
+ bearer_token=bearer_token,
48
57
  )
@@ -0,0 +1,34 @@
1
+ from vellum import ExecuteApiResponse, VellumSecret as ClientVellumSecret
2
+ from vellum.workflows.constants import APIRequestMethod, AuthorizationType
3
+ from vellum.workflows.nodes import APINode
4
+ from vellum.workflows.state import BaseState
5
+ from vellum.workflows.types.core import VellumSecret
6
+
7
+
8
+ def test_run_workflow__secrets(vellum_client):
9
+ vellum_client.execute_api.return_value = ExecuteApiResponse(
10
+ status_code=200,
11
+ text='{"status": 200, "data": [1, 2, 3]}',
12
+ json_={"data": [1, 2, 3]},
13
+ headers={"X-Response-Header": "bar"},
14
+ )
15
+
16
+ class SimpleBaseAPINode(APINode):
17
+ method = APIRequestMethod.POST
18
+ authorization_type = AuthorizationType.BEARER_TOKEN
19
+ url = "https://api.vellum.ai"
20
+ body = {
21
+ "key": "value",
22
+ }
23
+ headers = {
24
+ "X-Test-Header": "foo",
25
+ }
26
+ bearer_token_value = VellumSecret(name="secret")
27
+
28
+ node = SimpleBaseAPINode(state=BaseState())
29
+ terminal = node.run()
30
+
31
+ assert vellum_client.execute_api.call_count == 1
32
+ bearer_token = vellum_client.execute_api.call_args.kwargs["bearer_token"]
33
+ assert bearer_token == ClientVellumSecret(name="secret")
34
+ assert terminal.headers == {"X-Response-Header": "bar"}
@@ -3,6 +3,7 @@ from typing import Any, Dict, Generic, Optional, Union
3
3
  from requests import Request, RequestException, Session
4
4
  from requests.exceptions import JSONDecodeError
5
5
 
6
+ from vellum.client.types.vellum_secret import VellumSecret as ClientVellumSecret
6
7
  from vellum.workflows.constants import APIRequestMethod
7
8
  from vellum.workflows.errors.types import WorkflowErrorCode
8
9
  from vellum.workflows.exceptions import NodeException
@@ -45,29 +46,49 @@ class BaseAPINode(BaseNode, Generic[StateType]):
45
46
  self,
46
47
  method: APIRequestMethod,
47
48
  url: str,
48
- data: Optional[str] = None,
49
+ data: Optional[Union[str, Any]] = None,
49
50
  json: Any = None,
50
51
  headers: Any = None,
52
+ bearer_token: Optional[VellumSecret] = None,
51
53
  ) -> Outputs:
54
+ vellum_instance = False
55
+ for header in headers or {}:
56
+ if isinstance(headers[header], VellumSecret):
57
+ vellum_instance = True
58
+ if vellum_instance or bearer_token:
59
+ return self._vellum_execute_api(bearer_token, data, headers, method, url)
60
+ else:
61
+ return self._local_execute_api(data, headers, json, method, url)
62
+
63
+ def _local_execute_api(self, data, headers, json, method, url):
52
64
  try:
53
65
  prepped = Request(method=method.value, url=url, data=data, json=json, headers=headers).prepare()
54
66
  except Exception as e:
55
67
  raise NodeException(f"Failed to prepare HTTP request: {e}", code=WorkflowErrorCode.PROVIDER_ERROR)
56
-
57
68
  try:
58
69
  with Session() as session:
59
70
  response = session.send(prepped)
60
71
  except RequestException as e:
61
72
  raise NodeException(f"HTTP request failed: {e}", code=WorkflowErrorCode.PROVIDER_ERROR)
62
-
63
73
  try:
64
74
  json = response.json()
65
75
  except JSONDecodeError:
66
76
  json = None
67
-
68
77
  return self.Outputs(
69
78
  json=json,
70
79
  headers={header: value for header, value in response.headers.items()},
71
80
  status_code=response.status_code,
72
81
  text=response.text,
73
82
  )
83
+
84
+ def _vellum_execute_api(self, bearer_token, data, headers, method, url):
85
+ client_vellum_secret = ClientVellumSecret(name=bearer_token.name) if bearer_token else None
86
+ vellum_response = self._context.vellum_client.execute_api(
87
+ url=url, method=method.value, body=data, headers=headers, bearer_token=client_vellum_secret
88
+ )
89
+ return self.Outputs(
90
+ json=vellum_response.json_,
91
+ headers={header: value for header, value in vellum_response.headers.items()},
92
+ status_code=vellum_response.status_code,
93
+ text=vellum_response.text,
94
+ )
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  from uuid import UUID
3
- from typing import Any, ClassVar, Dict, Generic, Iterator, List, Optional, Sequence, Union, cast
3
+ from typing import Any, ClassVar, Dict, Generic, Iterator, List, Optional, Sequence, Union
4
4
 
5
5
  from vellum import (
6
6
  ChatHistoryInputRequest,
@@ -95,10 +95,19 @@ class BasePromptDeploymentNode(BasePromptNode, Generic[StateType]):
95
95
  elif isinstance(input_value, list) and all(
96
96
  isinstance(message, (ChatMessage, ChatMessageRequest)) for message in input_value
97
97
  ):
98
+ chat_history = [
99
+ (
100
+ message
101
+ if isinstance(message, ChatMessageRequest)
102
+ else ChatMessageRequest.model_validate(message.model_dump())
103
+ )
104
+ for message in input_value
105
+ if isinstance(message, (ChatMessage, ChatMessageRequest))
106
+ ]
98
107
  compiled_inputs.append(
99
108
  ChatHistoryInputRequest(
100
109
  name=input_name,
101
- value=cast(List[ChatMessage], input_value),
110
+ value=chat_history,
102
111
  )
103
112
  )
104
113
  else:
@@ -170,11 +170,11 @@ class CodeExecutionNode(BaseNode[StateType], Generic[StateType, _OutputType], me
170
170
  value=cast(Dict[str, Any], input_value),
171
171
  )
172
172
  )
173
- elif isinstance(input_value, float):
173
+ elif isinstance(input_value, (float, int)):
174
174
  compiled_inputs.append(
175
175
  NumberInput(
176
176
  name=input_name,
177
- value=input_value,
177
+ value=float(input_value),
178
178
  )
179
179
  )
180
180
  elif isinstance(input_value, FunctionCall):
@@ -1,10 +1,12 @@
1
1
  import pytest
2
2
  import os
3
+ from typing import Any
3
4
 
4
5
  from vellum import CodeExecutorResponse, NumberVellumValue, StringInput
5
6
  from vellum.client.types.code_execution_package import CodeExecutionPackage
6
7
  from vellum.client.types.code_executor_secret_input import CodeExecutorSecretInput
7
8
  from vellum.client.types.function_call import FunctionCall
9
+ from vellum.client.types.number_input import NumberInput
8
10
  from vellum.workflows.exceptions import NodeException
9
11
  from vellum.workflows.inputs.base import BaseInputs
10
12
  from vellum.workflows.nodes.displayable.code_execution_node import CodeExecutionNode
@@ -12,7 +14,7 @@ from vellum.workflows.references.vellum_secret import VellumSecretReference
12
14
  from vellum.workflows.state.base import BaseState, StateMeta
13
15
 
14
16
 
15
- def test_run_workflow__happy_path(vellum_client):
17
+ def test_run_node__happy_path(vellum_client):
16
18
  """Confirm that CodeExecutionNodes output the expected text and results when run."""
17
19
 
18
20
  # GIVEN a node that subclasses CodeExecutionNode
@@ -78,7 +80,7 @@ def main(word: str) -> int:
78
80
  )
79
81
 
80
82
 
81
- def test_run_workflow__code_attribute(vellum_client):
83
+ def test_run_node__code_attribute(vellum_client):
82
84
  """Confirm that CodeExecutionNodes can use the `code` attribute to specify the code to execute."""
83
85
 
84
86
  # GIVEN a node that subclasses CodeExecutionNode
@@ -146,7 +148,7 @@ def main(word: str) -> int:
146
148
  )
147
149
 
148
150
 
149
- def test_run_workflow__code_and_filepath_defined(vellum_client):
151
+ def test_run_node__code_and_filepath_defined(vellum_client):
150
152
  """Confirm that CodeExecutionNodes raise an error if both `code` and `filepath` are defined."""
151
153
 
152
154
  # GIVEN a node that subclasses CodeExecutionNode
@@ -197,7 +199,7 @@ def main(word: str) -> int:
197
199
  assert exc_info.value.message == "Cannot specify both `code` and `filepath` for a CodeExecutionNode"
198
200
 
199
201
 
200
- def test_run_workflow__code_and_filepath_not_defined(vellum_client):
202
+ def test_run_node__code_and_filepath_not_defined(vellum_client):
201
203
  """Confirm that CodeExecutionNodes raise an error if neither `code` nor `filepath` are defined."""
202
204
 
203
205
  # GIVEN a node that subclasses CodeExecutionNode
@@ -240,7 +242,7 @@ def test_run_workflow__code_and_filepath_not_defined(vellum_client):
240
242
  assert exc_info.value.message == "Must specify either `code` or `filepath` for a CodeExecutionNode"
241
243
 
242
244
 
243
- def test_run_workflow__vellum_secret(vellum_client):
245
+ def test_run_node__vellum_secret(vellum_client):
244
246
  """Confirm that CodeExecutionNodes can use Vellum Secrets"""
245
247
 
246
248
  # GIVEN a node that subclasses CodeExecutionNode that references a Vellum Secret
@@ -302,7 +304,53 @@ def main(word: str) -> int:
302
304
  )
303
305
 
304
306
 
305
- def test_run_workflow__run_inline(vellum_client):
307
+ def test_run_node__int_input(vellum_client):
308
+ """Confirm that CodeExecutionNodes can use int's as inputs"""
309
+
310
+ # GIVEN a node that subclasses CodeExecutionNode that references an int
311
+ class State(BaseState):
312
+ pass
313
+
314
+ fixture = os.path.abspath(os.path.join(__file__, "../fixtures/main.py"))
315
+
316
+ class ExampleCodeExecutionNode(CodeExecutionNode[State, int]):
317
+ filepath = fixture
318
+ runtime = "PYTHON_3_11_6"
319
+ packages = [
320
+ CodeExecutionPackage(
321
+ name="openai",
322
+ version="1.0.0",
323
+ )
324
+ ]
325
+
326
+ code_inputs = {
327
+ "counter": 1,
328
+ }
329
+
330
+ # AND we know what the Code Execution Node will respond with
331
+ mock_code_execution = CodeExecutorResponse(
332
+ log="",
333
+ output=NumberVellumValue(value=0),
334
+ )
335
+ vellum_client.execute_code.return_value = mock_code_execution
336
+
337
+ # WHEN we run the node
338
+ node = ExampleCodeExecutionNode(state=State())
339
+ outputs = node.run()
340
+
341
+ # THEN the node should have produced the outputs we expect
342
+ assert outputs == {"result": 0, "log": ""}
343
+
344
+ # AND we should have invoked the Code with the correct inputs
345
+ assert vellum_client.execute_code.call_args_list[0].kwargs["input_values"] == [
346
+ NumberInput(
347
+ name="counter",
348
+ value=1.0,
349
+ )
350
+ ]
351
+
352
+
353
+ def test_run_node__run_inline(vellum_client):
306
354
  """Confirm that CodeExecutionNodes run the code inline instead of through Vellum under certain conditions."""
307
355
 
308
356
  # GIVEN a node that subclasses CodeExecutionNode
@@ -329,7 +377,7 @@ def main(word: str) -> int:
329
377
  vellum_client.execute_code.assert_not_called()
330
378
 
331
379
 
332
- def test_run_workflow__run_inline__incorrect_output_type():
380
+ def test_run_node__run_inline__incorrect_output_type():
333
381
  """Confirm that CodeExecutionNodes raise an error if the output type is incorrect during inline execution."""
334
382
 
335
383
  # GIVEN a node that subclasses CodeExecutionNode that returns a string but is defined to return an int
@@ -353,7 +401,7 @@ def main(word: str) -> int:
353
401
  assert exc_info.value.message == "Expected an output of type 'int', but received 'str'"
354
402
 
355
403
 
356
- def test_run_workflow__run_inline__valid_dict_to_pydantic():
404
+ def test_run_node__run_inline__valid_dict_to_pydantic():
357
405
  """Confirm that CodeExecutionNodes can convert a dict to a Pydantic model during inline execution."""
358
406
 
359
407
  # GIVEN a node that subclasses CodeExecutionNode that returns a dict matching a Pydantic model
@@ -379,7 +427,7 @@ def main(word: str) -> int:
379
427
  assert outputs == {"result": FunctionCall(name="hello", arguments={}), "log": ""}
380
428
 
381
429
 
382
- def test_run_workflow__run_inline__invalid_dict_to_pydantic():
430
+ def test_run_node__run_inline__invalid_dict_to_pydantic():
383
431
  """Confirm that CodeExecutionNodes raise an error if the Pydantic validation fails during inline execution."""
384
432
 
385
433
  # GIVEN a node that subclasses CodeExecutionNode that returns a dict not matching a Pydantic model
@@ -413,3 +461,35 @@ name
413
461
  Field required [type=missing, input_value={'n': 'hello', 'a': {}}, input_type=dict]\
414
462
  """
415
463
  )
464
+
465
+
466
+ def test_run_node__run_inline__valid_dict_to_pydantic_any_type():
467
+ """Confirm that CodeExecutionNodes can convert a dict to a Pydantic model during inline execution."""
468
+
469
+ # GIVEN a node that subclasses CodeExecutionNode that returns a dict matching Any
470
+ class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, Any]):
471
+ code = """\
472
+ def main(word: str) -> dict:
473
+ return {
474
+ "name": "word",
475
+ "arguments": {},
476
+ }
477
+ """
478
+ runtime = "PYTHON_3_11_6"
479
+
480
+ code_inputs = {
481
+ "word": "hello",
482
+ }
483
+
484
+ # WHEN we run the node
485
+ node = ExampleCodeExecutionNode()
486
+ outputs = node.run()
487
+
488
+ # THEN the node should have produced the outputs we expect
489
+ assert outputs == {
490
+ "result": {
491
+ "name": "word",
492
+ "arguments": {},
493
+ },
494
+ "log": "",
495
+ }
@@ -91,19 +91,21 @@ __arg__out = main({", ".join(run_args)})
91
91
  logs = log_buffer.getvalue()
92
92
  result = exec_globals["__arg__out"]
93
93
 
94
- if issubclass(output_type, BaseModel) and not isinstance(result, output_type):
95
- try:
96
- result = output_type.model_validate(result)
97
- except ValidationError as e:
94
+ if output_type != Any:
95
+ if issubclass(output_type, BaseModel) and not isinstance(result, output_type):
96
+ try:
97
+ result = output_type.model_validate(result)
98
+ except ValidationError as e:
99
+ raise NodeException(
100
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
101
+ message=re.sub(r"\s+For further information visit [^\s]+", "", str(e)),
102
+ ) from e
103
+
104
+ if not isinstance(result, output_type):
98
105
  raise NodeException(
99
106
  code=WorkflowErrorCode.INVALID_OUTPUTS,
100
- message=re.sub(r"\s+For further information visit [^\s]+", "", str(e)),
101
- ) from e
102
-
103
- if not isinstance(result, output_type):
104
- raise NodeException(
105
- code=WorkflowErrorCode.INVALID_OUTPUTS,
106
- message=f"Expected an output of type '{output_type.__name__}', but received '{result.__class__.__name__}'",
107
- )
107
+ message=f"Expected an output of type '{output_type.__name__}',"
108
+ f" but received '{result.__class__.__name__}'",
109
+ )
108
110
 
109
111
  return logs, result
@@ -1,7 +1,9 @@
1
+ import pytest
1
2
  from uuid import uuid4
2
3
  from typing import Any, Iterator, List
3
4
 
4
5
  from vellum.client.types.chat_history_input_request import ChatHistoryInputRequest
6
+ from vellum.client.types.chat_message import ChatMessage
5
7
  from vellum.client.types.chat_message_request import ChatMessageRequest
6
8
  from vellum.client.types.execute_prompt_event import ExecutePromptEvent
7
9
  from vellum.client.types.fulfilled_execute_prompt_event import FulfilledExecutePromptEvent
@@ -11,14 +13,15 @@ from vellum.client.types.string_vellum_value import StringVellumValue
11
13
  from vellum.workflows.nodes.displayable.prompt_deployment_node.node import PromptDeploymentNode
12
14
 
13
15
 
14
- def test_run_node__chat_history_input(vellum_client):
16
+ @pytest.mark.parametrize("ChatMessageClass", [ChatMessageRequest, ChatMessage])
17
+ def test_run_node__chat_history_input(vellum_client, ChatMessageClass):
15
18
  """Confirm that we can successfully invoke a Prompt Deployment Node that uses Chat History Inputs"""
16
19
 
17
20
  # GIVEN a Prompt Deployment Node
18
21
  class ExamplePromptDeploymentNode(PromptDeploymentNode):
19
22
  deployment = "example_prompt_deployment"
20
23
  prompt_inputs = {
21
- "chat_history": [ChatMessageRequest(role="USER", text="Hello, how are you?")],
24
+ "chat_history": [ChatMessageClass(role="USER", text="Hello, how are you?")],
22
25
  }
23
26
 
24
27
  # AND we know what the Prompt Deployment will respond with
@@ -72,10 +72,19 @@ class SubworkflowDeploymentNode(BaseNode[StateType], Generic[StateType]):
72
72
  elif isinstance(input_value, list) and all(
73
73
  isinstance(message, (ChatMessage, ChatMessageRequest)) for message in input_value
74
74
  ):
75
+ chat_history = [
76
+ (
77
+ message
78
+ if isinstance(message, ChatMessageRequest)
79
+ else ChatMessageRequest.model_validate(message.model_dump())
80
+ )
81
+ for message in input_value
82
+ if isinstance(message, (ChatMessage, ChatMessageRequest))
83
+ ]
75
84
  compiled_inputs.append(
76
85
  WorkflowRequestChatHistoryInputRequest(
77
86
  name=input_name,
78
- value=cast(List[ChatMessage], input_value),
87
+ value=chat_history,
79
88
  )
80
89
  )
81
90
  elif isinstance(input_value, dict):
@@ -1,7 +1,9 @@
1
+ import pytest
1
2
  from datetime import datetime
2
3
  from uuid import uuid4
3
4
  from typing import Any, Iterator, List
4
5
 
6
+ from vellum.client.types.chat_message import ChatMessage
5
7
  from vellum.client.types.chat_message_request import ChatMessageRequest
6
8
  from vellum.client.types.workflow_execution_workflow_result_event import WorkflowExecutionWorkflowResultEvent
7
9
  from vellum.client.types.workflow_output_string import WorkflowOutputString
@@ -12,14 +14,15 @@ from vellum.client.types.workflow_stream_event import WorkflowStreamEvent
12
14
  from vellum.workflows.nodes.displayable.subworkflow_deployment_node.node import SubworkflowDeploymentNode
13
15
 
14
16
 
15
- def test_run_workflow__chat_history_input(vellum_client):
17
+ @pytest.mark.parametrize("ChatMessageClass", [ChatMessageRequest, ChatMessage])
18
+ def test_run_workflow__chat_history_input(vellum_client, ChatMessageClass):
16
19
  """Confirm that we can successfully invoke a Subworkflow Deployment Node that uses Chat History Inputs"""
17
20
 
18
21
  # GIVEN a Subworkflow Deployment Node
19
22
  class ExampleSubworkflowDeploymentNode(SubworkflowDeploymentNode):
20
23
  deployment = "example_subworkflow_deployment"
21
24
  subworkflow_inputs = {
22
- "chat_history": [ChatMessageRequest(role="USER", text="Hello, how are you?")],
25
+ "chat_history": [ChatMessageClass(role="USER", text="Hello, how are you?")],
23
26
  }
24
27
 
25
28
  # AND we know what the Subworkflow Deployment will respond with
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.13.22
3
+ Version: 0.13.24
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -80,7 +80,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_n
80
80
  vellum_ee/workflows/display/types.py,sha256=s1w2KELKI2kde4G2M3iniOEdPObNKYgYtr31sAgZqRI,2644
81
81
  vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
82
  vellum_ee/workflows/display/utils/vellum.py,sha256=IGHobHz0QG8TWdJNxlQ81khCmJv7piLjE64l4zc33kI,7743
83
- vellum_ee/workflows/display/vellum.py,sha256=-95xvit30nyP6Md29nHkfIrnFButZyCg8wz76oUHD0M,8105
83
+ vellum_ee/workflows/display/vellum.py,sha256=1mcZQQ4gd5GYrVKgIQ3ejy8SqRss2CWUL0KMf44zgUc,8122
84
84
  vellum_ee/workflows/display/workflows/__init__.py,sha256=kapXsC67VJcgSuiBMa86FdePG5A9kMB5Pi4Uy1O2ob4,207
85
85
  vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=8inuxnxeJbysEhJIGdxLZTvQ2aPJj-OSGmSeotwe7fo,15782
86
86
  vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=kp0u8LN_2IwshLrhMImhpZx1hRyAcD5gXY-kDuuaGMQ,1269
@@ -115,7 +115,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
115
115
  vellum/client/__init__.py,sha256=j6zi0NZ4BMC6JrwckvzMWuG5x8KoOvO4KqsLhvVCa68,117624
116
116
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
117
117
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
118
- vellum/client/core/client_wrapper.py,sha256=UHqsduK36o9isKel9Qci9hZN43L7ZADRoyzO7Xlx5Ws,1869
118
+ vellum/client/core/client_wrapper.py,sha256=CHUMF1rAO0mKKIpxyLeUmpjLICY4ZwyiCpiYCjAnHwE,1869
119
119
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
120
120
  vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
121
121
  vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
@@ -270,7 +270,7 @@ vellum/client/types/error_vellum_value_request.py,sha256=o0aSn34dRcpnAwAfwW_sgwP
270
270
  vellum/client/types/execute_api_request_bearer_token.py,sha256=agAhp9lzfzZcYGZdzg2jHAEHCaHlqzbgp6qeeNebcto,183
271
271
  vellum/client/types/execute_api_request_body.py,sha256=MArsO_-H41lU8Lz0dB78MVcFupjWtRV7UBEljY3Dnwk,169
272
272
  vellum/client/types/execute_api_request_headers_value.py,sha256=bHtGwOpknQDcQo6qtMKqJxaYpvbinDfwx2uaPzyuZ9s,184
273
- vellum/client/types/execute_api_response.py,sha256=QpUDx-A2tBELMLjxhcHwJyoNm-I0d8QfdCb5f1TAOEE,804
273
+ vellum/client/types/execute_api_response.py,sha256=1_wGY1eIF6Drwx5FEwnwBRLUxonXX7dOjhkvQakE-bw,842
274
274
  vellum/client/types/execute_prompt_event.py,sha256=wq_TZBDJcmXQhSj25jR9nMTnN-mP8Ku5Vq3rLqmwE5Q,521
275
275
  vellum/client/types/execute_prompt_response.py,sha256=n6ODveXcO8uWG-kr_B9wXziHH8JUaVTUcUAZKifClEo,334
276
276
  vellum/client/types/execute_workflow_response.py,sha256=0Q-NGPv5jpxjq6xNlHa3qUNK7yOmkU8h6Z2vQb6bHsU,1022
@@ -1351,28 +1351,30 @@ vellum/workflows/nodes/core/try_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW
1351
1351
  vellum/workflows/nodes/core/try_node/tests/test_node.py,sha256=Wc2kLl-MkffsBxl3IiFaqLd16e2Iosxhk7qBnojPvQg,4092
1352
1352
  vellum/workflows/nodes/displayable/__init__.py,sha256=6F_4DlSwvHuilWnIalp8iDjjDXl0Nmz4QzJV2PYe5RI,1023
1353
1353
  vellum/workflows/nodes/displayable/api_node/__init__.py,sha256=MoxdQSnidIj1Nf_d-hTxlOxcZXaZnsWFDbE-PkTK24o,56
1354
- vellum/workflows/nodes/displayable/api_node/node.py,sha256=KHuDTzOeXO3lCQm3lQqusAEhj84dhvszVpO1Xsx4qPM,2175
1354
+ vellum/workflows/nodes/displayable/api_node/node.py,sha256=QdpsyGVxo5PcN8nwGZpcpW_YMKHr3_VvmbK1BlrdOFk,2547
1355
+ vellum/workflows/nodes/displayable/api_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1356
+ vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py,sha256=yo3zTMRxgpSdWmJ68X610A5rrtCchyfqhcDd2X-GJiU,1249
1355
1357
  vellum/workflows/nodes/displayable/bases/__init__.py,sha256=0mWIx3qUrzllV7jqt7wN03vWGMuI1WrrLZeMLT2Cl2c,304
1356
1358
  vellum/workflows/nodes/displayable/bases/api_node/__init__.py,sha256=1jwx4WC358CLA1jgzl_UD-rZmdMm2v9Mps39ndwCD7U,64
1357
- vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=kKiwrz8XGJkvFjipBthxs9h1e2ndWPgmpEzZiYs0I5I,2579
1359
+ vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=nIFkP7eeXXSzOVUoQgjPPCzy3_P083X_F5fCm2OAjdU,3798
1358
1360
  vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
1359
1361
  vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=r_gOmeGFQQfzhAc1_bmzcwUvH-Xllc93gE7miTV4rQE,2824
1360
1362
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
1361
1363
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/constants.py,sha256=fnjiRWLoRlC4Puo5oQcpZD5Hd-EesxsAo9l5tGAkpZQ,270
1362
1364
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=UrmI8NkNJFGq9f59gD12S1e8D_R3ROHc934JmtfQk9I,6841
1363
- vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=tOhBHKBdGAIfZWr5HcQdA3JE7GXvYZ7-YyX2x0ptwJc,5339
1365
+ vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=NbwLOoWG5VVcnwL63WmaYck87y2QW36-JQWerOlKyx4,5713
1364
1366
  vellum/workflows/nodes/displayable/bases/search_node.py,sha256=3UtbqY3QO4kzfJHbmUNZGnEEfJmaoiF892u8H6TGjp8,5381
1365
1367
  vellum/workflows/nodes/displayable/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1366
1368
  vellum/workflows/nodes/displayable/bases/tests/test_utils.py,sha256=eqdqbKNRWVMDPevgwLg1i6YK0g4L4bCy-7xCBN5yYZI,3156
1367
1369
  vellum/workflows/nodes/displayable/bases/types.py,sha256=C37B2Qh2YP7s7pUjd-EYKc2Zl1TbnCgI_mENuUSb8bo,1706
1368
1370
  vellum/workflows/nodes/displayable/bases/utils.py,sha256=ckMUenSsNkiYmSw6FmjSMHYaCk8Y8_sUjL6lkFFEqts,5412
1369
1371
  vellum/workflows/nodes/displayable/code_execution_node/__init__.py,sha256=0FLWMMktpzSnmBMizQglBpcPrP80fzVsoJwJgf822Cg,76
1370
- vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=KZ5d3_mdpsrPF_ScmEqSfBhfup421RscO9hNiGa52T4,9068
1372
+ vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=wgtqPljUqan9SILMysPCdSmZ0HoCpTTTNNaW0y9nQQI,9082
1371
1373
  vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1372
1374
  vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1373
1375
  vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py,sha256=5QsbmkzSlSbcbWTG_JmIqcP-JNJzOPTKxGzdHos19W4,79
1374
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=ueVDw0GTSGzBZMFLs0NTir_0AE-pUrAYvpgg3Stex7Q,12350
1375
- vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=zRYM7B2t7355LzaAn6LkIn4tM5K7eQ0Kvje4NO6Kq30,3443
1376
+ vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=y_j4PieOpRYFmTqIEg1IPg-x-y_ezOcjcWCWPXYp1hI,14582
1377
+ vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=hF9tdCpta7WN1ANz467Q9LNlISOSmp79jDIkR5d2iQM,3542
1376
1378
  vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU1F9t8aLmbZU-rLh9ry6LCJ0uj0D8F0L5Uw,72
1377
1379
  vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=Qjfl33gZ3JEgxBA1EgzSUebboGvsARthIxxcQyvx5Gg,1152
1378
1380
  vellum/workflows/nodes/displayable/final_output_node/__init__.py,sha256=G7VXM4OWpubvSJtVkGmMNeqgb9GkM7qZT838eL18XU4,72
@@ -1390,15 +1392,15 @@ vellum/workflows/nodes/displayable/note_node/node.py,sha256=sIN1VBQ7zeT3GhN0kupX
1390
1392
  vellum/workflows/nodes/displayable/prompt_deployment_node/__init__.py,sha256=krX1Hds-TSVYZsx0wJFX4wsAKkEFYOX1ifwRGiIM-EA,82
1391
1393
  vellum/workflows/nodes/displayable/prompt_deployment_node/node.py,sha256=ruOgvpg_9KV_HkovPQeu6TKpur9DT_J4CYQo50tULCY,2680
1392
1394
  vellum/workflows/nodes/displayable/prompt_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1393
- vellum/workflows/nodes/displayable/prompt_deployment_node/tests/test_node.py,sha256=TO4wHNH1FASQxcM5-S8gMeC1k5HEISYcpzKy3cA0a6E,3772
1395
+ vellum/workflows/nodes/displayable/prompt_deployment_node/tests/test_node.py,sha256=ymEwMwrwRuQGyvkTnqeRZvfK7dhnf-kmRJTuwlycNjI,3939
1394
1396
  vellum/workflows/nodes/displayable/search_node/__init__.py,sha256=hpBpvbrDYf43DElRZFLzieSn8weXiwNiiNOJurERQbs,62
1395
1397
  vellum/workflows/nodes/displayable/search_node/node.py,sha256=_VHHuTNN4icZBgc7O5U9SVKrv1zgKipU72fOtxTyrQU,1453
1396
1398
  vellum/workflows/nodes/displayable/search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1397
1399
  vellum/workflows/nodes/displayable/search_node/tests/test_node.py,sha256=2-QCV7Vk_-YMls33p0GOUtCv3f2uPNZCjkB2CRjek7o,6562
1398
1400
  vellum/workflows/nodes/displayable/subworkflow_deployment_node/__init__.py,sha256=9yYM6001YZeqI1VOk1QuEM_yrffk_EdsO7qaPzINKds,92
1399
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=DAbSMN4GHBe-uTzJV-EcRfaRue113VrKl5m2SmA6Emc,7927
1401
+ vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=sSRo_zX5QVI7V0qmReWMBkEa78HfQfjNIKwvKh7-Om8,8307
1400
1402
  vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1401
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py,sha256=U5Y0WbceRbCtfgX759gIsbK2htg3eVdSe1mOiwdUbjw,5278
1403
+ vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py,sha256=c8RP-QnsERzIinVytAc0jVZ9nd7Jl3hbc9-_yG91Ros,5445
1402
1404
  vellum/workflows/nodes/displayable/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1403
1405
  vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py,sha256=CI7iMyyIlnds1rkVSjICOFg2UY0yV51NTKtKpfeEME4,4677
1404
1406
  vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py,sha256=VepO5z1277c1y5N6LLIC31nnWD1aak2m5oPFplfJHHs,6935
@@ -1462,8 +1464,8 @@ vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528
1462
1464
  vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
1463
1465
  vellum/workflows/workflows/base.py,sha256=uYT0TQnEDtVaH3pErq785FhxxEEmk7C5ZGfuSO3QK8c,18537
1464
1466
  vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1465
- vellum_ai-0.13.22.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1466
- vellum_ai-0.13.22.dist-info/METADATA,sha256=FKumzqZLqMjy0V1ohc4uZKBhxHBqQnoPPMXOR261yho,5335
1467
- vellum_ai-0.13.22.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1468
- vellum_ai-0.13.22.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1469
- vellum_ai-0.13.22.dist-info/RECORD,,
1467
+ vellum_ai-0.13.24.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1468
+ vellum_ai-0.13.24.dist-info/METADATA,sha256=6i1_pGA_JzLwbgGSvPKSioG96wTBmf5XnTrvtVKPcZM,5335
1469
+ vellum_ai-0.13.24.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1470
+ vellum_ai-0.13.24.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1471
+ vellum_ai-0.13.24.dist-info/RECORD,,
@@ -113,8 +113,8 @@ class WorkflowOutputVellumDisplayOverrides(WorkflowOutputDisplay, WorkflowOutput
113
113
  name: str
114
114
  label: str
115
115
  node_id: UUID
116
- target_handle_id: UUID
117
116
  display_data: NodeDisplayData
117
+ target_handle_id: Optional[UUID] = None
118
118
 
119
119
 
120
120
  @dataclass