The Dependency Graph for Form Fields: What requires Actually Encodes
7
min read
Product
A dependency graph for form fields is a structure that tells you which fields, checkboxes, or buttons on a page can only be interacted with after specific other elements are filled in or selected — and in what order. Manifest exposes this directly as a requires field on every action, so an agent (or a person debugging one) can see the fill order before it clicks anything.
Most extraction tools don't give you this. They give you a flat list: here are the buttons, here are the inputs, good luck. That's fine for reading a page. It falls apart the moment something has to act on it.
The problem with a flat action list
Take a checkout form. You get back something like:
json
An LLM given this list has no signal that shipping_method doesn't even render until country is set, that postal_code triggers a shipping-rate lookup that same_as_billing depends on, or that submit_order will silently no-op if you click it before the others resolve. It has to infer ordering from field names and DOM position, which works until it doesn't — and "doesn't" usually looks like a stuck agent retrying the same click in a loop.
A dependency graph for form fields removes that inference step. The ordering is data, not a guess.
What requires actually looks like
Each action's requires field is a list of lists of action names — an AND-of-OR structure:
json
Read it as: all of the outer groups must be satisfied (AND), and within each group, any one element satisfies it (OR). So submit_order requires country done, shipping_method done, either postal_code or pickup_location done, and either same_as_billing or billing_address done. That last pair matters — a checkbox and a full address field are two different ways to satisfy the same real-world precondition, and a flat list can't express "either of these," only "all of these."
This is the change we shipped in SDK 0.3.0: requires moved from a flat list[str] to list[list[str]] specifically because the flat version couldn't represent OR-conditions at all. It's a breaking change, but the old structure was quietly wrong for any form with conditional branches — which is most forms with more than four fields.
Walking the graph
An agent — or the local browser-agent loop we've been building — walks this dependency graph for form fields the same way you'd walk any DAG:
Pull the full action manifest for the page.
Filter to actions whose
requiresgroups are all currently satisfied (or empty).Act on one.
Re-fetch or re-derive the manifest, since satisfying one action can change what's now available — a country selection can reveal a state/province field that didn't exist in the first extraction.
Repeat until the target action (submit, confirm, next) is reachable.
That re-fetch step in point 4 is the part people underestimate. A dependency graph for form fields isn't static for the life of the page — it's evaluated fresh after every state-changing action, because the DOM itself is changing. This is also why we cache manifests on a 6-hour TTL keyed to the page, not to a specific interaction session: the graph structure is usually stable across users even when the runtime state (what's currently filled) isn't.
What this doesn't do
To be direct about the limits: requires encodes ordering dependencies Manifest can detect from DOM structure, ARIA relationships, and observed conditional rendering. It does not encode business logic Manifest can't see — a postal_code that's technically fillable but will fail server-side validation for a given country isn't reflected as a dependency, because there's no DOM signal for it. It also doesn't guarantee real-time correctness on pages where fields appear via delayed JS with no accessibility hook at all; those show up as NoActionsAvailableError rather than a wrong graph, which is the better failure mode but still a failure mode.
We also don't retroactively re-collapse duplicate actions across a changing graph within a single request — that's a related but separate bug track, not part of requires itself.
Why name it instead of leaving it implicit
We could have left field ordering as something the calling LLM infers from context, the way most scraping output does. Naming it as requires and giving it a formal AND-of-OR grammar means:
The ordering is testable. You can assert
requiresstructure in golden fixtures instead of eyeballing whether an agent "seemed to" click things in the right order.It's model-agnostic. A dumb rules engine can walk the same graph a frontier LLM can, which matters if you're trying to keep inference costs down on high-volume pages.
It's debuggable. When an agent gets stuck, you can print the unsatisfied
requiresgroups and know exactly what's blocking it, instead of re-running the whole trace.
That third point is the one that's paid off the most in practice. "Which precondition is unmet" is a much smaller question than "why did the agent do the wrong thing."
FAQ
What is a dependency graph for form fields? It's a structure representing which form fields, checkboxes, or buttons on a page require other elements to be filled or selected first, and in what order — used so an automated agent can sequence its actions correctly instead of guessing from DOM position alone.
What does the requires field do in Manifest? requires lists the preconditions for a given action as an AND-of-OR structure (list[list[str]]): every inner list must have at least one satisfied member, and every outer group must be satisfied, before that action is considered available.
Why did requires change from a flat list to a list of lists? The original flat list[str] structure could only express "all of these are required," with no way to say "either of these satisfies the requirement." Real forms have OR-conditions constantly — a checkbox versus a manually filled field being two ways to satisfy the same precondition — so the flat structure was undercounting valid paths.
Does the dependency graph update as the page changes? Yes. It's re-evaluated after each state-changing action rather than computed once, since filling one field can reveal or unlock others that weren't in the original extraction.
Does requires capture business-logic dependencies, like validation rules? No — only dependencies visible from DOM structure, ARIA relationships, and observed conditional rendering. A field that will fail server-side validation for a particular prior selection isn't reflected, because there's no DOM signal for it.