Skip to main content

Flows

The flows block in agent-pack.yaml declares the non-LLM behaviours of the agent — what it says when a user connects, what menu items it shows, when those items appear, and which built-in actions they trigger.

It's the part of the pack that doesn't reach the LLM at all: the welcome message goes out before the model sees the conversation, and menu actions run as deterministic flows.

Sub-blocks

flows:
welcome: # what the agent does on connect
enabled: true
sendOnProfile: true
templateKey: greetingMessage

authentication: # see ./authentication.md
enabled: true
required: true
credentialDefinitionId: ${CREDENTIAL_DEFINITION_ID}
userIdentityAttribute: name

menu: # contextual menu items
items:
- id: authenticate
labelKey: CREDENTIAL
action: authenticate
visibleWhen: unauthenticated
...

flows.welcome

flows:
welcome:
enabled: true # send a welcome message on connection
sendOnProfile: true # wait for the user's profile (locale) before sending
templateKey: greetingMessage # which language string to use
FieldDefaultDescription
enabledtrueSend a welcome on connection.
sendOnProfiletrueIf true, wait for the user's DIDComm Profile message (which carries their locale) and reply in their language. If false, send immediately in metadata.defaultLanguage.
templateKeygreetingMessageWhich key to look up in languages[*].

The looked-up template can include {userName} (from DIDComm profile) which is substituted before sending.

flows.menu

A contextual menu is the dropdown the user can open from the chat header in Hologram. It's the agent's UI for verbs that don't fit chat ("authenticate", "log out", "configure MCP", "view approvals"). Each entry is a deterministic action — the LLM doesn't see them, doesn't choose them.

flows:
menu:
items:
- id: authenticate
labelKey: CREDENTIAL
action: authenticate
visibleWhen: unauthenticated

- id: logout
labelKey: LOGOUT
action: logout
visibleWhen: authenticated

- id: mcp-config
labelKey: MCP_CONFIG_MENU
action: mcp-config
visibleWhen: notConfiguring

- id: abort-config
labelKey: MCP_CONFIG_ABORT
action: abort-config
visibleWhen: configuring

- id: my-approval-requests
labelKey: MY_APPROVAL_REQUESTS
action: my-approval-requests
visibleWhen: hasApprovalRequests
badge: approvalRequestCount

- id: pending-approvals
labelKey: PENDING_APPROVALS
action: pending-approvals
visibleWhen: hasPendingApprovals
badge: pendingApprovalCount

Per-item fields

FieldRequiredDescription
idyesStable identifier; appears in logs.
labelKeyyesKey into languages[*].strings — the displayed label.
actionyesBuilt-in action this item triggers. See below.
visibleWhennoWhen this item is shown. Defaults to always.
badgenoDynamic badge value (e.g. unread count). Currently used for approval items.

Built-in actions

actionTriggersUsed with
authenticateDIDComm presentation request for credentialDefinitionIdvisibleWhen: unauthenticated
logoutDrop the user's sessionvisibleWhen: authenticated
mcp-configPer-user MCP configuration flow (selects a server, prompts for fields, encrypts and stores)visibleWhen: notConfiguring
abort-configCancel the in-progress MCP config flowvisibleWhen: configuring
my-approval-requestsList the user's pending approval requests; pick one to cancelvisibleWhen: hasApprovalRequests
pending-approvalsList approval requests the user can approve; pick one to approve / rejectvisibleWhen: hasPendingApprovals

visibleWhen states

The agent maintains a simple state machine per user. Each menu item lists the states in which it appears.

StateTrue when
alwaysAlways (default if visibleWhen omitted).
authenticatedThe user has presented a valid credential.
unauthenticatedThe user has not authenticated yet. Always true if flows.authentication.enabled: false.
configuringThe user is in the middle of an MCP config flow.
notConfiguringInverse of configuring.
hasApprovalRequestsAt least one open approval request submitted by this user.
hasPendingApprovalsThe user holds an approver role and has at least one pending request to act on.

The states are mutually-aware — authenticated implies notConfiguring (can't auth and configure at the same time), but most others compose freely.

badge

Some items show a count badge — a small number next to the label.

badge valueMeaning
approvalRequestCountNumber of open approval requests the user submitted.
pendingApprovalCountNumber of approval requests the user can act on.

The runtime updates the badge in real time as state changes; the menu re-renders without the user reopening it.

Statistics

Statistics are not strictly part of flows, but they're emitted as the user moves through these flows. If you wire up a JMS broker (Apache ActiveMQ Artemis), the agent emits per-user events you can consume downstream.

integrations:
vsAgent:
stats:
enabled: ${VS_AGENT_STATS_ENABLED} # "true" / "false"
host: ${VS_AGENT_STATS_HOST}
port: ${VS_AGENT_STATS_PORT}
queue: ${VS_AGENT_STATS_QUEUE}
username: ${VS_AGENT_STATS_USER}
password: ${VS_AGENT_STATS_PASSWORD}

The bundled statisticsFetcher tool also lets the LLM ask the stats backend questions ("how many users connected today?"). It's enabled in tools.bundled:

tools:
bundled:
statisticsFetcher:
enabled: true
endpoint: ${STATISTICS_API_URL}
requiresAuth: true
defaultStatClass: USER_CONNECTED

For the full JMS integration, see JMS integration upstream.

Custom flows

The flow system is currently closed — you can't define your own actions in YAML. If you need a flow the built-ins don't cover (a fixed-question intake form, an outbound credential issuance trigger, etc.), the supported pattern is:

  1. Express the deterministic part as an LLM rule in agentPrompt, with explicit step-by-step instructions. See the customer-service PQRSD pack — its system prompt contains an 8-step flow the LLM follows verbatim.
  2. Or fork the chatbot. The hologram-generic-ai-agent-vs repo is open source; new actions live under src/chatbot/.

We expect to expose a wider set of declarative flow primitives in a future schema version.

Worked example — minimal multilingual menu

flows:
welcome:
enabled: true
sendOnProfile: true
templateKey: greetingMessage

authentication:
enabled: true
required: false
credentialDefinitionId: ${CREDENTIAL_DEFINITION_ID}

menu:
items:
- id: authenticate
labelKey: CREDENTIAL
action: authenticate
visibleWhen: unauthenticated
- id: logout
labelKey: LOGOUT
action: logout
visibleWhen: authenticated

languages:
en:
greetingMessage: "Hi {userName}, what can I help you with?"
strings:
CREDENTIAL: "Authenticate"
LOGOUT: "Logout"
es:
greetingMessage: "Hola {userName}, ¿en qué puedo ayudarte?"
strings:
CREDENTIAL: "Autenticar"
LOGOUT: "Cerrar sesión"

Next

  • Authentication — what action: authenticate actually does.
  • MCP — what action: mcp-config does.
  • RBAC — the approval menu items.
  • i18n — string declarations.