Skip to main content
Actions allow you to execute custom functionality at specific points in your conversation flow, giving you precise control over timing and sequencing.

Action Types

  • pre_actions execute immediately when transitioning to a new node, before the LLM inference begins.
  • post_actions execute after the LLM inference completes and any TTS has finished speaking.

Built-in Actions

Pipecat Flows includes several ready-to-use actions for common scenarios. tts_say and end_conversation need no Python at all; function names a handler.

tts_say

Speak a phrase immediately (useful for “please wait” messages):
The spoken text is appended to the LLM context by default. To prevent the text from being added to the context, set append_text_to_context to false:
A tts_say action’s text may contain {{ key }} placeholders, filled from the manager’s state when the node is entered. See Placeholders.

end_conversation

Gracefully terminate the conversation:
The goodbye text is appended to the LLM context by default. Set append_text_to_context to false to prevent that, the same way as for tts_say.

function

Execute a custom function at the specified timing. In a config, handler is the name of a callable in the handlers the Flow was constructed with; in code it is the callable itself:
handlers.py
A function action requires a handler; a config that omits one fails to load. The handler runs inline in the pipeline, queued behind the bot’s turn, which is what makes its timing predictable.

Custom Actions

You can define your own actions to handle specific business logic or integrations. In most cases, consider using a function action first, as it executes at the expected time in the pipeline. A custom action is a type Flows doesn’t provide. There are two ways to supply its code. Name a handler in the config. Like a function action, but with your own type. The handler runs immediately when the node’s actions execute, rather than being queued in the pipeline:
Register it in code. A custom type with no handler in the config must be registered with register_action(), which is also how a programmatic flow supplies every custom action:
Either way, any keys beyond type and handler pass through to the handler on the action dict — channel and text above.
Action handlers should accept (action, flow_manager). Single-argument handlers (action) are deprecated and will be removed in 2.0.0.
Once registered, use it in your node configuration:
Custom actions give you complete flexibility to execute any functionality your application needs, but require careful timing considerations.

Which Actions Need Python?

Action Timing

The execution order ensures predictable behavior:
  1. Pre-actions run first upon node entry (in the order they are defined)
  2. LLM inference processes the node’s messages and functions
  3. TTS speaks the LLM’s response
  4. Post-actions run after TTS completes (in the order they are defined)
This timing guarantees that actions execute in the correct sequence, such as ensuring the bot finishes speaking before ending the conversation. Note that custom actions may not follow this predictable timing, which is another reason to prefer function actions when possible.