Workflow definition (kletso.workflow/v1)beta
The node and edge document produced by the visual builder and executed by the runtime's workflow runner.
{ "schema": "kletso.workflow/v1",
"input": { "type": "object", "properties": { "orderId": { "type": "string" } }, "required": ["orderId"] },
"vars": {},
"nodes": [
{ "id": "start", "type": "start", "title": "Start", "config": {}, "position": { "x": 40, "y": 180 }, "onError": "fail", "timeoutMs": 0 },
{ "id": "order", "type": "http", "title": "Fetch order", "config": { "toolName": "get_order", "input": { "orderId": "{{ input.orderId }}" } }, "position": { "x": 260, "y": 180 }, "onError": "fail", "timeoutMs": 8000 },
{ "id": "eligible", "type": "condition", "title": "Refund eligible?", "config": { "expression": "order.ageDays <= 30 && order.status == \"delivered\"" }, "position": { "x": 490, "y": 180 }, "onError": "fail", "timeoutMs": 0 },
{ "id": "notify", "type": "notify", "title": "Notify the app", "config": { "title": "Refund on its way", "body": "{{ order.total }} back on your card in 3–5 days.", "channel": "banner", "openChat": true }, "position": { "x": 980, "y": 60 }, "onError": "continue", "timeoutMs": 0 },
{ "id": "end", "type": "end", "title": "End", "config": {}, "position": { "x": 1200, "y": 180 }, "onError": "fail", "timeoutMs": 0 }
],
"edges": [
{ "id": "e1", "from": "start", "to": "order" },
{ "id": "e2", "from": "order", "to": "eligible" },
{ "id": "e3", "from": "eligible", "to": "notify", "label": "true" },
{ "id": "e4", "from": "eligible", "to": "end", "label": "false" },
{ "id": "e5", "from": "notify", "to": "end" }
] }
Node
| Field | Notes |
|---|---|
id | unique; also the variable name for the node’s output |
type | start, end, return, condition, transform, http, tool, retrieve, render_ui, notify, ai, judge (Decision, beta: config.state, config.questions; output is Jev’s answers map) |
title | shown on the canvas |
config | type-specific, see Workflows |
position | canvas coordinates |
onError | fail (abort), continue (mark skipped, go on), retry (one immediate retry) |
timeoutMs | stored; not enforced by the runner yet |
Execution
Start at the start node; follow edges[0] from each node, except condition, which follows the edge labelled "true" or "false" (falling back to an unlabelled edge). Variables begin as { input, context } and each node’s output is stored under its id, available to later templates as {{ nodeId.field }}. The run ends at end, at return (whose rendered value becomes the output), or after 100 node executions. The result is { status, error, nodeLog[], output } where each log entry records nodeId, title, type, status completed·failed·skipped, durationMs, input, output.
Templates and expressions
Templates use {{ path.to.value }} with dotted paths; unknown paths render empty. Conditions support &&, ||, ==, !=, <, <=, >, >=, !, parentheses, strings, numbers, true, false, null. There is no eval.