feat(proxy-engine): add on-demand TTS caching for voicemail and IVR prompts

This commit is contained in:
2026-04-12 20:45:08 +00:00
parent cfadd7a2b6
commit 59d8c2557c
17 changed files with 460 additions and 488 deletions

View File

@@ -24,8 +24,6 @@ import {
getAllBrowserDeviceIds,
getBrowserDeviceWs,
} from './webrtcbridge.ts';
import { initAnnouncement } from './announcement.ts';
import { PromptCache } from './call/prompt-cache.ts';
import { VoiceboxManager } from './voicebox.ts';
import {
initProxyEngine,
@@ -170,7 +168,6 @@ for (const d of appConfig.devices) {
// Initialize subsystems
// ---------------------------------------------------------------------------
const promptCache = new PromptCache(log);
const voiceboxManager = new VoiceboxManager(log);
voiceboxManager.init(appConfig.voiceboxes ?? []);
@@ -519,6 +516,8 @@ async function startProxyEngine(): Promise<void> {
providers: appConfig.providers,
devices: appConfig.devices,
routing: appConfig.routing,
voiceboxes: appConfig.voiceboxes ?? [],
ivr: appConfig.ivr,
});
if (!configured) {
@@ -530,31 +529,8 @@ async function startProxyEngine(): Promise<void> {
const deviceList = appConfig.devices.map((d) => d.displayName).join(', ');
log(`proxy engine started | LAN ${appConfig.proxy.lanIp}:${appConfig.proxy.lanPort} | providers: ${providerList} | devices: ${deviceList}`);
// Generate TTS audio (WAV files on disk, played by Rust audio_player).
try {
await initAnnouncement(log);
// Pre-generate prompts.
await promptCache.generateBeep('voicemail-beep', 1000, 500, 8000);
for (const vb of appConfig.voiceboxes ?? []) {
if (!vb.enabled) continue;
const promptId = `voicemail-greeting-${vb.id}`;
if (vb.greetingWavPath) {
await promptCache.loadWavPrompt(promptId, vb.greetingWavPath);
} else {
const text = vb.greetingText || 'The person you are trying to reach is not available. Please leave a message after the tone.';
await promptCache.generatePrompt(promptId, text, vb.greetingVoice || 'af_bella');
}
}
if (appConfig.ivr?.enabled) {
for (const menu of appConfig.ivr.menus) {
await promptCache.generatePrompt(`ivr-menu-${menu.id}`, menu.promptText, menu.promptVoice || 'af_bella');
}
}
log(`[startup] prompts cached: ${promptCache.listIds().join(', ') || 'none'}`);
} catch (e) {
log(`[tts] init failed: ${e}`);
}
// TTS prompts (voicemail greetings, IVR menus) are generated on-demand
// by the Rust TTS engine when first needed. No startup pre-generation.
}
// ---------------------------------------------------------------------------
@@ -620,6 +596,8 @@ initWebUi(
providers: fresh.providers,
devices: fresh.devices,
routing: fresh.routing,
voiceboxes: fresh.voiceboxes ?? [],
ivr: fresh.ivr,
}).then((ok) => {
if (ok) log('[config] reloaded — proxy engine reconfigured');
else log('[config] reload failed — proxy engine rejected config');