TEN Framework

View as Markdown

This guide walks you through using Smallest AI as the STT and TTS provider in TEN Framework, an open-source framework for building real-time, multimodal conversational voice agents. TEN agents are declarative graphs — a voice agent is a pipeline of nodes (RTC transport → STT → LLM → TTS) defined in a property.json file, so switching to Smallest AI is a configuration change, not a code change.

Extensions

Two extensions are available, one per capability:

ExtensionCapabilityEndpoint
smallest_asr_pythonSpeech-to-textPulse real-time WebSocket (wss://api.smallest.ai/waves/v1/stt/live), 64ms TTFT, 38 languages
smallest_tts_pythonText-to-speechLightning streaming (https://api.smallest.ai/waves/v1/tts/live), ~100ms to first audio chunk

Prerequisites


Setup

1

Clone TEN Framework

$git clone https://github.com/TEN-framework/ten-framework.git
$cd ten-framework/ai_agents
2

Configure environment variables

Copy .env.example to .env and set:

$AGORA_APP_ID=...
$OPENAI_API_KEY=...
$SMALLEST_API_KEY=...
3

Point the agent graph at Smallest AI

Open agents/examples/voice-assistant/tenapp/property.json and change the addon field of the stt and tts nodes:

1{
2 "type": "extension",
3 "name": "stt",
4 "addon": "smallest_asr_python",
5 "property": {
6 "params": {
7 "language": "en",
8 "sample_rate": 16000
9 }
10 }
11},
12{
13 "type": "extension",
14 "name": "tts",
15 "addon": "smallest_tts_python",
16 "property": {
17 "params": {
18 "model": "lightning_v3.1",
19 "voice_id": "magnus",
20 "sample_rate": 24000
21 }
22 }
23}

The API key does not need to appear in the graph — both extensions read the SMALLEST_API_KEY environment variable by default.

4

Build and run

$docker compose up -d
$docker exec ten_agent_dev bash -c "cd /app/agents/examples/voice-assistant && task install"
$docker exec -d ten_agent_dev bash -c "cd /app/agents/examples/voice-assistant && task run"
5

Talk to your agent

Open the playground at http://localhost:3000, join a channel, and speak. Audio flows: microphone → Agora RTC → Smallest AI Pulse → LLM → Smallest AI Lightning → speakers.

You can also swap providers visually in TMAN Designer (started by the same task run) instead of editing JSON.


Configuration Reference

smallest_asr_python (STT)

ParamDefaultDescription
api_key$SMALLEST_API_KEYSmallest AI API key
modelpulseStreaming model. Only pulse supports the live endpoint
languageenISO language code (e.g. en, hi, es)
sample_rate16000Input PCM sample rate in Hz
urlwss://api.smallest.ai/waves/v1/stt/liveWebSocket endpoint override

Any additional key in params (e.g. word_timestamps, eou_timeout, punctuate) is forwarded verbatim as a query parameter to the live endpoint — see the Pulse feature docs for the full list.

smallest_tts_python (TTS)

ParamDefaultDescription
api_key$SMALLEST_API_KEYSmallest AI API key
modellightning_v3.1lightning_v3.1 (multilingual, cloning) or lightning_v3.1_pro (premium voices, English + Hindi)
voice_idmagnusCatalog voice or cloned voice (voice_*). Pair Pro voices (e.g. meher) with the Pro model
sample_rate24000Output PCM sample rate in Hz (8000–44100)
speed1.0Speech speed multiplier (0.5–2.0)
base_urlhttps://api.smallest.aiAPI base URL override

Any additional key in params (e.g. language, pronunciation_dicts) is forwarded verbatim in the request body — see the TTS API reference.


Notes

  • Graph-level property.params override the extension defaults, so different graphs in the same app can use different voices or languages.
  • Interruptions (barge-in) are handled by the framework: when the user speaks over the agent, TEN flushes the TTS extension and Lightning synthesis is cancelled mid-stream — no custom logic needed.
  • Interim transcripts stream with final=false for live captions; final results carry word-level timing.
  • For issues with the extensions, open an issue in the TEN Framework repository or contact us on Discord.