Supafone Labs · Documentation

E2E Testing#

Use focused tests for each surface: SDK, Labs Cloud, hosted-agent API, builder, and live provider paths.

Hosted-Agent Smoke Test#

bash
cd supafone-labs
SUPAFONE_TOKEN=sl_live_... \
SUPAFONE_API_BASE_URL=https://api.supafone.ai \
npx tsx examples/smoke-hosted-agent.ts

The script verifies:

Hosted Call-Plan Contract#

Test the same feature through REST, Python, TypeScript, and MCP. Each surface must return the same versioned plan fields and agent creation must install the stages into the executable runtime.

TestExpected result
REST POST /api/v1/labs/agent-plansValid 3–8 stage supafone_call_plan_v1 response
Python generate_call_stages()Same hosted contract using one SUPAFONE_TOKEN
TypeScript generateCallStages()Same hosted contract using one SUPAFONE_TOKEN
MCP generate_call_stagesCalls hosted planner; no local fake plan
Create with description onlyBackend generates and installs executable stages
Create with edited stagesExact approved stages are validated and installed
Planner timeout/invalid JSONSafe deterministic plan, fallback: true, warning returned
Secret-boundary testBYOK, carrier, provider, billing, and API secrets never enter planner input
Custom stage namesRuntime transitions through configured names, not hard-coded templates

The automated contract suite is credential-free: model calls are stubbed, HTTP is mocked, and no phone number is purchased or dialed.

Python SDK Tests#

bash
cd supafone-labs
python3.12 -m pytest tests -q -m "not live"
python3.12 -m ruff check src

Live provider tests should be opt-in and require provider keys and network access.

Fourteen-Runtime Injection Gate#

The release gate does not infer success from configuration. It sends a current provider event through the public facade, requires a belief and directive, and then validates the exact compiled control payload for all fourteen runtimes:

bash
cd supafone-labs
make test-provider-contracts PY=python3.12

The audited set is Supafone, Ultravox, Vapi, Retell, Bland, OpenAI Realtime, Grok, Gemini Developer Live, ElevenLabs, Deepgram Voice Agent, LiveKit Agents, Pipecat, Cartesia Line, and Inworld Realtime. Bland, Gemini Developer Live, and Cartesia deliberately assert a safe no-action result because their default adapters do not expose a documented universal hidden prompt-injection channel. That is not counted as an injection pass.

tests/test_cloud_phone_tester.py separately runs the fourteen runtime labels against all ten console telephony targets. Those 140 combinations must route through the same managed PSTN grader, proving that target-carrier metadata does not alter the test transport or the runtime injection contract.

Credentialed acceptance probes are separate:

bash
python3.12 -m pytest --collect-only -q tests/test_live_injection_contracts.py
make test-live-injection PY=python3.12

The second command needs the relevant provider credentials and an active call where required. Missing credentials produce a skip, never a pass. The live probes send production-adapter payloads and wait for the provider's documented acknowledgement or completed next turn.

Live probeRequired environment
UltravoxULTRAVOX_API_KEY, ULTRAVOX_LIVE_CALL_ID
VapiVAPI_CONTROL_URL from an active monitor-enabled call
OpenAI RealtimeOPENAI_API_KEY; optional OPENAI_REALTIME_MODEL
Grok Voice AgentXAI_API_KEY; optional XAI_VOICE_MODEL
ElevenLabs AgentsELEVENLABS_API_KEY, ELEVENLABS_AGENT_ID
Deepgram Voice AgentDEEPGRAM_API_KEY; optional DEEPGRAM_LIVE_SETTINGS_JSON
Inworld RealtimeINWORLD_API_KEY; optional socket URL/auth overrides

Run one provider with make test-live-injection PY=python3.12 plus a pytest filter, for example PYTEST_ADDOPTS="-k vapi".

TypeScript SDK Build#

bash
cd supafone-labs/sdk-ts
npm run build
npm --cache /tmp/supafone-npm-cache pack --dry-run

Labs Cloud API Smoke#

bash
curl https://api.labs.supafone.ai/healthz

curl https://api.labs.supafone.ai/v1/pricing

curl https://api.labs.supafone.ai/v1/billing/balance \
  -H "Authorization: Bearer $SUPAFONE_LABS_API_KEY"

Builder and QA E2E#

ts
await supafone.login(process.env.SM_EMAIL!, process.env.SM_PASSWORD!);

await supafone.builder.saveConfig({
  agent_prompt: "You are a careful intake agent. Never quote fees.",
  agent_label: "intake",
  framework: "ultravox",
  llm: { provider: "hosted" }
});

const turn = await supafone.builder.chat("e2e-1", [
  { role: "agent", text: "How can I help?" },
  { role: "caller", text: "What do you charge?" }
]);

const qa = await supafone.qa.run({ turns: 2 });

Logs Stream E2E#

The API exposes both snapshot logs and SSE streaming. Run the focused tests:

bash
cd supafone-labs
python3.12 -m pytest tests/test_cloud_logs_stream.py tests/test_hosted_agents_client.py -q

Manual stream check:

bash
curl -N "https://api.labs.supafone.ai/v1/logs/stream?limit=20&poll_ms=1000&snapshot=true" \
  -H "Authorization: Bearer $SUPAFONE_LABS_API_KEY"

The stream should emit event: log rows with the same shape as /v1/logs.

Voice Catalog and Preview E2E#

bash
curl https://api.labs.supafone.ai/v1/voices

curl https://api.labs.supafone.ai/v1/tts \
  -X POST \
  -H "Authorization: Bearer $SUPAFONE_LABS_API_KEY" \
  -H "Content-Type: application/json" \
  --output /tmp/supafone-preview.wav \
  -d '{"voice":"cartesia:sonic-warm","text":"Hi, this is a Supafone voice preview."}'

The hosted-agent voice catalog should also work with the hosted-agent key:

bash
curl "https://api.supafone.ai/api/v1/labs/voices?provider=cartesia" \
  -H "Authorization: Bearer $SUPAFONE_API_KEY"

Agent Factory E2E Matrix#

TestExpected result
createInboundWithNumber() default poolAgent plus assigned shared/pool number
createOutboundWithNumber() default poolOutbound/campaign agent plus assigned caller ID
labs.enabled: falseAgent created without watcher sidecar
labs.enabled: true, managedWatcher config uses Supafone-managed infrastructure
BYOK agent/provider stackRuntime keys/settings serialize separately from TTS and telephony
BYOK telephonyTwilio/Telnyx/Plivo/SignalWire/SIP credentials serialize under telephony
BYOK TTSCartesia/ElevenLabs/Inworld/Deepgram/custom TTS config serializes under TTS
Voice preview/v1/tts returns playable audio
Log stream/v1/logs/stream emits event: log rows
MCP tail_logsBounded polling returns new rows without leaking secrets

Number Purchase Test Safety#

Tests should default to numberStrategy: "default_pool" or mocked number inventory. Dedicated and premium purchase tests must be isolated, explicitly enabled, and clearly labeled as billable.

Use environment flags such as:

bash
export SUPAFONE_ALLOW_NUMBER_PURCHASES=0
export SUPAFONE_ALLOW_PREMIUM_NUMBERS=0

Only set them to 1 for intentional live billing tests.

View raw Markdown