Skip to main content

hermes-plivo-phone-gateway

Plivo voice channel for Hermes Agent. Real-time phone conversations with the agent over Plivo, inbound and outbound.

Capability Detail
Inbound calls Any Hermes agent becomes reachable on a phone number
Outbound calls The agent dials out and talks to whoever answers
Barge-in The agent stops speaking the moment it is interrupted
Keypad input DTMF digits reach the agent as text
Call end Silence, a call-length limit, a hangup, or the agent ending the call
Provisioning Plivo is configured automatically on every start, including a public URL

Speech-to-text, the model turn and text-to-speech are Hermes settings, shared with every other channel. The plugin handles telephony and barge-in.

Requirements

Hermes Agent With the gateway and its voice extra, which carries the speech-detection model. Python 3.11 or later
Plivo An account and a voice-enabled number
ffmpeg Only when PLIVO_VOICE_STREAMING_TTS is false, which is the default

cloudflared is fetched automatically when no public URL is configured.

Installation

1. Install

pip install hermes-plivo-phone-gateway

hermes-plivo-tools is installed alongside it and provides outbound calling.

2. Enable

hermes plugins enable plivo_voice-platform
hermes plugins list

The name includes the -platform suffix. Hermes strips it to derive the channel name plivo_voice, and rejects the short form.

3. Add credentials

In ~/.hermes/.env:

PLIVO_AUTH_ID=MAxxxxxxxxxxxxxxxxxx
PLIVO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PLIVO_PHONE_NUMBER=+14155550100

hermes gateway setup lists these three. Additional optional settings live in the same file and are listed under Configuration. A pip-installed plugin does not appear in the hermes config screens.

4. Start the gateway

hermes gateway run          # foreground
hermes gateway install      # or as a supervised service

The number can be reached once the log reads:

[plivo_voice] READY. Call +141****0100 to talk to the agent.

A temporary tunnel can take up to 2 minutes. Setting PLIVO_VOICE_PUBLIC_URL removes the delay. Numbers are masked in Hermes logs.

5. Verify

python -m hermes_plivo_voice.doctor

Checks credentials, the Plivo API, the registered answer URL, text-to-speech, speech detection and the caller allowlist, and reports which of them would stop a call working.

Outbound calls

hermes-plivo-tools is installed as a dependency and only needs enabling:

hermes plugins enable plivo-tools

Enabling adds make_call, send_sms and lookup_number. The plugin answers the outbound call itself, and whoever picks up talks to the agent exactly as an inbound caller would.

Call +14155550100 and ask what time the meeting starts.

A call is refused rather than placed when the plugin's answer URL is not responding, or when Plivo rejects the credentials.

Configuration

Read from ~/.hermes/.env. Speech providers are configured in ~/.hermes/config.yaml under stt and tts, documented in Hermes' voice mode guide.

Required

Variable Purpose
PLIVO_AUTH_ID Plivo auth ID
PLIVO_AUTH_TOKEN Plivo auth token. Also verifies callback signatures
PLIVO_PHONE_NUMBER The answering number, E.164

Optional

Variable Default Purpose
PLIVO_VOICE_PUBLIC_URL unset Public HTTPS base Plivo reaches the plugin on, and it must forward WebSocket upgrades as well as HTTP. Required for deployment. A temporary tunnel is opened when unset
PLIVO_VOICE_STREAMING_TTS false true speaks the reply as it is generated. Reduces time to first audio from 27 seconds to about 3, and removes the ffmpeg requirement. Needs a streaming-capable provider
PLIVO_VOICE_ALLOWED_USERS empty Comma-separated numbers allowed to call the agent, digits only. Empty admits every caller. Inbound only, and it does not grant outbound
PLIVO_VOICE_ALLOWED_DESTINATIONS empty Comma-separated numbers the agent is allowed to call, digits only. Empty refuses every outbound call. Independent of the inbound list
PLIVO_VOICE_IDLE_TIMEOUT 60 Seconds of caller silence before hangup. 0 disables
PLIVO_VOICE_MAX_CALL_SECONDS 600 Maximum call length. 0 disables
PLIVO_VOICE_MAX_CONCURRENT_CALLS 20 Simultaneous calls. 0 disables. Callers beyond the limit hear a short message
PLIVO_VOICE_AUTO_WIRE true false leaves the Plivo application and number untouched, to be configured by hand. The log prints the answer URL to use
PLIVO_VOICE_WS_PORT 8791 Local port for the HTTP and WebSocket server
PLIVO_VOICE_SYSTEM_PROMPT built-in Replaces the per-turn instruction keeping replies speakable
PLIVO_VOICE_SILERO_MODEL auto Path to a Silero ONNX model, when the bundled copy is unreachable
PLIVO_VOICE_INSECURE_NO_SIGNATURE false true accepts unverified callbacks. Development only
PLIVO_VOICE_RAW_DUMP unset Path to append raw inbound audio to. Unencrypted

