Workflows

Build visual AI workflows with drag-and-drop nodes, agent orchestration, conditional logic, and automated triggers.

Overview

Workflows enable you to create complex AI automation pipelines using a visual node-based editor. Features include:

  • Visual workflow builder with React Flow
  • Multiple trigger types (manual, webhook, cron, event)
  • Agent nodes for AI processing
  • Conditional branching and loops
  • Data transformation nodes
  • Integration with all Tenzro services

Quick Start

import { Tenzro } from 'tenzro';
const tenzro = new Tenzro({ apiKey: 'your-api-key' });
// Create a simple workflow
const workflow = await tenzro.workflows.create({
projectId: 'project-id',
workflowName: 'content-pipeline',
triggerType: 'webhook',
nodes: [
{
id: 'input',
type: 'trigger',
position: { x: 100, y: 100 },
data: { label: 'Webhook Trigger' },
},
{
id: 'agent',
type: 'agent',
position: { x: 300, y: 100 },
data: {
label: 'Content Agent',
agentId: 'your-agent-id',
},
},
{
id: 'output',
type: 'output',
position: { x: 500, y: 100 },
data: { label: 'Output' },
},
],
edges: [
{ id: 'e1', source: 'input', target: 'agent' },
{ id: 'e2', source: 'agent', target: 'output' },
],
});
// Publish the workflow
await tenzro.workflows.publish(workflow.workflow_id);
// Execute manually
const execution = await tenzro.workflows.execute(workflow.workflow_id, {
inputData: { topic: 'AI trends' },
});
console.log(execution.status); // 'COMPLETED'
console.log(execution.output_data); // Generated content

Node Types

Trigger Nodes

TypeDescription
manualManually triggered via API or console
webhookTriggered by HTTP POST to webhook URL
cronScheduled execution on cron schedule
eventTriggered by system events

Processing Nodes

NodeDescription
agentExecute an AI agent with input data
inferenceDirect LLM inference without agent
embedGenerate embeddings from text
transformTransform data with JavaScript
conditionalBranch based on conditions
loopIterate over arrays

Data Nodes

NodeDescription
vec-searchSearch vector database
vec-insertInsert into vector database
data-queryExecute SQL query
kev-getGet from key-value store
kev-setSet in key-value store
httpMake HTTP request

SDK Reference

Create Workflow

const workflow = await tenzro.workflows.create({
projectId: string,
workflowName: string,
workflowDescription?: string,
nodes?: WorkflowNode[],
edges?: WorkflowEdge[],
viewport?: { x: number, y: number, zoom: number },
variables?: Record<string, any>,
triggerType?: 'manual' | 'webhook' | 'cron' | 'event',
triggerConfig?: Record<string, any>,
});

Lifecycle Management

// Publish workflow (makes it executable)
await tenzro.workflows.publish(workflowId);
// Pause workflow (disable triggers)
await tenzro.workflows.pause(workflowId);
// Update workflow nodes/edges
await tenzro.workflows.update(workflowId, {
nodes: updatedNodes,
edges: updatedEdges,
});
// Delete workflow
await tenzro.workflows.delete(workflowId);

Execution

// Execute workflow
const execution = await tenzro.workflows.execute(workflowId, {
inputData?: Record<string, any>,
triggerType?: TriggerType,
triggerData?: Record<string, any>,
});
// Trigger via webhook-style endpoint
const result = await tenzro.workflows.trigger(workflowId, data);
// Get execution details
const execution = await tenzro.workflows.getExecution(workflowId, executionId);
// Get node-level execution details
const { nodeExecutions } = await tenzro.workflows.getNodeExecutions(
workflowId,
executionId
);
// Cancel running execution
await tenzro.workflows.cancelExecution(workflowId, executionId);

Templates

// Get available templates
const { data: templates } = await tenzro.workflows.getTemplates('automation');
// Create workflow from template
const workflow = await tenzro.workflows.createFromTemplate({
templateId: 'content-pipeline',
projectId: 'project-id',
workflowName: 'My Content Pipeline',
});

Statistics

const { stats } = await tenzro.workflows.getStats(workflowId);
// Stats include:
interface WorkflowStats {
totalExecutions: number;
successfulExecutions: number;
failedExecutions: number;
successRate: string;
avgExecutionTimeMs: number;
totalCostMicrodollars: number;
totalCostDollars: string;
lastExecutedAt?: string;
nodeCount: number;
edgeCount: number;
}

Building Workflows

RAG Pipeline

