diff --git a/api-reference/utilities/flows/pipecat-flows.mdx b/api-reference/utilities/flows/pipecat-flows.mdx
index 11884ff..554fc88 100644
--- a/api-reference/utilities/flows/pipecat-flows.mdx
+++ b/api-reference/utilities/flows/pipecat-flows.mdx
@@ -221,10 +221,8 @@ await flow_manager.set_node("start", create_start_node())
-## Function Handlers
-
- Functions that execute operations within a state without causing transitions.
+ Functions that execute operations within a state and optionally transition to a new state.
@@ -240,19 +238,20 @@ async def process_data(args: FlowArgs) -> FlowResult:
"processed_data": result
}
-# Node configuration
+# Node configuration with transition
{
"type": "function",
"function": {
"name": "process_data",
- "handler": process_data, # Handler required for node functions
+ "handler": process_data,
"description": "Process user data",
"parameters": {
"type": "object",
"properties": {
"data": {"type": "string"}
}
- }
+ },
+ "transition_to": "next_node" # Optional: Specify next node
}
}
```
@@ -262,7 +261,7 @@ async def process_data(args: FlowArgs) -> FlowResult:
- Functions that create transitions between nodes. No handler needed - the name must match a target node.
+ Functions that create transitions between nodes. Use transition_to to specify the target node.
@@ -271,9 +270,10 @@ async def process_data(args: FlowArgs) -> FlowResult:
{
"type": "function",
"function": {
- "name": "next_node", # Must match an existing node name
+ "name": "next_step",
"description": "Transition to next node",
- "parameters": {"type": "object", "properties": {}}
+ "parameters": {"type": "object", "properties": {}},
+ "transition_to": "target_node" # Required: Specify target node
}
}
```
@@ -282,6 +282,58 @@ async def process_data(args: FlowArgs) -> FlowResult:
+### Function Properties
+
+
+ Async function that processes data within a node
+
+
+
+ Name of the node to transition to after function execution
+
+
+### Transition Types
+
+
+ ```python Handler with Transition
+ # Process data and transition
+ {
+ "type": "function",
+ "function": {
+ "name": "save_order",
+ "handler": save_order_handler,
+ "parameters": {...},
+ "transition_to": "confirmation"
+ }
+ }
+ ```
+
+ ```python Pure Transition
+ # Transition only
+ {
+ "type": "function",
+ "function": {
+ "name": "go_to_checkout",
+ "parameters": {},
+ "transition_to": "checkout"
+ }
+ }
+ ```
+
+ ```python Handler Only
+ # Process without transition
+ {
+ "type": "function",
+ "function": {
+ "name": "validate_input",
+ "handler": validate_handler,
+ "parameters": {...}
+ }
+ }
+ ```
+
+
+
### Handler Signatures
diff --git a/guides/pipecat-flows.mdx b/guides/pipecat-flows.mdx
index 735fcf9..905e508 100644
--- a/guides/pipecat-flows.mdx
+++ b/guides/pipecat-flows.mdx
@@ -57,6 +57,58 @@ pip install "pipecat-ai[daily,google,deepgram]" # For Google
# Core Concepts
+## Designing Conversation Flows
+
+Functions in Pipecat Flows serve two key purposes: interfacing with external systems and advancing the conversation.
+
+### Function Handlers
+
+When you need to collect data, validate input, or retrieve information, add a handler to your function. These handlers are async functions that execute when the LLM calls the function, allowing you to interact with databases, APIs, or other external services:
+
+```python
+# Example function handler
+async def check_availability(args: FlowArgs) -> FlowResult:
+ """Check restaurant availability for the requested time."""
+ date = args["date"]
+ time = args["time"]
+ party_size = args["party_size"]
+
+ # Interface with reservation system
+ available = await reservation_system.check_availability(date, time, party_size)
+ return {"status": "success", "available": available}
+```
+
+### Transitioning Between Nodes
+
+To advance the conversation, Pipecat Flows offers two approaches based on your flow type:
+
+For static flows, use the `transition_to` property to specify the next node:
+
+```python
+{
+ "type": "function",
+ "function": {
+ "name": "confirm_reservation",
+ "handler": save_reservation, # Process the reservation
+ "parameters": {...},
+ "transition_to": "send_confirmation" # Move to confirmation node
+ }
+}
+```
+
+For dynamic flows, use a transition callback to determine the next node at runtime:
+
+```python
+async def handle_transitions(function_name: str, args: Dict, flow_manager):
+ if function_name == "check_availability":
+ if args["available"]:
+ await flow_manager.set_node("collect_details", create_details_node())
+ else:
+ await flow_manager.set_node("suggest_alternatives", create_alternatives_node())
+```
+
+You can combine both approaches: use handlers to process data and transitions to advance the conversation, creating flows that are both functional and conversational.
+
## Node Structure
Each node in your flow represents a conversation state and consists of three main components:
@@ -82,15 +134,15 @@ Messages set the context for the LLM at each state:
Functions come in two types, each serving a different purpose:
-#### Node Functions
+#### Node Functions with Transitions
-Execute operations within the current state:
+Process data and optionally transition to a new state:
```python
from pipecat_flows import FlowArgs, FlowResult
async def select_size(args: FlowArgs) -> FlowResult:
- """Handle pizza size selection."""
+ """Handle pizza size selection and transition."""
size = args["size"]
return {
"status": "success",
@@ -102,14 +154,15 @@ async def select_size(args: FlowArgs) -> FlowResult:
"type": "function",
"function": {
"name": "select_size",
- "handler": select_size, # Handler required for node functions
+ "handler": select_size,
"description": "Select pizza size",
"parameters": {
"type": "object",
"properties": {
"size": {"type": "string", "enum": ["small", "medium", "large"]}
}
- }
+ },
+ "transition_to": "toppings" # Optional: Specify next node
}
}
```
@@ -122,9 +175,10 @@ Create transitions between states:
{
"type": "function",
"function": {
- "name": "next_node", # Must match a node name
+ "name": "next_step",
"description": "Move to next state",
- "parameters": {"type": "object", "properties": {}}
+ "parameters": {"type": "object", "properties": {}},
+ "transition_to": "target_node" # Required: Specify target node
}
}
```
@@ -148,33 +202,7 @@ Actions execute during state transitions:
]
```
-## Function Types
-
-### Type Safety
-
-Pipecat Flows provides type definitions for function handlers:
-
-```python
-from pipecat_flows import FlowArgs, FlowResult
-
-async def my_handler(args: FlowArgs) -> FlowResult:
- """Type-safe function handler."""
- return {
- "status": "success",
- "data": process_args(args)
- }
-```
-
-### Handler Implementation
-
-Function handlers should:
-
-- Be async functions
-- Accept FlowArgs (or no args)
-- Return FlowResult
-- Include status in response
-
-## Provider Support
+## LLM Provider Support
Pipecat Flows automatically handles format differences between LLM providers:
@@ -266,15 +294,16 @@ flow_config = {
{
"type": "function",
"function": {
- "name": "choose_pizza", # Edge function
+ "name": "choose_pizza",
"description": "User wants pizza",
- "parameters": {"type": "object", "properties": {}}
+ "parameters": {"type": "object", "properties": {}},
+ "transition_to": "pizza_order" # Specify transition
}
},
{
"type": "function",
"function": {
- "name": "select_size", # Node function
+ "name": "select_size",
"handler": select_size,
"description": "Select pizza size",
"parameters": {
@@ -282,28 +311,24 @@ flow_config = {
"properties": {
"size": {"type": "string", "enum": ["small", "medium", "large"]}
}
- }
+ },
+ "transition_to": "toppings" # Optional transition after processing
}
}
- ],
- "pre_actions": [
- {
- "type": "tts_say",
- "text": "Welcome! What would you like to order?"
- }
]
}
}
}
```
-### Best Practices
+### Transition Best Practices
-- Define complete conversation paths upfront
-- Use clear, descriptive node names
-- Keep node messages focused on current state
-- Ensure edge functions match valid node names
-- Test all paths and transitions
+- Use `transition_to` to make state changes explicit
+- Combine handlers with transitions when appropriate
+- Keep transitions focused on single responsibilities
+- Use clear, descriptive names for target nodes
+- Validate all transition targets exist
+- Test both successful and failed transitions
## Dynamic Flows
@@ -444,25 +469,7 @@ The Pipecat Flow Editor provides a visual interface for creating and managing co
}
```
-### Node Configuration
-
-Each node can be configured with:
-
-- Messages for LLM context
-- Available functions
-- Pre/post actions
-- State transitions
-
-## Best Practices
-
-### Organization
-
-- Arrange nodes in logical flow
-- Group related nodes together
-- Use consistent spacing
-- Make transitions clear
-
-### Naming Conventions
+## Naming Conventions
- **Start Node**: Use descriptive names (e.g., "greeting", "welcome")
- **Flow Nodes**: Name based on purpose (e.g., "collect_info", "verify_data")
@@ -476,9 +483,10 @@ Each node can be configured with:
{
"type": "function",
"function": {
- "name": "next_state", # Matches target node name
+ "name": "next_state",
"description": "Clear transition description",
"parameters": {...}
+ "transition_to": "target_node_name" # Transition target
}
}
@@ -494,13 +502,6 @@ Each node can be configured with:
}
```
-### Testing Flows
-
-- Verify all paths lead to valid endpoints
-- Test node functions with sample data
-- Ensure edge functions connect properly
-- Validate configuration export
-
## Using the Editor
### Creating a New Flow