kind | yes | enum | one of complete, enum_equals, compare, default, llm_choice, tool_result, code | — | complete = fires once every REQUIRED goal of this stage is filled (the natural ‘this stage is done -> go here’); enum_equals = fires when a collected goal value equals a constant (data-driven branch); compare = numeric/boolean comparison on a collected goal (Business); default = unconditional else, MUST be last; llm_choice = the agent chooses among the declared targets; code = fires when the boolean expr evaluates truthy over the routing context — values/saved/current/stages (Business); tool_result = reserved for a later phase (never fires yet). |
key | no | string | — | — | For enum_equals/compare: the goal key on THIS stage whose collected value is tested. |
value | no | string | — | — | For enum_equals/compare: the value to test against (stored as a string; parsed to a number for numeric compares). |
op | no | enum | one of ==, !=, >=, <=, >, <, contains | — | For compare: the comparison operator applied as (collected <op> value). |
expr | no | string | Business+ | — | For kind=‘code’ (REQUIRED then): a JS-like boolean expression evaluated over the routing context, fires when truthy. Available variables: values.<goalKey> (collected this turn), saved.<goalKey> (collected in earlier stages), current.isComplete / current.missing, stages.<stageId>.isComplete. Operators: == != === !== < <= > >= && || ! + - * / % and ternary; functions len(), lower(), upper(), includes(). Evaluated in a strict sandbox (no I/O, no globals); a parse/eval error fails open (edge does not fire). Example: saved.severity >= 4 && stages.kyc.isComplete. |