Bot Workflow Nodes
Catalogue of all node types in the Platform workflow system. Two layers: Runtime Pipeline (hbf-bot ComponentTree) and Designer Flow (hbf-console visual graph). Last updated: 2026-03-06
Two-Layer Architecture
The workflow system operates at two distinct abstraction levels:
-
Runtime Pipeline (hbf-bot): A
ComponentTreeofComponentBasesubclasses that process every inbound message. This is the infrastructure layer. Fixed per deployment. Handles NLU, context matching, NLG, LiveChat routing, analytics. -
Designer Flow (hbf-console): A visual graph of nodes that users drag-and-drop in the console. This is the conversation logic layer. Stored as bot content in hbf-core. Interpreted by the
node_runnercomponent at runtime.
Inbound Event
|
v
[Runtime Pipeline: ComponentTree]
if_itc -> public_info -> convmanager_lite -> node_runner -> nlg -> data_collector
|
v
[Designer Flow: user-defined graph]
intro -> message -> select -> option -> jump ...
Part 1: Runtime Pipeline (hbf-bot)
How the Pipeline Executes
EventLifecycle Steps
| Step | What it does |
|---|---|
| LoadState | Load subscriber blackboard from storage |
| PowerUp | Initialize tenant-level config |
| SetLanguage | Detect/set active language |
| UserInputSanitizer | Clean and normalize user input |
| ValidateState | Validate blackboard integrity |
| ConversationFlow | Execute the ComponentTree pipeline |
| CheckForwarded | Check if message was forwarded from another tenant |
| SessionTracker | Track session boundaries |
Blackboard (Per-Turn State)
| Tier | Lifetime | Purpose | Examples |
|---|---|---|---|
| persistent | Across sessions | User profile, long-term vars | conversationStats, parameters, responsesQueue |
| session | One conversation | Context, slot values, survey state | survey, missedQuestionsCount |
| ephemeral | Single turn only | Temp computation, current-turn data | triggeredIntent, matchedConvNode, selectedResponses |
Standard ephemeral fields set during a turn:
event- the inbound HBFEventtriggeredIntent- intent name + score (set by NLU or convmanager_lite)matchedConvNode- selected conversation node (set by convmanager_lite)selectedResponsesIds- message IDs to render (set by node_runner)selectedResponses- rendered Response[] objects (set by nlg)contexts- active conversation contexts with lifespan trackinguserPublicInfo- user profile data from channel (set by public_info)
ComponentTree Schema
type ComponentTree = string[] | ComponentTreeNode;
interface ComponentTreeNode {
id: string; // Node type from registry
left?: ComponentTree; // "next" chain
right?: ComponentTree; // "altNext" chain (conditional)
}
Default tree for a new agent:
{
"id": "if_itc",
"left": [
"public_info", "convmanager_lite", "survey_session_mover",
"node_runner", "lcm_end_user", "nlg", "data_collector"
],
"right": {
"id": "if_message_is_postback",
"left": ["echo"],
"right": ["convmanager_lite", "node_runner", "nlg"]
}
}
Runtime Node Registry
| Type ID | Class | File | Status |
|---|---|---|---|
if_itc | IfITC | app/components/conditional/IfITC.ts | Active |
if_message_is_postback | IfMessageIsPostback | app/components/conditional/IfMessageIsPostback.ts | Active |
public_info | PublicInfoGetter | app/components/PublicInformationGetter.ts | Active |
convmanager_lite | ConvManagerLite | app/components/ConversationManagerLite.ts | Active |
node_runner | NodeRunnerComponent | app/components/NodeRunner.ts | Active |
nlg | NLG | app/components/nlg/Nlg.ts | Active |
nlg_translate | NLG | app/components/nlg/Nlg.ts | Active (alias) |
data_collector | DataCollector | app/components/DataCollector.ts | Active |
echo | Echo | app/components/EchoComponent.ts | Active |
lcm_end_user | LiveChatGatewayEndUserComponent | app/components/livechat/forEndUser/LiveChatGatewayEndUserComponent.ts | Active |
lcm_agent | LiveChatGatewayAgentComponent | app/components/livechat/forAgent/LiveChatGatewayAgentComponent.ts | Active |
survey_session_mover | SurveySessionMover | app/components/SurveySessionMover.ts | Active |
enqueue_reply | EnqueueReply | app/components/EnqueueReply.ts | Active |
debug_reply_injector | DebugReplyInjector | app/components/DebugReplyInjector.ts | Active |
local_messenger | LocalMessenger | app/components/LocalMessenger.ts | Active |
entity_email_check | EmailEntityCheck | app/components/entities/EmailEntityCheck.ts | Active |
nlu_lex | Lex | app/components/nlu/LexNlu.ts | Active |
mail_notification | Notificator | app/components/NotificatorComponent.ts | Deprecated |
convmanager | ConvManager | app/components/ConversationManager.ts | Deprecated |
session_tracker | Nope | (registry) | Deprecated |
livechat_end_user_state_loader | Nope | (registry) | Deprecated |
livechat_agent_state_loader | Nope | (registry) | Deprecated |
handover_manager | Nope | (registry) | Deprecated |
handover_request_builder | Nope | (registry) | Deprecated |
if_handover_request | Nope | (registry) | Deprecated |
Runtime Node Details
Conditional Nodes
if_itc
Routes based on event origin. ITC events go to altNext (left), others to next (right).
- Reads:
event.origin - Condition:
event.origin === EventOrigin.ITC
if_message_is_postback
Routes postback (button click) messages separately from text.
- Reads:
event.message.type - Condition:
messageIsPostback(event.message)
Input Nodes
public_info
Extracts user profile from channel event data (name, email, phone, timezone). Channel-specific: Teams gets objectId/tenantId, Slack gets timezone, WhatsApp gets phone, Facebook gets profile_pic.
- Writes: ephemeral
userPublicInfo
Logic / Control Nodes
convmanager_lite
Core orchestrator. Selects the next conversation node based on (in priority order):
currentNext(enqueued via blackboard)postbackConvNodeId(button click target)- Intent-to-node context matching (highest context intersection wins)
- Fallback to DEFAULT_NODE
- Reads:
triggeredIntent,postbackConvNodeId,currentNext,contexts.active - Writes: ephemeral
matchedConvNode,activity,activityType,sessionVariableNames - Writes: session
missedQuestionsCount,consecutiveMissedQuestionsCount
node_runner
Executes the matched conversation node's actions. Sets response message IDs. Invokes built-in functions (context manipulation) or Lambda custom actions. Enqueues next nodes.
- Config:
lambdaUrl(optional) - Reads:
matchedConvNode(messages, action, next) - Writes: ephemeral
selectedResponsesIds - Calls: Lambda API (if action configured)
survey_session_mover
Migrates survey data from persistent to session storage for isolation.
- Reads: persistent
survey - Writes: session
survey
data_collector
Captures conversation events into conversationStats for analytics. Tracks message sequence with timestamps. Supports input censoring for privacy.
- Config:
censorUserInput,useAutomatedAnswerTags - Reads:
event,triggeredIntent,matchedConvNode,selectedResponses,contexts - Writes: persistent
conversationStats
enqueue_reply
Accumulates responses in a queue for async delivery.
- Reads: ephemeral
selectedResponses - Writes: persistent
responsesQueue,lastResponses
NLP / AI Nodes
nlg
Transforms message IDs into rendered Response objects. Resolves variables, templates, multi-language. Response types: TEXT, IMAGE, VIDEO, CARD, BUTTON_SUGGESTION, CUSTOM.
- Reads:
selectedResponsesIds,language.activeLanguageCode - Writes: ephemeral
selectedResponses
entity_email_check
Extracts email from text, replaces with HBF_ENTITY_EMAIL placeholder.
- Reads:
event.message.text - Writes: modifies
event.message.text, ephemeralentity.email
nlu_lex
AWS Lex intent recognition. Disabled if another NLU already set intent or postback/next exists.
- Config:
botName,region - Writes: ephemeral
triggeredIntent - Calls: AWS Lex Runtime API
LiveChat Nodes
lcm_end_user
Routes end-user LiveChat messages through state handlers (PreRequest, Request, Active). Wraps node_runner execution.
- Reads:
liveChat.*,liveChatEventType,liveChatSender - Composition: Internally calls
node_runner._process()
lcm_agent
Routes agent LiveChat messages. Blocks async response (sets skipChannelSend = true).
- Reads:
liveChat.* - Writes: ephemeral
skipChannelSend = true
Output / Response Nodes
echo
Returns user input as bot response. Used for ITC message reflection and LiveChat event bridging.
- Reads:
event.message.text - Writes: ephemeral
selectedResponses,itcUserImage,liveChatEventType
debug_reply_injector
Injects debug metadata (intent name, score, language) into response. Only if debug-mode = true.
- Reads: ephemeral
debug-mode,triggeredIntent,language.activeLanguageCode - Writes: modifies
selectedResponses(prepends debug text)
local_messenger
Accumulates responses for synchronous clients (testing, local mode).
- Reads: ephemeral
selectedResponses - Writes: ephemeral
replies
Part 2: Designer Flow (hbf-console)
These are the nodes users see in the visual workflow designer. They define conversation logic within a bot.
Node Categories
| Category | Priority | Description |
|---|---|---|
| Popular | 1 | Most-used nodes, shown first |
| Send Message | 2 | Nodes that output messages to the user |
| Ask User | 3 | Nodes that collect input from the user |
| Actions | 4 | Logic, integrations, and side effects |
Designer Node Catalogue
Send Message Nodes
message
Label: Message | Icon: MessageOutlined | Categories: Popular, Send Message
Send a message to the end-user.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Message text (RichTextEditor) |
data.inlineFeedbackData.enabled | boolean | Enable thumb rating |
data.inlineFeedbackData | object | Feedback configuration |
media
Label: Media | Icon: VideoCameraOutlined | Category: Send Message
Add video or audio (video/mp4, audio/mpeg).
| Config Field | Type | Description |
|---|---|---|
data.mediaUrl | string (required) | URL to media file |
data.posterUrl | string | Thumbnail URL |
carousel
Label: Carousel | Icon: CarouselIcon | Category: Send Message
Series of swipeable cards. Feature-flagged (IS_CAROUSEL_NODE_ENABLED).
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Carousel title |
data.cards | array | Cards with title, description, imageUrl, buttons |
custom_response
Label: Custom Response | Icon: CodeIcon | Category: Send Message
Custom JSON payload for unique response types.
| Config Field | Type | Description |
|---|---|---|
data.jsonResponse | object (multilingual) | JSON response per language |
Ask User Nodes
select
Label: Question | Icon: QuestionCircleOutlined | Categories: Popular, Ask User
A question the agent asks. Children must be option/multi_option/text_input/dynamic_multi_option nodes.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Question text |
data.friendlyName | string | Short column name for exports |
data.questionId | string | Variable name (auto-generated) |
data.sendBox | string | SendBox status (enabled/disabled/default) |
data.exitKeyWords | array | Keywords to skip question |
option
Label: Option | Icon: CheckOutlined | Categories: Popular, Ask User
Single pre-set answer connected to a Question node.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Option text |
multi_option
Label: Multi-Options | Icon: UnorderedListOutlined | Category: Ask User
List of answers to choose from. Keys are visible to user, values are stored data.
| Config Field | Type | Description |
|---|---|---|
data.multiOptions | object (multilingual) | {key: value} dictionary per language |
dynamic_multi_option
Label: Dynamic Options | Icon: UnorderedListOutlined | Category: Ask User
Options populated dynamically from template data.
| Config Field | Type | Description |
|---|---|---|
data.dynamicDataKey | string (required) | Template data key |
text_input
Label: User Input | Icon: FormOutlined | Category: Ask User
Free-text input field. Validates by type.
| Config Field | Type | Description |
|---|---|---|
data.inputType | string (required) | string, email, date, number, phone, customRegex |
data.label | object (multilingual) | Placeholder text |
data.validationFallbackMessage | object (multilingual) | Invalid input message |
data.inputMaxCharacters | number | Max chars (1-10000) |
data.inputIsMandatory | boolean | Required field |
data.questionId | string | Variable name |
input_query
Label: Input collection (Beta) | Icon: FormOutlined | Categories: Popular, Ask User
Newer input collection with card rendering and submit/skip buttons.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Question text |
data.inputType | string (required) | Input type |
data.submitLabel | object (multilingual) | Submit button label |
data.skipLabel | object (multilingual) | Skip button label |
data.renderAsCard | boolean | Render as card (default: true) |
file_upload
Label: File Upload | Icon: UploadOutlined | Category: Ask User
Allow file upload. Supports jpg, png, pdf, doc, docx, csv, xls, xlsx, ppt, pptx, txt, zip, rar.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Prompt text |
data.supportedFileTypes | array | Allowed file extensions |
data.maxFileSize | number | Max size value |
data.maxFileSizeUnit | string | KB or MB (max 5 MB) |
data.questionId | string | Variable name |
Error handles: unsupported-file-type, exceeds-size, no-attachment, failed
user_info
Label: User info | Icon: ContactsOutlined | Category: Ask User
Collect personal info (email, name, phone) and custom fields.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Prompt text |
data.includeEmail | boolean | Collect email |
data.includeFullName | boolean | Collect name |
data.includePhone | boolean | Collect phone |
data.customUserInfoData | array | Custom fields with multilingual question/placeholder |
csat
Label: CSAT | Icon: StarOutlined | Categories: Popular, Ask User
Satisfaction rating. Feature-flagged (IS_CSAT_NODE_ENABLED). Rating styles: stars, numbers, emotions.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Question text |
data.sections | array | Rating sections with label and id |
data.ratingStyle | string | stars, numbers, emotions |
data.submitLabel | object (multilingual) | Submit button label |
data.variableName | string | Variable to store rating |
user_feedback_jump
Label: User Feedback | Icon: SmileOutlined | Category: Ask User
Redirect to feedback flow with configurable probability. Feature-flagged.
| Config Field | Type | Description |
|---|---|---|
data.jumpTo | string (required) | Feedback flow ID |
data.jumpProbability | number | Probability 0-1 |
Action Nodes
intro
Label: Intro | Icon: FlagOutlined | Category: Actions
Flow entry point. Dev-only visibility (is.dev()).
| Config Field | Type | Description |
|---|---|---|
id | string (required) | Node ID |
data.resetSession | boolean | Restart session |
jump
Label: Redirect | Icon: DecisionIcon | Categories: Popular, Actions
Jump to another flow/entry point.
| Config Field | Type | Description |
|---|---|---|
data.jumpTo | string (required) | Target flow/entry point ID |
switch_query
Label: Flow Control | Icon: SwitchQueryIcon | Categories: Popular, Actions
Branch flow based on variable value. Supports conditions: =, !=, <, >, <=, >=, contains, matches regex, null, not null.
| Config Field | Type | Description |
|---|---|---|
data.switchQuery | object (multilingual) | Query expressions (automated or custom LIQE) |
query
Label: Flow Control | Icon: SwitchQueryIcon | Categories: Popular, Actions
Branch based on NLP response. Valid children: Query, Pipeline.
| Config Field | Type | Description |
|---|---|---|
data.query | string | LIQE query expression |
pipeline
Label: NLP System | Icon: ThunderboltOutlined | Category: Actions
First NLP query returning non-empty response continues flow.
| Config Field | Type | Description |
|---|---|---|
data.pipelineId | string (required) | NLP Pipeline ID |
variable
Label: Variable | Icon: VariableIcon | Categories: Popular, Actions
Define session or contact-bound variables.
| Config Field | Type | Description |
|---|---|---|
data.variable.key | string (required) | Variable name |
data.variable.type | string | SESSION (default) or CONTACT |
data.variable.value | string | Initial value |
http_request
Label: HTTP Request | Icon: GlobalOutlined | Categories: Popular, Actions
Call external API. Maps response fields to variables.
| Config Field | Type | Description |
|---|---|---|
data.friendlyName | string | Short name (max 30 chars) |
data.httpRequestData.method | string (required) | GET, POST, PATCH, PUT, DELETE |
data.httpRequestData.url | string (required) | Request URL (supports variables) |
data.httpRequestData.headers | object | Custom headers |
data.httpRequestData.body | string | Request body |
data.httpRequestData.mappings | array | Response body variable mappings |
data.httpRequestData.responseHeaderMappings | array | Response header mappings |
data.httpRequestData.responseStatusCodeMapping | string | Status code variable |
send_stored_data
Label: Callback | Icon: CloudUploadOutlined | Category: Actions
POST collected survey/form data to an endpoint.
| Config Field | Type | Description |
|---|---|---|
data.sendStoredData.url | string (required) | Callback URL |
data.sendStoredData.headers | object | Custom headers |
email
Label: Send email | Icon: MailOutlined | Category: Actions
Send email to a specific address.
| Config Field | Type | Description |
|---|---|---|
data.email.address | array (required) | Recipient emails |
data.email.subject | string | Subject (max 998 chars) |
data.email.body | string | Body (HTML/Markdown) |
action
Label: Channel Action | Icon: ThunderboltOutlined | Category: Actions
Send actions to WebChat/Unity. Built-in: webchat_enableSendBox, webchat_disableSendBox, webchat_pauseIdleNotifications, webchat_showCustomRatingForm.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Action label |
data.actionData.name | string (required) | Action name |
data.actionData.parameters | array | Action parameters |
analytic_tags
Label: Tags | Icon: TagsOutlined | Categories: Popular, Actions
Add/remove tags for analytics. Tag "Outcome" appears in Analytics dashboards.
| Config Field | Type | Description |
|---|---|---|
data.analyticTags | array | Tags to add |
data.analyticTagsRemoved | array | Tags to remove |
reset
Label: Start new Session | Icon: RedoOutlined | Category: Actions
Reset the chat session. No config.
missed_question
Label: Missed Question | Icon: QuestionOutlined | Categories: Popular, Actions
Records unanswered question for analytics. No config form.
llm
Label: LLM | Icon: OpenAiIcon | Categories: Popular, Actions
LLM-powered task handling. Providers: OpenAI, Gemini, Azure.
| Config Field | Type | Description |
|---|---|---|
data.friendlyName | string | Short name |
data.llm.provider | string (required) | LLM provider |
data.llm.model | string | Model selection |
data.llm.temperature | number | Temperature (0-2) |
data.llm.variable | string | Output variable name |
data.llm.systemPrompt | string | System instructions |
data.llm.userPrompt | string | User prompt template |
generation
Label: LLM v2 (Beta) | Icon: OpenAiIcon | Categories: Popular, Actions
Advanced LLM with response format options (text, json).
| Config Field | Type | Description |
|---|---|---|
data.friendlyName | string | Short name |
data.generationParams.provider | string (required) | LLM provider |
data.generationParams.model | string | Model selection |
data.generationParams.variable | string | Output variable |
data.generationParams.configuration.responseType | string | text or json |
semantic_search
Label: Semantic Search | Icon: SearchOutlined | Categories: Popular, Actions
Query knowledge base with semantic search (RAG).
| Config Field | Type | Description |
|---|---|---|
data.maxResults | number | Max results (1-25, default: 10) |
data.filterByTags | boolean | Filter by content tags |
data.tags | array | Selected tags |
livechat_request
Label: LiveChat | Icon: LiveChatIcon | Category: Actions
Connect end-user with workspace agents.
| Config Field | Type | Description |
|---|---|---|
data.livechatGroup | string | User group for routing |
data.requestExtras | string | JSON extras (default: '{}') |
data.livechatPlugin | object | Plugin configuration |
Utility Nodes
sticky_note
Label: Sticky note | Icon: StickyNoteIcon
Standalone annotation. Does not connect to flow.
| Config Field | Type | Description |
|---|---|---|
data.label | object (multilingual) | Note text |
Legacy/Hidden Nodes
| Type | Label | Status |
|---|---|---|
link_option | Link-Option | Hidden (legacy) |
switch_variable | Flow Control | Hidden (legacy, replaced by switch_query) |
switch_case | Flow Option | Hidden (legacy, child of switch_variable) |
livechat | LiveChat | Hidden (legacy, replaced by livechat_request) |
Designer File Structure
Node components follow this pattern:
src/components/Graphs/Nodes/[NodeName]/
[NodeName]Node.jsx -- display component
[NodeName]NodeForm.jsx -- configuration form
Key files:
src/constants/flowGraph.js--NODE_TYPES_PROPERTIES: all node metadata, categories, valid targetssrc/components/Graphs/AddNodePanel.jsx-- node palette sidebarsrc/components/Graphs/NodeEditForm.jsx-- maps node types to form components
Console Variable System
Agent builders see available variables via a picker in the workflow designer. The list comes from hbf-core's BotContentCompilationMetadata.defaultVariables (Kotlin companion object) plus user-defined variables, served at GET /organizations/{orgId}/tenants/{tenantId}/bot-content/variables. Console renders them generically (no hardcoded variable names). To add a new built-in variable: (1) add VariableSpec to defaultVariables in hbf-core, (2) add resolution logic in the appropriate resolver in hbf-bot. Variable types: SYSTEM, CONTACT, LIVECHAT, SESSION, CALLBACK, QUESTION, CSAT, CONSTANT, AUTH. The Auth.* namespace (e.g., Auth.email, Auth.sub, Auth.name) resolves from the dedicated auth store on Blackboard via AuthVariablesResolver.
EventLifecycle Pipeline
Key runtime classes: EventLifecycle (9 steps: LoadState, ValidateState, EndUserAuth, SessionTracker, SetLanguage, UserInputSanitizer, ConversationFlow, CheckForwarded, Powerup), FlowBuilder, ComponentFlow, ExpandedBlackboard (3 tiers: persistent/session/ephemeral).
End-User Auth (OIDC): Two authentication strategies exist, both managed by AuthenticateUserAction:
- OidcAuthStrategy: Interactive OIDC authorization code flow. Sends a sign-in card, user authenticates with the IDP, hbf-bot exchanges the code for tokens via
OidcService, verifies the ID token (JWKS, 1hr cache), and stores claims. Config:TenantSettings.security.oidc. - PreAuthTokenStrategy: Pre-authenticated token validation. Reads a JWT from
channelData.auth.token, decodes theaudclaim, matches it againstTenantSettings.security.preAuthTokenProviders[], and verifies via JWKS. On-change-only: skips re-validation if the token matches the storedauth.rawToken. Config:PreAuthTokenProvider(name, aud, jwksUri, refreshTokenEndpoint).
Auth state is stored in a dedicated auth store on the session blackboard (setAuthData()/getAuthData()/clearAuthData()), not in regular session keys. setSessionValue('auth.*') throws to prevent accidental overwrites. Auth claims are exposed to workflow designers via {{Auth.email}}, {{Auth.sub}}, etc. through AuthVariablesResolver (the Auth.* namespace). Auth.isAuthenticated, Auth.rawToken, and Auth.refreshToken are blocked from template resolution.