Module scenario.voice.adapters.vapi
VapiAgentAdapter: call Vapi's REST API to create a call, then connect to the returned websocketCallUrl.
Source §5.5.
Expand source code
"""
VapiAgentAdapter: call Vapi's REST API to create a call, then connect to the
returned websocketCallUrl.
Source §5.5.
"""
from __future__ import annotations
from typing import ClassVar, Optional
from ..adapter import VoiceAgentAdapter
from ..audio_chunk import AudioChunk
from ..capabilities import AdapterCapabilities
from ._stub import PendingTransportError
class VapiAgentAdapter(VoiceAgentAdapter):
capabilities: ClassVar[AdapterCapabilities] = AdapterCapabilities(
streaming_transcripts=True,
native_vad=True,
dtmf=False,
input_formats=["pcm16/16000"],
output_formats=["pcm16/16000"],
)
def __init__(self, assistant_id: str, api_key: str):
super().__init__()
self.assistant_id = assistant_id
self.api_key = api_key
self.websocket_call_url: Optional[str] = None
self._ws: Optional[object] = None
async def connect(self) -> None:
# Integration: POST to Vapi REST API to get websocketCallUrl, then
# open websocket.
self.websocket_call_url = f"wss://vapi.ai/ws/{self.assistant_id}"
self._ws = object()
async def disconnect(self) -> None:
self._ws = None
async def send_audio(self, chunk: AudioChunk) -> None:
if self._ws is None:
raise RuntimeError("VapiAgentAdapter: not connected")
raise PendingTransportError("VapiAgentAdapter")
async def recv_audio(self, timeout: float) -> AudioChunk:
if self._ws is None:
raise RuntimeError("VapiAgentAdapter: not connected")
raise PendingTransportError("VapiAgentAdapter")
def __repr__(self) -> str: # redact credentials
return f"VapiAgentAdapter(assistant_id={self.assistant_id!r}, api_key='***')"
Classes
class VapiAgentAdapter (assistant_id: str, api_key: str)-
Abstract base for voice agents that exchange audio with the agent under test.
Subclasses implement
connect,disconnect,send_audio, andrecv_audio. The defaultcallimplementation threads audio extracted from the last incoming message through the transport and wraps the response back into an assistant message.Attributes
capabilities- Declaration of what the adapter can and cannot do. Each concrete subclass must set this as a class attribute.
response_timeout-
Seconds to wait for agent audio after sending user audio. Defaults to 60 seconds.
60 seconds covers a typical real-world STT → LLM → TTS round-trip including backoff/retry inside each provider, tool calls, and RAG lookups. If you see TimeoutError flakes against a fast LLM-only chain, you can lower this; if your agent does heavy processing (MCP roundtrips, multi-step tool chains), consider raising it.
Override per-adapter at construction time::
adapter = MyVoiceAdapter() adapter.response_timeout = 90.0 # slow tool-call chain
Expand source code
class VapiAgentAdapter(VoiceAgentAdapter): capabilities: ClassVar[AdapterCapabilities] = AdapterCapabilities( streaming_transcripts=True, native_vad=True, dtmf=False, input_formats=["pcm16/16000"], output_formats=["pcm16/16000"], ) def __init__(self, assistant_id: str, api_key: str): super().__init__() self.assistant_id = assistant_id self.api_key = api_key self.websocket_call_url: Optional[str] = None self._ws: Optional[object] = None async def connect(self) -> None: # Integration: POST to Vapi REST API to get websocketCallUrl, then # open websocket. self.websocket_call_url = f"wss://vapi.ai/ws/{self.assistant_id}" self._ws = object() async def disconnect(self) -> None: self._ws = None async def send_audio(self, chunk: AudioChunk) -> None: if self._ws is None: raise RuntimeError("VapiAgentAdapter: not connected") raise PendingTransportError("VapiAgentAdapter") async def recv_audio(self, timeout: float) -> AudioChunk: if self._ws is None: raise RuntimeError("VapiAgentAdapter: not connected") raise PendingTransportError("VapiAgentAdapter") def __repr__(self) -> str: # redact credentials return f"VapiAgentAdapter(assistant_id={self.assistant_id!r}, api_key='***')"Ancestors
- VoiceAgentAdapter
- AgentAdapter
- abc.ABC
Class variables
var capabilities : ClassVar[AdapterCapabilities]
Inherited members