vellum-ai 0.14.85__py3-none-any.whl → 0.14.86__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.
@@ -16,10 +16,10 @@ class BaseClientWrapper:
16
16
 
17
17
  def get_headers(self) -> typing.Dict[str, str]:
18
18
  headers: typing.Dict[str, str] = {
19
- "User-Agent": "vellum-ai/0.14.85",
19
+ "User-Agent": "vellum-ai/0.14.86",
20
20
  "X-Fern-Language": "Python",
21
21
  "X-Fern-SDK-Name": "vellum-ai",
22
- "X-Fern-SDK-Version": "0.14.85",
22
+ "X-Fern-SDK-Version": "0.14.86",
23
23
  }
24
24
  headers["X-API-KEY"] = self.api_key
25
25
  return headers
@@ -19,7 +19,7 @@ class ExecutionThinkingVellumValue(UniversalBaseModel):
19
19
 
20
20
  name: str
21
21
  type: typing.Literal["THINKING"] = "THINKING"
22
- value: StringVellumValue
22
+ value: typing.List[StringVellumValue]
23
23
 
24
24
  if IS_PYDANTIC_V2:
25
25
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -13,7 +13,7 @@ class ThinkingVellumValue(UniversalBaseModel):
13
13
  """
14
14
 
15
15
  type: typing.Literal["THINKING"] = "THINKING"
16
- value: StringVellumValue
16
+ value: typing.List[StringVellumValue]
17
17
 
18
18
  if IS_PYDANTIC_V2:
19
19
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -13,7 +13,7 @@ class ThinkingVellumValueRequest(UniversalBaseModel):
13
13
  """
14
14
 
15
15
  type: typing.Literal["THINKING"] = "THINKING"
16
- value: StringVellumValueRequest
16
+ value: typing.List[StringVellumValueRequest]
17
17
 
18
18
  if IS_PYDANTIC_V2:
19
19
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -64,8 +64,9 @@ class InlinePromptNode(BaseInlinePromptNode[StateType]):
64
64
  elif output.type == "FUNCTION_CALL":
65
65
  string_outputs.append(output.value.model_dump_json(indent=4))
66
66
  elif output.type == "THINKING":
67
- if output.value.type == "STRING":
68
- string_outputs.append(output.value.value)
67
+ for thinking_item in output.value:
68
+ if thinking_item.type == "STRING":
69
+ string_outputs.append(thinking_item.value)
69
70
  else:
70
71
  string_outputs.append(output.value.message)
71
72
 
@@ -66,8 +66,9 @@ class PromptDeploymentNode(BasePromptDeploymentNode[StateType]):
66
66
  elif output.type == "FUNCTION_CALL":
67
67
  string_outputs.append(output.value.model_dump_json(indent=4))
68
68
  elif output.type == "THINKING":
69
- if output.value.type == "STRING":
70
- string_outputs.append(output.value.value)
69
+ for thinking_item in output.value:
70
+ if thinking_item.type == "STRING":
71
+ string_outputs.append(thinking_item.value)
71
72
  else:
72
73
  string_outputs.append(output.value.message)
73
74
 
@@ -2,6 +2,7 @@ from datetime import datetime
2
2
  from functools import lru_cache
3
3
  import importlib
4
4
  import inspect
5
+ import logging
5
6
  from threading import Event as ThreadingEvent
6
7
  from uuid import UUID, uuid4
