vellum-ai 0.12.11__py3-none-any.whl → 0.12.13__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- vellum/client/core/client_wrapper.py +1 -1
- vellum/workflows/exceptions.py +1 -1
- vellum/workflows/runner/runner.py +10 -3
- vellum/workflows/workflows/base.py +41 -1
- {vellum_ai-0.12.11.dist-info → vellum_ai-0.12.13.dist-info}/METADATA +1 -1
- {vellum_ai-0.12.11.dist-info → vellum_ai-0.12.13.dist-info}/RECORD +9 -9
- {vellum_ai-0.12.11.dist-info → vellum_ai-0.12.13.dist-info}/LICENSE +0 -0
- {vellum_ai-0.12.11.dist-info → vellum_ai-0.12.13.dist-info}/WHEEL +0 -0
- {vellum_ai-0.12.11.dist-info → vellum_ai-0.12.13.dist-info}/entry_points.txt +0 -0
@@ -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.12.
|
21
|
+
"X-Fern-SDK-Version": "0.12.13",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
vellum/workflows/exceptions.py
CHANGED
@@ -2,7 +2,7 @@ from vellum.workflows.errors import WorkflowError, WorkflowErrorCode
|
|
2
2
|
|
3
3
|
|
4
4
|
class NodeException(Exception):
|
5
|
-
def __init__(self, message: str, code: WorkflowErrorCode):
|
5
|
+
def __init__(self, message: str, code: WorkflowErrorCode = WorkflowErrorCode.INTERNAL_ERROR):
|
6
6
|
self.message = message
|
7
7
|
self.code = code
|
8
8
|
super().__init__(message)
|
@@ -4,7 +4,7 @@ import logging
|
|
4
4
|
from queue import Empty, Queue
|
5
5
|
from threading import Event as ThreadingEvent, Thread
|
6
6
|
from uuid import UUID
|
7
|
-
from typing import TYPE_CHECKING, Any, Dict, Generic, Iterable, Iterator, Optional, Sequence, Set, Type, Union
|
7
|
+
from typing import TYPE_CHECKING, Any, Dict, Generic, Iterable, Iterator, List, Optional, Sequence, Set, Type, Union
|
8
8
|
|
9
9
|
from vellum.workflows.constants import UNDEF
|
10
10
|
from vellum.workflows.context import execution_context, get_parent_context
|
@@ -72,6 +72,7 @@ class WorkflowRunner(Generic[StateType]):
|
|
72
72
|
entrypoint_nodes: Optional[RunFromNodeArg] = None,
|
73
73
|
external_inputs: Optional[ExternalInputsArg] = None,
|
74
74
|
cancel_signal: Optional[ThreadingEvent] = None,
|
75
|
+
node_output_mocks: Optional[List[BaseOutputs]] = None,
|
75
76
|
parent_context: Optional[ParentContext] = None,
|
76
77
|
):
|
77
78
|
if state and external_inputs:
|
@@ -123,6 +124,9 @@ class WorkflowRunner(Generic[StateType]):
|
|
123
124
|
|
124
125
|
self._dependencies: Dict[Type[BaseNode], Set[Type[BaseNode]]] = defaultdict(set)
|
125
126
|
self._state_forks: Set[StateType] = {self._initial_state}
|
127
|
+
self._mocks_by_node_outputs_class = (
|
128
|
+
{mock.__class__: mock for mock in node_output_mocks} if node_output_mocks else {}
|
129
|
+
)
|
126
130
|
|
127
131
|
self._active_nodes_by_execution_id: Dict[UUID, BaseNode[StateType]] = {}
|
128
132
|
self._cancel_signal = cancel_signal
|
@@ -178,8 +182,11 @@ class WorkflowRunner(Generic[StateType]):
|
|
178
182
|
node_definition=node.__class__,
|
179
183
|
parent=parent_context,
|
180
184
|
)
|
181
|
-
|
182
|
-
|
185
|
+
if node.Outputs not in self._mocks_by_node_outputs_class:
|
186
|
+
with execution_context(parent_context=updated_parent_context):
|
187
|
+
node_run_response = node.run()
|
188
|
+
else:
|
189
|
+
node_run_response = self._mocks_by_node_outputs_class[node.Outputs]
|
183
190
|
ports = node.Ports()
|
184
191
|
if not isinstance(node_run_response, (BaseOutputs, Iterator)):
|
185
192
|
raise NodeException(
|
@@ -194,6 +194,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
194
194
|
entrypoint_nodes: Optional[RunFromNodeArg] = None,
|
195
195
|
external_inputs: Optional[ExternalInputsArg] = None,
|
196
196
|
cancel_signal: Optional[ThreadingEvent] = None,
|
197
|
+
node_output_mocks: Optional[List[BaseOutputs]] = None,
|
197
198
|
) -> TerminalWorkflowEvent:
|
198
199
|
"""
|
199
200
|
Invoke a Workflow, returning the last event emitted, which should be one of:
|
@@ -218,6 +219,9 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
218
219
|
|
219
220
|
cancel_signal: Optional[ThreadingEvent] = None
|
220
221
|
A threading event that can be used to cancel the Workflow Execution.
|
222
|
+
|
223
|
+
node_output_mocks: Optional[List[Outputs]] = None
|
224
|
+
A list of Outputs to mock for Nodes during Workflow Execution.
|
221
225
|
"""
|
222
226
|
|
223
227
|
events = WorkflowRunner(
|
@@ -227,6 +231,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
227
231
|
entrypoint_nodes=entrypoint_nodes,
|
228
232
|
external_inputs=external_inputs,
|
229
233
|
cancel_signal=cancel_signal,
|
234
|
+
node_output_mocks=node_output_mocks,
|
230
235
|
parent_context=self._context.parent_context,
|
231
236
|
).stream()
|
232
237
|
first_event: Optional[Union[WorkflowExecutionInitiatedEvent, WorkflowExecutionResumedEvent]] = None
|
@@ -290,6 +295,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
290
295
|
entrypoint_nodes: Optional[RunFromNodeArg] = None,
|
291
296
|
external_inputs: Optional[ExternalInputsArg] = None,
|
292
297
|
cancel_signal: Optional[ThreadingEvent] = None,
|
298
|
+
node_output_mocks: Optional[List[BaseOutputs]] = None,
|
293
299
|
) -> WorkflowEventStream:
|
294
300
|
"""
|
295
301
|
Invoke a Workflow, yielding events as they are emitted.
|
@@ -315,6 +321,9 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
315
321
|
|
316
322
|
cancel_signal: Optional[ThreadingEvent] = None
|
317
323
|
A threading event that can be used to cancel the Workflow Execution.
|
324
|
+
|
325
|
+
node_output_mocks: Optional[List[Outputs]] = None
|
326
|
+
A list of Outputs to mock for Nodes during Workflow Execution.
|
318
327
|
"""
|
319
328
|
|
320
329
|
should_yield = event_filter or workflow_event_filter
|
@@ -325,6 +334,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
325
334
|
entrypoint_nodes=entrypoint_nodes,
|
326
335
|
external_inputs=external_inputs,
|
327
336
|
cancel_signal=cancel_signal,
|
337
|
+
node_output_mocks=node_output_mocks,
|
328
338
|
parent_context=self.context.parent_context,
|
329
339
|
).stream():
|
330
340
|
if should_yield(self.__class__, event):
|
@@ -416,7 +426,6 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
416
426
|
def load_from_module(module_path: str) -> Type["BaseWorkflow"]:
|
417
427
|
workflow_path = f"{module_path}.workflow"
|
418
428
|
module = importlib.import_module(workflow_path)
|
419
|
-
|
420
429
|
workflows: List[Type[BaseWorkflow]] = []
|
421
430
|
for name in dir(module):
|
422
431
|
if name.startswith("__"):
|
@@ -435,9 +444,40 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
435
444
|
raise ValueError(f"No workflows found in {module_path}")
|
436
445
|
elif len(workflows) > 1:
|
437
446
|
raise ValueError(f"Multiple workflows found in {module_path}")
|
447
|
+
try:
|
448
|
+
BaseWorkflow.import_node_display(module_path)
|
449
|
+
except ModuleNotFoundError:
|
450
|
+
pass
|
438
451
|
|
439
452
|
return workflows[0]
|
440
453
|
|
454
|
+
@staticmethod
|
455
|
+
def import_node_display(module_path):
|
456
|
+
# Import the nodes package
|
457
|
+
nodes_package = importlib.import_module(f"{module_path}.display.nodes")
|
458
|
+
# Use the loader to get the code
|
459
|
+
if hasattr(nodes_package, "__spec__") and nodes_package.__spec__ and nodes_package.__spec__.loader:
|
460
|
+
loader = nodes_package.__spec__.loader
|
461
|
+
|
462
|
+
# Check if the loader has a code attribute
|
463
|
+
if hasattr(loader, "code"):
|
464
|
+
code = loader.code
|
465
|
+
|
466
|
+
# Parse the code to find import statements
|
467
|
+
import_lines = [line.strip() for line in code.splitlines() if line.startswith("from ")]
|
468
|
+
|
469
|
+
# Import each module specified in the code
|
470
|
+
for line in import_lines:
|
471
|
+
try:
|
472
|
+
# Extract module name from the import line
|
473
|
+
module_name = line.split(" ")[1]
|
474
|
+
full_module_path = f"{module_path}.display.nodes{module_name}"
|
475
|
+
importlib.import_module(full_module_path)
|
476
|
+
except Exception:
|
477
|
+
continue
|
478
|
+
# Also import from workflow.py
|
479
|
+
importlib.import_module(f"{module_path}.display.workflow")
|
480
|
+
|
441
481
|
|
442
482
|
WorkflowExecutionInitiatedBody.model_rebuild()
|
443
483
|
WorkflowExecutionFulfilledBody.model_rebuild()
|
@@ -77,7 +77,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
|
|
77
77
|
vellum/client/__init__.py,sha256=z59nOGe27vMDqsU-ljfULBwC5J4nyrqFunhmo8xnxbU,111521
|
78
78
|
vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
|
79
79
|
vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
|
80
|
-
vellum/client/core/client_wrapper.py,sha256=
|
80
|
+
vellum/client/core/client_wrapper.py,sha256=vjueLRJ8AxJ_TUVQkuXwAW-kVfBfyveLY3BAgl-dZqE,1869
|
81
81
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
82
82
|
vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
|
83
83
|
vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
|
@@ -1234,7 +1234,7 @@ vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
1234
1234
|
vellum/workflows/events/tests/test_event.py,sha256=izB6Y9U5ROgmHBBpLNUY2navK4-qFp6hdJqJNz6Beek,13350
|
1235
1235
|
vellum/workflows/events/types.py,sha256=cjRE8WL8tYCFradd9NOGl_H0mN3LiWWnA1uHmyT2Q0Q,3412
|
1236
1236
|
vellum/workflows/events/workflow.py,sha256=l5tXes0sg7iWaA1ZUE5dtAqNnGQ8iy6trVbOU9meu7U,5240
|
1237
|
-
vellum/workflows/exceptions.py,sha256=
|
1237
|
+
vellum/workflows/exceptions.py,sha256=l-FLGvXywxg6ivolCts71b8pcsYAWoB1cmUR4Jx7N8g,614
|
1238
1238
|
vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1239
1239
|
vellum/workflows/expressions/accessor.py,sha256=OFvAHAVABr-k7GceIhtzIurV4OuV_yHft7JPRsq87Es,1472
|
1240
1240
|
vellum/workflows/expressions/and_.py,sha256=I7lNqrUM3-m_5hmjjiMhaHhJtKcLj39kEFVWPDOqwfo,916
|
@@ -1367,7 +1367,7 @@ vellum/workflows/references/workflow_input.py,sha256=86IuhlBz-9cGxeUzizyjdp482aj
|
|
1367
1367
|
vellum/workflows/resolvers/__init__.py,sha256=eH6hTvZO4IciDaf_cf7aM2vs-DkBDyJPycOQevJxQnI,82
|
1368
1368
|
vellum/workflows/resolvers/base.py,sha256=WHra9LRtlTuB1jmuNqkfVE2JUgB61Cyntn8f0b0WZg4,411
|
1369
1369
|
vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
|
1370
|
-
vellum/workflows/runner/runner.py,sha256=
|
1370
|
+
vellum/workflows/runner/runner.py,sha256=DuFvMyejwdIdapQDHrfVtouaifLEZ02WYPARmK3UqdE,28006
|
1371
1371
|
vellum/workflows/sandbox.py,sha256=GVJzVjMuYzOBnSrboB0_6MMRZWBluAyQ2o7syeaeBd0,2235
|
1372
1372
|
vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
|
1373
1373
|
vellum/workflows/state/base.py,sha256=jpSzF1OQd3-fqi6dMGlNsQl-7JnJxCdzWIigmX8Wz-I,14425
|
@@ -1397,10 +1397,10 @@ vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrg
|
|
1397
1397
|
vellum/workflows/utils/vellum_variables.py,sha256=g5xHYB8etfHE32ek19nP6Anf8NyjhmUtOwO2KmQ5xZU,3111
|
1398
1398
|
vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528t75s,683
|
1399
1399
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
1400
|
-
vellum/workflows/workflows/base.py,sha256=
|
1400
|
+
vellum/workflows/workflows/base.py,sha256=TLk5NiDB8N_Ytkzj_T8o-E4WpTUH8qJYZcoOk2xR3mo,18986
|
1401
1401
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
1402
|
-
vellum_ai-0.12.
|
1403
|
-
vellum_ai-0.12.
|
1404
|
-
vellum_ai-0.12.
|
1405
|
-
vellum_ai-0.12.
|
1406
|
-
vellum_ai-0.12.
|
1402
|
+
vellum_ai-0.12.13.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1403
|
+
vellum_ai-0.12.13.dist-info/METADATA,sha256=uXAzy9xHbkmecOGR1GasDk6auS-Hbl12VwdAgqAuo5c,5161
|
1404
|
+
vellum_ai-0.12.13.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1405
|
+
vellum_ai-0.12.13.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1406
|
+
vellum_ai-0.12.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|