Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7144413
Add outbound calling ablity
codingjoe Mar 29, 2026
f8d7fa7
Add proper BYE hang_up to SIP sessions with dialog cleanup
Copilot Mar 30, 2026
c946126
Fix address
codingjoe Mar 30, 2026
1d2e345
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
0370426
Add ByeTransaction to acknowledge outbound BYE (RFC 3261 §17.1.2)
Copilot Mar 30, 2026
c834a4e
Await BYE 200 OK in hang_up() with configurable timeout (RFC 3261 §15)
Copilot Mar 30, 2026
69807ed
Refactor: transactions awaitable, Dialog owns call lifecycle, dialog_…
Copilot Mar 31, 2026
f8c8cb3
Address code review: simplify getattr, improve BYE_ACK_TIMEOUT docstr…
Copilot Mar 31, 2026
74c05f3
Refactor
codingjoe Mar 31, 2026
0398663
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 31, 2026
5a78337
Drop tests
codingjoe Mar 31, 2026
5139dbf
Address review: Transaction inherits asyncio.Event, ByeTransaction bu…
Copilot Mar 31, 2026
727bdcf
Fix: ByeTransaction.method defaults to SIPMethod.BYE; remove method= …
Copilot Mar 31, 2026
8dfc8c6
Update docs
codingjoe Apr 1, 2026
282820b
Update code
codingjoe Apr 1, 2026
7e38b87
Update docs
codingjoe Apr 1, 2026
14b780e
Rename
codingjoe Apr 1, 2026
35110bf
Move import
codingjoe Apr 1, 2026
c74bd39
Refactor: Transaction→Future, symmetric send/receive, fix routing, de…
Copilot Apr 1, 2026
22fb921
Fix docs
codingjoe Apr 1, 2026
08169c0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 1, 2026
10f011b
Cleanup
codingjoe Apr 2, 2026
8279155
more cleanup
codingjoe Apr 2, 2026
a01aa29
Fix tests: add dialog=Dialog() to Session instantiations in test_rtp.py
Copilot Apr 2, 2026
aeb89ce
Refactor URIs
codingjoe Apr 2, 2026
67f284f
Rename
codingjoe Apr 2, 2026
7f5216c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 2, 2026
b1610c4
Support TelURI as dial target in Dialog.dial(), InviteTransaction.sen…
Copilot Apr 2, 2026
0e1df3d
Convert TelURI to SipURI in InviteTransaction.send() using AOR host
Copilot Apr 2, 2026
bf28897
fixes
codingjoe Apr 3, 2026
7010596
update docs
codingjoe Apr 3, 2026
36de403
Drop tel URi
codingjoe Apr 3, 2026
0b6ab37
Acknowledge all responses
codingjoe Apr 3, 2026
58beb31
Fix tests
codingjoe Apr 3, 2026
b499392
Fix docs
codingjoe Apr 3, 2026
3eaff47
Set pre-commit python version to 3.14
codingjoe Apr 3, 2026
35b7fd0
Address some review comments
codingjoe Apr 4, 2026
c137ce4
Use correct IPs
codingjoe Apr 4, 2026
7c96eb6
Fix address names
codingjoe Apr 4, 2026
e784760
refactor: move dialog/tx state to protocol; fix dialog tags, double A…
Copilot Apr 4, 2026
016661c
fix: improve docstring and deduplicate complete() in response_received
Copilot Apr 4, 2026
63c0705
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 6, 2026
b947eed
Rename things
codingjoe Apr 7, 2026
acb0b12
Slim down implementation
codingjoe Apr 7, 2026
92ea1bb
Fix cookbook.md examples to match current API
Copilot Apr 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
default_language_version:
python: python3.14
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
Expand Down Expand Up @@ -36,6 +38,7 @@ repos:
- mdformat-footnote
- mdformat-gfm
- mdformat-gfm-alerts
- mdformat-mkdocs>=5.2.0b1
- mdformat-ruff
exclude: ^\.github/agents/.*\.agent\.md$
- repo: https://github.com/astral-sh/ruff-pre-commit
Expand Down
16 changes: 8 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ curl -sSL https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/m

To run the tests, use the following command:

```bash
```console
uv run pytest
```

Avoid mocking in your tests and instead use real dependencies to ensure that your tests are as close to real-world scenarios as possible.
You may only mock transports to avoid network IO or to mimic network counterparts.

Before your first commit, ensure that the pre-commit hooks are installed by running:
## Testing with Extra Dependencies

```bash
uvx prek install
```console
uv run --extra=cli --extra=pygments --extra=audio pytest
```

## Testing with Extra Dependencies
Before your first commit, ensure that the pre-commit hooks are installed by running:

```bash
uv run --extra=cli --extra=pygments --extra=audio pytest
```console
uvx prek install
```

## Writing documentation
Expand All @@ -34,6 +34,6 @@ The documentation is built using [MkDocs](https://www.mkdocs.org/) with [mkdocst

To serve the documentation locally for development, run:

```bash
```console
uv run --group docs mkdocs serve --livereload
```
38 changes: 27 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Comment thread
codingjoe marked this conversation as resolved.
### 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
Expand All @@ -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
Expand All @@ -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"),
)

Expand All @@ -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
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README’s Python API example still uses the old transaction-centric API (InviteTransaction subclass + transaction_class=), but this PR’s public API is dialog-centric (Dialog subclass + dialog_class=). Updating this example is necessary to keep the README runnable and aligned with the new architecture.

Copilot uses AI. Check for mistakes.
Expand Down
1 change: 1 addition & 0 deletions docs/contributing.md
Loading
Loading