-
-
Notifications
You must be signed in to change notification settings - Fork 0
Add outbound calling ability with proper SIP BYE hang-up (dialog-centric refactor) #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7144413
f8d7fa7
c946126
1d2e345
0370426
c834a4e
69807ed
f8c8cb3
74c05f3
0398663
5a78337
5139dbf
727bdcf
8dfc8c6
282820b
7e38b87
14b780e
35110bf
c74bd39
22fb921
08169c0
10f011b
8279155
a01aa29
aeb89ce
67f284f
7f5216c
b1610c4
0e1df3d
bf28897
7010596
36de403
0b6ab37
58beb31
b499392
3eaff47
35b7fd0
c137ce4
7c96eb6
e784760
016661c
63c0705
b947eed
acb0b12
92ea1bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,25 +20,41 @@ Async VoIP Python library for the AI age. | |
|
|
||
| ## Usage | ||
|
|
||
| To get started, you will need a SIP account. One is usually included with ISP. | ||
| Check your ISP's documentation or router for details. | ||
|
|
||
| You will need a SIP AOR (URI), which looks like this: | ||
|
|
||
| ```INI | ||
| sip:USER:PASSWORD@SIP_SERVER;transport=TCP | ||
| ``` | ||
|
|
||
| > [!NOTE] | ||
| > This library uses secure defaults (TLS transport on port 5061). | ||
| > However, most SIP servers only support unencrypted connections. | ||
| > Therefore, you will need to provide an explict transport parameter. | ||
|
|
||
| ### CLI | ||
|
|
||
| Answer calls and transcribe them live from the terminal: | ||
| A simple echo call can be started with: | ||
|
|
||
| ```console | ||
| uvx 'voip[cli]' sip sips:alice:********@sip.example.com transcribe | ||
| uvx 'voip[cli]' sip sips:alice:********@sip.example.com echo | ||
| ``` | ||
|
|
||
| A simple echo server can be started with: | ||
| Each command supports an optional `--dial` argument to initiate an | ||
| outbound call instead of waiting for an inbound one. | ||
|
|
||
| To dial a number, say a message, and hang up automatically: | ||
|
|
||
| ````console | ||
| ```console | ||
| uvx 'voip[cli]' sip sips:alice:********@sip.example.com echo | ||
| ```` | ||
| uvx 'voip[cli]' sip sips:alice:********@sip.example.com say sip:+15551234567@sip.example.com "Your package has arrived." | ||
| ``` | ||
|
|
||
| You can also talk to a local agent (needs [Ollama]): | ||
|
|
||
| ```console | ||
| uvx 'voip[cli]' sip sips:alice:********@sip.example.com agent | ||
| uvx 'voip[cli]' sip sips:alice:********@sip.example.com agent --initial-prompt "Hi, I am looking for a Mr. Ron, first name Mo?" | ||
| ``` | ||
|
|
||
| ### Python API | ||
|
|
@@ -48,15 +64,15 @@ uv add voip[audio,ai,pygments] | |
| ``` | ||
|
|
||
| Subclass `TranscribeCall` and override `transcription_received` to handle results. | ||
| Pass it as `call_class` when answering an incoming call: | ||
| Pass it as `session_class` when answering an incoming call: | ||
|
|
||
| ```python | ||
| import asyncio | ||
| import dataclasses | ||
| import ssl | ||
| from voip.ai import TranscribeCall | ||
| from voip.sip.protocol import SIP | ||
| from voip.sip.types import SipUri | ||
| from voip.sip.types import SipURI | ||
| from voip.sip.transactions import InviteTransaction | ||
| from voip.rtp import RealtimeTransportProtocol | ||
| from faster_whisper import WhisperModel | ||
|
|
@@ -72,7 +88,7 @@ class TranscribeInviteTransaction(InviteTransaction): | |
| def invite_received(self, request) -> None: | ||
| self.ringing() | ||
| self.answer( | ||
| call_class=TranscribingCall, | ||
| session_class=TranscribingCall, | ||
| stt_model=WhisperModel("kyutai/stt-1b-en_fr-trfs", device="cuda"), | ||
| ) | ||
|
|
||
|
|
@@ -87,7 +103,7 @@ async def main(): | |
| await loop.create_connection( | ||
| lambda: SIP( | ||
| rtp=rtp_protocol, | ||
| aor=SipUri.parse("sips:alice:********@example.com"), | ||
| aor=SipURI.parse("sips:alice:********@example.com"), | ||
| transaction_class=TranscribeInviteTransaction, | ||
| ), | ||
| host="sip.example.com", | ||
|
Comment on lines
73
to
109
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../CONTRIBUTING.md |
Uh oh!
There was an error while loading. Please reload this page.