Add version number (v1.1.0) and rewrite CHANGELOG to full Keep-a-Changelog spec
- Add VERSION file (1.1.0) at repo root
- core/constants.py: expose __version__ read from VERSION file
- routes/admin.py: GET /api/version endpoint returns {version}
- Settings → About: display "v1.1.0" next to app name via /api/version fetch
- CHANGELOG.md: full rewrite following Keep a Changelog + Semantic Versioning
- [Unreleased] staging section at top
- [1.1.0] 2026-05-29 — security, perf, refactor, UX changes from this session
- [1.0.0] 2026-05-28 — all pre-session features documented
- Compare links at bottom pointing to GitHub
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0a5b607fa5
commit
db6302f99d
284
CHANGELOG.md
284
CHANGELOG.md
@ -1,172 +1,184 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to TTS Voice Creator — Clone and Design are documented here.
|
All notable changes to **TTS Voice Creator — Clone and Design** are documented here.
|
||||||
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned with [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## [Unreleased] — 2026-05-29
|
## [Unreleased]
|
||||||
|
|
||||||
### 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
|
## [1.1.0] — 2026-05-29
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
- **Fixed path traversal in `/api/browse-dirs`** — Added a `_BROWSE_BLOCKED` blocklist
|
- **Fixed path traversal in `/api/browse-dirs`** — Added a `_BROWSE_BLOCKED` blocklist
|
||||||
(`/proc`, `/sys`, `/dev`, `/run`, `/boot`). Requests for paths under these directories
|
(`/proc`, `/sys`, `/dev`, `/run`, `/boot`). Requests for paths under these directories
|
||||||
now return HTTP 403 instead of listing kernel/system files.
|
now return HTTP 403 instead of listing kernel/system files.
|
||||||
|
- **Hardened yt-dlp output path** — After a YouTube download completes, the resolved
|
||||||
- **Hardened yt-dlp output path** — After a YouTube download completes the resolved output
|
output path is verified to be inside `TEMP_DIR` via `.relative_to()`. A file written
|
||||||
path is verified to be inside `TEMP_DIR` with `.relative_to()`. A file written outside
|
outside the temp directory is rejected with an SSE error event and never registered.
|
||||||
the temp directory is rejected with an SSE error event and never registered.
|
- **Removed CORS wildcard on `/api/proxy-audio`** — `Access-Control-Allow-Origin: *`
|
||||||
|
was unnecessary (all callers are same-origin) and exposed proxied audio to arbitrary
|
||||||
- **Removed CORS wildcard on `/api/proxy-audio`** — The `Access-Control-Allow-Origin: *`
|
cross-origin requests. Header removed.
|
||||||
header was unnecessary (all callers are same-origin) and exposed proxied audio to
|
- **Temp file registry now enforces a TTL** — `_registry` changed to
|
||||||
arbitrary cross-origin requests. Header removed.
|
`dict[str, tuple[Path, float]]`. `_registry_gc()` evicts entries older than
|
||||||
|
`TEMP_FILE_TTL_SECONDS` (default 2 h, configurable via env var) and unlinks their
|
||||||
- **Temp file registry now enforces a TTL** — `_registry` is now a
|
files, preventing unbounded disk growth on long-running instances.
|
||||||
`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
|
### Performance
|
||||||
|
|
||||||
- **Settings and routing rules cached in memory** — `_load_settings()` and
|
- **Settings and routing rules cached in memory** — `_load_settings()` and
|
||||||
`_load_tts_routes()` previously read from disk on every API request. Both now use
|
`_load_tts_routes()` previously read from disk on every API request (55+ calls per
|
||||||
mtime-checked in-memory caches (`_settings_cache`, `_routes_cache`) that are
|
TTS synthesis). Both now use mtime-checked in-memory caches that invalidate
|
||||||
invalidated automatically on write. Eliminates dozens of redundant file reads per
|
automatically on write, eliminating redundant file I/O.
|
||||||
TTS synthesis call.
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- **Container name field on Docker stack TTS/STT cards** — The engine cards rendered
|
- **Version number** — `VERSION` file at repo root; read by `core/constants.__version__`
|
||||||
dynamically in the *Engines → Text to Speech* and *Engines → Speech to Text* sections
|
and surfaced via `GET /api/version`. Displayed as `v1.1.0` in Settings → About.
|
||||||
(Qwen3 Voice Clone, Voice Design, Custom Voice, Streaming, NVIDIA Magpie, Parakeet ASR)
|
- **Text input in Conversation Playground** — a pill-shaped text field and send button
|
||||||
now show the same *container name (optional)* input row that the *Other Local TTS/STT*
|
(→) sit left of the mic button. Pressing Enter or → sends text directly through the
|
||||||
cards already had. Typing a container name immediately enables Stop / Start / Restart
|
LLM → TTS pipeline, skipping STT entirely. Makes the playground fully usable without
|
||||||
buttons wired to the Docker API. The static STT cards (faster-whisper-server,
|
a microphone (HTTP context, no mic permission, remote access). The backend
|
||||||
whisper.cpp) received the same treatment via `initStaticDockerManagement()`.
|
`/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" (green,
|
||||||
|
`check-network` icon) when already connected and toggles back on click. State
|
||||||
|
persists in `localStorage`.
|
||||||
|
- **Auto-apply on Connect** — a successful connection probe automatically saves the
|
||||||
|
URL to Settings and makes the backend available in TTS/STT dropdown menus immediately,
|
||||||
|
without requiring a separate "Use as TTS/STT" click.
|
||||||
|
|
||||||
### Refactored
|
### Changed
|
||||||
|
|
||||||
#### Backend — `server.py` split into `core/` + `routes/` packages
|
- **Connect button redesigned** — moved out of the URL input row into a dedicated
|
||||||
|
`dc-controls-row`. Restyled as a solid blue primary CTA (was a small teal outline
|
||||||
|
button). Shows a spinner icon while probing.
|
||||||
|
- **"Use as TTS / STT" button** — larger padding, bolder teal border, chevron icon,
|
||||||
|
tooltip explaining it sets the URL in Settings. Gains `.active` highlight once applied.
|
||||||
|
- **Unified controls row on every engine card** — consistent left-to-right order:
|
||||||
|
`[Connect/Disconnect]` `[Stop | Start | Restart]` `[Use as →]`. Docker action buttons
|
||||||
|
hidden until a container name is entered; Use-as button right-aligned.
|
||||||
|
- **`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.
|
||||||
|
- **Backend refactor — `server.py` (5 560 lines → 43 lines)** — all logic extracted
|
||||||
|
into single-responsibility modules:
|
||||||
|
|
||||||
`server.py` went from **5,560 lines** to a **43-line entry point** that creates the
|
| Package | Module | Responsibility |
|
||||||
FastAPI app, registers routers, and mounts static files. All logic was extracted into
|
|---|---|---|
|
||||||
single-responsibility modules:
|
| `core/` | `constants.py` | Boot-time env defaults, path constants, version, log buffer |
|
||||||
|
| | `registry.py` | TTL-based temp file registry |
|
||||||
|
| | `validation.py` | URL validation, SSRF guard, path safety |
|
||||||
|
| | `docker_client.py` | Raw Unix-socket Docker HTTP client |
|
||||||
|
| | `config.py` | Settings load/save/normalize, backend URL resolution |
|
||||||
|
| | `routing.py` | TTS route rules load/save/resolve, language detection |
|
||||||
|
| | `audio.py` | Audio conversion, normalisation, auto-trim scoring |
|
||||||
|
| | `voice.py` | Voice metadata, backup management, benchmark helpers |
|
||||||
|
| | `presets.py` | Voice Design preset load/save, virtual voice resolution |
|
||||||
|
| | `tts_helpers.py` | TTS request helpers, streaming, per-backend logic |
|
||||||
|
| `routes/` | `admin.py` | Index, favicon, browse-dirs, robots, version |
|
||||||
|
| | `settings.py` | `/api/settings`, routing rules, logs, design presets |
|
||||||
|
| | `library.py` | All voice CRUD, upload, save, normalize, export/import |
|
||||||
|
| | `stt.py` | `/api/transcribe*`, `/api/stt-backends` |
|
||||||
|
| | `sources.py` | Voice scraping, proxy-audio, yt-dlp download |
|
||||||
|
| | `docker.py` | `/api/local-containers/*`, `/api/probe-url` |
|
||||||
|
| | `tts.py` | TTS preview, streaming, voice design, `/v1/*`, backends |
|
||||||
|
| | `conversation.py` | Refine-text, effects, export/import, speak, MCP, conversation |
|
||||||
|
|
||||||
**`core/` — pure utilities (no FastAPI decorators)**
|
`Dockerfile` updated with `COPY core/ core/` and `COPY routes/ routes/`.
|
||||||
|
`docker-compose.yml` updated with `./core:/app/core:ro` and `./routes:/app/routes:ro`.
|
||||||
|
|
||||||
| Module | Responsibility |
|
- **Frontend refactor — `app.js` (8 744 lines → 16 modules)** — split into
|
||||||
|---|---|
|
`static/js/` with `loader.js` loading them sequentially in dependency order:
|
||||||
| `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 |
|
| Module | Lines | Responsibility |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `utils.js` | 364 | `$`, `toast`, `escHtml`, `debounce`, theme, language/flag helpers, searchable picker, tab helpers |
|
| `utils.js` | 364 | Core helpers: `$`, `toast`, `escHtml`, theme, language/flag, picker, tabs |
|
||||||
| `voice-inspector.js` | 397 | 3-pane voice workbench (`selectVoice`, `updateInspector`) |
|
| `voice-inspector.js` | 397 | 3-pane voice workbench |
|
||||||
| `voice-sources.js` | 277 | External voice source scraping UI (`loadGetVoices`, `renderGetVoices`) |
|
| `voice-sources.js` | 277 | External voice source scraping UI |
|
||||||
| `integrations.js` | 211 | Code snippet generation for SillyTavern, Open WebUI, HA, curl, MCP |
|
| `integrations.js` | 211 | Code snippet generation (SillyTavern, Open WebUI, HA, curl, MCP) |
|
||||||
| `routing.js` | 542 | TTS routing rules editor |
|
| `routing.js` | 542 | TTS routing rules editor |
|
||||||
| `settings.js` | 385 | `loadSettings`, `applyAndSaveSettings`, settings panel |
|
| `settings.js` | 385 | `loadSettings`, `applyAndSaveSettings`, settings panel |
|
||||||
| `voice-clone.js` | 774 | WaveSurfer waveform, drop zone, microphone, trim UI, voice design dialog |
|
| `voice-clone.js` | 774 | WaveSurfer, drop zone, mic recording, trim, voice design |
|
||||||
| `voice-library.js` | 2654 | Full voice library: list, row rendering, operations (save, rename, delete, normalize, benchmark) |
|
| `voice-library.js` | 2654 | Full voice library: list, CRUD, benchmark, normalize |
|
||||||
| `tts-preview.js` | 528 | `fetchTtsPreviewBlob`, `createTtsAudioSource`, preview panel |
|
| `tts-preview.js` | 528 | TTS preview, `fetchTtsPreviewBlob` |
|
||||||
| `benchmark.js` | 218 | Batch benchmark section |
|
| `benchmark.js` | 218 | Performance + batch benchmark |
|
||||||
| `stt.js` | 287 | STT→TTS playground, `refreshSttBackends` |
|
| `stt.js` | 287 | STT→TTS playground, `refreshSttBackends` |
|
||||||
| `init.js` | 49 | App bootstrap (calls `loadSettings`, syncs UI state) |
|
| `init.js` | 49 | App bootstrap |
|
||||||
| `engines.js` | 625 | ElevenLabs browser, custom engine cards, Docker container management |
|
| `engines.js` | 625 | ElevenLabs browser, custom engine cards, Docker management |
|
||||||
| `ai-backends.js` | 520 | AI backend cards, LLM snippet collapse, `initStaticDockerManagement`, collapsible cards |
|
| `ai-backends.js` | 520 | AI backend cards, LLM snippets, `initStaticDockerManagement` |
|
||||||
| `generation.js` | 393 | WAV merge, chunked TTS, generation history, playlist, audio effects, LLM refinement |
|
| `generation.js` | 393 | WAV merge, chunked TTS, history, playlist, audio effects |
|
||||||
| `conversation.js` | 520 | Settings logs/about, voices import, conversation playground |
|
| `conversation.js` | 520 | Conversation playground, LLM refinement, import, About |
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **`chrome://flags/…` URL unreadable in mic-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 with inline styles
|
||||||
|
(`background: rgba(0,0,0,.35); color: #fff`) on the `<code>` element, plus a
|
||||||
|
Copy button so users don't need to manually select invisible text.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Earlier history
|
## [1.0.0] — 2026-05-28
|
||||||
|
|
||||||
See `git log` for the full commit history prior to this release.
|
Initial feature-complete release.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Voice library** — clone voices from audio samples; design voices from text
|
||||||
|
descriptions using instruction-based synthesis; benchmark synthesis speed (RTF);
|
||||||
|
normalize loudness; export/import voice packages as ZIP bundles.
|
||||||
|
- **TTS backends** — Qwen3 TTS (Voice Clone, Voice Design, Custom Voice, Streaming),
|
||||||
|
NVIDIA Magpie / Zeroshot / Flow, Kokoro FastAPI, VibeVoice, XTTS v2, ElevenLabs.
|
||||||
|
- **STT backends** — OpenAI Whisper (port 8010), faster-whisper-server, whisper.cpp,
|
||||||
|
Groq Whisper (cloud, free tier), NVIDIA Parakeet ASR. Real transcription probe
|
||||||
|
in health check (not just TCP reachability).
|
||||||
|
- **App Routing** — per-app / per-voice / per-language TTS routing rules with
|
||||||
|
automatic language detection and optional before/after sound effects.
|
||||||
|
- **Conversation Playground** — full STT → LLM → TTS pipeline with real-time SSE
|
||||||
|
streaming, latency stats panel (STT / LLM TTFT / LLM total / TTS / Total), turn
|
||||||
|
history, system prompt, and insecure-context warning.
|
||||||
|
- **Engines section** — LLM / STT / TTS sub-pages; Docker container management
|
||||||
|
(Start / Stop / Restart via Docker socket); custom engine cards; ElevenLabs voice
|
||||||
|
library browser.
|
||||||
|
- **Performance Benchmark** — single-voice and batch benchmark with RTF tracking,
|
||||||
|
sparkline trend, and persistent history.
|
||||||
|
- **Audio effects** — reverb, chorus, delay, compressor, gain, pitch shift
|
||||||
|
(via `pedalboard`).
|
||||||
|
- **Chunked TTS + generation history** — long-text synthesis split into chunks,
|
||||||
|
per-chunk playback, playlist export as WAV.
|
||||||
|
- **MCP server** — built-in JSON-RPC 2.0 endpoint at `/mcp`; tools: `speak`,
|
||||||
|
`transcribe`, `list_captures`, `list_profiles`.
|
||||||
|
- **LLM refinement & persona rewriting** — clean up STT transcripts or rewrite
|
||||||
|
responses with a chosen persona via any OpenAI-compatible LLM endpoint.
|
||||||
|
- **Connect Apps** — ready-made config snippets for SillyTavern, Open WebUI,
|
||||||
|
Home Assistant, curl, and MCP (`claude mcp add` one-liner).
|
||||||
|
- **Voice sources** — scrape voice assets from Aiartes, Freesound, GitHub, and
|
||||||
|
Google Drive; YouTube download via yt-dlp; quick import directly to library.
|
||||||
|
- **OpenAI-compatible proxy** — `/v1/audio/speech` and `/v1/audio/transcriptions`
|
||||||
|
for drop-in use with Open WebUI, SillyTavern, and Home Assistant.
|
||||||
|
- **Settings** — sub-pages: General, Connections, Playback, Captures, Payloads,
|
||||||
|
Storage, API Keys, Logs, About.
|
||||||
|
- **Voice Design presets** — saved persona templates for instruction-based synthesis;
|
||||||
|
virtual `vd_…` voices usable from external apps without exporting WAV files.
|
||||||
|
- **Multilingual support** — language/flag pickers, per-language preview texts,
|
||||||
|
`LANG_FLAG_DEFAULT` mapping for 16 languages.
|
||||||
|
- **Tags, ratings, and metadata** — per-voice tags with autocomplete, star ratings,
|
||||||
|
gender label, country flag.
|
||||||
|
- **Dark/light theme** — toggle with persistence in `localStorage`.
|
||||||
|
- **Docker socket integration** — Start/Stop/Restart Docker containers from the UI
|
||||||
|
via raw Unix socket HTTP; container health visible in engine cards.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/compare/v1.1.0...HEAD
|
||||||
|
[1.1.0]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/compare/v1.0.0...v1.1.0
|
||||||
|
[1.0.0]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/releases/tag/v1.0.0
|
||||||
|
|||||||
@ -7,6 +7,17 @@ import shutil
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
# ── Version ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def _read_version() -> str:
|
||||||
|
v_file = Path(__file__).parent.parent / "VERSION"
|
||||||
|
try:
|
||||||
|
return v_file.read_text().strip()
|
||||||
|
except Exception:
|
||||||
|
return "0.0.0"
|
||||||
|
|
||||||
|
__version__: str = _read_version()
|
||||||
|
|
||||||
# ── Boot-time defaults ────────────────────────────────────────────────────────
|
# ── Boot-time defaults ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
_VOICES_DIR_DEFAULT = os.environ.get("VOICES_DIR", "/voices")
|
_VOICES_DIR_DEFAULT = os.environ.get("VOICES_DIR", "/voices")
|
||||||
|
|||||||
@ -6,7 +6,7 @@ from pathlib import Path
|
|||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException
|
||||||
from fastapi.responses import FileResponse, PlainTextResponse, Response
|
from fastapi.responses import FileResponse, PlainTextResponse, Response
|
||||||
|
|
||||||
from core.constants import STATIC_DIR
|
from core.constants import STATIC_DIR, __version__
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -47,6 +47,11 @@ async def browse_dirs(path: str = "/"):
|
|||||||
return {"path": str(p), "parent": parent, "dirs": entries}
|
return {"path": str(p), "parent": parent, "dirs": entries}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/api/version")
|
||||||
|
async def get_version():
|
||||||
|
return {"version": __version__}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/robots.txt", response_class=PlainTextResponse)
|
@router.get("/robots.txt", response_class=PlainTextResponse)
|
||||||
async def robots_txt():
|
async def robots_txt():
|
||||||
return "User-agent: *\nDisallow: /"
|
return "User-agent: *\nDisallow: /"
|
||||||
|
|||||||
@ -61,6 +61,15 @@ document.querySelectorAll('.s-log-filter').forEach(btn => {
|
|||||||
|
|
||||||
// ── Settings: About ───────────────────────────────────────────────────────
|
// ── Settings: About ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
// Fetch and display the server version in the About page
|
||||||
|
(async function loadAppVersion() {
|
||||||
|
try {
|
||||||
|
const d = await fetch('/api/version').then(r => r.json());
|
||||||
|
const el = $('s-about-version');
|
||||||
|
if (el && d.version) el.textContent = 'v' + d.version;
|
||||||
|
} catch (_) {}
|
||||||
|
})();
|
||||||
|
|
||||||
function renderSettingsAbout() {
|
function renderSettingsAbout() {
|
||||||
const el = $('s-about-backends');
|
const el = $('s-about-backends');
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
|
|||||||
@ -511,7 +511,10 @@
|
|||||||
<h3>About</h3>
|
<h3>About</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="s-about-block">
|
<div class="s-about-block">
|
||||||
<div class="s-about-name"><span class="mdi mdi-microphone-variant"></span> TTS Voice Creator</div>
|
<div class="s-about-name">
|
||||||
|
<span class="mdi mdi-microphone-variant"></span> TTS Voice Creator
|
||||||
|
<span id="s-about-version" style="font-size:13px;font-weight:500;color:var(--subtext);margin-left:8px;vertical-align:middle"></span>
|
||||||
|
</div>
|
||||||
<p class="s-about-desc">Clone, design, and deploy custom voices using local AI backends. Compatible with Qwen3-TTS, Kokoro FastAPI, NVIDIA Magpie, and any OpenAI-compatible TTS/STT endpoint.</p>
|
<p class="s-about-desc">Clone, design, and deploy custom voices using local AI backends. Compatible with Qwen3-TTS, Kokoro FastAPI, NVIDIA Magpie, and any OpenAI-compatible TTS/STT endpoint.</p>
|
||||||
<div class="s-about-stack">
|
<div class="s-about-stack">
|
||||||
<span class="s-about-chip"><span class="mdi mdi-language-python"></span> FastAPI</span>
|
<span class="s-about-chip"><span class="mdi mdi-language-python"></span> FastAPI</span>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user