Skip to main content

pipecat-piopiy

Give your Pipecat agent a phone.

Piopiy is a communication platform: we provide the phone numbers, carry the calls, and host all the voice infrastructure. You build the agent with Pipecat 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 Pipecat v1.8.1. Community-maintained by TeleCMI; not part of the Pipecat core.

Install

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

Python 3.10+.

Use with a pipeline

from pipecat_piopiy import PiopiyRunner, PiopiyCallControl, piopiy_tools
from pipecat_piopiy.processors import PiopiyEventsProcessor

async def bot(transport, call):
    control = PiopiyCallControl(call)
    tools = piopiy_tools(control, transfer_number="919876543210",
                         transfer_caller_id="911203134087")

    context = LLMContext(messages=[{"role": "system", "content": PROMPT}],
                         tools=tools.schemas)
    aggregators = LLMContextAggregatorPair(
        context, user_params=LLMUserAggregatorParams(vad_analyzer=SileroVADAnalyzer()))

    pipeline = Pipeline([
        transport.input(),
        PiopiyEventsProcessor(call),      # transfer progress -> frames + narration
        stt, aggregators.user(), llm, tts,
        transport.output(), aggregators.assistant(),
    ])
    task = PipelineTask(pipeline)

    @transport.event_handler("on_first_participant_joined")
    async def on_caller_joined(_t, participant_id):
        await task.queue_frames([LLMRunFrame()])

    @transport.event_handler("on_participant_left")
    async def on_caller_left(_t, participant_id, reason):
        await task.cancel()

    await PipelineRunner(handle_sigint=False).run(task)

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 builds a transport already connected to that call's audio and calls bot. The caller is joined the moment the transport is connected. Use PipelineRunner(handle_sigint=False): the runner owns the process signals.

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, and sip_account_id when the call came from a phone system you connected to Piopiy, so one agent can tell your sites apart.

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 one is refused with PiopiyAPIError(409, "transfer_in_progress").

piopiy_tools() - transfer_call and end_call as LLM function calls. Each FunctionSchema carries its handler, so advertising tools.schemas on the LLMContext is all the wiring. The destination is fixed in your code by default so a caller cannot talk the agent into dialling anywhere else; pass allow_model_destination=True to let the model choose. transfer_caller_id is the number shown to the human being called; use one of your Piopiy numbers.

PiopiyEventsProcessor - Piopiy tells the agent how a transfer is going. The processor turns each update into a PiopiyTransferStatusFrame (started, failed with a reason, completed) and, by default, speaks it: "I'm connecting you now" as the human's phone rings, an apology if nobody answers, plus a note into the LLM context so the model carries on sensibly. Pass narrate=False to handle the frames 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 cancelled so two agents never share one call.
  • Pipecat changes quickly. This release is tested against v1.8.1; the pinned range in pyproject.toml is >=1.8,<2.

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

pipecat_piopiy-0.2.2.tar.gz (18.7 kB view details)

Uploaded Source

Built Distribution

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

pipecat_piopiy-0.2.2-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

Details for the file pipecat_piopiy-0.2.2.tar.gz.

File metadata

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

File hashes

Hashes for pipecat_piopiy-0.2.2.tar.gz
Algorithm Hash digest
SHA256 8eebdea31c3815111e49a9e2af437e418f0b505b14e11b1e5eb6bb8ef6151b76
MD5 266fa5f1677b1ea45130f98afcca7787
BLAKE2b-256 c4b1bcc028be029e761708f8f77e5184297f76dd37cce6326f287af7c61b9da8

See more details on using hashes here.

File details

Details for the file pipecat_piopiy-0.2.2-py3-none-any.whl.

File metadata

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

File hashes

Hashes for pipecat_piopiy-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b566dcc6b86c7dded22a3e9eda182064eafe450c0cce88cab046f2c371ce1fb3
MD5 15763355d15459879126ac38532eeec5
BLAKE2b-256 cf39060aa4abe0399782983096985dbc756f080522f434ffed38a9ad46694064

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.4

2 files

This release

0.2.2 This release

2 files

0.2.1

2 files

0.2.0

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