Metadata-Version: 2.4
Name: pipecat-acefone
Version: 0.1.1
Summary: Acefone WebSocket frame serializer for Pipecat for hosting agents on telephony
Project-URL: Homepage, https://github.com/monster-anshu/pipecat-acefone
Project-URL: Repository, https://github.com/monster-anshu/pipecat-acefone
Project-URL: Issues, https://github.com/monster-anshu/pipecat-acefone/issues
Author: Himanshu Gunwant
License: BSD-2-Clause
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.10
Requires-Dist: pipecat-ai[cartesia,deepgram,local-smart-turn-v3,openai,runner,silero,websocket]>=0.0.101
Requires-Dist: pydantic
Requires-Dist: python-dotenv
Requires-Dist: uvicorn[standard]
Description-Content-Type: text/markdown

# Pipecat Acefone / Smartflo Telephony Serializer

Host your [Pipecat](https://github.com/pipecat-ai/pipecat) voice agents on the
[Acefone](https://acefone.in/) and [Smartflo](https://smartflo.tatatelebusiness.com/)
(Tata Tele Business) bi-directional audio streaming stack.

`AcefoneFrameSerializer` converts between Pipecat frames and the Acefone/Smartflo
Media Streams WebSocket protocol, enabling real-time, two-way audio over a single
WebSocket connection so you can serve an agent on an Indian phone number.

**Maintainer:** Himanshu Gunwant

## Installation

```bash
pip install pipecat-acefone
```

Or via `uv`, add it to your `pyproject.toml`:

```toml
[project]
name = "your-project"
version = "0.1.0"
dependencies = [
    "pipecat-acefone",
    "another-package"
]
```

```bash
uv sync
```

## Prerequisites

- An Acefone or Smartflo (Tata Tele Business) account with a phone number.
- Bi-directional audio streaming enabled on that number, pointed at your
  WebSocket endpoint (see the protocol docs under [Protocol](#protocol)).
- Python 3.10+.

## Usage

Construct the serializer with `AcefoneFrameSerializer.InputParams` and pass it to
your Pipecat WebSocket transport:

```python
from pipecat_acefone.serializer import AcefoneFrameSerializer, AcefoneMediaFormat
from pipecat.audio.vad.silero import SileroVADAnalyzer
from pipecat.transports.websocket.fastapi import (
    FastAPIWebsocketTransport,
    FastAPIWebsocketParams,
)

serializer = AcefoneFrameSerializer(
    AcefoneFrameSerializer.InputParams(
        # Required: the Media Stream SID for the call.
        stream_sid=stream_id,
        # Required only when auto_hang_up is enabled.
        call_sid=call_id,
        # Terminate the call via a WebSocket "end" event on EndFrame/CancelFrame.
        auto_hang_up=True,
        # Wire format: ULAW (default, 8kHz G.711 μ-law) or PCM (16-bit slin16).
        media_format=AcefoneMediaFormat.ULAW,
        acefone_sample_rate=8000,
    )
)

transport = FastAPIWebsocketTransport(
    websocket=websocket_client,
    params=FastAPIWebsocketParams(
        audio_out_enabled=True,
        add_wav_header=True,
        vad_audio_passthrough=True,
        serializer=serializer,
        audio_out_sample_rate=8000,
    ),
)
```

See [`bot.py`](bot.py) for a complete working example including STT/LLM/TTS
services, event handlers, and transport setup.

## Configuration

All configuration is passed through `AcefoneFrameSerializer.InputParams`:

| Parameter             | Type                | Default              | Description                                                                                     |
| --------------------- | ------------------- | -------------------- | ----------------------------------------------------------------------------------------------- |
| `media_format`        | `AcefoneMediaFormat`| `ULAW`               | Wire audio format. `ULAW` = 8kHz G.711 μ-law; `PCM` = 16-bit linear PCM (`slin16`).             |
| `acefone_sample_rate` | `int`               | `8000`               | Sample rate used by Acefone/Smartflo, in Hz.                                                    |
| `sample_rate`         | `int`               | `0`                  | Pipeline input rate override. `0` takes the rate from the `StartFrame` during setup.            |
| `stream_sid`          | `str`               | **required**         | Media Stream SID for the call.                                                                  |
| `call_sid`            | `str \| None`       | `None`               | Associated Call SID. Required when `auto_hang_up` is enabled.                                    |
| `auto_hang_up`        | `bool`              | `False`              | Emit a WebSocket `end` event to terminate the call on the first `EndFrame`/`CancelFrame`.       |

Regardless of the wire `media_format`, inbound audio is normalized to PCM
`InputAudioRawFrame` for the pipeline, and outbound audio is converted back to the
configured wire format.

## Features

- **Audio streaming** — `media` events in both directions, with automatic μ-law
  ⇄ PCM conversion and resampling between the pipeline and `acefone_sample_rate`.
- **Configurable wire format** — 8kHz μ-law (default) or 16-bit linear PCM.
- **DTMF input** — inbound `dtmf` events become `InputDTMFFrame` keypad entries.
- **Interruptions** — `InterruptionFrame` emits a `clear` event to flush queued
  audio on the provider side.
- **Auto hang-up** — when enabled, terminates the call over the same WebSocket via
  an `end` event instead of a separate REST call.

## Running the Example

1. Start ngrok to tunnel the local server:

   ```sh
   ngrok http 7860
   ```

2. Point your Acefone/Smartflo number's bi-directional audio streaming at your
   ngrok WebSocket endpoint (e.g. `wss://foo.bar.ngrok-free.dev/ws`). See the
   [Protocol](#protocol) docs for the dashboard/API configuration.

3. Install dependencies:

   ```bash
   uv sync
   ```

4. Set up your environment:

   ```bash
   cp .env.example .env
   ```

5. Run the bot:

   ```bash
   uv run bot.py --transport acefone --proxy your_ngrok_url
   ```

The bot creates a WebSocket that accepts connections from your Acefone/Smartflo
number. Once it's running, call the number to interact with the agent.

## Protocol

Reference docs for the wire protocol and events:

- Acefone: https://docs.acefone.in/docs/bi-directional-audio-streaming-integration-document
- Smartflo: https://docs.smartflo.tatatelebusiness.com/docs/bi-directional-audio-streaming-integration-document

## Compatibility

- **Tested with Pipecat v0.0.101**
- Python 3.10+

## License

BSD-2-Clause — see [LICENSE](LICENSE).

## Support

- Protocol docs: see [Protocol](#protocol) above for message formats.
- Pipecat Discord: https://discord.gg/pipecat (`#community-integrations`)
- Issues: https://github.com/monster-anshu/pipecat-acefone/issues
