graph

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package graph projects a workflow into a node/edge graph for visualization — the JSON contract behind a future visual graph tool (`awf graph --json`). It is a pure, read-only projection: static structure comes from walking ir.Graph; optional per-node run state comes from Overlay (obs.Project), keyed by runtime path.

Slice 1 scope (see docs/.gstack design + TODOS.md): static template graph + a FLAT run_overlay keyed by runtime path. There are no first-class runtime "instance" nodes (map item / gate attempt / loop iter) — that object model is deferred to the UI slice.

`Skip` nodes are omitted from the static graph: a `skip` carries no addressable identity and is absent from the §8 addressing grammar (same as ir.WalkNodes). A `skip:` between two siblings therefore does not render as a node; the control edge connects the surrounding nodes directly.

Index

Constants

View Source
const SchemaVersion = 2

SchemaVersion is the version of the projection JSON contract. This JSON is a stable boundary (consumed by external tooling), so every emission carries it — bump on any breaking shape change. v2 added data edges (Edge.Kind "data"), node_class, instance_of, and runtime instance nodes (see instances.go).

Variables

This section is empty.

Functions

func Overlay

func Overlay(events []state.Event) (map[string]NodeState, error)

Overlay derives per-path run state from a run's event log, keyed by runtime path. It reuses obs.Project — which already folds the event stream into spans carrying pending/failed/timing/outcome — because engine.Fold's RunState holds only COMMITTED facts and cannot represent running or failed nodes. The run-root span (Path "") is excluded: the overlay is node state, not run state.

obs.Project is computed from FoldFile output, which tolerates a torn tail, so Overlay works on a live or crashed run's log (running nodes appear with state "running").

Types

type Edge

type Edge struct {
	From string `json:"from"`
	To   string `json:"to"`
	Kind string `json:"kind"`
}

Edge is a control-flow edge between consecutive sibling nodes within one addressing scope (slice/declaration order). Containment (parent → child) is carried by Node.Parent, not by edges. Data edges (from `{{ }}` refs) are a deferred fast-follow (no edge here yet).

type Node

type Node struct {
	Path   string       `json:"path"`
	Kind   string       `json:"kind"`
	ID     string       `json:"id,omitempty"`
	Parent string       `json:"parent,omitempty"`
	With   ir.RawConfig `json:"with,omitempty"`
	// NodeClass is "template" (a node authored in the graph) or "instance" (a runtime
	// expansion that exists only for a given run — a map item, gate attempt, or loop
	// iteration and its children). InstanceOf, set only on instances, is the path of the
	// template node this instance is a copy of.
	NodeClass  string `json:"node_class,omitempty"`
	InstanceOf string `json:"instance_of,omitempty"`
}

Node is one template node in the static graph. Path is the static IR path (the same string the runtime uses, minus per-iteration suffixes). Parent is the immediate enclosing addressing scope: "" at the top level, a node path for parallel children (bare `parallel[i]`, no branch label), or a branch-scope path for branch children (e.g. `gate[1].generate`, `loop[0].body`, `try[0].catch`). With carries an agent step's opaque `with:` config verbatim — never interpreted (the RawConfig invariant).

type NodeState

type NodeState struct {
	State              string `json:"state"`
	Outcome            string `json:"outcome,omitempty"`
	LivePreview        string `json:"live_preview,omitempty"`
	LiveDisplayClass   string `json:"live_display_class,omitempty"`
	LiveDisplayTool    string `json:"live_display_tool,omitempty"`
	LiveDisplayLines   int    `json:"live_display_lines,omitempty"`
	LiveDisplayBytes   int    `json:"live_display_bytes,omitempty"`
	LiveDisplayIsError bool   `json:"live_display_is_error,omitempty"`
}

NodeState is the per-path run state in RunOverlay. State is one of running / completed / failed / skipped. Outcome carries the raw awf.node.outcome attribute when present.

type Projection

type Projection struct {
	SchemaVersion int                  `json:"schema_version"`
	Workflow      string               `json:"workflow"`
	Nodes         []Node               `json:"nodes"`
	Edges         []Edge               `json:"edges"`
	RunOverlay    map[string]NodeState `json:"run_overlay,omitempty"`
}

Projection is the full graph JSON. Nodes and Edges are emitted in deterministic walk order (NodeList declaration order). RunOverlay, when present, is keyed by runtime path and JSON-marshals with sorted keys (encoding/json sorts map keys), so the whole document is byte-deterministic for a given input.

func BuildStatic

func BuildStatic(wf *ir.Workflow) Projection

BuildStatic projects a workflow's static structure (nodes + control edges). It never errors and never touches a run log. A nil workflow yields an empty (but well-formed) projection. Nodes/Edges are always non-nil so the JSON emits [] rather than null.

func BuildStaticLoaded

func BuildStaticLoaded(ld *ir.LoadedDefinition) Projection

BuildStaticLoaded projects a loaded workflow definition, expanding imported child workflow templates under each concrete call site using runtime-shaped <call>.workflow.* paths.

func BuildWithRun

func BuildWithRun(wf *ir.Workflow, events []state.Event) (Projection, error)

BuildWithRun returns the static graph PLUS the runtime expansion for one run: an instance node for every runtime path that has no static template node (map items, gate attempts, loop iterations, and their children), nested under its runtime parent, with run state attached as RunOverlay. Instance control edges are the static control edges projected into each instance context, so an item's body steps connect just like the template's do.

Both the instance set and the overlay come from a single obs.Project of the event log (the source that carries running/failed/timing, which engine.Fold's RunState does not).

func BuildWithRunLoaded

func BuildWithRunLoaded(ld *ir.LoadedDefinition, events []state.Event) (Projection, error)

BuildWithRunLoaded returns the loaded static graph plus runtime instance nodes and overlay state. Imported child workflow template nodes are preserved under call sites, so callID.workflow.* runtime events overlay the corresponding template paths.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL