Building Workflows
Orchestrate multiple tools into automated processes
Workflows orchestrate multiple tools in sequence to automate complex processes. Unlike AI agents that decide which tools to call, workflows follow deterministic steps. Workflows in deco use the Mastra framework under the hood, giving you a set of composable patterns for control flow.
Workflow Basics
A workflow chains tools and other workflows into a deterministic sequence. Define one with createWorkflow() , specify schemas, chain steps with .then() , and finalize with .commit() .
import { createWorkflow, createStepFromTool } from "@deco/workers-runtime";
const createCustomerRegistrationWorkflow = (env: Env) => {
const captureInput = createStepFromTool(createCaptureCustomerInputTool(env));
const searchCep = createStepFromTool(createCepSearchTool(env));
const insertCustomer = createStepFromTool(createCustomerInsertTool(env));
const sendEmail = createStepFromTool(createSendWelcomeEmailTool(env));
return createWorkflow({
id: "CUSTOMER_REGISTRATION",
inputSchema: z.object({
name: z.string(),
cpf: z.string(),
cep: z.string(),
}),
outputSchema: z.object({
customerId: z.number(),
emailSent: z.boolean(),
}),
})
.then(captureInput)
.then(searchCep)
.map(({ captureInputOutput, searchCepOutput }) => ({
name: captureInputOutput.name,
cpf: captureInputOutput.cpf,
city: searchCepOutput.localidade,
state: searchCepOutput.uf,
}))
.then(insertCustomer)
.then(sendEmail)
.commit();
};
Control Flow Patterns
Sequential Steps ( .then() )
Chain tools one after another:
return createWorkflow({...})
.then(step1)
.then(step2)
.then(step3)
.commit();
Data Transformation ( .map() )
Transform data between steps:
.then(cepSearch)
.map(({ cepSearchOutput }) => ({
address: `${cepSearchOutput.logradouro}, ${cepSearchOutput.localidade}`,
state: cepSearchOutput.uf,
}))
.then(saveCustomer)
Parallel Execution ( .parallel() )
Run multiple tools simultaneously:
.parallel([
createStepFromTool(checkInventory(env)),
createStepFromTool(validatePayment(env)),
createStepFromTool(calculateShipping(env)),
])
.then(processOrder)
Conditional Logic ( .branch() )
Execute different paths based on conditions:
.branch([
{
condition: ({ previousOutput }) => previousOutput.type === "premium",
step: createStepFromTool(premiumProcessing(env)),
},
{
condition: ({ previousOutput }) => previousOutput.type === "standard",
step: createStepFromTool(standardProcessing(env)),
},
])
Looping ( .dowhile() / .dountil() / .foreach() )
Repeat steps based on conditions or iterate over arrays:
// Poll an API until a task is complete
.dountil(
createStepFromTool(checkTaskStatus(env)),
({ checkTaskStatusOutput }) => checkTaskStatusOutput.status === "completed"
)
// Process a list of items
.foreach(
createStepFromTool(processItem(env)),
{
concurrency: 3 // Process 3 items at a time
}
)
// Retry on failure
.dowhile(
createStepFromTool(attemptOperation(env)),
({ attemptOperationOutput }) =>
attemptOperationOutput.failed && attemptOperationOutput.retryCount < 3
)
Testing Workflows
Workflows appear as tools with three actions:
- Start: Begin workflow execution
- Resume: Continue a paused workflow
- Cancel: Stop workflow execution
Workflows run asynchronously. They return a run ID immediately and execute in the background.
Monitor Workflow Runs
- Go to your project on the deco CMS
- Click Workflows in the sidebar
- View execution details, including:
- Step-by-step progress
- Input/output for each step
- Execution time
- Success/failure status
Hybrid Approach: LLMs in Workflows
Use AI for specific steps within deterministic workflows:
const createDataProcessingWorkflow = (env: Env) => {
const extractStructuredData = createStepFromTool(createExtractDataTool(env));
const validateData = createStepFromTool(createValidateDataTool(env));
const saveData = createStepFromTool(createSaveDataTool(env));
return createWorkflow({
id: "PROCESS_CUSTOMER_MESSAGE",
inputSchema: z.object({
message: z.string(), // Unstructured user message
}),
outputSchema: z.object({
processed: z.boolean(),
}),
})
.then(extractStructuredData) // AI extracts structured data
.then(validateData) // Deterministic validation
.then(saveData) // Deterministic save
.commit();
};
This pattern handles unstructured input (user messages) but processes it deterministically.
Found an error or want to improve this page?
Edit this page