AutoFlow
Architecture

Schema Validation

JSON Schema validation and custom rules for workflow correctness.

AutoFlow validates all generated workflows against two JSON schemas plus custom structural rules implemented in src/autoflow/schemas/validator.py.

Workflow Schema

schemas/asksage_workflow/schema.json defines the structure of Agent Builder workflows:

Node Types

8 supported node types:

TypePurpose
llmCall an LLM with system prompt, user prompt template, temperature, and model
read_fileRead a file and expose its content as {{read_file.content}}
loopIterate over a list, exposing {{loop.item}} and collecting {{looped.items}}
if_elseBinary conditional routing (true/false or if/else handles)
variable_assignmentSet a variable to a static or computed value
flat_responseReturn a plain text response (no LLM call)
decision_treeMulti-way routing based on categories (dynamic sourceHandle names)
variable_transformTransform data with expression-based operations

Edge Rules

  • sourceHandle values: "out", "true"/"false", "if"/"else", "loop_out"/"complete", "pass"/"fail", or dynamic category names from decision_tree
  • targetHandle values: "in" or "loop_in"
  • Every edge must reference existing node IDs

Variable Patterns

Workflows use double-brace variable references:

PatternMeaning
{{input.message}}The user's input message
{{node_id.response}}Output from an LLM node
{{loop.item}}Current item in a loop iteration
{{looped.items}}Collected results after loop completes
{{read_file.content}}Content from a read_file node
{{node_id.category}}Category output from a decision_tree
{{node_id.confidence}}Confidence score from a decision_tree
{{node_id.value}}Value from a variable_transform

Identity Model (v1 vs v2)

AutoFlow supports two workflow identity formats. The validator auto-detects the version using detect_workflow_version():

v1 Format (Legacy)

Nodes use snake_case string IDs. Edges reference nodes by these string IDs.

{
  "id": "intake",
  "type": "llm",
  "label": "Intake",
  "position": { "x": 0, "y": 0 },
  "config": { ... }
}

v2 Format (Current)

Nodes use a three-layer identity model: UUID id (execution wiring), slug (variable references), and label (display). Edges wire by UUID. All nodes include a key field (default "").

{
  "id": "862ffdc5-f240-535b-ba94-05807abb7952",
  "slug": "extractor",
  "key": "",
  "type": "llm",
  "label": "Extractor",
  "position": { "x": 0, "y": 0 },
  "config": { ... }
}
LayerFieldFormatPurpose
ExecutionidUUID (v4 or v5)Edge wiring, Ask Sage internal
Referenceslugsnake_caseVariable references ({{slug.response}})
DisplaylabelFree textHuman-readable name in the UI

Variable references use slugs, not UUIDs: {{extractor.response}}, not {{862ffdc5-....response}}.

Custom Validation Rules

v1 Rules

  1. Unique snake_case node IDs — Every id must be unique and use snake_case formatting
  2. Valid edge references — All source and target in edges must reference existing node IDs
  3. No orphan nodes — Every node must be connected by at least one edge (except the entry node)
  4. Position bounds — Node positions must be within -10000 to 10000 on both axes
  5. Variable resolution — All {{variable}} references must resolve to a node that appears earlier in the graph

v2 Rules (Superset)

All v1 structural rules apply, plus:

  1. UUID node IDs — Every node id must be a valid UUID
  2. Slug required — Every node must have a slug field in snake_case format
  3. Slug uniqueness — No two nodes may share the same slug
  4. UUID edge IDs — Every edge id, source, and target must be valid UUIDs
  5. Edge references by UUID — Edge source/target must match node UUIDs
  6. Variable refs use slugs{{slug.response}} resolves against node slugs, not UUIDs

Semantic Validation (v2 Only)

Beyond structural checks, v2 workflows are validated for execution safety:

  1. Terminal node required — At least one flat_response node or an llm node with terminal_node: true in its config
  2. Dangling handle detectionif_else must have both branches wired (true/false or if/else); decision_tree must have an edge for every category; loop must have both loop_out and complete handles wired
  3. Mustache restrictionif_else condition fields must not contain {{...}} variable syntax
  4. Loop boundsloop nodes must have max_iterations set within allowed limits
  5. Registry config validation — Each node's config is validated against the node registry's parameter definitions (required fields, types, ranges, enums)

Node Registry

The node registry (node_registry/asksage_nodes.yaml) is the single source of truth for all 8 node types. It defines each type's parameters, handles, and constraints. The validator uses the registry for config validation, and per-node JSON Schemas are auto-generated from it into schemas/nodes/.

Output Envelope Schema

schemas/universal_output_envelop/schema.json validates the wrapper around every pipeline output:

{
  "objective": "string",
  "deliverable_artifact": "object",
  "quality_scores": {
    "correctness": "integer (1-5)",
    "completeness": "integer (1-5)",
    "format_validity": "integer (1-5)",
    "efficiency": "integer (1-5)",
    "reusability": "integer (1-5)"
  },
  "confidence": "number (0-1)",
  "assumptions": ["string"],
  "constraints": ["string"],
  "known_gaps": ["string"],
  "estimated_human_edit_minutes": "integer",
  "recommended_next_actions": ["string"],
  "metadata": "object"
}

Quality Rubric

The 5-point scoring scale used by the EvaluatorAgent:

DimensionWhat It Measures
CorrectnessDoes the workflow solve the stated objective?
CompletenessAre all necessary steps and edge cases covered?
Format ValidityIs the output valid Ask Sage Agent Builder JSON?
EfficiencyMinimal nodes, smart routing, no redundancy?
ReusabilityCan the workflow be generalized for similar tasks?

On this page