Skip to main content

Cross-Node State

Pipecat Flows supports cross-node state through the flow_manager.state dictionary. This persistent storage lets you share data across nodes throughout the entire conversation:
handlers.py
State is also where you put the facts a session starts with — a caller’s name, a tenant’s restaurant, a practice’s details — by writing them before 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 content of each of its task_messages
  • the text of a tts_say action
Because the manager does the rendering, placeholders work the same way in a flow config and in a 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 }} reads state["quote"]["monthly_premium"]. Values are rendered with str().
  • 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.
Store values in state already formatted for speech, as update_coverage does above. The placeholder is substituted verbatim, so "81.00" reads better than the 81.0 a raw float would produce.

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 the FlowManager at initialization:
List them at the top level of the config, then hand flow.global_functions to the manager:
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 functions.