Nous.Workflow.Compiler (nous v0.13.3)

View Source

Validates and compiles workflow graphs for execution.

Uses Kahn's algorithm for topological sort, which gives three things in a single O(V+E) pass:

  1. Topological order — valid execution sequence
  2. Cycle detection — remaining nodes after sort form cycle(s)
  3. Parallel levels — nodes in the same round are independent

Compilation Result

Returns a {:ok, compiled} map with:

  • :graph — the validated graph
  • :topo_order — topological ordering of node IDs
  • :levels — list of lists, each level can execute in parallel
  • :terminal_nodes — nodes with no outgoing edges
  • :fan_in_nodes — nodes with multiple incoming edges

Examples

{:ok, compiled} = Nous.Workflow.Compiler.compile(graph)
compiled.topo_order
#=> ["plan", "search", "synthesize", "report"]

Summary

Functions

Compile and validate a workflow graph.

Perform topological sort using Kahn's algorithm.

Validate a graph without computing topological sort.

Types

compiled()

@type compiled() :: %{
  graph: Nous.Workflow.Graph.t(),
  topo_order: [Nous.Workflow.Graph.node_id()],
  levels: [[Nous.Workflow.Graph.node_id()]],
  terminal_nodes: [Nous.Workflow.Graph.node_id()],
  fan_in_nodes: [Nous.Workflow.Graph.node_id()],
  cycle_nodes: MapSet.t()
}

Functions

compile(graph)

@spec compile(Nous.Workflow.Graph.t()) :: {:ok, compiled()} | {:error, [term()]}

Compile and validate a workflow graph.

Returns {:ok, compiled} or {:error, errors} where errors is a list of validation error tuples.

topological_sort(graph)

@spec topological_sort(Nous.Workflow.Graph.t()) ::
  {:ok, [Nous.Workflow.Graph.node_id()], [[Nous.Workflow.Graph.node_id()]]}
  | {:ok, [Nous.Workflow.Graph.node_id()], [[Nous.Workflow.Graph.node_id()]],
     map()}
  | {:error, [term()]}

Perform topological sort using Kahn's algorithm.

Returns {:ok, topo_order, levels} where levels is a list of lists — each level contains nodes that can execute in parallel.

Returns {:error, [{:cycle_detected, message}]} if cycles are found and the graph does not allow them.

validate(graph)

@spec validate(Nous.Workflow.Graph.t()) :: :ok | {:error, [term()]}

Validate a graph without computing topological sort.