Spaces:
Sleeping
Sleeping
| """Pipeline error types and cancellation primitives.""" | |
| from __future__ import annotations | |
| import threading | |
| from contextvars import ContextVar | |
| class PipelineOrderError(Exception): | |
| """A step requires a field that no earlier step provides.""" | |
| class PipelineConfigError(Exception): | |
| """Invalid pipeline wiring. | |
| Examples: | |
| - More than one ``async_boundary = True`` step in the same pipeline. | |
| - An ``async_boundary = True`` step inside a Branch child. | |
| """ | |
| class BranchError(Exception): | |
| """One or more branch pipelines failed. | |
| All branches always run to completion before this is raised. | |
| ``failures`` contains the full list of exceptions — one per failed branch. | |
| """ | |
| def __init__(self, failures: list[BaseException]) -> None: | |
| self.failures = failures | |
| super().__init__( | |
| f"{len(failures)} branch(es) failed: " | |
| + "; ".join(type(e).__name__ for e in failures) | |
| ) | |
| class PipelineCancelled(Exception): | |
| """A ``cancel_token`` was triggered between steps. | |
| Surfaces in ``SampleResult.error`` — never propagated to the caller of | |
| ``run()`` / ``run_async()``. Callers check for this type to distinguish | |
| cancellation from step failures. | |
| """ | |
| class CancellationToken: | |
| """Thread-safe cancellation signal for pipeline runs. | |
| Create a fresh token per ``run()`` / ``run_async()`` invocation. The | |
| pipeline checks ``is_cancelled`` between steps; call ``cancel()`` from | |
| any thread to stop processing. | |
| Uses ``threading.Event`` so it is safe to signal from a web endpoint | |
| handler, a background task, or a signal handler. | |
| """ | |
| def __init__(self) -> None: | |
| self._cancelled = threading.Event() | |
| def cancel(self) -> None: | |
| """Signal cancellation. Thread-safe, idempotent.""" | |
| self._cancelled.set() | |
| def is_cancelled(self) -> bool: | |
| return self._cancelled.is_set() | |
| # --------------------------------------------------------------------------- | |
| # Contextvar bridge — makes the current cancel token visible inside steps | |
| # without threading it through every method signature. | |
| # Pipeline.run_async() sets this; LLM clients read it. | |
| # asyncio.to_thread() copies contextvars automatically. | |
| # --------------------------------------------------------------------------- | |
| cancel_token_var: ContextVar[CancellationToken | None] = ContextVar( | |
| "cancel_token_var", default=None | |
| ) | |