Audio rates, speech-detection thresholds and interruption sensitivity are not configurable.

Tool scope

platform_toolsets in ~/.hermes/config.yaml limits the toolsets a caller can reach. The key is plivo_voice, the plugin name without the -platform suffix.

platform_toolsets:
  plivo_voice:
    - plivo_send_sms
    - plivo_make_call
    - plivo_lookup_number
    - web
    - memory

Without an entry a caller reaches every toolset except the ones Hermes ships switched off and anything under agent.disabled_toolsets. A plugin's toolsets are enabled by default, so the Plivo tools are reachable either way. Saving a toolset list for a platform through hermes tools reverses that for plugin toolsets, because from then on one absent from the saved list counts as switched off. The startup log names the toolsets a caller can reach.

Exclude any tool the agent can call but cannot complete. It calls the tool regardless, and the failure and retry are dead air on the line.

Security

  • Answer callbacks are signature-verified against every signature header Plivo sends
  • Each call mints a short-lived token carried in the audio WebSocket URL
  • Plivo applications and numbers the plugin did not create are never modified
  • PLIVO_VOICE_ALLOWED_USERS filters who may call the agent, and PLIVO_VOICE_ALLOWED_DESTINATIONS filters who the agent may call. The two lists are independent, so a number in one is not permitted by the other
  • An empty inbound list admits every caller, while an empty outbound list refuses every call. Outbound spends money and rings a stranger, where an unexpected inbound call only spends tokens
  • The caller's number is not verified, so anyone who knows an allowed number can dial in as that number
  • PLIVO_VOICE_INSECURE_NO_SIGNATURE and PLIVO_VOICE_RAW_DUMP both weaken the above

Troubleshooting

Run python -m hermes_plivo_voice.doctor first.

Symptom Cause
Plugin 'plivo_voice' is not installed or bundled The enable name needs the -platform suffix
No Plivo settings in hermes config Expected for a pip-installed plugin. Edit ~/.hermes/.env
READY never appears DNS propagation on a fresh tunnel, up to 3 minutes. A warning instead means the hostname does not resolve locally, which does not affect Plivo
Agent will not call a number The number is absent from PLIVO_VOICE_ALLOWED_DESTINATIONS, which is empty by default and is not granted by the inbound list
Agent has no make_call The tools plugin is not enabled as plivo-tools
Outbound call refused before Plivo is contacted The plugin's answer URL is not responding, or Plivo rejected the credentials
Long spoken replies Reply length is requested in the prompt, not enforced. Interrupt by speaking

Uninstalling

Plivo keeps sending calls to a number until it is detached. Undo the Plivo side before removing the plugin:

python -m hermes_plivo_voice.unwire
pip uninstall hermes-plivo-phone-gateway

Tests

python -m unittest discover -s tests
ruff check .

tests/ also holds scripts driving a synthetic call through a live gateway. See tests/README.md.

Limitations

  • One Plivo number answers through one application, leaving the voice and SMS plugins unable to share a number
  • Reply length is requested in the per-turn prompt, not enforced
  • Speech providers are global Hermes settings, and changing one affects every channel

License

MIT

Download files

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

Source Distribution

hermes_plivo_phone_gateway-0.2.1.tar.gz (136.2 kB view details)

Uploaded Source

Built Distribution

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

hermes_plivo_phone_gateway-0.2.1-py3-none-any.whl (66.6 kB view details)

Uploaded Python 3

File details

Details for the file hermes_plivo_phone_gateway-0.2.1.tar.gz.

File metadata

File hashes

Hashes for hermes_plivo_phone_gateway-0.2.1.tar.gz
Algorithm Hash digest
SHA256 1a4002dc9a35849de41ae2eedaf529f33d6d58434dafda4d834f79d4b07629d9
MD5 5cbf2a432cb04a61193e853855f9f570
BLAKE2b-256 5df6ba9d6165f469b7e4fe70c4d843e394727684a845d73eeae4766d8745495a

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermes_plivo_phone_gateway-0.2.1.tar.gz:

Publisher: publish.yml on plivo-dev/hermes-plivo-phone-gateway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hermes_plivo_phone_gateway-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for hermes_plivo_phone_gateway-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 86263354858dcd1b47a8e3d406f5cc77de349bb68657cd4fcbd7a6d14f688597
MD5 15713d77a62c31977f16762b1db8e5ca
BLAKE2b-256 2f709e8d13b416621cc6b5dd40f6f8a49f184b522439e8bfa1173839e88f82e9

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermes_plivo_phone_gateway-0.2.1-py3-none-any.whl:

Publisher: publish.yml on plivo-dev/hermes-plivo-phone-gateway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 files

0.2.0

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

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