Inspector: - Skinny 2-row header: 72px avatar + name/ID row / subtitle row / note row - Searchable flag picker (dblclick flag icon) — filtered by voice language, falls back to ALL_FLAGS - Searchable language picker (dblclick lang code) — shows full language names - Tag reuse: entered tags persist to localStorage as datalist suggestions - Compact active toggle (32×18px), slim save button (12px/4px padding) - Show/hide eye toggle and "✓ Key saved" badge on API key fields AI Backends (s-llms.html + style.css): - Full CSS design: pill tabs with active accent, animated section transitions - Service cards: icon bubbles, tier badges (Free/Demo/Paid), stat chips, endpoint rows, model tags - Highlighted recommended card with accent border - Dark code blocks for local service snippets with copy feedback - Show/hide password toggle and auto-appearing "✓ Key saved" badge per card Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
635 lines
30 KiB
HTML
635 lines
30 KiB
HTML
<div class="section-head">
|
|
<span class="section-icon">🤖</span>
|
|
<div class="section-title">
|
|
<h2>AI Backends</h2>
|
|
<p>Connect cloud or local services for speech recognition, synthesis, and text generation.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Category filter tabs -->
|
|
<div class="llm-cat-tabs" id="llm-cat-tabs">
|
|
<button class="llm-cat-tab active" data-llm-cat="stt">🎤 ASR · STT</button>
|
|
<button class="llm-cat-tab" data-llm-cat="tts">🔊 TTS</button>
|
|
<button class="llm-cat-tab" data-llm-cat="llm">🤖 LLM</button>
|
|
<button class="llm-cat-tab" data-llm-cat="local">💻 Local</button>
|
|
</div>
|
|
|
|
<!-- ── STT section ─────────────────────────────────────────── -->
|
|
<div class="llm-section" id="llm-sec-stt" data-llm-section="stt">
|
|
<div class="llm-sec-header">
|
|
<div>
|
|
<h3 class="llm-sec-title">ASR · Speech-to-Text</h3>
|
|
<p class="llm-sec-note">Used for auto-transcribing reference audio. The app calls these when you click <em>Re-recognise text</em>.</p>
|
|
</div>
|
|
<span class="llm-free-badge">Free tiers available</span>
|
|
</div>
|
|
|
|
<div class="llm-service-grid">
|
|
|
|
<div class="llm-card llm-card-highlight">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">⚡</span>
|
|
<div>
|
|
<div class="llm-card-name">Groq Whisper</div>
|
|
<div class="llm-card-sub">whisper-large-v3-turbo · OpenAI-compatible</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>2 000 req / day</span>
|
|
<span>Fastest inference</span>
|
|
<span>OpenAI API format</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="gsk_…" data-llm-key="groq_stt">
|
|
<a class="llm-link" href="https://console.groq.com" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://api.groq.com/openai/v1</code>
|
|
</div>
|
|
<div class="llm-models">
|
|
<span class="llm-model-tag">whisper-large-v3-turbo</span>
|
|
<span class="llm-model-tag">whisper-large-v3</span>
|
|
<span class="llm-model-tag">distil-whisper-large-v3-en</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="llm-card">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">🤗</span>
|
|
<div>
|
|
<div class="llm-card-name">HuggingFace Inference</div>
|
|
<div class="llm-card-sub">Serverless Whisper models</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>~1 000 req / day</span>
|
|
<span>Slower cold starts</span>
|
|
<span>Many model variants</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="hf_…" data-llm-key="hf_stt">
|
|
<a class="llm-link" href="https://huggingface.co/settings/tokens" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://api-inference.huggingface.co/models/openai/whisper-large-v3</code>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="llm-card">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">📋</span>
|
|
<div>
|
|
<div class="llm-card-name">AssemblyAI</div>
|
|
<div class="llm-card-sub">High-accuracy transcription + speaker diarization</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>100 h lifetime</span>
|
|
<span>Speaker labels</span>
|
|
<span>Auto-chapters</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="AssemblyAI key…" data-llm-key="assemblyai">
|
|
<a class="llm-link" href="https://www.assemblyai.com" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://api.assemblyai.com/v2/transcript</code>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div><!-- /stt -->
|
|
|
|
<!-- ── TTS section ─────────────────────────────────────────── -->
|
|
<div class="llm-section" id="llm-sec-tts" data-llm-section="tts" hidden>
|
|
<div class="llm-sec-header">
|
|
<div>
|
|
<h3 class="llm-sec-title">Text-to-Speech</h3>
|
|
<p class="llm-sec-note">Cloud TTS backends you can add as routing targets alongside your local cloned voices.</p>
|
|
</div>
|
|
<span class="llm-free-badge">Free tiers available</span>
|
|
</div>
|
|
|
|
<div class="llm-service-grid">
|
|
|
|
<div class="llm-card llm-card-highlight">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">💉</span>
|
|
<div>
|
|
<div class="llm-card-name">ElevenLabs</div>
|
|
<div class="llm-card-sub">High-quality voice cloning & synthesis</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>10 000 chars / month</span>
|
|
<span>2 500 char / request max</span>
|
|
<span>Voice cloning supported</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="xi-api-key…" data-llm-key="elevenlabs">
|
|
<a class="llm-link" href="https://elevenlabs.io" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://api.elevenlabs.io/v1/text-to-speech</code>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="llm-card">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">🏭</span>
|
|
<div>
|
|
<div class="llm-card-name">Fish Audio</div>
|
|
<div class="llm-card-sub">Voice cloning & multilingual TTS</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>1 h audio / month</span>
|
|
<span>100 req / min</span>
|
|
<span>30+ languages</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="Fish Audio key…" data-llm-key="fish_audio">
|
|
<a class="llm-link" href="https://fish.audio" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://api.fish.audio/v1/tts</code>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="llm-card">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">🎵</span>
|
|
<div>
|
|
<div class="llm-card-name">Kokoro TTS</div>
|
|
<div class="llm-card-sub">82M model · HuggingFace Spaces demo</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-demo">Demo</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>Free web demo</span>
|
|
<span><$1 per 1M chars (paid)</span>
|
|
<span>High naturalness</span>
|
|
</div>
|
|
<div class="llm-info-box">
|
|
Use the HF Spaces web demo for quick tests, or run Kokoro locally via Docker for production use.
|
|
<br>
|
|
<a class="llm-link-inline" href="https://huggingface.co/spaces/hexgrad/Kokoro-TTS" target="_blank" rel="noopener">→ Open Kokoro HF Space</a>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div><!-- /tts -->
|
|
|
|
<!-- ── LLM section ─────────────────────────────────────────── -->
|
|
<div class="llm-section" id="llm-sec-llm" data-llm-section="llm" hidden>
|
|
<div class="llm-sec-header">
|
|
<div>
|
|
<h3 class="llm-sec-title">Large Language Models</h3>
|
|
<p class="llm-sec-note">Use LLMs to generate text for TTS, write scripts, clean transcripts, or power agentic voice pipelines.</p>
|
|
</div>
|
|
<span class="llm-free-badge">Free tiers available</span>
|
|
</div>
|
|
|
|
<div class="llm-service-grid">
|
|
|
|
<div class="llm-card llm-card-highlight">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">⚡</span>
|
|
<div>
|
|
<div class="llm-card-name">Groq</div>
|
|
<div class="llm-card-sub">Ultra-fast inference · OpenAI-compatible</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>30 000 tokens / min</span>
|
|
<span>14 400 req / day</span>
|
|
<span>Lowest latency</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="gsk_…" data-llm-key="groq_llm">
|
|
<a class="llm-link" href="https://console.groq.com" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://api.groq.com/openai/v1</code>
|
|
</div>
|
|
<div class="llm-models">
|
|
<span class="llm-model-tag">llama-3.3-70b-versatile</span>
|
|
<span class="llm-model-tag">qwen-qwq-32b</span>
|
|
<span class="llm-model-tag">deepseek-r1-distill-llama-70b</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="llm-card">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">🌐</span>
|
|
<div>
|
|
<div class="llm-card-name">OpenRouter</div>
|
|
<div class="llm-card-sub">50+ free models · OpenAI-compatible</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>20 req / min</span>
|
|
<span>200 req / day (free models)</span>
|
|
<span>Single API for all models</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="sk-or-…" data-llm-key="openrouter">
|
|
<a class="llm-link" href="https://openrouter.ai" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://openrouter.ai/api/v1</code>
|
|
</div>
|
|
<div class="llm-models">
|
|
<span class="llm-model-tag">qwen/qwen3-235b-a22b:free</span>
|
|
<span class="llm-model-tag">deepseek/deepseek-r1-0528:free</span>
|
|
<span class="llm-model-tag">mistralai/mistral-7b-instruct:free</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="llm-card">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">💎</span>
|
|
<div>
|
|
<div class="llm-card-name">Google Gemini</div>
|
|
<div class="llm-card-sub">Gemini 2.5 Flash · Generous free tier</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>250 000 tokens / min</span>
|
|
<span>15 req / min free</span>
|
|
<span>1M context window</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="AIza…" data-llm-key="gemini">
|
|
<a class="llm-link" href="https://ai.google.dev" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://generativelanguage.googleapis.com/v1beta/openai/</code>
|
|
</div>
|
|
<div class="llm-info-note">Uses OpenAI-compat wrapper — use model <code>gemini-2.5-flash</code></div>
|
|
</div>
|
|
|
|
<div class="llm-card">
|
|
<div class="llm-card-head">
|
|
<span class="llm-card-icon">🅓</span>
|
|
<div>
|
|
<div class="llm-card-name">Mistral AI</div>
|
|
<div class="llm-card-sub">OpenAI-compatible · EU-based</div>
|
|
</div>
|
|
<span class="llm-tier-badge llm-tier-free">Free</span>
|
|
</div>
|
|
<div class="llm-card-stats">
|
|
<span>1B tokens / month</span>
|
|
<span>2 req / min free</span>
|
|
<span>GDPR-compliant</span>
|
|
</div>
|
|
<div class="llm-field-row">
|
|
<label class="llm-label">API key</label>
|
|
<input type="password" class="llm-input" placeholder="Mistral key…" data-llm-key="mistral">
|
|
<a class="llm-link" href="https://mistral.ai" target="_blank" rel="noopener">Get key ↗</a>
|
|
</div>
|
|
<div class="llm-endpoint">
|
|
<span class="llm-endpoint-label">Endpoint</span>
|
|
<code>https://api.mistral.ai/v1</code>
|
|
</div>
|
|
<div class="llm-models">
|
|
<span class="llm-model-tag">mistral-small-latest</span>
|
|
<span class="llm-model-tag">mistral-large-latest</span>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div><!-- /llm -->
|
|
|
|
<!-- ── Local section ───────────────────────────────────────── -->
|
|
<div class="llm-section" id="llm-sec-local" data-llm-section="local" hidden>
|
|
<div class="llm-sec-header">
|
|
<div>
|
|
<h3 class="llm-sec-title">Local AI Services</h3>
|
|
<p class="llm-sec-note">Run everything on your own hardware — no API key, no rate limits, no data leaves your machine.</p>
|
|
</div>
|
|
<span class="llm-free-badge llm-free-local">100% Local</span>
|
|
</div>
|
|
|
|
<!-- Local LLMs -->
|
|
<h4 class="llm-local-cat">Language Models (LLM)</h4>
|
|
<div class="llm-local-grid">
|
|
|
|
<div class="llm-local-card">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">Ollama</span>
|
|
<span class="llm-local-compat">OpenAI-compat</span>
|
|
</div>
|
|
<p class="llm-local-desc">Easiest local LLM setup. Pull any model with one command. Runs Llama, Mistral, Qwen, Phi, Gemma and many more.</p>
|
|
<div class="llm-local-url">
|
|
<span>Default URL</span>
|
|
<code>http://localhost:11434/v1</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar">
|
|
<span>Quick start</span>
|
|
<button class="llm-copy-btn" data-copy="curl https://ollama.ai/install.sh | sh ollama pull llama3.3">Copy</button>
|
|
</div>
|
|
<pre>curl https://ollama.ai/install.sh | sh
|
|
ollama pull llama3.3</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://ollama.ai" target="_blank" rel="noopener">ollama.ai ↗</a>
|
|
</div>
|
|
|
|
<div class="llm-local-card llm-local-card-running">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">vLLM ⚡</span>
|
|
<span class="llm-local-compat llm-compat-detected">Detected in stack</span>
|
|
</div>
|
|
<p class="llm-local-desc">High-throughput GPU inference. Already in your Docker stack. Serve any HuggingFace model with PagedAttention.</p>
|
|
<div class="llm-local-url">
|
|
<span>Default URL</span>
|
|
<code>http://localhost:8000/v1</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar">
|
|
<span>Add a model to your stack</span>
|
|
<button class="llm-copy-btn" data-copy="--model Qwen/Qwen3-8B --served-model-name qwen3-8b">Copy</button>
|
|
</div>
|
|
<pre>--model Qwen/Qwen3-8B \
|
|
--served-model-name qwen3-8b</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://docs.vllm.ai" target="_blank" rel="noopener">docs.vllm.ai ↗</a>
|
|
</div>
|
|
|
|
<div class="llm-local-card">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">LM Studio</span>
|
|
<span class="llm-local-compat">OpenAI-compat</span>
|
|
</div>
|
|
<p class="llm-local-desc">GUI app for running quantized models. Built-in model browser, chat UI, and a local server with OpenAI API.</p>
|
|
<div class="llm-local-url">
|
|
<span>Default URL</span>
|
|
<code>http://localhost:1234/v1</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar"><span>Enable in LM Studio</span></div>
|
|
<pre>Developer tab → Start server → Port 1234
|
|
Check "Enable CORS" for browser access</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://lmstudio.ai" target="_blank" rel="noopener">lmstudio.ai ↗</a>
|
|
</div>
|
|
|
|
<div class="llm-local-card">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">llama.cpp</span>
|
|
<span class="llm-local-compat">OpenAI-compat</span>
|
|
</div>
|
|
<p class="llm-local-desc">Lightweight GGUF model server. Minimal RAM usage. Runs on CPU or GPU. Great for embedding in Docker.</p>
|
|
<div class="llm-local-url">
|
|
<span>Default URL</span>
|
|
<code>http://localhost:8080/v1</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar">
|
|
<span>Docker one-liner</span>
|
|
<button class="llm-copy-btn" data-copy="docker run -p 8080:8080 ghcr.io/ggml-org/llama.cpp:server -hf QuantFactory/Meta-Llama-3-8B-GGUF -hff Meta-Llama-3-8B.Q4_K_M.gguf">Copy</button>
|
|
</div>
|
|
<pre>docker run -p 8080:8080 ghcr.io/ggml-org/llama.cpp:server \
|
|
-hf QuantFactory/Meta-Llama-3-8B-GGUF \
|
|
-hff Meta-Llama-3-8B.Q4_K_M.gguf</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://github.com/ggml-org/llama.cpp" target="_blank" rel="noopener">github.com/ggml-org/llama.cpp ↗</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Local STT -->
|
|
<h4 class="llm-local-cat" style="margin-top:24px">Speech Recognition (STT)</h4>
|
|
<div class="llm-local-grid">
|
|
|
|
<div class="llm-local-card">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">faster-whisper-server</span>
|
|
<span class="llm-local-compat">OpenAI-compat</span>
|
|
</div>
|
|
<p class="llm-local-desc">Drop-in local replacement for the Whisper API. GPU-accelerated via CTranslate2. OpenAI-compatible endpoint.</p>
|
|
<div class="llm-local-url">
|
|
<span>Default URL</span>
|
|
<code>http://localhost:8000/v1</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar">
|
|
<span>docker-compose snippet</span>
|
|
<button class="llm-copy-btn" data-copy="services: whisper: image: fedirz/faster-whisper-server:latest-cuda ports: ["8000:8000"] environment: - WHISPER__MODEL=large-v3 deploy: resources: reservations: devices: [{driver: nvidia, count: 1, capabilities: [gpu]}]">Copy</button>
|
|
</div>
|
|
<pre>services:
|
|
whisper:
|
|
image: fedirz/faster-whisper-server:latest-cuda
|
|
ports: ["8000:8000"]
|
|
environment:
|
|
- WHISPER__MODEL=large-v3
|
|
deploy:
|
|
resources:
|
|
reservations:
|
|
devices: [{driver: nvidia, count: 1, capabilities: [gpu]}]</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://github.com/fedirz/faster-whisper-server" target="_blank" rel="noopener">github.com/fedirz/faster-whisper-server ↗</a>
|
|
</div>
|
|
|
|
<div class="llm-local-card">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">whisper.cpp</span>
|
|
<span class="llm-local-compat">HTTP server</span>
|
|
</div>
|
|
<p class="llm-local-desc">Minimal C++ Whisper with a built-in HTTP server. CPU or Metal/CUDA. Low memory, fast on consumer hardware.</p>
|
|
<div class="llm-local-url">
|
|
<span>Default URL</span>
|
|
<code>http://localhost:8080</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar">
|
|
<span>Build & run</span>
|
|
<button class="llm-copy-btn" data-copy="git clone https://github.com/ggml-org/whisper.cpp cd whisper.cpp && cmake -B build && cmake --build build -j ./build/bin/whisper-server -m models/ggml-large-v3.bin --port 8080">Copy</button>
|
|
</div>
|
|
<pre>git clone https://github.com/ggml-org/whisper.cpp
|
|
cd whisper.cpp && cmake -B build && cmake --build build -j
|
|
./build/bin/whisper-server \
|
|
-m models/ggml-large-v3.bin --port 8080</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://github.com/ggml-org/whisper.cpp" target="_blank" rel="noopener">github.com/ggml-org/whisper.cpp ↗</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Local TTS -->
|
|
<h4 class="llm-local-cat" style="margin-top:24px">Text-to-Speech (local TTS)</h4>
|
|
<div class="llm-local-grid">
|
|
|
|
<div class="llm-local-card">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">Piper TTS</span>
|
|
<span class="llm-local-compat">Fast · offline</span>
|
|
</div>
|
|
<p class="llm-local-desc">Lightning-fast offline TTS. Runs on CPU in real time. 50+ language voices available. Ideal for low-latency pipelines.</p>
|
|
<div class="llm-local-url">
|
|
<span>Wyoming protocol port</span>
|
|
<code>localhost:10200</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar">
|
|
<span>Docker</span>
|
|
<button class="llm-copy-btn" data-copy="docker run -p 10200:10200 rhasspy/wyoming-piper --voice en_US-lessac-medium">Copy</button>
|
|
</div>
|
|
<pre>docker run -p 10200:10200 \
|
|
rhasspy/wyoming-piper \
|
|
--voice en_US-lessac-medium</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://github.com/rhasspy/piper" target="_blank" rel="noopener">github.com/rhasspy/piper ↗</a>
|
|
</div>
|
|
|
|
<div class="llm-local-card">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">Kokoro FastAPI</span>
|
|
<span class="llm-local-compat">OpenAI-compat TTS</span>
|
|
</div>
|
|
<p class="llm-local-desc">Kokoro-82M running behind an OpenAI-compatible TTS endpoint. Drop-in replacement for OpenAI’s TTS API.</p>
|
|
<div class="llm-local-url">
|
|
<span>Default URL</span>
|
|
<code>http://localhost:8880/v1/audio/speech</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar">
|
|
<span>Docker</span>
|
|
<button class="llm-copy-btn" data-copy="docker run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu:v0.2.2">Copy</button>
|
|
</div>
|
|
<pre>docker run -p 8880:8880 \
|
|
ghcr.io/remsky/kokoro-fastapi-cpu:v0.2.2
|
|
# GPU:
|
|
docker run -p 8880:8880 --gpus all \
|
|
ghcr.io/remsky/kokoro-fastapi-gpu:v0.2.2</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://github.com/remsky/Kokoro-FastAPI" target="_blank" rel="noopener">github.com/remsky/Kokoro-FastAPI ↗</a>
|
|
</div>
|
|
|
|
<div class="llm-local-card">
|
|
<div class="llm-local-head">
|
|
<span class="llm-local-name">XTTS v2</span>
|
|
<span class="llm-local-compat">Voice cloning</span>
|
|
</div>
|
|
<p class="llm-local-desc">Coqui XTTS — multilingual voice cloning from a 6-second sample. 17 languages. Compatible with this app’s voice library.</p>
|
|
<div class="llm-local-url">
|
|
<span>API endpoint</span>
|
|
<code>http://localhost:8020/tts_to_audio</code>
|
|
</div>
|
|
<div class="llm-local-snippet">
|
|
<div class="llm-snippet-bar">
|
|
<span>Docker</span>
|
|
<button class="llm-copy-btn" data-copy="docker run -p 8020:80 --gpus all -v /voices:/voices daswer123/xtts-api-server:latest">Copy</button>
|
|
</div>
|
|
<pre>docker run -p 8020:80 --gpus all \
|
|
-v /voices:/voices \
|
|
daswer123/xtts-api-server:latest</pre>
|
|
</div>
|
|
<a class="llm-local-link" href="https://github.com/daswer123/xtts-api-server" target="_blank" rel="noopener">xtts-api-server ↗</a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Generic how-to tip -->
|
|
<div class="llm-local-howto">
|
|
<div class="llm-howto-icon">💡</div>
|
|
<div class="llm-howto-body">
|
|
<strong>Adding a local service to this app</strong>
|
|
<p>All OpenAI-compatible services work the same way: open <em>App Routing</em> in the sidebar, add a new backend entry with the local URL as base endpoint, and leave the API key field empty (or enter any string — it’s ignored by local servers). Set it as the default backend for the voice type you want (clone, design, or tryout) and the app will start routing requests to it immediately.</p>
|
|
</div>
|
|
</div>
|
|
|
|
</div><!-- /local -->
|
|
|
|
<script>
|
|
(function () {
|
|
// ── Category tabs ──────────────────────────────────────────
|
|
var tabs = document.querySelectorAll('.llm-cat-tab');
|
|
tabs.forEach(function (tab) {
|
|
tab.addEventListener('click', function () {
|
|
var cat = tab.dataset.llmCat;
|
|
tabs.forEach(function (t) { t.classList.toggle('active', t === tab); });
|
|
document.querySelectorAll('[data-llm-section]').forEach(function (sec) {
|
|
sec.hidden = sec.dataset.llmSection !== cat;
|
|
});
|
|
});
|
|
});
|
|
|
|
// ── Copy buttons ───────────────────────────────────────────
|
|
document.querySelectorAll('.llm-copy-btn').forEach(function (btn) {
|
|
btn.addEventListener('click', function () {
|
|
var text = btn.dataset.copy.replace(/ /g, '\n');
|
|
navigator.clipboard?.writeText(text).then(function () {
|
|
var orig = btn.textContent;
|
|
btn.textContent = '✓ Copied';
|
|
setTimeout(function () { btn.textContent = orig; }, 1600);
|
|
});
|
|
});
|
|
});
|
|
|
|
// ── API key inputs: persist + show/hide toggle + saved badge ──
|
|
document.querySelectorAll('[data-llm-key]').forEach(function (inp) {
|
|
var k = 'llm-key-' + inp.dataset.llmKey;
|
|
var stored = localStorage.getItem(k) || '';
|
|
inp.value = stored;
|
|
|
|
// Insert show/hide toggle
|
|
var eyeBtn = document.createElement('button');
|
|
eyeBtn.type = 'button';
|
|
eyeBtn.className = 'llm-eye-btn';
|
|
eyeBtn.title = 'Show / hide key';
|
|
eyeBtn.textContent = '👁';
|
|
eyeBtn.addEventListener('click', function () {
|
|
inp.type = inp.type === 'password' ? 'text' : 'password';
|
|
eyeBtn.classList.toggle('active', inp.type === 'text');
|
|
});
|
|
inp.after(eyeBtn);
|
|
|
|
// Saved badge in parent card head
|
|
var card = inp.closest('.llm-card');
|
|
var savedBadge = card && card.querySelector('.llm-saved-badge');
|
|
if (!savedBadge && card) {
|
|
savedBadge = document.createElement('span');
|
|
savedBadge.className = 'llm-saved-badge';
|
|
savedBadge.textContent = '✓ Key saved';
|
|
var head = card.querySelector('.llm-card-head');
|
|
if (head) head.appendChild(savedBadge);
|
|
}
|
|
function updateBadge() {
|
|
if (savedBadge) savedBadge.hidden = !inp.value.trim();
|
|
}
|
|
updateBadge();
|
|
|
|
inp.addEventListener('input', function () {
|
|
localStorage.setItem(k, inp.value.trim());
|
|
updateBadge();
|
|
});
|
|
});
|
|
})();
|
|
</script>
|