livekit-piopiy
Give your LiveKit Agents agent a phone.
Piopiy is a communication platform: we provide the phone numbers, carry the calls, and host all the voice infrastructure, including the LiveKit rooms your agent talks in. You build the agent with LiveKit Agents and run it wherever you like; this package connects the two. Your agent answers calls to your Piopiy numbers, places calls through the Piopiy API, and mid-call it can hand the caller to a human or end the call. Nothing telephony-related to host or configure on your side.
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+.
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 registers your process with Piopiy as the worker for your
agent. For every call, Piopiy hands it the call; the runner connects the
room for that call and calls bot(room, call). The caller is joined as soon
as the room is connected. call.wait_for_end() returns when the caller
leaves, and the room is closed when bot returns.
You run the process; Piopiy runs everything else. There is no LiveKit project to create, no rooms to manage and no telephony to set up.
Run the example
cd examples/foundational
cp .env.example .env # your agent id and token, the transfer number, your keys
python 01_piopiy_agent.py
Then call your agent: ring one of your Piopiy numbers, or place a call with
POST /v3/voice/agent/call. 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
Two values, both from your Piopiy dashboard:
| variable | what |
|---|---|
PIOPIY_AGENT_ID |
the agent this process serves |
PIOPIY_TOKEN |
your API token |
Optional: PIOPIY_MAX_SESSIONS (calls one process handles at once, default
10). PIOPIY_API_URL and PIOPIY_REGISTER exist only for regional or
private deployments; the public platform needs neither.
What the package gives you
PiopiyCall - the call in hand: call_id, direction, from_number,
to_number, agent_id, the variables you attached when placing the call,
sip_account_id when the call came from a phone system you connected to
Piopiy, and wait_for_end().
PiopiyCallControl - act on the 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 in conversation
with the agent; when the human answers the caller is handed over and the
agent leaves; if nobody answers the conversation simply 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 your code so a caller
cannot talk the agent into dialling anywhere else. transfer_caller_id is
the number shown to the human being called; use one of your Piopiy numbers.
attach_transfer_status() - Piopiy tells the agent how a transfer is
going. This speaks "I'm connecting you now" as the human's phone rings, an
apology if nobody answers, 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
PiopiyCall.call_id; the runner gives you the right one. - Accept timing is handled for you: if your process was too slow to join a call, the bot is not run, so two agents never share one 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file livekit_piopiy-0.1.2.tar.gz.
File metadata
- Download URL: livekit_piopiy-0.1.2.tar.gz
- Upload date:
- Size: 14.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3a2ba8abb7b453a423ea00139c16778d4f00aebfd1cb1124d12687ad89319d9
|
|
| MD5 |
4e226c1311bda2e99b8b0060bc3590de
|
|
| BLAKE2b-256 |
062bec10609486d84ab2cd0e435ae3893693dd952f7da35223651a97a1d45de5
|
File details
Details for the file livekit_piopiy-0.1.2-py3-none-any.whl.
File metadata
- Download URL: livekit_piopiy-0.1.2-py3-none-any.whl
- Upload date:
- Size: 13.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dea49ce43cd4b42dabd869bcba037f2fd0970311fea08bf1561a8ddc274884c9
|
|
| MD5 |
8ed277e262842e1739a3a3c969a46a1b
|
|
| BLAKE2b-256 |
9a1740e1f2a5d86f10f92cb3bc892c05f6db34d88066222d032fbb68f1e19e33
|