Skip to main content

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

TypeEvaluationUse Case
Natural LanguageLLM-basedIntent detection, sentiment
Structured EquationRule-basedVariable comparisons, thresholds
DTMFKeypad inputIVR menus, quick selection
AlwaysNo conditionFallback / 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

OperatorDescription
equalsExact match
not_equalsNot equal
greater_thanNumeric
less_thanNumeric
greater_than_or_equalNumeric
less_than_or_equalNumeric
containsString contains substring
not_containsString does not contain
existsVariable has any value
not_existsVariable 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