tts-voice-creator-clone-and.../CHANGELOG.md
mARTin-B78 0a5b607fa5 Add text input to Conversation Playground (bypass mic / STT)
Frontend:
- Add pill-shaped text input + send button (→) to the left of the mic button
- Enter key or → click sends text directly without recording audio
- Input is disabled while a turn is processing; cleared on submit
- Welcome message updated to mention both input methods
- New CSS: .conv-input-bar, .conv-text-row, .conv-text-inp, .conv-send-btn,
  .conv-divider (visual separator between text and mic sections)

Backend:
- /api/conversation/turn: audio is now optional (UploadFile | None)
- New text form field — when provided, STT step is skipped and text is
  used as the transcript directly; SSE emits transcript event with stt_ms=null
- Raises 400 if neither audio nor text is supplied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 13:12:27 +02:00

9.4 KiB

Changelog

All notable changes to TTS Voice Creator — Clone and Design are documented here. Format follows Keep a Changelog.


[Unreleased] — 2026-05-29

Added

  • Text input in Conversation Playground — a pill-shaped text field and send button (→) now sit left of the mic button. Typing a message and pressing Enter or → skips STT entirely and sends text directly through LLM → TTS. Makes the playground fully usable without a microphone (HTTP context, no mic permission, remote access). Backend /api/conversation/turn now accepts an optional text form field; when set, the STT step is skipped and the STT latency row shows .

  • Container name field on all engine cards — every TTS and STT engine card (Docker stack cards and static "Other Local" cards) now always shows the Docker container name input row. Previously absent/not-installed cards hid it; now it is always visible so the container can be pre-configured before starting.

  • Connect / Disconnect toggle — the Connect button now shows "Disconnect" when already connected (with a green check-network icon) and toggles back on click, persisting state in localStorage.

  • Auto-apply on Connect — when a successful connection probe is completed the URL is automatically saved to Settings and the backend becomes available in the TTS / STT dropdown menus immediately, without requiring the user to also click "Use as TTS/STT". The manual "Use as" button still exists for overrides and shows an active highlight once applied.

Changed

  • Connect button — moved out of the URL input row into a dedicated dc-controls-row below the URL and container-name inputs. Restyled as a solid blue primary CTA button (was a small teal outline button).

  • "Use as TTS / STT" — made visually distinct as a teal "apply" action (larger padding, bolder border, chevron icon). Tooltip explains it sets the URL in Settings and enables the backend in dropdowns. Gains .active class once the URL has been applied.

  • Unified controls row layout — all engine cards now follow the same left-to-right order: [Connect/Disconnect] [Stop | Start | Restart] [Use as →]. Docker action buttons are hidden until a container name is entered; the Use-as button is right-aligned via margin-left: auto.

  • Static engine cards (initStaticDockerManagement) — rebuilt to use the same dc-controls-row structure as the dynamic Docker stack cards. The existing .llm-local-ping button is moved from inside the URL row into the controls row at initialisation time.

Fixed

  • chrome://flags/… URL unreadable in microphone-blocked warning — the global code { background: var(--panel) } rule caused the URL text to render as white-on-light-grey inside the red warning box. Fixed by applying inline styles (background: rgba(0,0,0,.35); color: #fff) directly on the <code> element and adding a "Copy" button so users can copy the URL without having to manually select invisible text.

[Unreleased] — 2026-05-29

Security

  • Fixed path traversal in /api/browse-dirs — Added a _BROWSE_BLOCKED blocklist (/proc, /sys, /dev, /run, /boot). Requests for paths under these directories now return HTTP 403 instead of listing kernel/system files.

  • Hardened yt-dlp output path — After a YouTube download completes the resolved output path is verified to be inside TEMP_DIR with .relative_to(). A file written outside the temp directory is rejected with an SSE error event and never registered.

  • Removed CORS wildcard on /api/proxy-audio — The Access-Control-Allow-Origin: * header was unnecessary (all callers are same-origin) and exposed proxied audio to arbitrary cross-origin requests. Header removed.

  • Temp file registry now enforces a TTL_registry is now a dict[str, tuple[Path, float]] storing each entry with a creation timestamp. _registry_gc() evicts entries older than TEMP_FILE_TTL_SECONDS (default 2 hours, configurable via env var) and unlinks their files, preventing unbounded disk growth.

Performance

  • Settings and routing rules cached in memory_load_settings() and _load_tts_routes() previously read from disk on every API request. Both now use mtime-checked in-memory caches (_settings_cache, _routes_cache) that are invalidated automatically on write. Eliminates dozens of redundant file reads per TTS synthesis call.

