# LiveKit Flows
A Python library for building declarative, flow-based conversational AI agents with [LiveKit](https://livekit.io/).
LiveKit Flows allows you to define complex conversation flows using simple Python code or YAML files, making it easy to build structured voice agents that guide users through multi-step interactions.
## Features
- 🎯 **Declarative Flow Definition** - Define conversation flows using Python or YAML
- 🔄 **State Management** - Built-in flow state tracking and transitions
- 🎤 **Voice-First** - Seamlessly integrates with LiveKit's real-time audio/video
- 🔌 **HTTP Actions** - Execute HTTP requests during conversation flows
- 📊 **Data Collection** - Collect and validate structured data from conversations
- 🎨 **Visual Editor** - Interactive web-based flow editor
## Installation
Install from PyPI using your preferred package manager:
### pip
```bash
pip install livekit-flows
```
### uv
```bash
uv add livekit-flows
```
### Poetry
```bash
poetry add livekit-flows
```
### Development Installation
```bash
git clone https://github.com/mateuszkulpa/livekit-flows.git
cd livekit-flows
uv sync
```
## Quick Start
Here's a minimal example of a restaurant reservation agent:
```python
from livekit.agents import AgentSession, JobContext, WorkerOptions, cli
from livekit.plugins import openai, cartesia, deepgram, silero
from livekit_flows import FlowAgent, ConversationFlow, FlowNode, Edge
# Define the conversation flow
reservation_flow = ConversationFlow(
system_prompt="You are a friendly restaurant reservation assistant.",
initial_node="welcome",
nodes=[
FlowNode(
id="welcome",
name="Welcome",
static_text="Hi! I'll help you make a reservation. What's your name?",
edges=[
Edge(
condition="Got name",
id="to_details",
target_node_id="get_details",
)
],
),
FlowNode(
id="get_details",
name="Get Details",
instruction="Ask about party size, date, and time.",
edges=[
Edge(
condition="Got all details",
id="to_confirm",
target_node_id="confirm",
)
],
),
FlowNode(
id="confirm",
name="Confirm",
instruction="Confirm all reservation details with the user.",
edges=[
Edge(condition="Confirmed", id="to_done", target_node_id="done"),
Edge(condition="Need changes", id="to_details", target_node_id="get_details"),
],
),
FlowNode(
id="done",
name="Done",
static_text="Perfect! Your reservation is confirmed. See you then!",
is_final=True,
),
],
)
async def entrypoint(ctx: JobContext):
await ctx.connect()
agent = FlowAgent(flow=reservation_flow)
session = AgentSession(
vad=silero.VAD.load(),
stt=deepgram.STT(),
llm=openai.LLM(model="gpt-4o-mini"),
tts=cartesia.TTS(),
)
await session.start(agent=agent, room=ctx.room)
if __name__ == "__main__":
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
```
## YAML Configuration
You can also define flows using YAML for better readability and easier editing:
```yaml
system_prompt: "You are a friendly restaurant reservation assistant."
initial_node: "welcome"
nodes:
- id: "welcome"
name: "Welcome"
static_text: "Hi! I'll help you make a reservation. What's your name?"
edges:
- condition: "Got name"
id: "to_details"
target_node_id: "get_details"
- id: "get_details"
name: "Get Details"
instruction: "Ask about party size, date, and time."
edges:
- condition: "Got all details"
id: "to_confirm"
target_node_id: "confirm"
- id: "confirm"
name: "Confirm"
instruction: "Confirm all reservation details with the user."
edges:
- condition: "Confirmed"
id: "to_done"
target_node_id: "done"
- condition: "Need changes"
id: "to_details"
target_node_id: "get_details"
- id: "done"
name: "Done"
static_text: "Perfect! Your reservation is confirmed. See you then!"
is_final: true
```
Load the YAML flow in your Python code:
```python
from livekit_flows import ConversationFlow
flow = ConversationFlow.from_yaml_file("path/to/flow.yaml")
agent = FlowAgent(flow=flow)
```
## HTTP Actions
Execute HTTP requests during your flows with built-in action support:
```yaml
actions:
- id: "get_cat_fact"
name: "Get Cat Fact"
description: "Fetches a random cat fact"
method: "GET"
url: "https://catfact.ninja/fact"
store_response_as: "cat_fact"
nodes:
- id: "share_fact"
name: "Share Fact"
instruction: |
Share this fact with the user:
{% if actions.cat_fact and actions.cat_fact.success %}
{{ actions.cat_fact.data.fact }}
{% endif %}
actions:
- trigger_type: "on_enter"
action_id: "get_cat_fact"
```
## Core Concepts
### FlowNode
A node represents a state in your conversation. Each node can have:
- **static_text**: Fixed text to speak to the user
- **instruction**: Dynamic instructions for the LLM
- **edges**: Conditions for transitioning to other nodes
- **actions**: HTTP actions to execute when entering the node
### Edge
An edge defines a transition between nodes based on:
- **condition**: Natural language condition evaluated by the LLM
- **target_node_id**: The destination node
- **input_schema**: Optional JSON schema for data validation
### CustomAction
HTTP actions that can be triggered during the flow:
- Supports GET, POST, PUT, DELETE, PATCH methods
- Template-based request bodies with Jinja2
- Automatic response storage for use in subsequent nodes
## Visual Editor
This project includes a web-based visual editor for designing flows:
```bash
cd editor
pnpm install
pnpm dev
```
Open http://localhost:3000 to design flows visually and export them as YAML or Python code.
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Links
- [GitHub Repository](https://github.com/mateuszkulpa/livekit-flows)
- [LiveKit Documentation](https://docs.livekit.io/)
- [LiveKit Agents Framework](https://github.com/livekit/agents)
Raw data
{
"_id": null,
"home_page": null,
"name": "livekit-flows",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": "Mateusz Kulpa <mateusz.kulpa@outlook.com>",
"keywords": "agents, ai, conversational-ai, declarative, flow, livekit, real-time, voice, webrtc, workflow",
"author": null,
"author_email": "Mateusz Kulpa <mateusz.kulpa@outlook.com>",
"download_url": "https://files.pythonhosted.org/packages/d1/5b/78ed356ee57ffcdb7b242b18bb4c5daf4cbf1f7cd95c58e4530cf772544e/livekit_flows-0.1.0.tar.gz",
"platform": null,
"description": "# LiveKit Flows\n\nA Python library for building declarative, flow-based conversational AI agents with [LiveKit](https://livekit.io/).\n\nLiveKit Flows allows you to define complex conversation flows using simple Python code or YAML files, making it easy to build structured voice agents that guide users through multi-step interactions.\n\n## Features\n\n- \ud83c\udfaf **Declarative Flow Definition** - Define conversation flows using Python or YAML\n- \ud83d\udd04 **State Management** - Built-in flow state tracking and transitions\n- \ud83c\udfa4 **Voice-First** - Seamlessly integrates with LiveKit's real-time audio/video\n- \ud83d\udd0c **HTTP Actions** - Execute HTTP requests during conversation flows\n- \ud83d\udcca **Data Collection** - Collect and validate structured data from conversations\n- \ud83c\udfa8 **Visual Editor** - Interactive web-based flow editor\n\n## Installation\n\nInstall from PyPI using your preferred package manager:\n\n### pip\n```bash\npip install livekit-flows\n```\n\n### uv\n```bash\nuv add livekit-flows\n```\n\n### Poetry\n```bash\npoetry add livekit-flows\n```\n\n### Development Installation\n\n```bash\ngit clone https://github.com/mateuszkulpa/livekit-flows.git\ncd livekit-flows\nuv sync\n```\n\n## Quick Start\n\nHere's a minimal example of a restaurant reservation agent:\n\n```python\nfrom livekit.agents import AgentSession, JobContext, WorkerOptions, cli\nfrom livekit.plugins import openai, cartesia, deepgram, silero\nfrom livekit_flows import FlowAgent, ConversationFlow, FlowNode, Edge\n\n# Define the conversation flow\nreservation_flow = ConversationFlow(\n system_prompt=\"You are a friendly restaurant reservation assistant.\",\n initial_node=\"welcome\",\n nodes=[\n FlowNode(\n id=\"welcome\",\n name=\"Welcome\",\n static_text=\"Hi! I'll help you make a reservation. What's your name?\",\n edges=[\n Edge(\n condition=\"Got name\",\n id=\"to_details\",\n target_node_id=\"get_details\",\n )\n ],\n ),\n FlowNode(\n id=\"get_details\",\n name=\"Get Details\",\n instruction=\"Ask about party size, date, and time.\",\n edges=[\n Edge(\n condition=\"Got all details\",\n id=\"to_confirm\",\n target_node_id=\"confirm\",\n )\n ],\n ),\n FlowNode(\n id=\"confirm\",\n name=\"Confirm\",\n instruction=\"Confirm all reservation details with the user.\",\n edges=[\n Edge(condition=\"Confirmed\", id=\"to_done\", target_node_id=\"done\"),\n Edge(condition=\"Need changes\", id=\"to_details\", target_node_id=\"get_details\"),\n ],\n ),\n FlowNode(\n id=\"done\",\n name=\"Done\",\n static_text=\"Perfect! Your reservation is confirmed. See you then!\",\n is_final=True,\n ),\n ],\n)\n\nasync def entrypoint(ctx: JobContext):\n await ctx.connect()\n\n agent = FlowAgent(flow=reservation_flow)\n session = AgentSession(\n vad=silero.VAD.load(),\n stt=deepgram.STT(),\n llm=openai.LLM(model=\"gpt-4o-mini\"),\n tts=cartesia.TTS(),\n )\n\n await session.start(agent=agent, room=ctx.room)\n\nif __name__ == \"__main__\":\n cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))\n```\n\n## YAML Configuration\n\nYou can also define flows using YAML for better readability and easier editing:\n\n```yaml\nsystem_prompt: \"You are a friendly restaurant reservation assistant.\"\n\ninitial_node: \"welcome\"\n\nnodes:\n - id: \"welcome\"\n name: \"Welcome\"\n static_text: \"Hi! I'll help you make a reservation. What's your name?\"\n edges:\n - condition: \"Got name\"\n id: \"to_details\"\n target_node_id: \"get_details\"\n\n - id: \"get_details\"\n name: \"Get Details\"\n instruction: \"Ask about party size, date, and time.\"\n edges:\n - condition: \"Got all details\"\n id: \"to_confirm\"\n target_node_id: \"confirm\"\n\n - id: \"confirm\"\n name: \"Confirm\"\n instruction: \"Confirm all reservation details with the user.\"\n edges:\n - condition: \"Confirmed\"\n id: \"to_done\"\n target_node_id: \"done\"\n - condition: \"Need changes\"\n id: \"to_details\"\n target_node_id: \"get_details\"\n\n - id: \"done\"\n name: \"Done\"\n static_text: \"Perfect! Your reservation is confirmed. See you then!\"\n is_final: true\n```\n\nLoad the YAML flow in your Python code:\n\n```python\nfrom livekit_flows import ConversationFlow\n\nflow = ConversationFlow.from_yaml_file(\"path/to/flow.yaml\")\nagent = FlowAgent(flow=flow)\n```\n\n## HTTP Actions\n\nExecute HTTP requests during your flows with built-in action support:\n\n```yaml\nactions:\n - id: \"get_cat_fact\"\n name: \"Get Cat Fact\"\n description: \"Fetches a random cat fact\"\n method: \"GET\"\n url: \"https://catfact.ninja/fact\"\n store_response_as: \"cat_fact\"\n\nnodes:\n - id: \"share_fact\"\n name: \"Share Fact\"\n instruction: |\n Share this fact with the user:\n {% if actions.cat_fact and actions.cat_fact.success %}\n {{ actions.cat_fact.data.fact }}\n {% endif %}\n actions:\n - trigger_type: \"on_enter\"\n action_id: \"get_cat_fact\"\n```\n\n## Core Concepts\n\n### FlowNode\nA node represents a state in your conversation. Each node can have:\n- **static_text**: Fixed text to speak to the user\n- **instruction**: Dynamic instructions for the LLM\n- **edges**: Conditions for transitioning to other nodes\n- **actions**: HTTP actions to execute when entering the node\n\n### Edge\nAn edge defines a transition between nodes based on:\n- **condition**: Natural language condition evaluated by the LLM\n- **target_node_id**: The destination node\n- **input_schema**: Optional JSON schema for data validation\n\n### CustomAction\nHTTP actions that can be triggered during the flow:\n- Supports GET, POST, PUT, DELETE, PATCH methods\n- Template-based request bodies with Jinja2\n- Automatic response storage for use in subsequent nodes\n\n## Visual Editor\n\nThis project includes a web-based visual editor for designing flows:\n\n```bash\ncd editor\npnpm install\npnpm dev\n```\n\nOpen http://localhost:3000 to design flows visually and export them as YAML or Python code.\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Links\n\n- [GitHub Repository](https://github.com/mateuszkulpa/livekit-flows)\n- [LiveKit Documentation](https://docs.livekit.io/)\n- [LiveKit Agents Framework](https://github.com/livekit/agents)\n",
"bugtrack_url": null,
"license": null,
"summary": "A library for building declarative agent flows with LiveKit.",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/mateuszkulpa/livekit-flows",
"Repository": "https://github.com/mateuszkulpa/livekit-flows"
},
"split_keywords": [
"agents",
" ai",
" conversational-ai",
" declarative",
" flow",
" livekit",
" real-time",
" voice",
" webrtc",
" workflow"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c733a9460b2559026ac1212c71ed5082db0fec720829895bce92f93aa5e5145c",
"md5": "e537913ed67e5636f6fb9d2e21539c67",
"sha256": "1bf7c1e60cd3425cd4362e74bef2c95ff1939c56dc66948d02f5864b1c6fc35a"
},
"downloads": -1,
"filename": "livekit_flows-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e537913ed67e5636f6fb9d2e21539c67",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 15166,
"upload_time": "2025-10-26T14:06:17",
"upload_time_iso_8601": "2025-10-26T14:06:17.156964Z",
"url": "https://files.pythonhosted.org/packages/c7/33/a9460b2559026ac1212c71ed5082db0fec720829895bce92f93aa5e5145c/livekit_flows-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d15b78ed356ee57ffcdb7b242b18bb4c5daf4cbf1f7cd95c58e4530cf772544e",
"md5": "63ad2634c221b9370448169cc0c41661",
"sha256": "60deceac3ea621d48ee943f921d1eb65a73305dcab62f5c78e6d64b4499839fa"
},
"downloads": -1,
"filename": "livekit_flows-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "63ad2634c221b9370448169cc0c41661",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 43984392,
"upload_time": "2025-10-26T14:07:48",
"upload_time_iso_8601": "2025-10-26T14:07:48.960315Z",
"url": "https://files.pythonhosted.org/packages/d1/5b/78ed356ee57ffcdb7b242b18bb4c5daf4cbf1f7cd95c58e4530cf772544e/livekit_flows-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-26 14:07:48",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "mateuszkulpa",
"github_project": "livekit-flows",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "livekit-flows"
}