Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Edge kinds reference

Three edge kinds. Differ in semantics, not in field shape.

Kind condition required Used for
sequential no Unconditional next-step. Most edges.
conditional yes Branches from a logic_decision node, or any place a condition gates control.
data no Pure data dependency without control transfer. Rare.

Shape#

Same for all three:

jsonc
{
  "id": "edge_<random>",
  "type": "sequential",                   // or conditional, data
  "source": { "node": "node_a", "port": "out" },
  "target": { "node": "node_b", "port": "in" },
  "condition": "confidence > 0.7"        // required when type === "conditional"
}

source.port and target.port must refer to actually-existing port ids on the respective nodes — the analyze stage validates this and refuses dangling references.

sequential#

jsonc
{ "type": "sequential",
  "source": { "node": "node_classify", "port": "out" },
  "target": { "node": "node_respond", "port": "in" } }

Plain control-flow edge. The target runs after the source completes.

conditional#

jsonc
{ "type": "conditional",
  "condition": "confidence > 0.7",
  "source": { "node": "node_decision", "port": "out" },
  "target": { "node": "node_respond_directly", "port": "in" } }

The target runs only if condition evaluates truthy in the source's emitted scope.

For a Decision node with three branches, you'd have three conditional edges all leaving the same out port, each with its own condition:

jsonc
[
  { "type": "conditional", "condition": "intent == 'refund'", "source": {...}, "target": {...} },
  { "type": "conditional", "condition": "intent == 'complaint'", "source": {...}, "target": {...} },
  { "type": "conditional", "condition": "true", "source": {...}, "target": {...} }  // fallthrough
]

The fallthrough edge could also be sequential — they're semantically equivalent when the prior conditionals have been evaluated. Decision-style conventions vary.

data#

jsonc
{ "type": "data",
  "source": { "node": "node_produce_value", "port": "out_aux" },
  "target": { "node": "node_consume_value", "port": "in_aux" } }

Documents that the target needs a value from the source, but doesn't transfer control. Useful when the target is on a different control branch but still references a value the source bound.

Currently advisory — the compiler emits them on the IR but ScaiCore's runtime doesn't enforce data-only edges differently from sequential. Reserved for richer dependency-tracking in future.

Editing edges#

In the canvas:

  • Click an edge to select it. The property panel shows the edge's type, condition (when conditional), source, and target.
  • Decision branches: click the Decision node first — the property panel's Branches section lists every outgoing edge inline with editable conditions. Easier than clicking each edge separately.

In code:

  • PUT /v1/flows/{id} with the updated edges array.
  • Or programmatic via flowStore.updateEdge(edge_id, { condition: ... }) from the canvas.
Updated 2026-05-18 16:05:21 View source (.md) rev 3