Baton.Flow (Baton v0.27.4)

Copy Markdown View Source

Declarative flows: describe a DAG once as a list of Baton.Flow.Steps, then either build it into an executable Baton workflow or project it into a node/edge graph for display. Single-sourcing the two means they can't drift.

A step names its worker, its logical deps, and an optional Baton.Flow.FanOut (one node per item in a collection). Everything here is domain-agnostic: the build subject is an opaque term threaded only to the fan-out functions, and consumer-specific data (prompt keys, payloads, …) rides on each step's opaque meta, which project/1 echoes but never interprets. So the whole flow layer is reusable by any Baton consumer, not just one app.

Build

Baton.Flow.build(steps, subject, base_args, name: "rating:42") |> Baton.insert!()

Each node's args are base_args plus "logical_step" — the step name the node was expanded from (equal to the node name except under fan-out), so a worker can look up its own step without restating it.

Project

%{nodes: nodes, edges: edges} = Baton.Flow.project(steps)

One node per step (a fan-out step stays a single badged node — its per-item expansion depends on a concrete subject and belongs to a run view). Nodes carry the generic shape plus the worker's introspected output_schema/0 and the opaque meta; layout is by topological layer.

Summary

Functions

Build (but do not insert) the Baton workflow for steps.

Recover the immutable logical definition that produced a stored flow run.

The logical graph for steps — one node per step, laid out by layer.

Return the stored logical and compiled projections for a flow run.

Types

edge()

@type edge() :: %{from: String.t(), to: String.t()}

proj_node()

@type proj_node() :: %{
  id: String.t(),
  label: String.t(),
  kind: :llm | :function,
  description: String.t() | nil,
  deps: [String.t()],
  fan_out: %{gate: atom()} | nil,
  worker: module(),
  output_schema: map() | nil,
  has_schema: boolean(),
  meta: map(),
  layer: non_neg_integer(),
  pos_x: float(),
  pos_y: float()
}

projection()

@type projection() :: %{nodes: [proj_node()], edges: [edge()]}

Functions

build(steps, subject, base_args, opts \\ [])

@spec build([Baton.Flow.Step.t()], term(), map(), keyword()) :: Baton.t()

Build (but do not insert) the Baton workflow for steps.

subject is the domain object fan-out collections read (pass nil when no step fans out). base_args is the string-keyed map every node carries. Options:

  • :name — the workflow name (required).

definition_for_run(workflow_id)

Recover the immutable logical definition that produced a stored flow run.

project(steps)

@spec project([Baton.Flow.Step.t()]) :: projection()

The logical graph for steps — one node per step, laid out by layer.

project_run(workflow_id)

Return the stored logical and compiled projections for a flow run.