Expo / React Native
Example: examples/react-native-expo
Full binding: expo-adapters.ts.
cd examples/react-native-expocp .env.example .envbun run startPreferred input: 16 kHz · mono · PCM16. The runtime does not depend on Expo packages; you inject small adapters:
import { createExpoRuntime } from '@ottervoice/runtime-react-native';import { createVoiceSession } from '@ottervoice/core';
const runtime = createExpoRuntime({ input: { /* Expo AudioStream / recorder bindings */ }, output: { /* AudioPlaylist / playback bindings */ },});
const session = createVoiceSession({ mode: 'full_duplex', pipeline: 'audio_llm', audioLlmStartTiming: 'after_audio', // Run final caption ASR in parallel. runtime, providers: { asr, llm, audioLlm },});Dual delivery:
delivery: 'stream'— small PCM buffers → streaming ASRdelivery: 'turn'— complete WAV → batch ASR / Audio LLM
Use audioLlmStartTiming: 'after_audio' for the lowest speech-to-speech
latency. The compatible default, after_asr_final, avoids starting a paid
reply request until authoritative caption ASR confirms the turn.
Suspend encoded capture during assistant playback while keeping volume callbacks for barge-in. See runtime-react-native.