Added

  • Container name field on Docker stack TTS/STT cards — The engine cards rendered dynamically in the Engines → Text to Speech and Engines → Speech to Text sections (Qwen3 Voice Clone, Voice Design, Custom Voice, Streaming, NVIDIA Magpie, Parakeet ASR) now show the same container name (optional) input row that the Other Local TTS/STT cards already had. Typing a container name immediately enables Stop / Start / Restart buttons wired to the Docker API. The static STT cards (faster-whisper-server, whisper.cpp) received the same treatment via initStaticDockerManagement().

Refactored

Backend — server.py split into core/ + routes/ packages

server.py went from 5,560 lines to a 43-line entry point that creates the FastAPI app, registers routers, and mounts static files. All logic was extracted into single-responsibility modules:

core/ — pure utilities (no FastAPI decorators)

Module Responsibility
constants.py Boot-time env defaults, CONFIG_DIR/CONFIG_FILE/STATIC_DIR paths, in-memory log buffer
registry.py TEMP_DIR, TTL-based temp file registry (_registry_put/get/gc)
validation.py _validate_http_url, _normalize_service_url, _copy_limited, _safe_child_path
docker_client.py Raw Unix-socket Docker HTTP client (_docker_get_json, _docker_post)
config.py Settings load/save/normalize, TTS stability helpers, backend URL resolution
routing.py TTS route rules load/save/resolve, language detection, routing log
audio.py _to_wav_24k/16k, _trim, _duration, _normalize_segment, auto-trim scoring
voice.py Voice metadata helpers, backup management, benchmark helpers
presets.py Voice Design preset load/save, virtual voice resolution
tts_helpers.py TTS request helpers, streaming, NVIDIA/VibeVoice/XTTS backends, audio proxy

routes/ — FastAPI APIRouter modules

Module Routes
admin.py GET /, GET /favicon.ico, GET /api/browse-dirs, GET /robots.txt
settings.py /api/settings, /api/tts-routes, /api/tts-routing-log, /api/logs, /api/voice-design-presets
library.py All /api/voice* and /api/voices*, /api/save, /api/upload, /api/route-sounds*, /api/audio/{fid}, /api/auto-trim, /api/process
stt.py /api/stt-backends, /api/transcribe, /api/transcribe-bytes
sources.py /api/voice-sources, /api/import-source-audio, /api/proxy-audio, /api/quick-import-voice, /api/download-yt, /api/elevenlabs/voices
docker.py /api/local-containers/*, /api/probe-url
tts.py /api/tts-preview, /api/tts-style-variation, /api/tts-stream-*, /api/voice-design, /v1/*, /api/tts-voices, /api/tts-backends, restart endpoints
conversation.py /api/refine-text, /api/rewrite-with-persona, /api/audio/effects, /api/voices/export, /api/voices/import, /speak*, /mcp, /api/conversation/*

Dockerfile updated to COPY core/ core/ and COPY routes/ routes/. docker-compose.yml updated to mount ./core:/app/core:ro and ./routes:/app/routes:ro.

Frontend — static/app.js split into static/js/ modules

app.js (8,744 lines) split into 16 focused modules totalling the same 8,744 lines. static/loader.js updated to load them sequentially in dependency order.

Module Lines Responsibility
utils.js 364 $, toast, escHtml, debounce, theme, language/flag helpers, searchable picker, tab helpers
voice-inspector.js 397 3-pane voice workbench (selectVoice, updateInspector)
voice-sources.js 277 External voice source scraping UI (loadGetVoices, renderGetVoices)
integrations.js 211 Code snippet generation for SillyTavern, Open WebUI, HA, curl, MCP
routing.js 542 TTS routing rules editor
settings.js 385 loadSettings, applyAndSaveSettings, settings panel
voice-clone.js 774 WaveSurfer waveform, drop zone, microphone, trim UI, voice design dialog
voice-library.js 2654 Full voice library: list, row rendering, operations (save, rename, delete, normalize, benchmark)
tts-preview.js 528 fetchTtsPreviewBlob, createTtsAudioSource, preview panel
benchmark.js 218 Batch benchmark section
stt.js 287 STT→TTS playground, refreshSttBackends
init.js 49 App bootstrap (calls loadSettings, syncs UI state)
engines.js 625 ElevenLabs browser, custom engine cards, Docker container management
ai-backends.js 520 AI backend cards, LLM snippet collapse, initStaticDockerManagement, collapsible cards
generation.js 393 WAV merge, chunked TTS, generation history, playlist, audio effects, LLM refinement
conversation.js 520 Settings logs/about, voices import, conversation playground

Earlier history

See git log for the full commit history prior to this release.