Update, 15 October 2026: Sipral 1.2 is released, a month ahead of plan, with the week of calls done and the sipral package on PyPI (the release).
An AI voice agent that answers the phone needs an extension on the PBX, the caller’s audio at the rate its speech service works at, a way to go quiet the moment the caller talks, and the call’s digits and transfers. Sipral 1.2 is the release that puts all of that in one process, with no media server in between. It is planned for November 2026 (roadmap); most of it is already on the main branch. None of it is in a package registry yet: it is used from a checkout of the repository until 1.2 ships.
sipral-agents: five services, no framework
The Python package sipral-agents joins a SIP call straight to the realtime speech APIs of five voice-agent services over their WebSocket protocols. One call to serve(account, factory) answers every call to an account and opens one session per call, so one process serves many calls at once.
What it does for every service:
- Rate. The call’s audio is switched to the service’s rate inside the library (G.711 at 8 kHz, G.722 at 16, Opus at 48, in and out), so nothing is resampled in Python.
- Barge-in. The agent’s audio goes to the call one codec frame at a time, never more than 40 ms queued; when the service says the caller started talking, what is queued is dropped at once.
- Reconnection. A dropped connection is opened again with backoff (0.5 s doubling to 8 s, six tries) and the call is hung up only after that.
- Events and ending. Connection, speech, interruption, transcript and error events for the application; either side hanging up ends the other.
The connectors are tested against local stand-ins written from each vendor’s public protocol documentation, not against the vendors’ own services. A new service is one Provider subclass. The connector documentation lists them and their formats.
A bridge from one configuration file
python -m sipral_agents bridge.toml registers every account the file lists on its PBX and hands each one’s calls to the agent named for it: one of the five WebSocket services, or service = "sip" and the SIP address of an agent that answers SIP itself. In that case Sipral places a second call to the agent and joins the two; when the agent hangs up, the outcome is handed back to the PBX in a header on the BYE or as a transfer, and a transfer the agent asks for becomes a REFER the PBX places. Keys and passwords are named by the environment variable that holds them, never written in the file, and --check prints the routes without starting anything (docs/24).
For everything else there is a Pipecat transport, sipral-pipecat, so every speech service Pipecat supports is one pipeline away.
Hear it before you have a key
cargo build --release -p sipral-ffi
python3 -m pip install websockets cffi
export SIPRAL_LIBRARY=target/release PYTHONPATH=integrations/agents:bindings/python
python3 -m sipral_agents.demo
The demo answers calls from any softphone, or on a PBX extension. With no key it answers with a local echo agent that speaks the same protocol and plays your voice back, so the whole path is heard working; with a key for the realtime speech service, the same command answers with the real agent (the five-minute guide).
How long the stack takes
Three hundred calls from Asterisk to the headless application, each bridged to a reference echo agent over the socket, release build, measured on 7 October (docs/19):
| Figure | Median | 95th percentile |
|---|---|---|
| INVITE in, to the first audio frame the agent reads | 31.5 ms | 31.9 ms |
| The agent’s first frame written, to the first RTP packet carrying it | 20.4 ms | 20.6 ms |
All 300 calls were timed and none failed. No speech service sits behind the agent here, so this is the stack and the socket, not a model’s thinking time. The first figure is the answer’s round trip (200 OK out, ACK back) and then the next 20 ms media tick. The second is one frame: audio leaves on a steady 20 ms clock, and the echo agent replies just after a tick, which is the worst case; an agent whose reply falls anywhere in the frame waits 10 ms on average.
What is still to come before 1.2: calls held for a day and for a week with no growth in memory or processor time, measured and published. More on the voice agents page.