Scopes & visibility
Agent Flow's scopes are lexical and statically decidable. One chain, outermost to innermost:
workflow : input, context, use aliases (agent/team)
pipeline : (inherits workflow) + completed stage results (source-order progressive)
stage : (inherits pipeline) + its explicitly declared dependencies
block : if then / else bodies
map : the parallel-map loop variable
verify : check names (visible to pass when only)
Inner sees outer; siblings never see each other.
Key rules
Inside a stage: dependencies are a whitelist
A stage reads only the stage results declared in its header:
stage a -> A { ... }
stage b -> B { ... }
stage c after a -> C {
let x = a // ✓ a declared
let y = b // ✗ undeclared-dependency — even though b is earlier & done
return x
}
This puts every stage's input set in its signature — reviewing one stage requires no whole-file reading to know what it touches.
At pipeline level: progressive visibility
Pipeline-level statements see the results of every stage earlier in source order:
stage summary after classify, drafts -> TriageSummary { ... }
if summary.urgent_count > 0 { // stage result at pipeline level
emit progress { attention: true }
}
let binds in the current scope
let takes effect in the current scope; reusing a name in the same
scope is duplicate-variable. Inner scopes (if blocks, map bodies) may
reference outer variables; separate scopes (then vs else) may each have
their own same-named let.
input and context
input: the declared workflow parameter, typed by the input type (possibly external); validated against its Schema first — failing raisesWorkflowInputValidationErrorcontext: host-injected read-only JSON. Declaringcontext: ContextTypeenables static member checks and runtime Schema validation; omitting the declaration leaves it asany
Common traps and their diagnostics
| Trap | Diagnostic |
|---|---|
| Reading an undeclared dependency in a stage | undeclared-dependency |
| Depending on a later stage | forward-dependency |
| Depending on a name that doesn't exist | unknown-stage |
Shorthand field { plan } with no visible plan | unknown-variable |
| Same-scope let reuse | duplicate-variable |
Reserved word as the map variable (as task) | a hard syntax error |
Shorthand object fields
input {
request: input
plan // equivalent to plan: plan — plan must be visible
}
Example: a full tour of the scopes
Excerpted from examples/data-report.flow:
stage profile -> DataProfile {
require unique(input.columns[*].name) // workflow-scope input
else fail "column names must be unique"
let result = agent(analyst) { /*...*/ expect DataProfile }
return result // stage-scope let
}
stage charts after profile -> ChartSpec[] { // dependency profile → visible
let specs = agent(analyst) {
input { table: input, profile: profile } // input and dependency both usable
expect ChartSpec[]
}
return specs
}
stage report after profile, charts -> text { // multiple dependencies
let narrative = agent(analyst) {
input { profile: profile, charts: charts }
expect text
}
return narrative
}
return { profile: profile, charts: charts, summary: report } // pipeline sees all