mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-07-09 17:08:29 +00:00
Split the legacy core speech stack into two built-in, independently toggleable plugins: `_kokoro_tts` for TTS and `_whisper_stt` for STT. This refactor keeps dependency installation and bootstrap concerns in Docker/bootstrap/preload, while moving speech-specific tooling, APIs, prompts, UI, and runtime behavior into the plugins. Core now exposes engine-agnostic `tts-service` and `stt-service` brokers, with browser-native TTS preserved as the fallback when Kokoro is disabled. Included in this change: - add built-in `_kokoro_tts` plugin with plugin-owned synth API, config, status UI, and provider registration - add built-in `_whisper_stt` plugin with plugin-owned transcribe API, mic runtime, device UI, prompt injection, and provider registration - remove legacy core speech APIs/helpers/settings/UI and delete unused `webui/js/speech_browser.js` - replace the old hardcoded speech settings section with a generic voice surface backed by plugin extensions - update preload/docs/tests to match the new plugin-owned speech architecture Behavioral intent: - both plugins are built-in but not `always_enabled` - users can now hot-switch TTS and STT independently - browser TTS remains available when `_kokoro_tts` is off - Whisper mic UI only appears when `_whisper_stt` is enabled
107 lines
2.9 KiB
HTML
107 lines
2.9 KiB
HTML
<div x-data x-init="$store.whisperStt.ensureStatusLoaded()" x-show="$store.whisperStt">
|
|
<div class="voice-plugin-card">
|
|
<div class="voice-plugin-card-header">
|
|
<div>
|
|
<div class="voice-plugin-title">Whisper STT</div>
|
|
<div class="voice-plugin-description">
|
|
Browser microphone input routed into the built-in Whisper transcription backend.
|
|
</div>
|
|
</div>
|
|
<span class="voice-plugin-badge" :class="`is-${$store.whisperStt.statusClass || 'warn'}`" x-text="$store.whisperStt.statusText || 'Idle'"></span>
|
|
</div>
|
|
|
|
<div class="voice-plugin-meta">
|
|
<div class="voice-plugin-meta-row">
|
|
<span>Model size</span>
|
|
<span x-text="$store.whisperStt.config.model_size || 'base'"></span>
|
|
</div>
|
|
<div class="voice-plugin-meta-row">
|
|
<span>Language</span>
|
|
<span x-text="$store.whisperStt.config.language || 'en'"></span>
|
|
</div>
|
|
<div class="voice-plugin-meta-row">
|
|
<span>Message</span>
|
|
<span x-text="$store.whisperStt.messageModeLabel"></span>
|
|
</div>
|
|
<div class="voice-plugin-meta-row">
|
|
<span>Microphone</span>
|
|
<span x-text="$store.whisperStt.selectedDeviceLabel"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="voice-plugin-actions">
|
|
<button class="btn btn-field" @click="$store.whisperStt.openConfig()">Configure</button>
|
|
<button class="btn btn-field" @click="$store.whisperStt.openPanel()">Status</button>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.voice-plugin-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
padding: 14px;
|
|
background: var(--color-input);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.voice-plugin-card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.voice-plugin-title {
|
|
font-weight: 700;
|
|
font-size: 0.98rem;
|
|
}
|
|
|
|
.voice-plugin-description {
|
|
color: var(--color-text-secondary);
|
|
font-size: var(--font-size-small);
|
|
margin-top: 0.25rem;
|
|
}
|
|
|
|
.voice-plugin-badge {
|
|
padding: 2px 8px;
|
|
border-radius: 999px;
|
|
font-size: 0.76rem;
|
|
font-weight: 600;
|
|
border: 1px solid transparent;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.voice-plugin-badge.is-ok {
|
|
color: #1b5e20;
|
|
background: rgba(46, 125, 50, 0.14);
|
|
border-color: rgba(46, 125, 50, 0.24);
|
|
}
|
|
|
|
.voice-plugin-badge.is-warn {
|
|
color: #8a6100;
|
|
background: rgba(191, 144, 0, 0.14);
|
|
border-color: rgba(191, 144, 0, 0.24);
|
|
}
|
|
|
|
.voice-plugin-meta {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
font-size: 0.84rem;
|
|
}
|
|
|
|
.voice-plugin-meta-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
}
|
|
|
|
.voice-plugin-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
flex-wrap: wrap;
|
|
}
|
|
</style>
|
|
</div>
|