vellum-ai 1.8.1__py3-none-any.whl → 1.8.3__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.
- vellum/client/core/client_wrapper.py +2 -2
- vellum/client/types/integration_name.py +1 -0
- vellum/workflows/expressions/concat.py +6 -3
- vellum/workflows/expressions/tests/test_concat.py +63 -8
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +20 -5
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +11 -7
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +42 -0
- vellum/workflows/nodes/displayable/final_output_node/node.py +7 -1
- vellum/workflows/nodes/displayable/final_output_node/tests/test_node.py +28 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +84 -56
- vellum/workflows/nodes/experimental/__init__.py +1 -3
- vellum/workflows/runner/runner.py +144 -0
- vellum/workflows/state/context.py +59 -7
- vellum/workflows/workflows/base.py +17 -0
- vellum/workflows/workflows/event_filters.py +13 -0
- vellum/workflows/workflows/tests/test_event_filters.py +126 -0
- {vellum_ai-1.8.1.dist-info → vellum_ai-1.8.3.dist-info}/METADATA +1 -1
- {vellum_ai-1.8.1.dist-info → vellum_ai-1.8.3.dist-info}/RECORD +23 -23
- vellum_ee/workflows/display/utils/expressions.py +4 -0
- vellum_ee/workflows/display/utils/tests/test_expressions.py +86 -0
- vellum/workflows/nodes/experimental/openai_chat_completion_node/__init__.py +0 -5
- vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py +0 -266
- {vellum_ai-1.8.1.dist-info → vellum_ai-1.8.3.dist-info}/LICENSE +0 -0
- {vellum_ai-1.8.1.dist-info → vellum_ai-1.8.3.dist-info}/WHEEL +0 -0
- {vellum_ai-1.8.1.dist-info → vellum_ai-1.8.3.dist-info}/entry_points.txt +0 -0
|
@@ -74,6 +74,9 @@ from vellum.workflows.references import ExternalInputReference, OutputReference
|
|
|
74
74
|
from vellum.workflows.references.state_value import StateValueReference
|
|
75
75
|
from vellum.workflows.state.base import BaseState
|
|
76
76
|
from vellum.workflows.state.delta import StateDelta
|
|
77
|
+
from vellum.workflows.triggers.base import BaseTrigger
|
|
78
|
+
from vellum.workflows.triggers.integration import IntegrationTrigger
|
|
79
|
+
from vellum.workflows.triggers.manual import ManualTrigger
|
|
77
80
|
from vellum.workflows.types.core import CancelSignal
|
|
78
81
|
from vellum.workflows.types.generics import InputsType, OutputsType, StateType
|
|
79
82
|
|
|
@@ -109,6 +112,7 @@ class WorkflowRunner(Generic[StateType]):
|
|
|
109
112
|
max_concurrency: Optional[int] = None,
|
|
110
113
|
timeout: Optional[float] = None,
|
|
111
114
|
init_execution_context: Optional[ExecutionContext] = None,
|
|
115
|
+
trigger: Optional[BaseTrigger] = None,
|
|
112
116
|
):
|
|
113
117
|
if state and external_inputs:
|
|
114
118
|
raise ValueError("Can only run a Workflow providing one of state or external inputs, not both")
|
|
@@ -198,7 +202,24 @@ class WorkflowRunner(Generic[StateType]):
|
|
|
198
202
|
)
|
|
199
203
|
|
|
200
204
|
self._entrypoints = self.workflow.get_entrypoints()
|
|
205
|
+
elif trigger:
|
|
206
|
+
# When trigger is provided, set up default state and filter entrypoints by trigger type
|
|
207
|
+
normalized_inputs = deepcopy(inputs) if inputs else self.workflow.get_default_inputs()
|
|
208
|
+
if state:
|
|
209
|
+
self._initial_state = deepcopy(state)
|
|
210
|
+
self._initial_state.meta.workflow_inputs = normalized_inputs
|
|
211
|
+
self._initial_state.meta.span_id = uuid4()
|
|
212
|
+
self._initial_state.meta.workflow_definition = self.workflow.__class__
|
|
213
|
+
else:
|
|
214
|
+
self._initial_state = self.workflow.get_default_state(normalized_inputs)
|
|
215
|
+
self._should_emit_initial_state = False
|
|
216
|
+
|
|
217
|
+
# Validate and bind trigger, then filter entrypoints
|
|
218
|
+
self._validate_and_bind_trigger(trigger)
|
|
219
|
+
self._entrypoints = self.workflow.get_entrypoints()
|
|
220
|
+
self._filter_entrypoints_for_trigger(trigger)
|
|
201
221
|
else:
|
|
222
|
+
# Default case: no entrypoint overrides and no trigger
|
|
202
223
|
normalized_inputs = deepcopy(inputs) if inputs else self.workflow.get_default_inputs()
|
|
203
224
|
if state:
|
|
204
225
|
self._initial_state = deepcopy(state)
|
|
@@ -213,6 +234,9 @@ class WorkflowRunner(Generic[StateType]):
|
|
|
213
234
|
self._should_emit_initial_state = False
|
|
214
235
|
self._entrypoints = self.workflow.get_entrypoints()
|
|
215
236
|
|
|
237
|
+
# Check if workflow requires a trigger but none was provided
|
|
238
|
+
self._validate_no_trigger_provided()
|
|
239
|
+
|
|
216
240
|
# This queue is responsible for sending events from WorkflowRunner to the outside world
|
|
217
241
|
self._workflow_event_outer_queue: Queue[WorkflowEvent] = Queue()
|
|
218
242
|
|
|
@@ -250,6 +274,126 @@ class WorkflowRunner(Generic[StateType]):
|
|
|
250
274
|
self._cancel_thread: Optional[Thread] = None
|
|
251
275
|
self._timeout_thread: Optional[Thread] = None
|
|
252
276
|
|
|
277
|
+
def _has_manual_trigger(self) -> bool:
|
|
278
|
+
"""Check if workflow has ManualTrigger."""
|
|
279
|
+
for subgraph in self.workflow.get_subgraphs():
|
|
280
|
+
for trigger in subgraph.triggers:
|
|
281
|
+
if issubclass(trigger, ManualTrigger):
|
|
282
|
+
return True
|
|
283
|
+
return False
|
|
284
|
+
|
|
285
|
+
def _get_entrypoints_for_trigger_type(self, trigger_class: Type) -> List[Type[BaseNode]]:
|
|
286
|
+
"""Get all entrypoints connected to a specific trigger type.
|
|
287
|
+
|
|
288
|
+
Allows subclasses: if trigger_class is a subclass of any declared trigger,
|
|
289
|
+
returns those entrypoints.
|
|
290
|
+
"""
|
|
291
|
+
entrypoints: List[Type[BaseNode]] = []
|
|
292
|
+
for subgraph in self.workflow.get_subgraphs():
|
|
293
|
+
for trigger in subgraph.triggers:
|
|
294
|
+
# Check if the provided trigger_class is a subclass of the declared trigger
|
|
295
|
+
# This allows runtime instances to be subclasses of what's declared in the workflow
|
|
296
|
+
if issubclass(trigger_class, trigger):
|
|
297
|
+
entrypoints.extend(subgraph.entrypoints)
|
|
298
|
+
return entrypoints
|
|
299
|
+
|
|
300
|
+
def _validate_and_bind_trigger(self, trigger: BaseTrigger) -> None:
|
|
301
|
+
"""
|
|
302
|
+
Validate that trigger is compatible with workflow and bind it to state.
|
|
303
|
+
|
|
304
|
+
Supports all trigger types derived from BaseTrigger:
|
|
305
|
+
- IntegrationTrigger instances (Slack, Gmail, etc.)
|
|
306
|
+
- ManualTrigger instances (explicit manual execution)
|
|
307
|
+
- ScheduledTrigger instances (time-based triggers)
|
|
308
|
+
- Any future trigger types
|
|
309
|
+
|
|
310
|
+
Raises:
|
|
311
|
+
WorkflowInitializationException: If trigger type is not compatible with workflow
|
|
312
|
+
"""
|
|
313
|
+
trigger_class = type(trigger)
|
|
314
|
+
|
|
315
|
+
# Search for a compatible trigger type in the workflow
|
|
316
|
+
found_compatible_trigger = False
|
|
317
|
+
has_any_triggers = False
|
|
318
|
+
incompatible_trigger_names: List[str] = []
|
|
319
|
+
|
|
320
|
+
for subgraph in self.workflow.get_subgraphs():
|
|
321
|
+
for declared_trigger in subgraph.triggers:
|
|
322
|
+
has_any_triggers = True
|
|
323
|
+
# Allow subclasses: if workflow declares BaseSlackTrigger, accept SpecificSlackTrigger instances
|
|
324
|
+
if issubclass(trigger_class, declared_trigger):
|
|
325
|
+
found_compatible_trigger = True
|
|
326
|
+
break
|
|
327
|
+
else:
|
|
328
|
+
incompatible_trigger_names.append(declared_trigger.__name__)
|
|
329
|
+
|
|
330
|
+
if found_compatible_trigger:
|
|
331
|
+
break
|
|
332
|
+
|
|
333
|
+
# Special case: workflows with no explicit triggers implicitly support ManualTrigger
|
|
334
|
+
if not has_any_triggers and not isinstance(trigger, ManualTrigger):
|
|
335
|
+
raise WorkflowInitializationException(
|
|
336
|
+
message=f"Provided trigger type {trigger_class.__name__} is not compatible with workflow. "
|
|
337
|
+
f"Workflow has no explicit triggers and only supports ManualTrigger.",
|
|
338
|
+
workflow_definition=self.workflow.__class__,
|
|
339
|
+
code=WorkflowErrorCode.INVALID_INPUTS,
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
# Validate that we found a compatible trigger type
|
|
343
|
+
if has_any_triggers and not found_compatible_trigger:
|
|
344
|
+
raise WorkflowInitializationException(
|
|
345
|
+
message=f"Provided trigger type {trigger_class.__name__} is not compatible with workflow triggers. "
|
|
346
|
+
f"Workflow has: {sorted(set(incompatible_trigger_names))}",
|
|
347
|
+
workflow_definition=self.workflow.__class__,
|
|
348
|
+
code=WorkflowErrorCode.INVALID_INPUTS,
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
# Bind trigger to state (works for all trigger types via BaseTrigger.bind_to_state)
|
|
352
|
+
trigger.bind_to_state(self._initial_state)
|
|
353
|
+
|
|
354
|
+
def _filter_entrypoints_for_trigger(self, trigger: BaseTrigger) -> None:
|
|
355
|
+
"""
|
|
356
|
+
Filter entrypoints to those connected to the specific trigger type.
|
|
357
|
+
|
|
358
|
+
Uses the specific trigger subclass, not the parent class, allowing workflows
|
|
359
|
+
with multiple triggers to route to the correct path.
|
|
360
|
+
"""
|
|
361
|
+
trigger_class = type(trigger)
|
|
362
|
+
specific_entrypoints = self._get_entrypoints_for_trigger_type(trigger_class)
|
|
363
|
+
if specific_entrypoints:
|
|
364
|
+
self._entrypoints = specific_entrypoints
|
|
365
|
+
|
|
366
|
+
def _validate_no_trigger_provided(self) -> None:
|
|
367
|
+
"""
|
|
368
|
+
Validate that workflow can run without a trigger.
|
|
369
|
+
|
|
370
|
+
If workflow has IntegrationTrigger(s) but no ManualTrigger, it requires a trigger instance.
|
|
371
|
+
If workflow has both, filter entrypoints to ManualTrigger path only.
|
|
372
|
+
|
|
373
|
+
Raises:
|
|
374
|
+
WorkflowInitializationException: If workflow requires trigger but none was provided
|
|
375
|
+
"""
|
|
376
|
+
# Collect all IntegrationTrigger types in the workflow
|
|
377
|
+
workflow_integration_triggers = []
|
|
378
|
+
for subgraph in self.workflow.get_subgraphs():
|
|
379
|
+
for trigger_type in subgraph.triggers:
|
|
380
|
+
if issubclass(trigger_type, IntegrationTrigger):
|
|
381
|
+
workflow_integration_triggers.append(trigger_type)
|
|
382
|
+
|
|
383
|
+
if workflow_integration_triggers:
|
|
384
|
+
if not self._has_manual_trigger():
|
|
385
|
+
# Workflow has ONLY IntegrationTrigger - this is an error
|
|
386
|
+
raise WorkflowInitializationException(
|
|
387
|
+
message="Workflow has IntegrationTrigger which requires trigger parameter",
|
|
388
|
+
workflow_definition=self.workflow.__class__,
|
|
389
|
+
code=WorkflowErrorCode.INVALID_INPUTS,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
# Workflow has both IntegrationTrigger and ManualTrigger - filter to ManualTrigger path
|
|
393
|
+
manual_entrypoints = self._get_entrypoints_for_trigger_type(ManualTrigger)
|
|
394
|
+
if manual_entrypoints:
|
|
395
|
+
self._entrypoints = manual_entrypoints
|
|
396
|
+
|
|
253
397
|
@contextmanager
|
|
254
398
|
def _httpx_logger_with_span_id(self) -> Iterator[None]:
|
|
255
399
|
"""
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
1
2
|
from functools import cached_property
|
|
2
3
|
from queue import Queue
|
|
3
4
|
from uuid import UUID, uuid4
|
|
4
|
-
from typing import TYPE_CHECKING, Dict, List, Optional, Type
|
|
5
|
+
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type
|
|
5
6
|
|
|
6
7
|
from vellum import Vellum, __version__
|
|
7
8
|
from vellum.workflows.context import ExecutionContext, get_execution_context, set_execution_context
|
|
@@ -19,6 +20,18 @@ if TYPE_CHECKING:
|
|
|
19
20
|
from vellum.workflows.workflows.base import BaseWorkflow
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
@dataclass
|
|
24
|
+
class WorkflowDeploymentMetadata:
|
|
25
|
+
"""Metadata about a workflow deployment needed for parent context construction."""
|
|
26
|
+
|
|
27
|
+
deployment_id: UUID
|
|
28
|
+
deployment_name: str
|
|
29
|
+
deployment_history_item_id: UUID
|
|
30
|
+
release_tag_id: UUID
|
|
31
|
+
release_tag_name: str
|
|
32
|
+
workflow_version_id: UUID
|
|
33
|
+
|
|
34
|
+
|
|
22
35
|
class WorkflowContext:
|
|
23
36
|
def __init__(
|
|
24
37
|
self,
|
|
@@ -148,7 +161,7 @@ class WorkflowContext:
|
|
|
148
161
|
|
|
149
162
|
def resolve_workflow_deployment(
|
|
150
163
|
self, deployment_name: str, release_tag: str, state: "BaseState"
|
|
151
|
-
) -> Optional["BaseWorkflow"]:
|
|
164
|
+
) -> Optional[Tuple[Type["BaseWorkflow"], Optional[WorkflowDeploymentMetadata]]]:
|
|
152
165
|
"""
|
|
153
166
|
Resolve a workflow deployment by name and release tag.
|
|
154
167
|
|
|
@@ -158,20 +171,22 @@ class WorkflowContext:
|
|
|
158
171
|
state: The base state to pass to the workflow
|
|
159
172
|
|
|
160
173
|
Returns:
|
|
161
|
-
BaseWorkflow
|
|
174
|
+
Tuple of (BaseWorkflow class, deployment metadata) if found
|
|
162
175
|
"""
|
|
163
176
|
if not self._generated_files or not self._namespace:
|
|
164
177
|
return None
|
|
165
178
|
|
|
166
179
|
expected_prefix = generate_workflow_deployment_prefix(deployment_name, release_tag)
|
|
167
180
|
|
|
181
|
+
deployment_metadata = self._fetch_deployment_metadata(deployment_name, release_tag)
|
|
182
|
+
|
|
168
183
|
try:
|
|
169
184
|
from vellum.workflows.workflows.base import BaseWorkflow
|
|
170
185
|
|
|
171
186
|
WorkflowClass = BaseWorkflow.load_from_module(f"{self.namespace}.{expected_prefix}")
|
|
172
187
|
WorkflowClass.is_dynamic = True
|
|
173
|
-
|
|
174
|
-
return
|
|
188
|
+
# Return the class, not an instance, so caller can instantiate within proper execution context
|
|
189
|
+
return (WorkflowClass, deployment_metadata)
|
|
175
190
|
except Exception:
|
|
176
191
|
pass
|
|
177
192
|
|
|
@@ -200,14 +215,51 @@ class WorkflowContext:
|
|
|
200
215
|
|
|
201
216
|
WorkflowClass = BaseWorkflow.load_from_module(f"{self.namespace}.{expected_prefix}")
|
|
202
217
|
WorkflowClass.is_dynamic = True
|
|
203
|
-
|
|
204
|
-
return
|
|
218
|
+
# Return the class, not an instance, so caller can instantiate within proper execution context
|
|
219
|
+
return (WorkflowClass, deployment_metadata)
|
|
205
220
|
|
|
206
221
|
except Exception:
|
|
207
222
|
pass
|
|
208
223
|
|
|
209
224
|
return None
|
|
210
225
|
|
|
226
|
+
def _fetch_deployment_metadata(
|
|
227
|
+
self, deployment_name: str, release_tag: str
|
|
228
|
+
) -> Optional[WorkflowDeploymentMetadata]:
|
|
229
|
+
"""
|
|
230
|
+
Fetch deployment metadata from the Vellum API.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
deployment_name: The name of the workflow deployment
|
|
234
|
+
release_tag: The release tag name
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
WorkflowDeploymentMetadata if successful, None otherwise
|
|
238
|
+
"""
|
|
239
|
+
try:
|
|
240
|
+
# Fetch deployment details
|
|
241
|
+
deployment = self.vellum_client.workflow_deployments.retrieve(deployment_name)
|
|
242
|
+
|
|
243
|
+
deployment_id = UUID(deployment.id)
|
|
244
|
+
|
|
245
|
+
# Fetch release tag details
|
|
246
|
+
release_tag_info = self.vellum_client.workflow_deployments.retrieve_workflow_release_tag(
|
|
247
|
+
deployment.id, release_tag
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
return WorkflowDeploymentMetadata(
|
|
251
|
+
deployment_id=deployment_id,
|
|
252
|
+
deployment_name=deployment.name,
|
|
253
|
+
deployment_history_item_id=UUID(deployment.last_deployed_history_item_id),
|
|
254
|
+
release_tag_id=UUID(release_tag_info.release.id),
|
|
255
|
+
release_tag_name=release_tag_info.name,
|
|
256
|
+
workflow_version_id=uuid4(),
|
|
257
|
+
)
|
|
258
|
+
except Exception:
|
|
259
|
+
# If we fail to fetch metadata, return None - the workflow can still run
|
|
260
|
+
# but won't have the full parent context hierarchy
|
|
261
|
+
return None
|
|
262
|
+
|
|
211
263
|
@classmethod
|
|
212
264
|
def create_from(cls, context):
|
|
213
265
|
return cls(
|
|
@@ -79,6 +79,7 @@ from vellum.workflows.runner.runner import ExternalInputsArg, RunFromNodeArg
|
|
|
79
79
|
from vellum.workflows.state.base import BaseState, StateMeta
|
|
80
80
|
from vellum.workflows.state.context import WorkflowContext
|
|
81
81
|
from vellum.workflows.state.store import Store
|
|
82
|
+
from vellum.workflows.triggers.base import BaseTrigger
|
|
82
83
|
from vellum.workflows.types import CancelSignal
|
|
83
84
|
from vellum.workflows.types.generics import InputsType, StateType
|
|
84
85
|
from vellum.workflows.types.utils import get_original_base
|
|
@@ -382,6 +383,7 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
|
382
383
|
node_output_mocks: Optional[MockNodeExecutionArg] = None,
|
|
383
384
|
max_concurrency: Optional[int] = None,
|
|
384
385
|
timeout: Optional[float] = None,
|
|
386
|
+
trigger: Optional[BaseTrigger] = None,
|
|
385
387
|
) -> TerminalWorkflowEvent:
|
|
386
388
|
"""
|
|
387
389
|
Invoke a Workflow, returning the last event emitted, which should be one of:
|
|
@@ -422,6 +424,12 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
|
422
424
|
timeout: Optional[float] = None
|
|
423
425
|
The maximum time in seconds to allow the Workflow to run. If the timeout is exceeded, the Workflow
|
|
424
426
|
will be rejected with a WORKFLOW_TIMEOUT error code and any nodes in flight will be rejected.
|
|
427
|
+
|
|
428
|
+
trigger: Optional[BaseTrigger] = None
|
|
429
|
+
A trigger instance for workflows with triggers (e.g., IntegrationTrigger, ManualTrigger, ScheduledTrigger).
|
|
430
|
+
The trigger instance is bound to the workflow state, making its attributes accessible to downstream nodes.
|
|
431
|
+
Required for workflows that only have IntegrationTrigger; optional for workflows with both ManualTrigger
|
|
432
|
+
and IntegrationTrigger.
|
|
425
433
|
"""
|
|
426
434
|
|
|
427
435
|
runner = WorkflowRunner(
|
|
@@ -436,6 +444,7 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
|
436
444
|
max_concurrency=max_concurrency,
|
|
437
445
|
timeout=timeout,
|
|
438
446
|
init_execution_context=self._execution_context,
|
|
447
|
+
trigger=trigger,
|
|
439
448
|
)
|
|
440
449
|
self._current_runner = runner
|
|
441
450
|
events = runner.stream()
|
|
@@ -507,6 +516,7 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
|
507
516
|
node_output_mocks: Optional[MockNodeExecutionArg] = None,
|
|
508
517
|
max_concurrency: Optional[int] = None,
|
|
509
518
|
timeout: Optional[float] = None,
|
|
519
|
+
trigger: Optional[BaseTrigger] = None,
|
|
510
520
|
) -> WorkflowEventStream:
|
|
511
521
|
"""
|
|
512
522
|
Invoke a Workflow, yielding events as they are emitted.
|
|
@@ -548,6 +558,12 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
|
548
558
|
timeout: Optional[float] = None
|
|
549
559
|
The maximum time in seconds to allow the Workflow to run. If the timeout is exceeded, the Workflow
|
|
550
560
|
will be rejected with a WORKFLOW_TIMEOUT error code and any nodes in flight will be rejected.
|
|
561
|
+
|
|
562
|
+
trigger: Optional[BaseTrigger] = None
|
|
563
|
+
A trigger instance for workflows with triggers (e.g., IntegrationTrigger, ManualTrigger, ScheduledTrigger).
|
|
564
|
+
The trigger instance is bound to the workflow state, making its attributes accessible to downstream nodes.
|
|
565
|
+
Required for workflows that only have IntegrationTrigger; optional for workflows with both ManualTrigger
|
|
566
|
+
and IntegrationTrigger.
|
|
551
567
|
"""
|
|
552
568
|
|
|
553
569
|
should_yield = event_filter or workflow_event_filter
|
|
@@ -563,6 +579,7 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
|
563
579
|
max_concurrency=max_concurrency,
|
|
564
580
|
timeout=timeout,
|
|
565
581
|
init_execution_context=self._execution_context,
|
|
582
|
+
trigger=trigger,
|
|
566
583
|
)
|
|
567
584
|
self._current_runner = runner
|
|
568
585
|
runner_stream = runner.stream()
|
|
@@ -52,5 +52,18 @@ def root_workflow_event_filter(workflow_definition: Type["BaseWorkflow"], event:
|
|
|
52
52
|
return event_parent_definition.model_dump() == current_workflow_definition.model_dump()
|
|
53
53
|
|
|
54
54
|
|
|
55
|
+
def workflow_sandbox_event_filter(workflow_definition: Type["BaseWorkflow"], event: "WorkflowEvent") -> bool:
|
|
56
|
+
"""
|
|
57
|
+
Filter designed for Workflow Sandbox interfaces: include all events except
|
|
58
|
+
workflow.execution.snapshotted events from nested/subworkflows. Only allow
|
|
59
|
+
snapshotted events when they belong to the root workflow definition.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
if event.name == "workflow.execution.snapshotted":
|
|
63
|
+
return event.workflow_definition == workflow_definition
|
|
64
|
+
|
|
65
|
+
return True
|
|
66
|
+
|
|
67
|
+
|
|
55
68
|
def all_workflow_event_filter(workflow_definition: Type["BaseWorkflow"], event: "WorkflowEvent") -> bool:
|
|
56
69
|
return True
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
from vellum.workflows.inputs import BaseInputs
|
|
2
|
+
from vellum.workflows.nodes import BaseNode, InlineSubworkflowNode
|
|
3
|
+
from vellum.workflows.outputs.base import BaseOutputs
|
|
4
|
+
from vellum.workflows.state.base import BaseState
|
|
5
|
+
from vellum.workflows.workflows.base import BaseWorkflow
|
|
6
|
+
from vellum.workflows.workflows.event_filters import workflow_sandbox_event_filter
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class NestedInputs(BaseInputs):
|
|
10
|
+
value: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class NestedNode(BaseNode):
|
|
14
|
+
value = NestedInputs.value
|
|
15
|
+
|
|
16
|
+
class Outputs(BaseOutputs):
|
|
17
|
+
result: str
|
|
18
|
+
|
|
19
|
+
def run(self) -> Outputs:
|
|
20
|
+
return self.Outputs(result=f"nested: {self.value}")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class NestedWorkflow(BaseWorkflow[NestedInputs, BaseState]):
|
|
24
|
+
graph = NestedNode
|
|
25
|
+
|
|
26
|
+
class Outputs(BaseOutputs):
|
|
27
|
+
result = NestedNode.Outputs.result
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ParentInputs(BaseInputs):
|
|
31
|
+
value: str
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SubworkflowNode(InlineSubworkflowNode):
|
|
35
|
+
subworkflow_inputs = {
|
|
36
|
+
"value": ParentInputs.value,
|
|
37
|
+
}
|
|
38
|
+
subworkflow = NestedWorkflow
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ParentWorkflow(BaseWorkflow[ParentInputs, BaseState]):
|
|
42
|
+
graph = SubworkflowNode
|
|
43
|
+
|
|
44
|
+
class Outputs(BaseOutputs):
|
|
45
|
+
result = SubworkflowNode.Outputs.result
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_workflow_sandbox_event_filter__filters_nested_workflow_snapshotted_events():
|
|
49
|
+
"""
|
|
50
|
+
Tests that workflow_sandbox_event_filter filters out snapshotted events from nested workflows.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
workflow = ParentWorkflow()
|
|
54
|
+
|
|
55
|
+
# WHEN we stream the workflow with workflow_sandbox_event_filter
|
|
56
|
+
events = list(
|
|
57
|
+
workflow.stream(
|
|
58
|
+
inputs=ParentInputs(value="test"),
|
|
59
|
+
event_filter=workflow_sandbox_event_filter,
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
snapshotted_events = [e for e in events if e.name == "workflow.execution.snapshotted"]
|
|
64
|
+
assert len(snapshotted_events) > 0
|
|
65
|
+
|
|
66
|
+
for event in snapshotted_events:
|
|
67
|
+
assert event.workflow_definition == ParentWorkflow
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_workflow_sandbox_event_filter__includes_root_workflow_snapshotted_events():
|
|
71
|
+
"""
|
|
72
|
+
Tests that workflow_sandbox_event_filter includes snapshotted events from the root workflow.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
class SimpleNode(BaseNode):
|
|
76
|
+
class Outputs(BaseOutputs):
|
|
77
|
+
result: str = "simple"
|
|
78
|
+
|
|
79
|
+
def run(self) -> Outputs:
|
|
80
|
+
return self.Outputs()
|
|
81
|
+
|
|
82
|
+
class SimpleWorkflow(BaseWorkflow[BaseInputs, BaseState]):
|
|
83
|
+
graph = SimpleNode
|
|
84
|
+
|
|
85
|
+
class Outputs(BaseOutputs):
|
|
86
|
+
result = SimpleNode.Outputs.result
|
|
87
|
+
|
|
88
|
+
workflow = SimpleWorkflow()
|
|
89
|
+
|
|
90
|
+
# WHEN we stream the workflow with workflow_sandbox_event_filter
|
|
91
|
+
events = list(
|
|
92
|
+
workflow.stream(
|
|
93
|
+
inputs=BaseInputs(),
|
|
94
|
+
event_filter=workflow_sandbox_event_filter,
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
snapshotted_events = [e for e in events if e.name == "workflow.execution.snapshotted"]
|
|
99
|
+
assert len(snapshotted_events) > 0
|
|
100
|
+
|
|
101
|
+
for event in snapshotted_events:
|
|
102
|
+
assert event.workflow_definition == SimpleWorkflow
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_workflow_sandbox_event_filter__includes_nested_workflow_non_snapshotted_events():
|
|
106
|
+
"""
|
|
107
|
+
Tests that workflow_sandbox_event_filter includes non-snapshotted events from nested workflows.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
workflow = ParentWorkflow()
|
|
111
|
+
|
|
112
|
+
# WHEN we stream the workflow with workflow_sandbox_event_filter
|
|
113
|
+
events = list(
|
|
114
|
+
workflow.stream(
|
|
115
|
+
inputs=ParentInputs(value="test"),
|
|
116
|
+
event_filter=workflow_sandbox_event_filter,
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
nested_workflow_events = [
|
|
121
|
+
e for e in events if hasattr(e, "workflow_definition") and e.workflow_definition == NestedWorkflow
|
|
122
|
+
]
|
|
123
|
+
assert len(nested_workflow_events) > 0
|
|
124
|
+
|
|
125
|
+
for event in nested_workflow_events:
|
|
126
|
+
assert event.name != "workflow.execution.snapshotted"
|
|
@@ -121,11 +121,12 @@ vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
|
|
|
121
121
|
vellum_ee/workflows/display/utils/auto_layout.py,sha256=f4GiLn_LazweupfqTpubcdtdfE_vrOcmZudSsnYIY9E,3906
|
|
122
122
|
vellum_ee/workflows/display/utils/events.py,sha256=XcaQSfmk2s9ZNiU8__ZqH_zfp6KUVACczz9TBWVy7Jc,2208
|
|
123
123
|
vellum_ee/workflows/display/utils/exceptions.py,sha256=E8Lvo7LY1BoZ54M_NR_opDjJsAAiCUfow1HgoHcTHmg,989
|
|
124
|
-
vellum_ee/workflows/display/utils/expressions.py,sha256=
|
|
124
|
+
vellum_ee/workflows/display/utils/expressions.py,sha256=q6jgr13gET3rsAtz9XAPqtWQ2RKq_ZMq2OwrtyPhlRg,21345
|
|
125
125
|
vellum_ee/workflows/display/utils/registry.py,sha256=1qXiBTdsnro6FeCX0FGBEK7CIf6wa--Jt50iZ_nEp_M,3460
|
|
126
126
|
vellum_ee/workflows/display/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
127
127
|
vellum_ee/workflows/display/utils/tests/test_auto_layout.py,sha256=vfXI769418s9vda5Gb5NFBH747WMOwSgHRXeLCTLVm8,2356
|
|
128
128
|
vellum_ee/workflows/display/utils/tests/test_events.py,sha256=CiBx4WxeNAf1WGfgRdJ_I-Hc12RDfza73CMLB5HkOFg,6688
|
|
129
|
+
vellum_ee/workflows/display/utils/tests/test_expressions.py,sha256=s8aHAwuuJS1_WI1B9geJCpTVKPk83XqrCI_ofVG80TI,4268
|
|
129
130
|
vellum_ee/workflows/display/utils/vellum.py,sha256=Bt7kdLdXoBsHn5dVEY2uKcF542VL09jwu8J_30rl2vk,6413
|
|
130
131
|
vellum_ee/workflows/display/vellum.py,sha256=J2mdJZ1sdLW535DDUkq_Vm8Z572vhuxHxVZF9deKSdk,391
|
|
131
132
|
vellum_ee/workflows/display/workflows/__init__.py,sha256=JTB9ObEV3l4gGGdtfBHwVJtTTKC22uj-a-XjTVwXCyA,148
|
|
@@ -163,7 +164,7 @@ vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
|
|
|
163
164
|
vellum/client/__init__.py,sha256=-nugZzQKoUJsStXe6PnOD__8kbDLKKokceDgpGxQ_q0,74576
|
|
164
165
|
vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
|
|
165
166
|
vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
|
|
166
|
-
vellum/client/core/client_wrapper.py,sha256=
|
|
167
|
+
vellum/client/core/client_wrapper.py,sha256=llC4_oYnck1KfRr1_t-bhr-vbslTBI_bKlGt64fTYQY,2840
|
|
167
168
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
|
168
169
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
|
169
170
|
vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
|
|
@@ -497,7 +498,7 @@ vellum/client/types/integration.py,sha256=WqfHEskiMzNxuy5mmcXTARPQ4F3r99Jf-g-wVl
|
|
|
497
498
|
vellum/client/types/integration_auth_config_integration.py,sha256=W3DrzVPwLrqm0wCYVF-sHyQPoKNxoliFgFJWEwW_Yqc,710
|
|
498
499
|
vellum/client/types/integration_auth_config_integration_credential.py,sha256=lUNuJ1GyFps3M85Mff1C-SAeEacCMkJdmayFfYrTFXA,547
|
|
499
500
|
vellum/client/types/integration_credential_access_type.py,sha256=sWkuDjW3aD7ApZ1xQ7Bu8g5kCIwqUqzm1TDliUQWeRI,178
|
|
500
|
-
vellum/client/types/integration_name.py,sha256=
|
|
501
|
+
vellum/client/types/integration_name.py,sha256=5YatDLwjK5QttKIAgwc662WVJZyfVmK7D7DIqkmNZdw,1226
|
|
501
502
|
vellum/client/types/integration_provider.py,sha256=lIh3yPyPEzmSAu8L4Gsd-iDkmDSNobo0_TB75zMtIXk,129
|
|
502
503
|
vellum/client/types/integration_read.py,sha256=sUNCS01TIlHPJHEH3ZheIbPi-CplbFQ5XAV1QtOO1Gg,1035
|
|
503
504
|
vellum/client/types/invoked_port.py,sha256=nw2k-y7NrpcH6T1V96U3F8_pbrsceqBPIz3RQXN8gJY,518
|
|
@@ -1846,7 +1847,7 @@ vellum/workflows/expressions/begins_with.py,sha256=FnWsQXbENm0ZwkfEP7dR8Qx4_MMrz
|
|
|
1846
1847
|
vellum/workflows/expressions/between.py,sha256=dVeddT6YA91eOAlE1Utg7C7gnCiYE7WP-dg17yXUeAY,1492
|
|
1847
1848
|
vellum/workflows/expressions/coalesce_expression.py,sha256=s4pcfu8KkUaUlQkB6BoQUKitGmV1FIQfV4agHHZtd98,1194
|
|
1848
1849
|
vellum/workflows/expressions/comparison_utils.py,sha256=99eioXIMvqqSvm0iqluCtwzMkJGLq-bkVSaJ4LtZYBQ,1206
|
|
1849
|
-
vellum/workflows/expressions/concat.py,sha256=
|
|
1850
|
+
vellum/workflows/expressions/concat.py,sha256=6FWnlBf-sSCelGVa922Tyh2u7A4VD6LGBwVgjUT7DkA,1167
|
|
1850
1851
|
vellum/workflows/expressions/contains.py,sha256=6QET3cuGTj_OF5GCYgOZUh7-_l3lsDiaOYsEEuHV-9E,1642
|
|
1851
1852
|
vellum/workflows/expressions/does_not_begin_with.py,sha256=qcnIJsxg4Jt82i2L-PW6ZhKP3C-OlEiXbiIgwHQc5RE,1137
|
|
1852
1853
|
vellum/workflows/expressions/does_not_contain.py,sha256=ZdHVewTe_pbPGB0cGv_gIq_4jKkv_oG2tX3RBdEGWoA,1266
|
|
@@ -1877,7 +1878,7 @@ vellum/workflows/expressions/parse_json.py,sha256=xsk6j3HF7bU1yF6fwt5P9Ugcyd5D9Z
|
|
|
1877
1878
|
vellum/workflows/expressions/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1878
1879
|
vellum/workflows/expressions/tests/test_accessor.py,sha256=g2z0mJjuWwVKeXS0yGoFW-aRmT5n_LrhfuBorSmj9kI,7585
|
|
1879
1880
|
vellum/workflows/expressions/tests/test_add.py,sha256=_MjlRvIGAVM5wve2ru5jc_5Ae4x_ywvh4vN0S2yQ-8M,1615
|
|
1880
|
-
vellum/workflows/expressions/tests/test_concat.py,sha256=
|
|
1881
|
+
vellum/workflows/expressions/tests/test_concat.py,sha256=KE4fFRh96K_vuIZid2bZ-4kxaW3jTxyQ578UIrsLkPE,3205
|
|
1881
1882
|
vellum/workflows/expressions/tests/test_contains.py,sha256=9jO9U0Idcjwxb9gnK1f_CFsn-vahAKE7TG45xNWWcmg,4878
|
|
1882
1883
|
vellum/workflows/expressions/tests/test_expressions.py,sha256=e5CMwcOPQPvvDerhJ5Zm3TaXv84oyOYKu7oRRtQnmSA,17192
|
|
1883
1884
|
vellum/workflows/expressions/tests/test_length.py,sha256=pQA1tYSwqxE6euclboY024NXEOs7yaVgwTKkMPYUT08,1035
|
|
@@ -1942,11 +1943,11 @@ vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=cOYaIqimzDL6TuX
|
|
|
1942
1943
|
vellum/workflows/nodes/displayable/bases/api_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1943
1944
|
vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py,sha256=5C59vn_yg4r5EWioKIr658Jr1MSGX3YF4yKJokY37Xc,4726
|
|
1944
1945
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
|
|
1945
|
-
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=
|
|
1946
|
+
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=Qzy8ZJ_2jnRk6p4FVrSj7MJ0hQu9vdVP41OslH2PsHA,5825
|
|
1946
1947
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
|
|
1947
|
-
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=
|
|
1948
|
+
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=3juPEPESTztVMHm6zj534_1SZs7k91Z39MjsLF2MJX4,19470
|
|
1948
1949
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1949
|
-
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=
|
|
1950
|
+
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=5xaGT7YsfYI5gpoL0ggHvY8JiDkj9Do4vCRq9M_NRZ8,31785
|
|
1950
1951
|
vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=iwYZBxrZsbJnifBV11ANPOnVLGhWIlJZaOt7br6srqQ,12620
|
|
1951
1952
|
vellum/workflows/nodes/displayable/bases/search_node.py,sha256=9TtFn6oNpEkpCL59QdBViUe4WPjcITajbiS7EOjOGag,6114
|
|
1952
1953
|
vellum/workflows/nodes/displayable/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -1965,9 +1966,9 @@ vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU
|
|
|
1965
1966
|
vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=2g32hWosE3zwVaK2UPFnVEer1Nbn04s3friF2rGztmE,1195
|
|
1966
1967
|
vellum/workflows/nodes/displayable/conftest.py,sha256=K2kLM2JGAfcrmmd92u8DXInUO5klFdggPWblg5RVcx4,5729
|
|
1967
1968
|
vellum/workflows/nodes/displayable/final_output_node/__init__.py,sha256=G7VXM4OWpubvSJtVkGmMNeqgb9GkM7qZT838eL18XU4,72
|
|
1968
|
-
vellum/workflows/nodes/displayable/final_output_node/node.py,sha256=
|
|
1969
|
+
vellum/workflows/nodes/displayable/final_output_node/node.py,sha256=ypetAGBaTjVozKqAos-C1LG5HHZ3iUekw7v2mnnUlOw,5175
|
|
1969
1970
|
vellum/workflows/nodes/displayable/final_output_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1970
|
-
vellum/workflows/nodes/displayable/final_output_node/tests/test_node.py,sha256=
|
|
1971
|
+
vellum/workflows/nodes/displayable/final_output_node/tests/test_node.py,sha256=Drj7tMNEBDzHIYQ5iLkIK0zHHj-NxiswCtefVbfDFRo,3418
|
|
1971
1972
|
vellum/workflows/nodes/displayable/guardrail_node/__init__.py,sha256=Ab5eXmOoBhyV4dMWdzh32HLUmnPIBEK_zFCT38C4Fng,68
|
|
1972
1973
|
vellum/workflows/nodes/displayable/guardrail_node/node.py,sha256=axYUojar_kdB3gi4LG3g9euJ8VkOxNtiFxJNI46v-SQ,5869
|
|
1973
1974
|
vellum/workflows/nodes/displayable/guardrail_node/test_node.py,sha256=SAGv6hSFcBwQkudn1VxtaKNsXSXWWELl3eK05zM6tS0,5410
|
|
@@ -1990,7 +1991,7 @@ vellum/workflows/nodes/displayable/search_node/node.py,sha256=hbPsZhyXfq9dx0mfBK
|
|
|
1990
1991
|
vellum/workflows/nodes/displayable/search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1991
1992
|
vellum/workflows/nodes/displayable/search_node/tests/test_node.py,sha256=YXgIIAJHVQxrfyJ0gxeJC0fAJaic10_zbqvsS8hyZSc,9368
|
|
1992
1993
|
vellum/workflows/nodes/displayable/subworkflow_deployment_node/__init__.py,sha256=9yYM6001YZeqI1VOk1QuEM_yrffk_EdsO7qaPzINKds,92
|
|
1993
|
-
vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=
|
|
1994
|
+
vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=_4aJxlnSEQKUlL9DAXYdrv1ic0tC7IyvYV389HHGyvE,16281
|
|
1994
1995
|
vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1995
1996
|
vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py,sha256=PII44speqT4fJvj60y_3KDAnH1L6Ivtq9R4BykY-X_A,19092
|
|
1996
1997
|
vellum/workflows/nodes/displayable/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -2011,9 +2012,7 @@ vellum/workflows/nodes/displayable/web_search_node/node.py,sha256=NQYux2bOtuBF5E
|
|
|
2011
2012
|
vellum/workflows/nodes/displayable/web_search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2012
2013
|
vellum/workflows/nodes/displayable/web_search_node/tests/test_node.py,sha256=H3titxCYFsfIJ3EDeRL6Pe9I-tdKMRt1axOwb2qIw6U,10983
|
|
2013
2014
|
vellum/workflows/nodes/experimental/README.md,sha256=eF6DfIL8t-HbF9-mcofOMymKrraiBHDLKTlnBa51ZiE,284
|
|
2014
|
-
vellum/workflows/nodes/experimental/__init__.py,sha256=
|
|
2015
|
-
vellum/workflows/nodes/experimental/openai_chat_completion_node/__init__.py,sha256=lsyD9laR9p7kx5-BXGH2gUTM242UhKy8SMV0SR6S2iE,90
|
|
2016
|
-
vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py,sha256=cKI2Ls25L-JVt4z4a2ozQa-YBeVy21Z7BQ32Sj7iBPE,10460
|
|
2015
|
+
vellum/workflows/nodes/experimental/__init__.py,sha256=juqd9PbXs4yg45zMJ7BHAOPQjb7sgEbWE9InBtGZhfo,24
|
|
2017
2016
|
vellum/workflows/nodes/mocks.py,sha256=FXvP049s1KuilDqjUub12Y81rjR9vgPdX8pu6oBSjoE,10931
|
|
2018
2017
|
vellum/workflows/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2019
2018
|
vellum/workflows/nodes/tests/test_mocks.py,sha256=mfPvrs75PKcsNsbJLQAN6PDFoVqs9TmQxpdyFKDdO60,7837
|
|
@@ -2046,11 +2045,11 @@ vellum/workflows/resolvers/resolver.py,sha256=3uEYscB_2PHTazc0Y9SzOe_yiQZhVLfey1
|
|
|
2046
2045
|
vellum/workflows/resolvers/tests/test_resolver.py,sha256=PnUGzsulo1It_LjjhHsRNiILvvl5G_IaK8ZX56zKC28,6204
|
|
2047
2046
|
vellum/workflows/resolvers/types.py,sha256=Hndhlk69g6EKLh_LYg5ILepW5U_h_BYNllfzhS9k8p4,237
|
|
2048
2047
|
vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
|
|
2049
|
-
vellum/workflows/runner/runner.py,sha256=
|
|
2048
|
+
vellum/workflows/runner/runner.py,sha256=mMJzRT1iMsJ8YLYcbTsrKH8l2VDxqlC-sD8xY7pIoGY,54834
|
|
2050
2049
|
vellum/workflows/sandbox.py,sha256=mezSZmilR_fwR8164n8CEfzlMeQ55IqfapHp4ftImvQ,3212
|
|
2051
2050
|
vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
|
|
2052
2051
|
vellum/workflows/state/base.py,sha256=8Zr7UIM_eC0O2N6w_1gYqyrjgJ9D9z-VqLFnBETEF7Q,26753
|
|
2053
|
-
vellum/workflows/state/context.py,sha256=
|
|
2052
|
+
vellum/workflows/state/context.py,sha256=wMp6g23V1RNGWMksogfYIg8PqtFE9UxlfLfLpvhD9EU,10412
|
|
2054
2053
|
vellum/workflows/state/delta.py,sha256=7h8wR10lRCm15SykaPj-gSEvvsMjCwYLPsOx3nsvBQg,440
|
|
2055
2054
|
vellum/workflows/state/encoder.py,sha256=elZ70SEUTxhGa3vpxdrfjUotDT6NvhDCPWtP-VSjCH0,2029
|
|
2056
2055
|
vellum/workflows/state/store.py,sha256=uVe-oN73KwGV6M6YLhwZMMUQhzTQomsVfVnb8V91gVo,1147
|
|
@@ -2093,13 +2092,14 @@ vellum/workflows/utils/vellum_variables.py,sha256=X3lZn-EoWengRWBWRhTNW7hqbj7LkV
|
|
|
2093
2092
|
vellum/workflows/utils/zip.py,sha256=HVg_YZLmBOTXKaDV3Xhaf3V6sYnfqqZXQ8CpuafkbPY,1181
|
|
2094
2093
|
vellum/workflows/vellum_client.py,sha256=3iDR7VV_NgLSm1iZQCKDvrmfEaX1bOJiU15QrxyHpv0,1237
|
|
2095
2094
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
|
2096
|
-
vellum/workflows/workflows/base.py,sha256=
|
|
2097
|
-
vellum/workflows/workflows/event_filters.py,sha256=
|
|
2095
|
+
vellum/workflows/workflows/base.py,sha256=jeIjmHclZtBG9I5uh0H0rqHOF6nVpxoF0bomvOHK2sU,33361
|
|
2096
|
+
vellum/workflows/workflows/event_filters.py,sha256=OzaS1y_z1f7H4f4M914HttAfAuTiN0jXUmo1TUQagCY,2504
|
|
2098
2097
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2099
2098
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=Boa-_m9ii2Qsa1RvVM-VYniF7zCpzGgEGy-OnPZkrHg,23941
|
|
2100
2099
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
|
2101
|
-
|
|
2102
|
-
vellum_ai-1.8.
|
|
2103
|
-
vellum_ai-1.8.
|
|
2104
|
-
vellum_ai-1.8.
|
|
2105
|
-
vellum_ai-1.8.
|
|
2100
|
+
vellum/workflows/workflows/tests/test_event_filters.py,sha256=CPsgtn2F8QMuNMxN5MB6IwTY0y_8JWBCZsio75vxp6c,3638
|
|
2101
|
+
vellum_ai-1.8.3.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
|
2102
|
+
vellum_ai-1.8.3.dist-info/METADATA,sha256=hc54GAN5QhytozkoojSXEZ30tE_YUqvfOFrOUy-OK_Y,5547
|
|
2103
|
+
vellum_ai-1.8.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
2104
|
+
vellum_ai-1.8.3.dist-info/entry_points.txt,sha256=xVavzAKN4iF_NbmhWOlOkHluka0YLkbN_pFQ9pW3gLI,117
|
|
2105
|
+
vellum_ai-1.8.3.dist-info/RECORD,,
|