livekit-flows


Namelivekit-flows JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryA library for building declarative agent flows with LiveKit.
upload_time2025-10-26 14:07:48
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseNone
keywords agents ai conversational-ai declarative flow livekit real-time voice webrtc workflow
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 1.95174s