Voicebeta

Add the microphone to KletsoChat, drive voice sessions from your own UI, and bring your own audio stack if you need to.

kletso_flutter draws the mic button, the voice sheet and the avatar but ships no platform code. Add kletso_voice for the microphone and speaker:

flutter pub add kletso_voice
final client = await Kletso.init(KletsoConfig(publishableKey: 'kl_pub_…', agentId: 'agt_…'));
KletsoVoice.install(client);

That is all. When the agent has voice enabled, KletsoChat shows a microphone next to the send button. Tapping it asks for microphone permission, opens the voice sheet (big avatar, state label, live captions, rendered surfaces, mute, keyboard and End) and starts the session. The chat transcript fills in as the conversation goes.

Platforms

PlatformCapturePlayback
Androidrecord_android (RECORD_AUDIO permission in your manifest)audio_stream_player
iOSrecord_ios (NSMicrophoneUsageDescription in Info.plist)audio_stream_player
Web (JS and Wasm)Web Audio through package:web (no dart:html)audio_stream_player
macOS, Windows, Linuxrecord_* implementationsaudio_stream_player

Browsers need a user gesture before audio plays; the mic tap counts. Voice needs the WebSocket transport (the default); on the SSE fallback the mic button is hidden.

Driving it yourself

Everything the sheet does is available on client.voice, a KletsoVoiceController:

final voice = client.voice;
voice.status;          // KletsoValueListenable<KletsoVoiceStatus>: idle, connecting, listening, thinking, speaking
voice.userTranscript;  // what the user is saying (partial, then final)
voice.caption;         // what the assistant is saying
voice.outputLevel;     // 0..1 loudness of the assistant, for your own lip-sync or meter
voice.available;       // agent has voice, socket can carry audio, audio IO installed

await voice.start();   // throws KletsoServerException(code: 'not_configured') when the customer has no key
voice.setMuted(true);
voice.sendText('Make that two tickets');  // typed text, answered aloud
voice.commit();        // push-to-talk release
await voice.stop();

Put a KletsoAvatar anywhere in your app; bound to the client it reacts to the same events as the chat (see the avatar section of the chat UI page).

Your own audio stack

Implement KletsoAudioIo from kletso_core (capture stream, enqueue, flush, playedMs, levels) and hand it to client.voice.setAudioIo(yourIo). If your app already plays and records audio, call client.voice.setHostHandlesAudio(true), feed client.voice.sendAudio(pcm) and play client.voice.audioOut. PCM is 16-bit little-endian mono at 24 kHz on both sides.

Testing

KletsoFakeBackend has a voice scenario: about one second of any audio counts as the utterance scenario.voiceTranscript, which the fake answers aloud (a synthesised tone with a transcript), so widget tests and the example app exercise the whole flow without a key or a microphone.

Last updated 2026-09-28 · Report an issue with this page