Initialization
Initialize your flow by creating aFlowManager instance and calling initialize() with the node the conversation starts in.
- Declarative
- Programmatic
Load the config, join it to your handlers, and let the
Flow supply both the starting node and the global functions:Cross-Node State
Pipecat Flows supports cross-node state through theflow_manager.state dictionary. This persistent storage lets you share data across nodes throughout the entire conversation:
- Declarative
- Programmatic
handlers.py
initialize().
Placeholders
A node’s prompt text can read from state with{{ key }} placeholders. FlowManager fills them in each time it enters the node, so a value a handler stored earlier in the conversation can appear in a later prompt, including after a context reset.
Placeholders are rendered in three places:
- a node’s
role_message - the
contentof each of itstask_messages - the
textof atts_sayaction
NodeConfig built in code.
Session Facts
Write the facts before initializing, and every node’s prompts can refer to them:Values a Handler Stored
A placeholder is filled on every entry, not once at load, so a prompt sees whatever handlers have stored by the time the node is reached. The insurance quote example turns on this: each quote handler stores the figures in state, and the results node reads them back.handlers.py
update_coverage leads back to quote_results, so re-entering the node renders it again with the new figures. That is a loop with no code behind it.
Dotted Paths, Escaping, and Missing Keys
- Dotted paths walk into a stored mapping:
{{ quote.monthly_premium }}readsstate["quote"]["monthly_premium"]. Values are rendered withstr(). - Escaping: to show the LLM a literal
{{ key }}, write\{{ key }}. - A missing key raises. If a placeholder names a key that isn’t in state when the node is entered, Flows raises a
FlowError. There is no silent empty string — a prompt with a hole in it is a bug worth failing on.
Global Functions
Pipecat Flows supports defining functions that are available across all nodes in your flow. They’re defined the same way as node-specific functions, and are passed into theFlowManager at initialization:
- Declarative
- Programmatic
List them at the top level of the config, then hand A global function is written like any other entry, so it can transition too. Its name can’t also be used by a node’s
flow.global_functions to the manager:functions.