Skip to main content

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:

  1. Runtime Pipeline (hbf-bot): A ComponentTree of ComponentBase subclasses that process every inbound message. This is the infrastructure layer. Fixed per deployment. Handles NLU, context matching, NLG, LiveChat routing, analytics.

  2. 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_runner component 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

StepWhat it does
LoadStateLoad subscriber blackboard from storage
PowerUpInitialize tenant-level config
SetLanguageDetect/set active language
UserInputSanitizerClean and normalize user input
ValidateStateValidate blackboard integrity
ConversationFlowExecute the ComponentTree pipeline
CheckForwardedCheck if message was forwarded from another tenant
SessionTrackerTrack session boundaries

Blackboard (Per-Turn State)

TierLifetimePurposeExamples
persistentAcross sessionsUser profile, long-term varsconversationStats, parameters, responsesQueue
sessionOne conversationContext, slot values, survey statesurvey, missedQuestionsCount
ephemeralSingle turn onlyTemp computation, current-turn datatriggeredIntent, matchedConvNode, selectedResponses

Standard ephemeral fields set during a turn:

  • event - the inbound HBFEvent
  • triggeredIntent - 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 tracking
  • userPublicInfo - 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 IDClassFileStatus
if_itcIfITCapp/components/conditional/IfITC.tsActive
if_message_is_postbackIfMessageIsPostbackapp/components/conditional/IfMessageIsPostback.tsActive
public_infoPublicInfoGetterapp/components/PublicInformationGetter.tsActive
convmanager_liteConvManagerLiteapp/components/ConversationManagerLite.tsActive
node_runnerNodeRunnerComponentapp/components/NodeRunner.tsActive
nlgNLGapp/components/nlg/Nlg.tsActive
nlg_translateNLGapp/components/nlg/Nlg.tsActive (alias)
data_collectorDataCollectorapp/components/DataCollector.tsActive
echoEchoapp/components/EchoComponent.tsActive
lcm_end_userLiveChatGatewayEndUserComponentapp/components/livechat/forEndUser/LiveChatGatewayEndUserComponent.tsActive
lcm_agentLiveChatGatewayAgentComponentapp/components/livechat/forAgent/LiveChatGatewayAgentComponent.tsActive
survey_session_moverSurveySessionMoverapp/components/SurveySessionMover.tsActive
enqueue_replyEnqueueReplyapp/components/EnqueueReply.tsActive
debug_reply_injectorDebugReplyInjectorapp/components/DebugReplyInjector.tsActive
local_messengerLocalMessengerapp/components/LocalMessenger.tsActive
entity_email_checkEmailEntityCheckapp/components/entities/EmailEntityCheck.tsActive
nlu_lexLexapp/components/nlu/LexNlu.tsActive
mail_notificationNotificatorapp/components/NotificatorComponent.tsDeprecated
convmanagerConvManagerapp/components/ConversationManager.tsDeprecated
session_trackerNope(registry)Deprecated
livechat_end_user_state_loaderNope(registry)Deprecated
livechat_agent_state_loaderNope(registry)Deprecated
handover_managerNope(registry)Deprecated
handover_request_builderNope(registry)Deprecated
if_handover_requestNope(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):

  1. currentNext (enqueued via blackboard)
  2. postbackConvNodeId (button click target)
  3. Intent-to-node context matching (highest context intersection wins)
  4. 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, ephemeral entity.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

CategoryPriorityDescription
Popular1Most-used nodes, shown first
Send Message2Nodes that output messages to the user
Ask User3Nodes that collect input from the user
Actions4Logic, 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 FieldTypeDescription
data.labelobject (multilingual)Message text (RichTextEditor)
data.inlineFeedbackData.enabledbooleanEnable thumb rating
data.inlineFeedbackDataobjectFeedback configuration
media

Label: Media | Icon: VideoCameraOutlined | Category: Send Message

Add video or audio (video/mp4, audio/mpeg).

Config FieldTypeDescription
data.mediaUrlstring (required)URL to media file
data.posterUrlstringThumbnail URL

