> ## Documentation Index
> Fetch the complete documentation index at: https://daily-docs-pr-4892.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Actions

> Execute custom functionality at specific points in your conversation flow.

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

Speak a phrase immediately (useful for "please wait" messages):

```python theme={null}
"pre_actions": [
    {
        "type": "tts_say",
        "text": "Please hold while I process your request..."
    }
]
```

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=False`:

```python theme={null}
"pre_actions": [
    {
        "type": "tts_say",
        "text": "Processing...",
        "append_text_to_context": False
    }
]
```

### end\_conversation

Gracefully terminate the conversation:

```python theme={null}
"post_actions": [
    {
        "type": "end_conversation",
        "text": "Thank you for your time!"
    }
]
```

The goodbye text is appended to the LLM context by default. To prevent the text from being added to the context, set `append_text_to_context=False`:

```python theme={null}
"post_actions": [
    {
        "type": "end_conversation",
        "text": "Goodbye!",
        "append_text_to_context": False
    }
]
```

### function

Execute a custom function at the specified timing:

```python theme={null}
"post_actions": [
    {
        "type": "function",
        "handler": end_conversation_handler
    }
]
```

## 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.

Register custom action handlers using `register_action()`:

```python theme={null}
async def notify_slack(action: dict, flow_manager: FlowManager):
    channel = action.get("channel", "#general")
    await slack_client.post_message(channel=channel, text=action["text"])

flow_manager.register_action("notify_slack", notify_slack)
```

<Note>
  Action handlers should accept `(action, flow_manager)`. Single-argument
  handlers `(action)` are deprecated and will be removed in 2.0.0.
</Note>

Once registered, use it in your node configuration:

```python theme={null}
"pre_actions": [
    {"type": "notify_slack", "channel": "#support", "text": "Session started"}
]
```

Custom actions give you complete flexibility to execute any functionality your application needs, but require careful timing considerations.

## 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.
