STT (Silero VAD + Whisper via sherpa-onnx), Chatterbox TTS HTTP server, query completeness classifier (Ollama), multi-voice demo scripts, and planning docs. Kept as reference; clean rewrite planned in separate repos. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
65 lines
1.8 KiB
JavaScript
65 lines
1.8 KiB
JavaScript
/**
|
|
* Optional LLM cleanup via Ollama REST API.
|
|
*
|
|
* Cleans up raw Whisper output: fixes punctuation, capitalization,
|
|
* removes filler words, corrects obvious recognition errors.
|
|
*
|
|
* Set OLLAMA_MODEL env var to choose the model (default: phi3:mini).
|
|
* Set OLLAMA_URL env var to change the base URL (default: http://localhost:11434).
|
|
*/
|
|
|
|
const OLLAMA_URL = process.env.OLLAMA_URL || 'http://localhost:11434'
|
|
const OLLAMA_MODEL = process.env.OLLAMA_MODEL || 'phi3:mini'
|
|
|
|
export async function llm_available() {
|
|
try {
|
|
const res = await fetch(`${OLLAMA_URL}/api/tags`, {
|
|
signal: AbortSignal.timeout(2000),
|
|
})
|
|
return res.ok
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
export async function list_models() {
|
|
const res = await fetch(`${OLLAMA_URL}/api/tags`)
|
|
const data = await res.json()
|
|
return (data.models ?? []).map(m => m.name)
|
|
}
|
|
|
|
/**
|
|
* Clean up a raw STT transcription.
|
|
* Returns the cleaned string, or the original if the request fails.
|
|
*/
|
|
export async function cleanup(raw_text, model = OLLAMA_MODEL) {
|
|
const prompt = [
|
|
'You are a transcription editor. Clean up this speech-to-text output:',
|
|
'- Fix punctuation and capitalization',
|
|
'- Remove meaningless filler words (um, uh, like, you know)',
|
|
'- Correct obvious word recognition errors based on context',
|
|
'- Keep the meaning and phrasing intact',
|
|
'- Return ONLY the cleaned text, no explanation, no quotes',
|
|
'',
|
|
raw_text,
|
|
].join('\n')
|
|
|
|
try {
|
|
const res = await fetch(`${OLLAMA_URL}/api/generate`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
model,
|
|
prompt,
|
|
stream: false,
|
|
options: { temperature: 0.1, num_predict: 256 },
|
|
}),
|
|
signal: AbortSignal.timeout(10_000),
|
|
})
|
|
const data = await res.json()
|
|
return data.response?.trim() || raw_text
|
|
} catch {
|
|
return raw_text
|
|
}
|
|
}
|