A spec's node positions: the author's arrangement where there is one, a computed layout elsewhere.
Why this is not LayoutTaskGraph. That function lays a spec out from scratch and ignores
node.layout entirely — correct for a graph an agent emitted, which has no opinion about where
the boxes go, and wrong for one compiled from a Flow agent, where every position is something a
person dragged into place.
Why it is shared rather than written at each call site. Two surfaces render a stored graph —
the agent run's detail panel, from the spec recorded on the step, and the Workflows run view, from
the Task rows — and a viewer that computed its own arrangement would draw the same workflow
differently depending on which screen it was opened from. Mixing per-node rather than choosing one
source for the whole graph matters too: a workflow whose author positioned some steps and left
others keeps the positions they chose.
Returning positions is the whole point. A caller that cannot supply them leaves every node at the
origin, and a canvas asked to fit a graph whose nodes are all in one place zooms until that single
point fills the viewport — which is what a 265% zoom over a four-step workflow actually was.
A spec's node positions: the author's arrangement where there is one, a computed layout elsewhere.
Why this is not
LayoutTaskGraph. That function lays a spec out from scratch and ignoresnode.layoutentirely — correct for a graph an agent emitted, which has no opinion about where the boxes go, and wrong for one compiled from a Flow agent, where every position is something a person dragged into place.Why it is shared rather than written at each call site. Two surfaces render a stored graph — the agent run's detail panel, from the spec recorded on the step, and the Workflows run view, from the Task rows — and a viewer that computed its own arrangement would draw the same workflow differently depending on which screen it was opened from. Mixing per-node rather than choosing one source for the whole graph matters too: a workflow whose author positioned some steps and left others keeps the positions they chose.
Returning positions is the whole point. A caller that cannot supply them leaves every node at the origin, and a canvas asked to fit a graph whose nodes are all in one place zooms until that single point fills the viewport — which is what a 265% zoom over a four-step workflow actually was.