Skip to main content

Overview

Composition utilities let you build workflows from Steps without introducing a new DSL. In coevolved.base.compose, you’ll find patterns you’ll use constantly:
  • sequences (pipelines)
  • fallback chains (try primary → fallback)
  • parallel fan-out (run independent work)
  • retry wrappers (resilience)
  • graph compilation (introspection / visualization)

Sequential composition

Use run_sequence when step outputs feed into the next step:
from coevolved.base.compose import run_sequence

final_state = run_sequence([step1, step2, step3], state)

Fallback chains

Use run_first_success when you want “try A, then B, then C”:
from coevolved.base.compose import run_first_success

result = run_first_success([primary, fallback], state)
This pattern is useful for “fast path / slow path” designs.

Parallel execution

Use run_parallel to run multiple steps against the same input state.
from coevolved.base.compose import run_parallel

results = run_parallel([a, b, c], state)
Only parallelize steps that don’t mutate shared state (or rely on global mutable state). Prefer returning new values.

Retry wrappers

Wrap a step in a retry policy with exponential backoff:
from coevolved.base.compose import RetryPolicy, with_retry

policy = RetryPolicy(attempts=3, backoff_seconds=0.5)
safe_step = with_retry(unreliable_step, policy)

Compiling step graphs

compile_steps converts a sequence into a small graph structure containing node metadata and edges. This is useful for:
  • Debugging “what is in this workflow?”
  • Basic visualization
  • Metadata inspection (step kinds, schemas, annotations)

Next steps