Voice agents Pipecat

Pipecat

Pipecat is an open-source Python framework for real-time voice and multimodal conversational agents. The pipecat-plugins-munsit package bridges Munsit TTS into Pipecat pipelines, so you can build Arabic voice agents with low-latency streaming audio.

1

Install the plugin

You need Python 3.9+ and a Munsit account. Generate a key at Munsit — API Keys before you start.

shell
pip install pipecat-plugins-munsit
Your API key is only shown once. Save it securely — set it as the MUNSIT_API_KEY environment variable rather than hardcoding it.
2

Quick start

The service takes your API key and a shared aiohttp session. That's the whole handshake — drop the resulting tts processor into any Pipecat pipeline.

python
import aiohttp from pipecat_plugins_faseeh import FaseehTTSService async with aiohttp.ClientSession() as session: tts = FaseehTTSService( api_key="your-api-key", aiohttp_session=session, )
3

Where it sits in the pipeline

In a typical Pipecat pipeline, data flows through processors in sequence:

data flow
Microphone → Transport → Munsit STT → LLM → Munsit TTS → Transport → Speaker

The user speaks; the transport (e.g. Daily WebRTC) captures audio; Munsit STT converts speech to text; the LLM (e.g. OpenAI GPT-4o) generates a response; Munsit TTS converts it to Arabic audio — streaming PCM16 at 24 kHz — and the transport plays it back. Pipecat's TTSService base class aggregates LLM tokens into complete sentences before calling Munsit: each sentence triggers one HTTP streaming request, and PCM16 chunks are yielded back to the pipeline as they arrive.

4

Full example

A complete Daily-transported agent: auto-creates a Daily room, wires Munsit STT → GPT-4o → Munsit TTS, and speaks first when a participant joins.

agent.py
import asyncio import os import aiohttp from dotenv import load_dotenv from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import EndFrame, LLMMessagesUpdateFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.task import PipelineParams, PipelineTask from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, LLMUserAggregatorParams, ) from pipecat_plugins_munsit import MunsitSTTService from pipecat.services.openai.llm import OpenAILLMService from pipecat.transports.daily.transport import DailyParams, DailyTransport from pipecat_plugins_faseeh import FaseehTTSService load_dotenv(override=True) async def main(): async with aiohttp.ClientSession() as session: # Auto-create a Daily room from pipecat.transports.daily.utils import DailyRESTHelper, DailyRoomParams daily_helper = DailyRESTHelper( daily_api_key=os.getenv("DAILY_API_KEY", ""), aiohttp_session=session, ) room = await daily_helper.create_room(DailyRoomParams()) token = await daily_helper.get_token(room.url) transport = DailyTransport( room.url, token, "Munsit Bot", DailyParams( audio_in_enabled=True, audio_out_enabled=True, audio_out_sample_rate=48000, ), ) stt = MunsitSTTService(api_key=os.getenv("MUNSIT_API_KEY", "")) llm = OpenAILLMService(api_key=os.getenv("OPENAI_API_KEY", ""), model="gpt-4o") tts = FaseehTTSService( api_key=os.getenv("MUNSIT_API_KEY"), aiohttp_session=session, ) messages = [ { "role": "system", "content": "You are a helpful Arabic-speaking assistant. Respond in Arabic.", } ] context = LLMContext(messages=messages) context_aggregator = LLMContextAggregatorPair( context, user_params=LLMUserAggregatorParams(vad_analyzer=SileroVADAnalyzer()), ) pipeline = Pipeline([ transport.input(), stt, context_aggregator.user(), llm, tts, transport.output(), context_aggregator.assistant(), ]) task = PipelineTask(pipeline, params=PipelineParams(allow_interruptions=True)) @transport.event_handler("on_first_participant_joined") async def on_joined(transport, participant): await task.queue_frames([LLMMessagesUpdateFrame(messages, run_llm=True)]) @transport.event_handler("on_participant_left") async def on_left(transport, participant, reason): await task.queue_frame(EndFrame()) runner = PipelineRunner() await runner.run(task) if __name__ == "__main__": asyncio.run(main())
5

Configuration

Constructor parameters on FaseehTTSService. To pick a voice, browse the Voice Library, listen, and click "Copy Voice ID" next to the one you want.

ParameterTypeDefaultDescription
api_keystrenv MUNSIT_API_KEYMunsit API key
voice_idstrar-hijazi-female-2Voice identifier
modelstrfaseeh-v1-previewTTS model
stabilityfloat0.5Voice consistency (0.0–1.0)
speedfloat1.0Speech rate (0.7–1.2)
sample_rateint48000Output PCM rate requested from the API. 48000 is the engine's native rate — no downsampling, no client-side resampling. Match your transport's audio_out_sample_rate to it.
base_urlstrhttps://api.munsit.com/api/v1API base URL

You can also change voice, model, speed, or stability mid-conversation by queueing a TTSUpdateSettingsFrame:

pick a voice
tts = FaseehTTSService( api_key="your-api-key", voice_id="ar-uae-male-1", # Paste the copied voice ID here aiohttp_session=session, )
6

Error handling & troubleshooting

The plugin yields non-fatal ErrorFrame objects instead of raising exceptions — your pipeline keeps running even if a single TTS request fails.

HTTP statusMeaningAction
401Invalid API keyCheck MUNSIT_API_KEY
402Insufficient balanceAdd credits at app.munsit.com
404Voice or model not foundCheck voice_id and model
429Rate limit exceededReduce request frequency
python
from pipecat.frames.frames import ErrorFrame @task.event_handler("on_error") async def on_error(task, error: ErrorFrame): logger.error(f"TTS error: {error.error}")

No audio output? Verify MUNSIT_API_KEY is set and valid, that voice_id exists in the voice library, and that the pipeline sample rate matches the plugin's (48000 Hz default). High latency? The plugin already uses HTTP streaming for lowest latency — check connectivity to api.munsit.com, or try a voice with faster generation characteristics. Import errors? Make sure both pipecat-ai and pipecat-plugins-munsit are installed; minimum Pipecat version is 0.0.100.

7

Where next

Explore the voices, or compare frameworks.

Working with an AI assistant? Every page is available as Markdown: add .md to the URL, or send an Accept: text/markdown header. For the whole documentation in one request, point it at llms-full.txt; the page index is llms.txt. Or use Copy Page, top right.