7
8
  from typing import (
@@ -76,6 +77,8 @@ from vellum.workflows.types.utils import get_original_base
76
77
  from vellum.workflows.utils.uuids import uuid4_from_hash
77
78
  from vellum.workflows.workflows.event_filters import workflow_event_filter
78
79
 
80
+ logger = logging.getLogger(__name__)
81
+
79
82
 
80
83
  class _BaseWorkflowMeta(type):
81
84
  def __new__(mcs, name: str, bases: Tuple[Type, ...], dct: Dict[str, Any]) -> Any:
@@ -123,13 +126,70 @@ class _BaseWorkflowMeta(type):
123
126
  raise TypeError(f"Unexpected graph type: {graph_item.__class__}")
124
127
  return nodes
125
128
 
129
+ def filter_overlapping_nodes_from_unused_graphs(
130
+ unused_graphs: Set[GraphAttribute], overlapping_nodes: Set[Type[BaseNode]]
131
+ ) -> Set[GraphAttribute]:
132
+ filtered_graphs: Set[GraphAttribute] = set()
133
+
134
+ for item in unused_graphs:
135
+ if isinstance(item, Graph):
136
+ graph_nodes = set(item.nodes)
137
+ overlapping_in_graph = graph_nodes & overlapping_nodes
138
+
139
+ if not overlapping_in_graph:
140
+ filtered_graphs.add(item)
141
+ else:
142
+ non_overlapping_nodes = graph_nodes - overlapping_nodes
143
+ for node in non_overlapping_nodes:
144
+ filtered_graphs.add(node)
145
+
146
+ elif isinstance(item, set):
147
+ filtered_nodes: Set[Type[BaseNode]] = set()
148
+ filtered_graphs_in_set: Set[Graph] = set()
149
+
150
+ for subitem in item:
151
+ if isinstance(subitem, Graph):
152
+ graph_nodes = set(subitem.nodes)
153
+ overlapping_in_graph = graph_nodes & overlapping_nodes
154
+
155
+ if not overlapping_in_graph:
156
+ filtered_graphs_in_set.add(subitem)
157
+ else:
158
+ non_overlapping_nodes = graph_nodes - overlapping_nodes
159
+ filtered_nodes.update(non_overlapping_nodes)
160
+ elif isinstance(subitem, type) and issubclass(subitem, BaseNode):
161
+ if subitem not in overlapping_nodes:
162
+ filtered_nodes.add(subitem)
163
+ else:
164
+ raise TypeError(f"Unexpected item type in unused_graphs set: {subitem.__class__}")
165
+
166
+ # Add non-empty sets back to filtered_graphs
167
+ if filtered_nodes:
168
+ filtered_graphs.add(filtered_nodes)
169
+ if filtered_graphs_in_set:
170
+ filtered_graphs.add(filtered_graphs_in_set)
171
+
172
+ elif isinstance(item, type) and issubclass(item, BaseNode):
173
+ if item not in overlapping_nodes:
174
+ filtered_graphs.add(item)
175
+ else:
176
+ filtered_graphs.add(item)
177
+
178
+ return filtered_graphs
179
+
126
180
  graph_nodes = collect_nodes(dct.get("graph", set()))
127
181
  unused_nodes = collect_nodes(dct.get("unused_graphs", set()))
128
182
 
129
183
  overlap = graph_nodes & unused_nodes
130
184
  if overlap:
131
185
  node_names = [node.__name__ for node in overlap]
132
- raise ValueError(f"Node(s) {', '.join(node_names)} cannot appear in both graph and unused_graphs")
186
+ logger.warning(
187
+ f"Node(s) {', '.join(node_names)} appear in both graph and unused_graphs. Removing from unused_graphs."
188
+ )
189
+
190
+ # Filter out overlapping nodes from unused_graphs
191
+ if "unused_graphs" in dct:
192
+ dct["unused_graphs"] = filter_overlapping_nodes_from_unused_graphs(dct["unused_graphs"], overlap)
133
193
 
134
194
  cls = super().__new__(mcs, name, bases, dct)
135
195
  workflow_class = cast(Type["BaseWorkflow"], cls)
@@ -1,4 +1,5 @@
1
1
  import pytest
2
+ import logging
2
3
  from uuid import UUID, uuid4
3
4
 
4
5
  from vellum.workflows.edges.edge import Edge
@@ -79,7 +80,6 @@ def test_subworkflow__inherit_base_outputs():
79
80
 
80
81
  # TEST that the Outputs classes do not inherit from object
81
82
  assert object not in MainWorkflow.Outputs.__bases__
82
- assert object not in SubWorkflow.Outputs.__bases__
83
83
 
84
84
  # TEST execution
85
85
  workflow = MainWorkflow()
@@ -295,7 +295,7 @@ def test_workflow__no_unused_edges():
295
295
  assert edges == set()
296
296
 
297
297
 
298
- def test_workflow__node_in_both_graph_and_unused():
298
+ def test_workflow__node_in_both_graph_and_unused(caplog):
299
299
  class NodeA(BaseNode):
300
300
  pass
301
301
 
@@ -305,15 +305,28 @@ def test_workflow__node_in_both_graph_and_unused():
305
305
  class NodeC(BaseNode):
306
306
  pass
307
307
 
308
- # WHEN we try to create a workflow where NodeA appears in both graph and unused
309
- with pytest.raises(ValueError) as exc_info:
308
+ # WHEN we create a workflow where NodeA appears in both graph and unused
309
+ with caplog.at_level(logging.WARNING):
310
310
 
311
311
  class TestWorkflow(BaseWorkflow[BaseInputs, BaseState]):
312
312
  graph = NodeA >> NodeB
313
313
  unused_graphs = {NodeA >> NodeC}
314
314
 
315
- # THEN it should raise an error
316
- assert "Node(s) NodeA cannot appear in both graph and unused_graphs" in str(exc_info.value)
315
+ # THEN it should log a warning
316
+ assert len(caplog.records) == 1
317
+ assert caplog.records[0].levelname == "WARNING"
318
+ assert (
319
+ "Node(s) NodeA appear in both graph and unused_graphs. Removing from unused_graphs."
320
+ in caplog.records[0].message
321
+ )
322
+
323
+ # AND the workflow should be created successfully
324
+ assert TestWorkflow is not None
325
+
326
+ # AND NodeA should be removed from unused_graphs while NodeC remains
327
+ unused_nodes = set(TestWorkflow.get_unused_nodes())
328
+ assert NodeA not in unused_nodes
329
+ assert NodeC in unused_nodes
317
330
 
318
331
 
319
332
  def test_workflow__unsupported_graph_item():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.85
3
+ Version: 0.14.86
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -144,7 +144,7 @@ vellum/client/README.md,sha256=47bNYmRLSISR1ING58kXXZ88nFLPGFv0bAspBtuXG3g,4306
144
144
  vellum/client/__init__.py,sha256=tKLc-F8I8_62RSZg7J7Lvo1dUQ_or7DGsDhbMyhWfGA,120958
145
145
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
146
146
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
147
- vellum/client/core/client_wrapper.py,sha256=X9SbAOmZu48N8-Sgi-VoDoEM3tro2SNf1grdzvosVww,1916
147
+ vellum/client/core/client_wrapper.py,sha256=K_siMZE7rIopQdqNiIxKekgGPV2iWv2OagS8NwMBP_8,1916
148
148
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
149
149
  vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
150
150
  vellum/client/core/http_client.py,sha256=cKs2w0ybDBk1wHQf-fTALm_MmvaMe3cZKcYJxqmCxkE,19539
@@ -330,7 +330,7 @@ vellum/client/types/execution_json_vellum_value.py,sha256=oGY3CsJBKeOuEexmITfRYc
330
330
  vellum/client/types/execution_number_vellum_value.py,sha256=b2TpqyafRHCdl6EhgctNgUSLU-JBdouU6OgM8Jk_O78,809
331
331
  vellum/client/types/execution_search_results_vellum_value.py,sha256=HkxoXaUF6pMbfXd5wLk5VKmcXed2IRfEzkxsoGpwmg0,898
332
332
  vellum/client/types/execution_string_vellum_value.py,sha256=4w0ottwB5F2NL3uEXBBggP7XkcdE_D2lGmEobkXWY7o,807
333
- vellum/client/types/execution_thinking_vellum_value.py,sha256=5WGuCVue3OMAdM881fDUFGjwOuWhImT6ALQq1qHyTks,866
333
+ vellum/client/types/execution_thinking_vellum_value.py,sha256=n66gPYgiDpOGhOniQlRE6jDUOBnPkHnfOvz8RVyzw1g,879
334
334
  vellum/client/types/execution_vellum_value.py,sha256=gJ4UWA4KKzWGJZpEZGQV8Efqh27PmyWz6RZSsbtNux8,1088
335
335
  vellum/client/types/external_input_descriptor.py,sha256=ErOW2OfFMz1FDGmVY6NgiUBPsleaWhdJBekwFp4ru7o,805
336
336
  vellum/client/types/external_test_case_execution.py,sha256=TkO1CQcEI8LA7sdYJfAqhbdkj27sXEkF8VL7zBeDBM4,877
@@ -699,8 +699,8 @@ vellum/client/types/test_suite_test_case_replace_bulk_operation_request.py,sha25
699
699
  vellum/client/types/test_suite_test_case_replaced_bulk_result.py,sha256=BIlXI7udygWrwtyRhCl8hmExHbkAl9lI8s3sm1G5iGc,1019
700
700
  vellum/client/types/test_suite_test_case_replaced_bulk_result_data.py,sha256=ORmcUvwzvRLRaoFhxdXFIKzPxOI6PU1kESl0R6rsJuw,651
701
701
  vellum/client/types/test_suite_test_case_upsert_bulk_operation_request.py,sha256=PrKuqePiXBQv6iLAxsk4xQg29KGdOlqMDhIVdGNxuz4,1071
702
- vellum/client/types/thinking_vellum_value.py,sha256=q6IZFZrAXkoYCQOfHLLKWCTYj_zW8HJIzovO6IlzY-A,742
703
- vellum/client/types/thinking_vellum_value_request.py,sha256=dHxjlH_6nxRjcixAudmvwwOMkWc4JmLHfRWKK4rGssA,771
702
+ vellum/client/types/thinking_vellum_value.py,sha256=XLeSzCwbO9kVek6zdMn6pQChLKDYFeyabE9OiFeoq_I,755
703
+ vellum/client/types/thinking_vellum_value_request.py,sha256=n6FqEZs5TKhhNZqe9yau_Vcn55ktXxFQO5sWa0aRNbg,784
704
704
  vellum/client/types/token_overlapping_window_chunker_config.py,sha256=_8vR9AiZQmb5OA3OojbjuTOGiGNTS9EY0vXrmej_TM0,731
705
705
  vellum/client/types/token_overlapping_window_chunker_config_request.py,sha256=O58w5om6EsCgZeqM7n3KSzwo1PqINyHWln46EFW4Inc,738
706
706
  vellum/client/types/token_overlapping_window_chunking.py,sha256=TghiPKWZg3Eg_UzGI9VmjQgVPZFABrnhfsz4iPLEem8,889
@@ -1654,7 +1654,7 @@ vellum/workflows/nodes/displayable/guardrail_node/test_node.py,sha256=SAGv6hSFcB
1654
1654
  vellum/workflows/nodes/displayable/guardrail_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1655
1655
  vellum/workflows/nodes/displayable/guardrail_node/tests/test_node.py,sha256=X2pd6TI8miYxIa7rgvs1pHTEreyWcf77EyR0_Jsa700,2055
1656
1656
  vellum/workflows/nodes/displayable/inline_prompt_node/__init__.py,sha256=gSUOoEZLlrx35-tQhSAd3An8WDwBqyiQh-sIebLU9wU,74
1657
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py,sha256=LkFaS7GDPdhqMjQ3duHPX6pjl0z6xKzGxDueQC4aeA0,2999
1657
+ vellum/workflows/nodes/displayable/inline_prompt_node/node.py,sha256=pj1tjx3XfiGQz9a6x3xsK1DR7v1XeVHM93AKVi-GgRQ,3060
1658
1658
  vellum/workflows/nodes/displayable/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1659
1659
  vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py,sha256=bBHs90mV5SZ3rJPAL0wx4WWyawUA406LgMPOdvpZC_A,10923
1660
1660
  vellum/workflows/nodes/displayable/merge_node/__init__.py,sha256=J8IC08dSH7P76wKlNuxe1sn7toNGtSQdFirUbtPDEs0,60
@@ -1662,7 +1662,7 @@ vellum/workflows/nodes/displayable/merge_node/node.py,sha256=nZtGGVAvY4fvGg8vwV6
1662
1662
  vellum/workflows/nodes/displayable/note_node/__init__.py,sha256=KWA3P4fyYJ-fOTky8qNGlcOotQ-HeHJ9AjZt6mRQmCE,58
1663
1663
  vellum/workflows/nodes/displayable/note_node/node.py,sha256=sIN1VBQ7zeT3GhN0kupXbFfdpvgedWV79k4woJNp5IQ,394
1664
1664
  vellum/workflows/nodes/displayable/prompt_deployment_node/__init__.py,sha256=krX1Hds-TSVYZsx0wJFX4wsAKkEFYOX1ifwRGiIM-EA,82
1665
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py,sha256=rRUIM-zbVCV_0odyPExEZay0k4VCjsYyZ3OC9ZpHQsc,3399
1665
+ vellum/workflows/nodes/displayable/prompt_deployment_node/node.py,sha256=d71QJmtozr06z9tX_7IZHnDUFBGg05YmQ7USu1XEs0M,3460
1666
1666
  vellum/workflows/nodes/displayable/prompt_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1667
1667
  vellum/workflows/nodes/displayable/prompt_deployment_node/tests/test_node.py,sha256=c_nuuqrwiIjgj4qIbVypfDuOc-3TlgO6CbXFqQl2Nqw,19725
1668
1668
  vellum/workflows/nodes/displayable/search_node/__init__.py,sha256=hpBpvbrDYf43DElRZFLzieSn8weXiwNiiNOJurERQbs,62
@@ -1753,13 +1753,13 @@ vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrg
1753
1753
  vellum/workflows/utils/vellum_variables.py,sha256=zVzZSRWKV64fmu9MaoEVebW9r8UsXPvRPMvOuBmwI24,5307
1754
1754
  vellum/workflows/vellum_client.py,sha256=xkfoucodxNK5JR2-lbRqZx3xzDgExWkP6kySrpi_Ubc,1079
1755
1755
  vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
1756
- vellum/workflows/workflows/base.py,sha256=ehJSHDf1vuNjJtKryqKgb5HKGtx_D-wWUiJNBWZ50JU,24347
1756
+ vellum/workflows/workflows/base.py,sha256=DIQP5b4B5z3h0Bp1_IPdhpFAyBZxn_2owjFxnCEMBYA,27090
1757
1757
  vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1758
1758
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1759
- vellum/workflows/workflows/tests/test_base_workflow.py,sha256=fROqff6AZpCIzaSwOKSdtYy4XR0UZQ6ejxL3RJOSJVs,20447
1759
+ vellum/workflows/workflows/tests/test_base_workflow.py,sha256=ptMntHzVyy8ZuzNgeTuk7hREgKQ5UBdgq8VJFSGaW4Y,20832
1760
1760
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1761
- vellum_ai-0.14.85.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1762
- vellum_ai-0.14.85.dist-info/METADATA,sha256=YJsUjCnTdDuvxb-FOhV6litvxWf_owaPkWBUv8RXjq4,5556
1763
- vellum_ai-0.14.85.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1764
- vellum_ai-0.14.85.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1765
- vellum_ai-0.14.85.dist-info/RECORD,,
1761
+ vellum_ai-0.14.86.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1762
+ vellum_ai-0.14.86.dist-info/METADATA,sha256=IvjzAyM7NKtDy7yBw7058E6f13UfiQ02VV0rR87ts3o,5556
1763
+ vellum_ai-0.14.86.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1764
+ vellum_ai-0.14.86.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1765
+ vellum_ai-0.14.86.dist-info/RECORD,,