Ultravox Speech to Speech
Using jambonz to connect custom telephony to the Ultravox open-weight Speech Language Model
The jambonz application referenced in this article can be found here.
This is an example Jambonz application that connects to the Ultravox Realtime API and illustrates how to build a Voice-AI application using Jambonz and Ultravox.
When building agents with Ultravox, you can extend your agents’ capabilities by connecting them to external services and systems via tools—functions that agents can invoke to perform specific actions or retrieve information.
These tools can be implemented as either client or server tools; we’re covering both in this sample application.
Read more about client vs server tools in the Ultravox docs.
This example application covers four scenarios:
- weather agent using Ultravox clientTools
- weather agent using Ultravox serverTools
- call transfer agent using Ultravox clientTools
- call transfer agent using Ultravox serverTools.
The weather agent utilizes a weather REST API to enable Ultravox to answer callers’ questions about the weather for specified locations. The call transfer agent uses Jambonz to redirect the inbound call to a destination number of your choice.
Prerequisites
- a jambonz.cloud account
- an Ultravox account
- a carrier and virtual phone number of your choice
Running instructions
Set Environment Variables
Duplicate the examples.env file as .env and fill in your credentials as shown below.
Jambonz Setup
-
Create a carrier entity in the Jambonz portal.
-
Add your speech provider of choice in the Jambonz portal.
-
Create a new Jambonz application in your portal under the Applications tab. Give it a name, then set both
Calling webhook
andCall status webhook
values to the same URL, based on which scenario you’d like to run:- weather agent using Ultravox clientTools:
ws://your-example-domain.ngrok.io/weather-agent-client-tool
- weather agent using Ultravox serverTools:
ws://your-example-domain.ngrok.io/weather-agent-server-tool
- call transfer agent using Ultravox clientTools:
ws://your-example-domain.ngrok.io/call-transfer-agent
- call transfer agent using Ultravox serverTools:
ws://your-example-domain.ngrok.io/call-transfer-agent-server-tool
- weather agent using Ultravox clientTools:
-
Having created a carrier, you also need to provision the phone number that you will be receiving calls on from that carrier. At the bottom of the page select the Jambonz application you just created to link your new virtual number to that application.
Run Your App
Ensure all environment variables are properly configured before starting the application.
Navigate to the root of this project in your terminal, then run npm install
and npm start
.
Call your virtual number and test it out!
To switch between scenarios, update the Calling webhook
and Call status webhook
values to another URL, as explained in step 3 of the Jambonz Setup section.
A note on ActionHook
Jambonz integrates with Ultravox via the llm verb.
Like many Jambonz verbs, the llm
verb sends an actionHook
with a final status when the verb completes. The payload includes a completion_reason
property indicating why the llm
session ended. Possible values for completion_reason
are:
- Normal conversation end
- Connection failure
- Disconnect from remote end
- Server failure
- Server error
Resources
- Ultravox Documentation
- tools in Ultravox
- Jambonz Documentation:
- the ‘llm’ verb
- the ‘dial’ verb
- the ‘sip_refer’ verb
- step-by-step guides for adding carriers to Jambonz