Recipes
Full offline turn with real engines
import { VoicePipeline, WhisperCppStt, OllamaLlm, PiperTts } from 'whispa';
const pipeline = new VoicePipeline({
stt: new WhisperCppStt({ model: 'models/ggml-base.en.bin' }),
llm: new OllamaLlm({ model: 'llama3.2' }),
tts: new PiperTts({ model: 'voices/en_US-amy-medium.onnx' }),
systemPrompt: 'You are a concise voice assistant.',
});
const { transcript, reply, audio } = await pipeline.turn('recording.wav');
Text-only assistant (skip STT/TTS)
import { VoicePipeline, MockStt, MockTts, OllamaLlm } from 'whispa';
const chat = new VoicePipeline({ stt: new MockStt(''), tts: new MockTts(), llm: new OllamaLlm({ model: 'llama3.2' }) });
const reply = await chat.respond('Summarize today in one line.');
Bring your own LLM engine
import type { LlmEngine, Message } from 'whispa';
class OpenAILlm implements LlmEngine {
async chat(messages: Message[]): Promise<string> {
const res = await client.chat.completions.create({ model: 'gpt-4o-mini', messages });
return res.choices[0].message.content ?? '';
}
}
const pipeline = new VoicePipeline({ stt, llm: new OpenAILlm(), tts });
Push-to-talk loop
async function onButtonPress() {
const { reply, audio } = await pipeline.turn('capture.wav'); // your recorder writes this
await playback(audio);
}
Cap the conversation memory
new VoicePipeline({ stt, llm, tts, systemPrompt: '…', maxHistory: 12 }); // keeps last 12 turns