Sub-flows
A flow can invoke another deployed Core via the subflow_call node. The compiler emits an IRCoreCallBlock (kind: "core_call") per the ScaiCore IR spec.
Per-node config#
jsonc
{
"type": "subflow_call",
"config": {
"target": "core://acme/customer-lookup",
"flow_name": "LookupCustomer",
"input_bindings": { "customer_id": "{{message.customer_id}}" },
"instance_key": null,
"version": null,
"timeout": "30s",
"is_async": false
}
}
target— acore://{tenant_slug}/{slug}URI pointing at the called Core. Cross-tenant calls supported if the caller's principal has access on the other tenant.flow_name— optional; targets a specific flow within the called Core when the Core exposes multiple.input_bindings— map of{argument_name: expression}. Expressions can reference the calling flow's scope.instance_key— for entity-mode targets, picks the instance. Pass-through to the runtime.version— pin to a specific Core version. Omit to follow the target's default.timeout— wall-clock budget.is_async—truefor fire-and-forget;false(default) waits for the sub-flow's result.
Canvas picker#
The Sub-flow Target editor lists the calling tenant's flows from flowsListStore, lets you click one to fill in the core:// URI, and falls back to a free-text URI input for cross-tenant calls.
When to reach for sub-flows#
- Reuse. A "summarize transcript" flow that lives once and is called from three different parent flows.
- Specialization. A heavy reasoning step that warrants its own deploy/lifecycle (different model registry, different deploy cadence).
- Composition with HITL. The sub-flow contains the HITL surface; the parent doesn't have to know about it.
- Cross-tenant integration. Calling out to a partner-published Core via its
core://{partner}/{slug}URI.
When NOT to#
- "Just to organize the canvas" — large flows are easier to manage as one graph with named sections than as a fan-out of tiny sub-flows.
- "To split deterministic steps" —
@rigidblocks and plugin calls compose cheaply within the same flow. Sub-flows have invocation overhead.
IR shape#
python
1 2 3 4 5 6 7 8 9 10 | |
Per SCAICORE-COMPILER-IR.md §5.9.
YAML shape#
yaml
1 2 3 4 5 6 7 8 | |
The core_call YAML keyword isn't yet shown in ScaiGrid's public scaicore.md example — this is a best-effort emission matching the IR field names. If ScaiGrid's YAML loader doesn't recognize it on your deployment, fall back to --format ir.