Documentation Index
Fetch the complete documentation index at: https://docs.tryhamsa.com/llms.txt
Use this file to discover all available pages before exploring further.
Transitions define when and how the conversation moves from one node to another. Each node can have multiple transitions; they are evaluated by priority (highest first) and the first matching transition fires.
Transition Types
| Type | Evaluation | Use Case |
|---|
| Natural Language | LLM-based | Intent detection, sentiment |
| Structured Equation | Rule-based | Variable comparisons, thresholds |
| DTMF | Keypad input | IVR menus, quick selection |
| Always | No condition | Fallback / default path |
Priority
Each transition has a numeric priority. Higher values are evaluated first. When multiple transitions have the same priority, their order is indeterminate.
Default priorities if not set manually:
- Natural Language: 100
- Structured Equation: 200
- DTMF: 300
- Always: 0
Set priorities explicitly when you need a specific evaluation order.
Always include an Always transition as a fallback. If no transitions match, the conversation stalls.
Natural Language Transitions
The LLM evaluates whether the condition (prompt) is met based on the user’s input and conversation context.
Configuration
{
type: 'natural_language',
prompt: string, // Condition description (required)
description?: string
}
Examples
Prompt: "The user wants to speak with a human agent"
→ Target: Transfer_to_Agent
Prompt: "The user is asking about billing or payment issues"
→ Target: Billing_Department
Prompt: "The user agrees or says yes"
→ Target: Confirm_Path
Prompt: "The user declines or says no"
→ Target: Alternative_Path
Write conditions that describe user intent, not exact phrases. “The user wants to speak with a human” matches “get me an agent”, “transfer me”, “I need a person”, etc.
Structured Equation Transitions
Equation transitions evaluate variable conditions using rule-based logic — no LLM involved.
Configuration
{
type: 'structured_equation',
logic: 'all' | 'any', // AND or OR
conditions: Array<{
variable: string,
operator: Operator,
value: string | number | boolean,
description?: string
}>,
description?: string
}
Operators
| Operator | Description |
|---|
equals | Exact match |
not_equals | Not equal |
greater_than | Numeric |
less_than | Numeric |
greater_than_or_equal | Numeric |
less_than_or_equal | Numeric |
contains | String contains substring |
not_contains | String does not contain |
exists | Variable has any value |
not_exists | Variable is null/undefined |
Examples
Single condition:
Variable: account_status
Operator: equals
Value: 'active'
→ Target: Active_Account_Path
AND logic (all conditions must pass):
Logic: all
Conditions:
- account_balance > 1000
- account_type equals "premium"
→ Target: VIP_Path
OR logic (any condition passes):
Logic: any
Conditions:
- support_tier equals "platinum"
- is_enterprise equals true
→ Target: Priority_Support
Existence check:
Variable: customer_id
Operator: exists
→ Target: Known_Customer_Path
Hamsa handles type coercion automatically — a string "25" compared to number 21 with greater_than evaluates correctly.
DTMF Transitions
DTMF transitions fire when the user presses a specific keypad key.
→ See DTMF Features for full documentation on all DTMF capabilities.
Configuration
{
type: 'dtmf',
key: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '*' | '#',
description?: string
}
Example
Conversation Node: "Main Menu"
Message: "Press 1 for Sales, Press 2 for Support, Press 3 for Billing"
Transitions:
- DTMF: key=1 → Sales_Department
- DTMF: key=2 → Support_Department
- DTMF: key=3 → Billing_Department
- Always → Repeat_Menu
Always Transitions
Always transitions have no condition — they fire when no other transition matches. Use them as the fallback on every node that has conditional transitions.
Configuration
{
type: 'always',
description: string
}
Examples
Menu fallback:
Transitions:
- DTMF: key=1 → Sales
- DTMF: key=2 → Support
- Always → Repeat_Menu # User didn't press a valid key
Router else path:
Transitions:
- Equation: account_type equals "premium" → Premium_Flow
- Equation: account_type equals "standard" → Standard_Flow
- Always → Basic_Flow
Always transitions should have the lowest priority (default 0) so they are evaluated last.
Advanced Patterns
Combining types
Node: "Support Menu"
Message: "Describe your issue, or press 0 for an agent"
Transitions:
- DTMF: key=0 → Transfer_Agent (priority: 1000)
- Natural: "urgent issue" → Urgent (priority: 200)
- Natural: "billing" → Billing (priority: 200)
- Always → General_Inquiry (priority: 0)
Loops with exit conditions
Node: "Collect Account Number"
Message: "Please provide your 8-digit account number"
Transitions:
- Equation: account_number.length equals 8 → Proceed (priority: 200)
- Natural: "speak to agent" → Transfer (priority: 150)
- Equation: attempt_count >= 3 → Max_Attempts (priority: 100)
- Always → Retry_Input (priority: 0)
Time-based routing
Router Node: "Hours Check"
Transitions:
- Logic: all
Conditions:
- current_hour >= 9
- current_hour < 17
Target: Business_Hours_Flow (priority: 200)
- Always → After_Hours_Flow (priority: 0)
Validation
The flow builder validates transitions before deployment:
- All transitions have non-empty conditions
- Target nodes exist
- Every non-terminal node has at least one transition
- DTMF keys are valid (0–9, *, #)
- Warning if no Always transition (routing may stall)
Transition Schema
interface Transition {
id: string;
name?: string;
condition:
| NaturalLanguageCondition
| StructuredEquationCondition
| DTMFCondition
| AlwaysCondition;
targetNodeId: string;
priority: number;
isEnabled: boolean;
}
Next Steps
Global Nodes
Nodes reachable from anywhere in the flow
DTMF Features
Full keypad interaction documentation
Variables
Variables used in equation conditions
Router Node
Pure routing without conversation