Pipecat AI Flows
Pipecat AI Flows provides a powerful conversation flow management system for Pipecat AI applications. It allows developers to define structured conversational experiences using dynamic nodes and functions, managing transitions and LLM interactions. The library is currently at version 1.0.0 and follows an active release cadence, with frequent updates preceding major version releases.
Common errors
-
TypeError: 'role' field in task message must be 'developer'
cause Using `"role": "user"` for bot instructions within `task_messages` in `NodeConfig` or summary messages.fixChange the `"role"` for all bot-generated instructions to `"developer"` in `task_messages` arrays. -
ImportError: cannot import name 'FlowConfig' from 'pipecat_ai_flows'
cause Attempting to import or use `FlowConfig` or the deprecated static flow configuration after version 1.0.0.fixMigrate your flow definitions to use `NodeConfig` for dynamic flows. `FlowConfig` and the `flow_config` argument in `FlowManager` have been removed. -
RuntimeError: A newer version of pipecat-ai is required. Please upgrade to pipecat-ai>=1.0.0.
cause Your installed `pipecat-ai` package is older than the minimum required version for `pipecat-ai-flows` v1.0.0.fixRun `pip install --upgrade pipecat-ai` to ensure you have `pipecat-ai` version 1.0.0 or newer. -
SyntaxError: invalid syntax (related to new Python features like f-strings, type hints)
cause Running `pipecat-ai-flows` v1.0.0 (which requires Python 3.11+) with an older Python interpreter.fixUpgrade your Python environment to version 3.11 or higher. Check your active Python version with `python --version`.
Warnings
- breaking Version 1.0.0 requires Python >= 3.11 and `pipecat-ai>=1.0.0`. Older Python or Pipecat AI versions are not supported.
- breaking All task and summary messages in `NodeConfig` must now use `"role": "developer"` instead of `"role": "user"` to correctly distinguish application instructions from user speech.
- breaking Static Flows (configured via the `flow_config` argument and `FlowConfig` type) have been deprecated since v0.0.19 and are now removed in v1.0.0. Only Dynamic Flows using `NodeConfig` are supported.
- gotcha The `role_message` field is now the preferred way to set the bot's role/personality. System instructions are sent via `LLMUpdateSettingsFrame` rather than as system messages in the conversation context.
- gotcha The `@flows_direct_function` decorator allows configuring specific behaviors like `cancel_on_interruption` for functions directly invoked by the flow manager. This is crucial for controlling function execution during user interruptions.
- gotcha `FlowManager` now supports a `global_functions` parameter during initialization, making functions available at every node without explicit definition in each `NodeConfig`.
Install
-
pip install pipecat-ai-flows
Imports
- FlowManager
from pipecat_ai_flows import FlowManager
- NodeConfig
from pipecat_ai_flows import NodeConfig
- flows_direct_function
from pipecat_ai_flows import flows_direct_function
- ActionConfig
from pipecat_ai_flows import ActionConfig
Quickstart
import asyncio
from pipecat_ai_flows import FlowManager, NodeConfig, flows_direct_function
from pipecat_ai_flows.llm import LLMService # Base class
from pipecat.frames.frames import TextFrame, EndFrame # Required for type hints
import os
# Minimal mock LLMService and Transport to make the example runnable
class MockLLM(LLMService):
def __init__(self):
super().__init__("mock_llm")
async def process_input(self, input_frames):
for frame in input_frames:
if isinstance(frame, TextFrame):
yield TextFrame(f"Mock LLM received: {frame.text}")
yield EndFrame()
class MockTransport:
async def send_frame(self, frame):
if isinstance(frame, TextFrame):
print(f"Transport received text: {frame.text}")
elif isinstance(frame, EndFrame):
print("Transport received EndFrame")
async def receive_audio_frame(self): return None
async def receive_text_frame(self): return None
@flows_direct_function(cancel_on_interruption=True)
async def greet_user(flow_manager: FlowManager, user_name: str = "there"):
"""Greets the user by their name."""
await flow_manager.transport.send_frame(TextFrame(f"Hello, {user_name}!"))
return "Greeting complete.", "start" # Transition back to start
async def main():
print("Setting up Pipecat AI Flow Manager...")
# Define nodes for the conversation flow
start_node = NodeConfig(
name="start",
task_messages=[
{"role": "developer", "content": "Ask the user for their name or just say hello."}
],
functions=[greet_user], # Make `greet_user` available from this node
next_node="ask_name_node", # Define a transition
)
ask_name_node = NodeConfig(
name="ask_name_node",
task_messages=[
{"role": "developer", "content": "If the user hasn't provided a name, ask for it. Otherwise, acknowledge the name."}
],
next_node=None # End of simple flow for this example
)
# Initialize the FlowManager with nodes and required services
flow_manager = FlowManager(
initial_node=start_node, # The starting point of the flow
llm_service=MockLLM(), # In a real app, use pipecat_ai.services.openai.OpenAILLMService etc.
transport=MockTransport(), # In a real app, use pipecat_ai.transports.daily.DailyService etc.
)
print(f"Flow Manager initialized. Current node: {flow_manager.current_node.name}")
print("\nTo activate the flow and start a conversation, integrate this FlowManager with a Pipecat AI PipelineRunner.")
print("For example: `pipeline = Pipeline(llm=flow_manager.llm_service, vad=..., stt=..., tts=..., transport=flow_manager.transport)`")
print("Then: `await PipelineRunner().run(pipeline)`")
if __name__ == "__main__":
asyncio.run(main())