S2S Runtime Library#
The supafone-labs package is Supafone's speech-to-speech (S2S) runtime library. It gives an agent one canonical event and decision contract while the speaking runtime changes underneath it. Use it to observe a live call, compile one supervisor decision, and send the provider-native control when that runtime supports a silent control channel.
This is an adapter library, not a replacement audio socket. Your provider still owns the realtime media session. Supafone normalizes the events around that session and keeps the supervision, state, QA, and provider-specific control logic in one place.
Install the library#
Python: local runtime adapters#
pip install supafone-labsThe Python package includes the canonical runtime, provider adapters, supervisor facade, replay tests, and offline BYOK mode.
TypeScript: cloud and hosted-agent client#
npm install supafone-labsThe TypeScript client exposes the same Supafone account contracts for hosted agents, the cloud oracle, realtime transcription, QA, and operational APIs. Use whisper() when your application owns the provider socket and needs a concise silent directive to pass to that socket.
One contract, multiple S2S runtimes#
The Python runtime selects an adapter by provider id. Changing the provider changes the adapter and compiled control; the event, directive, and state contracts stay the same.
from supafone_labs import Feed, SupafoneLabs
runtime = SupafoneLabs(
provider="gpt_realtime",
mode="return",
feed=Feed(guardrails=["Never quote fees. Acknowledge injury first."]),
)
result = await runtime.observe(provider_event)
for action in result.actions:
await send_to_your_live_socket(action.payload)Switch the adapter without rewriting the agent loop:
runtime = SupafoneLabs(provider="grok", mode="return", feed=feed)
# Other supported ids include: ultravox, inworld, elevenlabs, deepgram,
# vapi, retell, livekit, pipecat, gemini_live, bland, and cartesia.Use mode="apply" with an agent that exposes a supported injector method, or use mode="return" when your application owns delivery and will send the compiled action itself. See Provider Injection Examples for provider-specific socket payloads.
TypeScript cloud path#
When the TypeScript application owns the realtime session, ask the cloud oracle for the directive and pass the result to the provider's native control:
import { Supafone } from "supafone-labs";
const supafone = new Supafone({
apiKey: process.env.SUPAFONE_LABS_API_KEY!,
});
const directive = await supafone.whisper(
"Agent: How can I help?\nCaller: I was rear-ended — what do you charge?",
{ guardrails: "Never quote fees. Acknowledge injury first." },
);
if (directive) {
// Map this one directive to your provider's native silent-control event.
await sendToYourProvider({ text: directive });
}An empty directive means the runtime found no safe correction to send. The provider-specific mapping is documented in the framework matrix.
Support classes#
The library reports support honestly because S2S providers do not expose the same control surface:
| Runtime group | Examples | What Supafone does |
|---|---|---|
| Managed/native control | Supafone Agent Factory, Ultravox | Owns the managed delivery path and sends a deferred silent data message |
| Native S2S control | OpenAI Realtime, Grok Voice, ElevenLabs Agents, Inworld Realtime | Compiles the directive into the provider's documented live event |
| Developer-owned context | Retell custom LLM, LiveKit Agents, Pipecat | Adds the directive to the context your application owns |
| Observation only | Gemini Developer Live, Bland | Normalizes events and scores the call without inventing an unsupported hidden action |
| Explicit host hook | Cartesia Line | Emits a custom event for the host agent to handle |
Vapi and Deepgram Voice Agent support native controls and developer-owned LLM paths. The complete acceptance criteria and exact event names are in Framework Coverage.
What stays stable when the runtime changes#
- Canonical call events and runtime state
- Supervisor beliefs, directives, guardrails, and no-op safety behavior
- Provider capability checks and action compilation
- Transcript, recording, QA, and post-call evidence contracts
- Python, TypeScript, REST, WebSocket, and MCP access to the same hosted APIs
The S2S library does not claim that every provider has the same live injection capability. Unsupported or uncertain controls degrade to no action so the speaking agent can continue safely.
Next steps#
- Install the Python or TypeScript SDK.
- Run the provider injection examples.
- Review the framework support matrix.
- Try the hosted agent builder when you want
Supafone to own the call and phone delivery path.