Label: Carousel | Icon: CarouselIcon | Category: Send Message

Series of swipeable cards. Feature-flagged (IS_CAROUSEL_NODE_ENABLED).

Config FieldTypeDescription
data.labelobject (multilingual)Carousel title
data.cardsarrayCards with title, description, imageUrl, buttons
custom_response

Label: Custom Response | Icon: CodeIcon | Category: Send Message

Custom JSON payload for unique response types.

Config FieldTypeDescription
data.jsonResponseobject (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 FieldTypeDescription
data.labelobject (multilingual)Question text
data.friendlyNamestringShort column name for exports
data.questionIdstringVariable name (auto-generated)
data.sendBoxstringSendBox status (enabled/disabled/default)
data.exitKeyWordsarrayKeywords to skip question
option

Label: Option | Icon: CheckOutlined | Categories: Popular, Ask User

Single pre-set answer connected to a Question node.

Config FieldTypeDescription
data.labelobject (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 FieldTypeDescription
data.multiOptionsobject (multilingual){key: value} dictionary per language
dynamic_multi_option

Label: Dynamic Options | Icon: UnorderedListOutlined | Category: Ask User

Options populated dynamically from template data.

Config FieldTypeDescription
data.dynamicDataKeystring (required)Template data key
text_input

Label: User Input | Icon: FormOutlined | Category: Ask User

Free-text input field. Validates by type.

Config FieldTypeDescription
data.inputTypestring (required)string, email, date, number, phone, customRegex
data.labelobject (multilingual)Placeholder text
data.validationFallbackMessageobject (multilingual)Invalid input message
data.inputMaxCharactersnumberMax chars (1-10000)
data.inputIsMandatorybooleanRequired field
data.questionIdstringVariable name
input_query

Label: Input collection (Beta) | Icon: FormOutlined | Categories: Popular, Ask User

Newer input collection with card rendering and submit/skip buttons.

Config FieldTypeDescription
data.labelobject (multilingual)Question text
data.inputTypestring (required)Input type
data.submitLabelobject (multilingual)Submit button label
data.skipLabelobject (multilingual)Skip button label
data.renderAsCardbooleanRender 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 FieldTypeDescription
data.labelobject (multilingual)Prompt text
data.supportedFileTypesarrayAllowed file extensions
data.maxFileSizenumberMax size value
data.maxFileSizeUnitstringKB or MB (max 5 MB)
data.questionIdstringVariable 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 FieldTypeDescription
data.labelobject (multilingual)Prompt text
data.includeEmailbooleanCollect email
data.includeFullNamebooleanCollect name
data.includePhonebooleanCollect phone
data.customUserInfoDataarrayCustom 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 FieldTypeDescription
data.labelobject (multilingual)Question text
data.sectionsarrayRating sections with label and id
data.ratingStylestringstars, numbers, emotions
data.submitLabelobject (multilingual)Submit button label
data.variableNamestringVariable to store rating
user_feedback_jump

Label: User Feedback | Icon: SmileOutlined | Category: Ask User

Redirect to feedback flow with configurable probability. Feature-flagged.

Config FieldTypeDescription
data.jumpTostring (required)Feedback flow ID
data.jumpProbabilitynumberProbability 0-1

Action Nodes

intro

Label: Intro | Icon: FlagOutlined | Category: Actions

Flow entry point. Dev-only visibility (is.dev()).

Config FieldTypeDescription
idstring (required)Node ID
data.resetSessionbooleanRestart session
jump

Label: Redirect | Icon: DecisionIcon | Categories: Popular, Actions

Jump to another flow/entry point.

Config FieldTypeDescription
data.jumpTostring (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 FieldTypeDescription
data.switchQueryobject (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 FieldTypeDescription
data.querystringLIQE query expression
pipeline

Label: NLP System | Icon: ThunderboltOutlined | Category: Actions

First NLP query returning non-empty response continues flow.

Config FieldTypeDescription
data.pipelineIdstring (required)NLP Pipeline ID
variable

Label: Variable | Icon: VariableIcon | Categories: Popular, Actions

Define session or contact-bound variables.

Config FieldTypeDescription
data.variable.keystring (required)Variable name
data.variable.typestringSESSION (default) or CONTACT
data.variable.valuestringInitial value
http_request

Label: HTTP Request | Icon: GlobalOutlined | Categories: Popular, Actions

Call external API. Maps response fields to variables.

Config FieldTypeDescription
data.friendlyNamestringShort name (max 30 chars)
data.httpRequestData.methodstring (required)GET, POST, PATCH, PUT, DELETE
data.httpRequestData.urlstring (required)Request URL (supports variables)
data.httpRequestData.headersobjectCustom headers
data.httpRequestData.bodystringRequest body
data.httpRequestData.mappingsarrayResponse body variable mappings
data.httpRequestData.responseHeaderMappingsarrayResponse header mappings
data.httpRequestData.responseStatusCodeMappingstringStatus code variable
send_stored_data

Label: Callback | Icon: CloudUploadOutlined | Category: Actions

POST collected survey/form data to an endpoint.

Config FieldTypeDescription
data.sendStoredData.urlstring (required)Callback URL
data.sendStoredData.headersobjectCustom headers
email

Label: Send email | Icon: MailOutlined | Category: Actions

Send email to a specific address.

Config FieldTypeDescription
data.email.addressarray (required)Recipient emails
data.email.subjectstringSubject (max 998 chars)
data.email.bodystringBody (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 FieldTypeDescription
data.labelobject (multilingual)Action label
data.actionData.namestring (required)Action name
data.actionData.parametersarrayAction parameters
analytic_tags

Label: Tags | Icon: TagsOutlined | Categories: Popular, Actions

Add/remove tags for analytics. Tag "Outcome" appears in Analytics dashboards.

Config FieldTypeDescription
data.analyticTagsarrayTags to add
data.analyticTagsRemovedarrayTags 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 FieldTypeDescription
data.friendlyNamestringShort name
data.llm.providerstring (required)LLM provider
data.llm.modelstringModel selection
data.llm.temperaturenumberTemperature (0-2)
data.llm.variablestringOutput variable name
data.llm.systemPromptstringSystem instructions
data.llm.userPromptstringUser prompt template
generation

Label: LLM v2 (Beta) | Icon: OpenAiIcon | Categories: Popular, Actions

Advanced LLM with response format options (text, json).

Config FieldTypeDescription
data.friendlyNamestringShort name
data.generationParams.providerstring (required)LLM provider
data.generationParams.modelstringModel selection
data.generationParams.variablestringOutput variable
data.generationParams.configuration.responseTypestringtext or json

Label: Semantic Search | Icon: SearchOutlined | Categories: Popular, Actions

Query knowledge base with semantic search (RAG).

Config FieldTypeDescription
data.maxResultsnumberMax results (1-25, default: 10)
data.filterByTagsbooleanFilter by content tags
data.tagsarraySelected tags
livechat_request

Label: LiveChat | Icon: LiveChatIcon | Category: Actions

Connect end-user with workspace agents.

Config FieldTypeDescription
data.livechatGroupstringUser group for routing
data.requestExtrasstringJSON extras (default: '{}')
data.livechatPluginobjectPlugin configuration

Utility Nodes

sticky_note

Label: Sticky note | Icon: StickyNoteIcon

Standalone annotation. Does not connect to flow.

Config FieldTypeDescription
data.labelobject (multilingual)Note text

Legacy/Hidden Nodes

TypeLabelStatus
link_optionLink-OptionHidden (legacy)
switch_variableFlow ControlHidden (legacy, replaced by switch_query)
switch_caseFlow OptionHidden (legacy, child of switch_variable)
livechatLiveChatHidden (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 targets
  • src/components/Graphs/AddNodePanel.jsx -- node palette sidebar
  • src/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 the aud claim, matches it against TenantSettings.security.preAuthTokenProviders[], and verifies via JWKS. On-change-only: skips re-validation if the token matches the stored auth.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.