const workflow = await tenzro.workflows.create({
projectId: 'project-id',
workflowName: 'rag-pipeline',
triggerType: 'webhook',
nodes: [
{
id: 'trigger',
type: 'trigger',
position: { x: 100, y: 200 },
data: { label: 'User Query' },
},
{
id: 'embed',
type: 'embed',
position: { x: 300, y: 200 },
data: {
taskType: 'RETRIEVAL_QUERY',
dimensionality: 768,
},
},
{
id: 'search',
type: 'vec-search',
position: { x: 500, y: 200 },
data: {
vecDbId: 'your-vec-db-id',
topK: 5,
},
},
{
id: 'agent',
type: 'agent',
position: { x: 700, y: 200 },
data: {
agentId: 'your-agent-id',
inputMapping: {
query: '{{trigger.query}}',
context: '{{search.results}}',
},
},
},
{
id: 'output',
type: 'output',
position: { x: 900, y: 200 },
data: {},
},
],
edges: [
{ id: 'e1', source: 'trigger', target: 'embed' },
{ id: 'e2', source: 'embed', target: 'search' },
{ id: 'e3', source: 'search', target: 'agent' },
{ id: 'e4', source: 'agent', target: 'output' },
],
});

Conditional Branching

const nodes = [
{
id: 'classify',
type: 'agent',
position: { x: 300, y: 200 },
data: {
agentId: 'classifier-agent',
prompt: 'Classify this message as: support, sales, or other',
},
},
{
id: 'condition',
type: 'conditional',
position: { x: 500, y: 200 },
data: {
conditions: [
{ path: 'support', condition: "{{classify.result}} === 'support'" },
{ path: 'sales', condition: "{{classify.result}} === 'sales'" },
{ path: 'default', condition: 'true' },
],
},
},
{
id: 'support-agent',
type: 'agent',
position: { x: 700, y: 100 },
data: { agentId: 'support-agent' },
},
{
id: 'sales-agent',
type: 'agent',
position: { x: 700, y: 200 },
data: { agentId: 'sales-agent' },
},
{
id: 'general-agent',
type: 'agent',
position: { x: 700, y: 300 },
data: { agentId: 'general-agent' },
},
];
const edges = [
{ id: 'e1', source: 'trigger', target: 'classify' },
{ id: 'e2', source: 'classify', target: 'condition' },
{ id: 'e3', source: 'condition', target: 'support-agent', sourceHandle: 'support' },
{ id: 'e4', source: 'condition', target: 'sales-agent', sourceHandle: 'sales' },
{ id: 'e5', source: 'condition', target: 'general-agent', sourceHandle: 'default' },
];

Scheduled Workflow

const workflow = await tenzro.workflows.create({
projectId: 'project-id',
workflowName: 'daily-report',
triggerType: 'cron',
triggerConfig: {
schedule: '0 9 * * *', // Every day at 9 AM UTC
timezone: 'America/New_York',
},
nodes: [
{
id: 'query',
type: 'data-query',
position: { x: 200, y: 200 },
data: {
dataDbId: 'analytics-db',
sql: `
SELECT date, SUM(revenue) as total
FROM orders
WHERE date = CURRENT_DATE - 1
GROUP BY date
`,
},
},
{
id: 'summarize',
type: 'agent',
position: { x: 400, y: 200 },
data: {
agentId: 'report-agent',
prompt: 'Generate a daily sales summary from this data: {{query.results}}',
},
},
{
id: 'email',
type: 'http',
position: { x: 600, y: 200 },
data: {
method: 'POST',
url: 'https://api.sendgrid.com/v3/mail/send',
headers: { Authorization: 'Bearer {{env.SENDGRID_KEY}}' },
body: {
to: 'team@company.com',
subject: 'Daily Sales Report',
content: '{{summarize.result}}',
},
},
},
],
});

Variables and Data Flow

Reference data between nodes using template syntax:

// Access trigger data
'{{trigger.field}}'
// Access previous node output
'{{nodeId.result}}'
'{{nodeId.data.field}}'
// Access workflow variables
'{{variables.apiKey}}'
// Access environment variables
'{{env.SECRET_KEY}}'
// Array access
'{{nodeId.results[0].text}}'
// Conditional expressions
'{{trigger.type === "urgent" ? "high" : "normal"}}'

Best Practices

  • Test in draft: Use manual execution to test before publishing
  • Use variables: Store configuration in workflow variables, not hardcoded
  • Handle errors: Add error handling nodes for critical paths
  • Monitor executions: Review failed executions and optimize
  • Version control: Workflows are versioned; track changes

Limits

ResourceLimit
Max nodes per workflow100
Max edges per workflow200
Execution timeout30 minutes
Max concurrent executions10
Cron minimum interval5 minutes