Skip to main content

livekit-piopiy

Piopiy telephony for LiveKit Agents. Your LiveKit agent takes real phone calls on the Piopiy platform by TeleCMI: calls the Piopiy API places, calls arriving on your numbers, and calls arriving from your PBX over SIP Connect. Mid-call it can transfer the caller to a human, warm or blind, and hang up.

Piopiy bridges each call into a LiveKit room and hands your worker the room and a per-call token. Your AgentSession runs in that room; this package supplies the rest: taking the call, knowing who is calling, acting on the call, and hearing about transfers.

Tested with livekit-agents v1.7.1. Maintained by TeleCMI.

Install

pip install livekit-piopiy
# for the example, with Deepgram + OpenAI + Silero VAD:
pip install "livekit-piopiy[example]"

Python 3.10+. Depends on livekit-agents and piopiy-agent, the framework-agnostic Piopiy worker SDK.

Use with an AgentSession

from livekit.agents import Agent, AgentSession
from livekit.plugins import deepgram, openai, silero
from livekit_piopiy import PiopiyRunner, PiopiyCallControl, piopiy_tools, attach_transfer_status

async def bot(room, call):
    control = PiopiyCallControl(call)
    tools = piopiy_tools(control, transfer_number="919876543210",
                         transfer_caller_id="911203134087")
    agent = Agent(instructions=PROMPT, tools=tools.tools)

    session = AgentSession(stt=deepgram.STT(model="nova-3", language="en"),
                           llm=openai.LLM(model="gpt-4o-mini"),
                           tts=deepgram.TTS(), vad=silero.VAD.load())
    attach_transfer_status(call, session)     # narrates transfer progress

    await session.start(agent=agent, room=room)
    session.generate_reply(instructions="Greet the caller.")
    await call.wait_for_end()
    await session.aclose()

PiopiyRunner().run(bot)

PiopiyRunner connects to Piopiy as a worker for your agent. For every call it connects an rtc.Room with the token the platform minted, accepts the call (which is when the caller is bridged in), and calls bot(room, call). The room is disconnected when bot returns; call.wait_for_end() returns when the caller leaves.

This is the "bring your own worker" model: your process runs anywhere with outbound internet, no LiveKit Cloud agent dispatch is involved, and the livekit-agents CLI worker is not used.

Run the example

cd examples/foundational
cp .env.example .env        # agent id, token, API base, transfer number, keys
python 01_piopiy_agent.py

Then call your agent: place a call with POST /v3/voice/agent/call, ring one of your numbers mapped to the agent, or dial the agent id from a PBX registered over SIP Connect. Ask for a person to see a warm transfer, ask for "the billing line" to see a blind transfer, and say goodbye to see it hang up.

Configuration

variable what
PIOPIY_AGENT_ID the agent this worker serves, from the dashboard
PIOPIY_TOKEN the Bearer token, the same one that creates calls
PIOPIY_API_URL optional; the REST base, default https://rest.piopiy.com/v3
PIOPIY_REGISTER optional; default register.piopiy.com (host only); host:port for a private register
PIOPIY_TLS optional; false to talk to the register without TLS (development)
PIOPIY_MAX_SESSIONS calls one process handles at once

What the package gives you

PiopiyCall - call_id, direction, from_number, to_number, agent_id, variables, sip_account_id on SIP Connect calls, and wait_for_end().

PiopiyCallControl (from piopiy-agent) - actions on the live call:

result  = await control.warm_transfer(to_number="9198...", transfer_summary="Refund on order A-1042")
result  = await control.blind_transfer(to_number="9198...", caller_id="9112...")
await control.hangup(reason="resolved")
verdict = await control.wait_for_transfer(result.request_id)   # queued -> completed | failed

A warm transfer rings the human while the caller stays with the agent; on answer the caller is handed over and the agent leaves; if nobody answers the conversation continues. A blind transfer hands the caller over at once. One transfer at a time per call: a second is refused with PiopiyAPIError(409, "transfer_in_progress").

piopiy_tools() - transfer_call and end_call as LiveKit function tools (tools.tools). The destination is fixed in code; pass transfer_caller_id for the DID to present, which SIP Connect calls require.

attach_transfer_status() - the platform pushes every transfer's progress into the room as transfer_status data messages. This speaks "I'm connecting you now" as the target rings, an apology if it fails, and adds a note to the agent's chat context so the model carries on. Pass narrate=False and on_status= to handle it yourself.

Notes

  • Every action uses the call's customer leg, which PiopiyCall.call_id is.
  • SIP Connect calls consume no phone number, so a transfer to a phone from one needs transfer_caller_id (a DID you own).
  • Accept timing is handled for you: the runner accepts right after the room connects; a join past the platform's deadline leaves the room and does not run the bot, so two agents never share a call.
  • The Pipecat equivalent is pipecat-piopiy.

License

MIT. Copyright TeleCMI.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

livekit_piopiy-0.1.1.tar.gz (15.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

livekit_piopiy-0.1.1-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file livekit_piopiy-0.1.1.tar.gz.

File metadata

  • Download URL: livekit_piopiy-0.1.1.tar.gz
  • Upload date:
  • Size: 15.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for livekit_piopiy-0.1.1.tar.gz
Algorithm Hash digest
SHA256 56929a8e08e798def864d4090a89cb83c49cc4fd1ba469d805d49d4e31c5b527
MD5 0c95f8319b3fbee25c9d68dc938459db
BLAKE2b-256 88177717990207911bf5ae7b089e74a38041b1cb7237e587edc9de44c6104152

See more details on using hashes here.

File details

Details for the file livekit_piopiy-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: livekit_piopiy-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for livekit_piopiy-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 daa11feca9e8ab4cbd0808969bfb841219af5c9c85a762b41193b8812217bc3b
MD5 d5c4dc0f09f98c60eba78e3f0fb90b23
BLAKE2b-256 9cfe8aee54fae0744f22a1112675bfebca717950084295de9439d79a6fc76e98

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page