Building Workflows
Workflows are the core of your automation. They connect individual steps together to move data, make decisions, and interact with external systems.
In the @culvii/kit SDK, you build workflows by creating Step instances and connecting them, then wrapping them in a Workflow.
Create your first workflow
Every workflow needs a trigger-type step as its entry point: a manualTrigger, a cronTrigger, a webhookTrigger, or a connector trigger like gmailTrigger. Without one, there's nothing for a run to start from: a manual run and an automatic trigger both reference the workflow by that step's name, and neither works if it's missing. Let's start with a simple manual trigger that passes data to an output step.
import { Step, Workflow } from '@culvii/kit';
// 1. Create the trigger
const trigger = new Step({
name: 'Manual Trigger',
type: 'manualTrigger',
});
// 2. Create an action step
const output = new Step({
name: 'Set Output Data',
type: 'core.set',
params: {
values: {
triggered: true,
source: 'sdk',
},
},
});
// 3. Connect them
trigger.connectTo(output);
// 4. Group them into a workflow
const workflow = new Workflow({
id: 'my-first-workflow',
name: 'My First Workflow',
steps: [trigger, output],
});
Step IDs and Names
By default, the SDK generates a unique ID for each step. If you want stable snapshots for testing, you can provide your own id.
The name must be unique within the workflow. Dynamic values can only be set on a node's properties, inside params (serialized as nodeParams), not on name.
const step = new Step({
id: 'enrich-lead-step',
name: 'Enrich Lead',
type: 'core.set',
});
Chaining steps and passing data
When you call source.connectTo(target), you create a connection from the main output of the first step to the main input of the second. Data flows automatically along this path.
trigger.connectTo(enrichLead);
enrichLead.connectTo(notifySales);
Use an expression when a later step needs a value produced by an earlier step:
const saveReply = new Step({
name: 'Save Reply',
type: 'core.set',
params: {
values: {
reply: "={{ $('Support Agent').json.response }}",
},
},
});
See Workflow data and expressions for nested fields, arrays, items, and conditional branches.
Conditional logic and multiple outputs
Some steps have multiple outputs, like an "If" node that routes data based on a condition. You can specify exactly which output connects to which downstream step using connection options.
// Connect the "true" branch (output index 0) to the success step
checkCondition.connectTo(handleSuccess, {
fromPort: 'main',
fromOutputIndex: 0,
});
// Connect the "false" branch (output index 1) to the fallback step
checkCondition.connectTo(handleFallback, {
fromPort: 'main',
fromOutputIndex: 1,
});
fromOutputIndex chooses the branch. It is not part of the expression used by the target step.
Adding steps
Steps don't have to go in the Workflow constructor. Add them with addStep/addSteps as you build them out:
import { Step, Workflow } from '@culvii/kit';
const trigger = new Step({ name: 'Manual Trigger', type: 'manualTrigger' });
const output = new Step({
name: 'Set Output Data',
type: 'core.set',
params: { values: { triggered: true } },
});
trigger.connectTo(output);
const workflow = new Workflow({ id: 'my-first-workflow', name: 'My First Workflow' });
workflow.addSteps(trigger, output);
If you connect a step, it must be added to the workflow too. A step that connects to one missing from the workflow throws when validated.