Workflow Steps
Deep dive into all chain step types including prompts, API calls, conditionals, and data transformations.
Overview
Chain steps are the building blocks of workflows. Each step performs a specific action and can pass its output to subsequent steps. Steps execute in order unless conditional logic alters the flow.
| Parameter | Type | Description |
|---|---|---|
PROMPT | StepType | Execute an AI prompt with dynamic inputs |
API_CALL | StepType | Call an external API endpoint |
CONDITION | StepType | Branch execution based on a condition |
TRANSFORM | StepType | Transform or manipulate data |
MERGE | StepType | Combine outputs from multiple steps |
MEMORY | StepType | Store and retrieve persistent data |
Step Anatomy
Every step has the following core properties:
| Parameter | Type | Description |
|---|---|---|
orderrequired | number | Execution order (0-indexed). Steps execute in ascending order |
typerequired | StepType | The type of step (PROMPT, API_CALL, CONDITION, TRANSFORM, MERGE, MEMORY) |
config | JSON | Step-specific configuration (varies by type) |
inputMapping | JSON | How to map previous outputs to this step's inputs |
outputKey | string | Key to store this step's output for later steps to reference |
tags | string[] | Tags for conditional execution (used with CONDITION steps) |
PROMPT Steps
Prompt steps execute an AI prompt with inputs from the chain context. They are the most common step type and the core of most workflows.
Basic Structure
{
"order": 0,
"type": "PROMPT",
"promptId": "cm1234567890",
"inputMapping": {
"text": "{{userMessage}}",
"context": "{{previousStep.summary}}"
},
"outputKey": "analysis_result",
"config": {}
}Configuration Options
| Parameter | Type | Description |
|---|---|---|
promptIdrequired | ID | ID of the prompt to execute |
version | number | Specific prompt version to use (defaults to latest) |
overrideParams | JSON | Override model parameters (temperature, max_tokens) for this execution |
Override Model Parameters
{
"order": 0,
"type": "PROMPT",
"promptId": "cm1234567890",
"inputMapping": {
"text": "{{userMessage}}"
},
"outputKey": "creative_response",
"config": {
"overrideParams": {
"temperature": 0.9,
"max_tokens": 500
}
}
}Example Use Cases
Sentiment Analysis
Analyze customer messages to determine sentiment before routing or responding
Content Generation
Generate personalized responses based on user context and previous step outputs
Data Extraction
Extract structured data from unstructured text for use in subsequent steps
API_CALL Steps
API call steps make HTTP requests to external services. They enable integration with third-party APIs, databases, or internal services.
Basic Structure
{
"order": 1,
"type": "API_CALL",
"config": {
"url": "https://api.example.com/v1/users",
"method": "POST",
"headers": {
"Authorization": "Bearer {{apiKey}}",
"Content-Type": "application/json"
},
"body": {
"email": "{{userEmail}}",
"sentiment": "{{sentiment_analysis.sentiment}}",
"message": "{{userMessage}}"
},
"timeout": 5000
},
"outputKey": "api_response"
}Configuration Options
| Parameter | Type | Description |
|---|---|---|
urlrequired | string | API endpoint URL (supports template variables) |
methodrequired | string | HTTP method (GET, POST, PUT, PATCH, DELETE) |
headers | object | Request headers (supports template variables) |
body | object | Request body for POST/PUT/PATCH (supports template variables) |
queryParams | object | URL query parameters (supports template variables) |
timeout | number | Request timeout in milliseconds (default: 10000) |
GET Request Example
{
"order": 0,
"type": "API_CALL",
"config": {
"url": "https://api.example.com/v1/users/{{userId}}",
"method": "GET",
"headers": {
"Authorization": "Bearer {{apiKey}}"
},
"queryParams": {
"include": "profile,settings"
}
},
"outputKey": "user_data"
}Response Handling
The API response is automatically parsed as JSON and stored in the output key. You can reference nested response data in subsequent steps:
// API response stored in "api_response":
{
"status": "success",
"data": {
"ticketId": "TKT-12345",
"assignedTo": "support-team"
}
}
// Reference in next step:
{
"inputMapping": {
"ticketId": "{{api_response.data.ticketId}}",
"assignee": "{{api_response.data.assignedTo}}"
}
}Example Use Cases
CRM Integration
Create or update customer records in Salesforce, HubSpot, or custom CRMs
Database Queries
Fetch user data, preferences, or historical information via REST APIs
Notification Services
Send emails, SMS, or push notifications via third-party services
CONDITION Steps
Condition steps enable branching logic in workflows. They evaluate expressions and tag subsequent steps for conditional execution.
Basic Structure
{
"order": 2,
"type": "CONDITION",
"config": {
"condition": "{{sentiment_analysis.sentiment}} == 'Negative'",
"trueTag": "escalate",
"falseTag": "standard"
}
}Configuration Options
| Parameter | Type | Description |
|---|---|---|
conditionrequired | string | Boolean expression to evaluate (supports ==, !=, >, <, >=, <=, &&, ||) |
trueTagrequired | string | Tag for steps to execute when condition is true |
falseTagrequired | string | Tag for steps to execute when condition is false |
Supported Operators
| Parameter | Type | Description |
|---|---|---|
== | operator | Equality comparison |
!= | operator | Inequality comparison |
> | operator | Greater than |
< | operator | Less than |
>= | operator | Greater than or equal |
<= | operator | Less than or equal |
&& | operator | Logical AND |
|| | operator | Logical OR |
Complex Conditions
{
"order": 1,
"type": "CONDITION",
"config": {
"condition": "{{sentiment.confidence}} >= 0.8 && {{sentiment.sentiment}} == 'Negative'",
"trueTag": "high_priority_escalation",
"falseTag": "normal_processing"
}
}Tagging Steps for Conditional Execution
[
{
"order": 0,
"type": "PROMPT",
"promptId": "sentiment-analyzer",
"inputMapping": { "text": "{{message}}" },
"outputKey": "sentiment"
},
{
"order": 1,
"type": "CONDITION",
"config": {
"condition": "{{sentiment.sentiment}} == 'Negative'",
"trueTag": "escalate",
"falseTag": "standard"
}
},
{
"order": 2,
"type": "PROMPT",
"promptId": "escalation-response",
"tags": ["escalate"],
"inputMapping": { "message": "{{message}}", "sentiment": "{{sentiment}}" },
"outputKey": "response"
},
{
"order": 3,
"type": "PROMPT",
"promptId": "standard-response",
"tags": ["standard"],
"inputMapping": { "message": "{{message}}" },
"outputKey": "response"
}
]TRANSFORM Steps
Transform steps manipulate data between steps. They can format strings, perform calculations, merge objects, or restructure data.
Basic Structure
{
"order": 1,
"type": "TRANSFORM",
"config": {
"operation": "merge",
"inputs": ["{{user_data}}", "{{sentiment_analysis}}"]
},
"outputKey": "combined_data"
}Supported Operations
| Parameter | Type | Description |
|---|---|---|
merge | operation | Merge multiple objects into one |
extract | operation | Extract specific fields from an object |
format | operation | Format strings with template syntax |
calculate | operation | Perform mathematical calculations |
array_map | operation | Transform each element in an array |
array_filter | operation | Filter array elements by condition |
Merge Operation
{
"order": 2,
"type": "TRANSFORM",
"config": {
"operation": "merge",
"inputs": [
"{{user_profile}}",
"{{sentiment_data}}",
{ "processedAt": "{{now}}" }
]
},
"outputKey": "enriched_data"
}Extract Operation
{
"order": 1,
"type": "TRANSFORM",
"config": {
"operation": "extract",
"input": "{{api_response}}",
"fields": ["data.userId", "data.email", "status"]
},
"outputKey": "user_info"
}Format Operation
{
"order": 1,
"type": "TRANSFORM",
"config": {
"operation": "format",
"template": "User {{user.name}} ({{user.email}}) - Sentiment: {{sentiment.result}}",
"inputs": {
"user": "{{user_data}}",
"sentiment": "{{sentiment_analysis}}"
}
},
"outputKey": "formatted_summary"
}Calculate Operation
{
"order": 3,
"type": "TRANSFORM",
"config": {
"operation": "calculate",
"expression": "{{price}} * {{quantity}} * (1 - {{discount}})",
"inputs": {
"price": "{{product.price}}",
"quantity": "{{order.quantity}}",
"discount": "{{user.discountRate}}"
}
},
"outputKey": "total_cost"
}MERGE Steps
Merge steps combine outputs from multiple previous steps into a single unified object or array. This is useful when you need to consolidate data from parallel operations or combine results for downstream processing.
Basic Structure
{
"order": 3,
"type": "MERGE",
"config": {
"sources": ["sentiment_analysis", "user_profile", "risk_score"],
"strategy": "object"
},
"outputKey": "combined_context"
}Configuration Options
| Parameter | Type | Description |
|---|---|---|
sourcesrequired | string[] | Array of output keys from previous steps to merge |
strategyrequired | string | Merge strategy: "object" (merge properties) or "array" (collect as array) |
Object Merge Strategy
The object strategy merges all properties from the specified sources into a single object. If sources have overlapping properties, later values override earlier ones.
{
"order": 3,
"type": "MERGE",
"config": {
"sources": ["user_data", "sentiment_result", "risk_assessment"],
"strategy": "object"
},
"outputKey": "enriched_profile"
}
// Input:
// user_data: { "userId": "123", "name": "John" }
// sentiment_result: { "sentiment": "positive", "confidence": 0.95 }
// risk_assessment: { "riskScore": 0.12, "category": "low" }
// Output (enriched_profile):
{
"userId": "123",
"name": "John",
"sentiment": "positive",
"confidence": 0.95,
"riskScore": 0.12,
"category": "low"
}Array Collection Strategy
The array strategy collects all source values into an array, preserving each source as a separate element.
{
"order": 4,
"type": "MERGE",
"config": {
"sources": ["analysis_1", "analysis_2", "analysis_3"],
"strategy": "array"
},
"outputKey": "all_analyses"
}
// Input:
// analysis_1: { "result": "positive" }
// analysis_2: { "result": "neutral" }
// analysis_3: { "result": "positive" }
// Output (all_analyses):
[
{ "result": "positive" },
{ "result": "neutral" },
{ "result": "positive" }
]Example Use Cases
Multi-Model Analysis
Run the same input through multiple AI models and merge their outputs for comparison
Context Enrichment
Combine user data from CRM, sentiment analysis, and historical interactions into a unified context
Parallel Processing
Collect results from multiple API calls or analyses that run independently
MEMORY Steps
Memory steps provide persistent, user-scoped key-value storage with versioning and automatic compression. Use memory to maintain context across multiple chain executions, store user preferences, or track conversation history.
Basic Structure
{
"order": 2,
"type": "MEMORY",
"config": {
"operation": "set",
"key": "customer.sentiment_history"
},
"inputMapping": {
"value": "{{sentiment_analysis}}"
},
"outputKey": "memory_result"
}Memory Operations
| Parameter | Type | Description |
|---|---|---|
get | operation | Retrieve a single memory value by key |
set | operation | Store or update a memory value with optional compression |
query | operation | Search memories using pattern matching (e.g., customer.*) |
delete | operation | Delete all versions of a memory key |
getKeys | operation | List all available memory keys |
getHistory | operation | Get version history for a memory key |
GET Operation
Retrieve a stored memory value by its key. Returns null if the key does not exist.
{
"order": 0,
"type": "MEMORY",
"config": {
"operation": "get",
"key": "customer.profile"
},
"outputKey": "customer_profile"
}
// Output:
{
"value": {
"name": "John Doe",
"preferences": ["email", "sms"],
"lastInteraction": "2025-01-15"
},
"version": 3,
"compressed": false
}SET Operation
Store a value in memory with optional automatic compression. If the content exceeds the specified token limit, it will be automatically summarized using an LLM.
{
"order": 1,
"type": "MEMORY",
"config": {
"operation": "set",
"key": "customer.sentiment",
"maxTokens": 500
},
"inputMapping": {
"value": "{{sentiment_analysis}}"
},
"outputKey": "memory_result"
}
// Output:
{
"id": "mem_abc123",
"key": "customer.sentiment",
"version": 2,
"compressed": false,
"tokenCount": 45
}| Parameter | Type | Description |
|---|---|---|
keyrequired | string | Hierarchical key using dot notation (e.g., customer.profile.preferences) |
valuerequired | any | The value to store (provided via inputMapping) |
maxTokens | number | Maximum tokens before compression (default: 500) |
summarizationPromptId | ID | Custom prompt for summarization (optional) |
QUERY Operation
Search for memories using wildcard patterns. This is useful for retrieving related memories or exploring what data is stored under a namespace.
{
"order": 0,
"type": "MEMORY",
"config": {
"operation": "query",
"keyPattern": "customer.*",
"limit": 10
},
"outputKey": "customer_memories"
}
// Output:
{
"results": [
{
"key": "customer.profile",
"value": { "name": "John", "email": "john@example.com" },
"version": 1
},
{
"key": "customer.sentiment",
"value": { "sentiment": "positive", "confidence": 0.95 },
"version": 2
},
{
"key": "customer.preferences",
"value": ["email", "sms"],
"version": 1
}
],
"count": 3
}| Parameter | Type | Description |
|---|---|---|
keyPatternrequired | string | Pattern with wildcards (e.g., customer.* matches customer.profile, customer.sentiment) |
limit | number | Maximum number of memories to return (default: 50) |
valueType | string | Filter by value type: string, object, array, number |
Memory Keys and Namespacing
Memory keys use dot notation to create hierarchical namespaces. This helps organize related data and makes pattern-based queries more powerful.
// Good key structure examples:
"customer.profile" // Customer profile data
"customer.sentiment_history" // Historical sentiment data
"customer.preferences.contact" // Contact preferences
"session.context" // Current session context
"analytics.summary" // Analytics summaries
// Query examples:
"customer.*" // All customer data
"customer.preferences.*" // All customer preferences
"*.summary" // All summaries across namespacesAutomatic Compression
When memory content exceeds the specified maxTokens, the system automatically compresses it using an LLM-based summarization prompt. This keeps memory storage efficient while preserving important information.
{
"order": 1,
"type": "MEMORY",
"config": {
"operation": "set",
"key": "conversation.history",
"maxTokens": 500,
"summarizationPromptId": "custom-summarizer"
},
"inputMapping": {
"value": "{{conversation_transcript}}"
},
"outputKey": "stored_memory"
}
// If conversation_transcript is 2000 tokens:
// - System detects it exceeds maxTokens (500)
// - Automatically summarizes using the specified prompt
// - Stores compressed version
// - Sets compressed: true in metadataExample Use Cases
Conversation History
Store conversation context across multiple interactions to provide personalized responses
User Preferences
Remember user preferences, settings, and behavior patterns for customized experiences
Analytics Tracking
Track sentiment trends, interaction patterns, or any time-series data per user
Progressive Profiling
Build rich user profiles over time by accumulating insights from each interaction
DELETE Operation
{
"order": 5,
"type": "MEMORY",
"config": {
"operation": "delete",
"key": "customer.old_data"
},
"outputKey": "delete_result"
}
// Output:
{
"success": true,
"deletedCount": 3 // Number of versions deleted
}GET KEYS Operation
{
"order": 0,
"type": "MEMORY",
"config": {
"operation": "getKeys",
"pattern": "customer.*"
},
"outputKey": "available_keys"
}
// Output:
{
"keys": [
"customer.profile",
"customer.sentiment",
"customer.preferences",
"customer.history"
]
}GET HISTORY Operation
{
"order": 0,
"type": "MEMORY",
"config": {
"operation": "getHistory",
"key": "customer.sentiment"
},
"outputKey": "sentiment_history"
}
// Output:
{
"versions": [
{
"version": 3,
"value": { "sentiment": "positive", "confidence": 0.95 },
"createdAt": "2025-01-15T10:30:00Z",
"compressed": false
},
{
"version": 2,
"value": { "sentiment": "neutral", "confidence": 0.87 },
"createdAt": "2025-01-10T14:20:00Z",
"compressed": false
},
{
"version": 1,
"value": { "sentiment": "negative", "confidence": 0.91 },
"createdAt": "2025-01-05T09:15:00Z",
"compressed": false
}
]
}Step Execution Flow
Steps execute in order based on their order property:
- Chain receives input and initializes context
- Steps are sorted by order (0, 1, 2, ...)
- For each step:
- Check if step has tags (skip if tags don't match active condition)
- Resolve input mapping from context
- Execute step (prompt, API call, etc.)
- Store output in context with outputKey
- Record metrics (latency, cost, status)
- Return final output (usually from last executed step)