Commit Graph

27 Commits

Author SHA1 Message Date
dd697590ef Back user state with SQLite voice index 2026-06-30 15:06:43 +02:00
bc6c4842b5 Optimize startup and persist engine keys 2026-06-30 14:52:17 +02:00
586dc3dc3f release: v1.12.52 2026-06-30 13:53:08 +02:00
01a2097c5e feat: add Native Speed control to Try it out and Read aloud
Exposes the `speed` parameter (0.5–2.0) on the TTS `/v1/audio/speech`
request so audio is generated at the target tempo natively via the
faster-qwen3-tts backend rather than post-processing.

- Backend: `/api/tts-preview` now extracts and forwards a `speed`
  override (clamped 0.1–4.0) through the same extra-params mechanism
  already used for seed/temperature; backends that reject it fall back
  cleanly via `_post_tts_with_fallback`.
- Try it out: "Native Speed" number input (0.5–2, step 0.05) added to
  the text card; value persists in localStorage per browser; passed as
  `extra` through `createTtsAudioSource` and `generateChunkedTts`.
- Read aloud: "Native Speed" control added to the generation controls
  row alongside seed/temperature; included in `readerGenParams()` and
  saved/restored with library documents (each book tracks its own speed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:01:08 +02:00
495550bf6a Release v1.9.0 — Character Library + richer character sheets
Add a persistent, book-scoped Character Library (new Characters section,
IndexedDB) that auto-fills from Character-sheet analysis with editable cards.
Enrich extraction with six narrative fields (backstory, relationships,
motivation, fears, mannerisms, voice/speech) plus the greyscale Good↔Evil
alignment bar, arc arrow, and 5-area Deep Analysis. Add ⋯ separators between
non-contiguous passages in Recast unknown, and harden dialogue attribution
against hallucination with same-language emotion tags.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 21:22:40 +02:00
18b4c1959c Release v1.8.1 2026-06-25 18:48:42 +02:00
f82a2cfb6a chore: Commit all pending local changes 2026-06-22 14:59:37 +02:00
88c74ab826 feat: persistent seed pinning and batch seeds 2026-06-22 10:43:56 +02:00
36437478a6 feat: Read Aloud reader, multi-voice audiobook casting, character sheets (v1.7.0)
Read Aloud (new "Vorlesen" tab):
- PDF (real page render + overlay highlight) / TXT reader with live word
  highlighting, voice + speed, per-sentence synthesis-state colours, zoom
  (fit-width/height, two-page, ±), resume, and a server-side book library
  (syncs across devices; per-unit MP3 audio fetched on demand).

Book -> multi-speaker audiobook:
- "Cast as audiobook" attributes dialogue to characters via the LLM
  (guillemet/quote-style aware, turn-taking, recent-context), with a
  deterministic speech-tag fallback. Editable preview, non-blocking live
  casting panel, then auto-saved as a reopenable Script Rehearser play.
- Audiobook export: synthesise every cast line -> one MP3 per chapter.

Character sheets:
- LLM-extracted, self-filling RPG-style sheets (with page+quote sources)
  in both Read Aloud and the Rehearser.

Also: MP3 storage + per-page/sentence export, voice-library "Precompute
embeddings" pre-warm, German "Vorlesen" i18n + flag language toggle,
large-PDF performance (lazy raster, buffer/canvas eviction, yielded parse),
and the Seed Finder changelog entry.

New: routes/reader.py, POST /api/attribute-dialogue, POST /api/character-sheets,
static/js/{reader,audiobook,character-sheets}.js, static/sections/s-reader.html.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 15:08:46 +02:00
fff6e7e096 feat: add Seed Finder panel to voice inspector
Adds a collapsible "🎲 Seed Finder" panel to the voice inspector pane.
Select a voice, expand the panel, set a seed range (default 1–15), and
click Run to generate audio samples with different seeds.

Each result row has Play and "Use this seed" buttons. "Use this seed"
saves the chosen seed to the faster-qwen3-tts voices.json via the new
/api/tts-voice-seed proxy endpoint (which calls /voice-seed on the TTS
server). The saved row gets a ✓ marker.

Test sentence auto-selects DE/EN mixed or EN-only based on voice name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 14:53:51 +02:00
8ce84e5523 Fix voice_clone/streaming backends and POST /v1/audio/voices (port from -1 repo)
- voice_clone and streaming now return active library voices instead of
  probing upstream /v1/models (which only exposed 8 model entries)
- Accept POST on /v1/audio/voices for clients that probe with POST
- Fall back to first active voice when voice field missing in /v1/audio/speech

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 02:23:43 +02:00
f469d428e2 Persist section reloads and reuse voice samples 2026-06-05 15:07:09 +02:00
2547619998 Refine benchmark tabs and model pickers 2026-06-05 14:44:30 +02:00
10a11132c0 Add benchmark mode tabs 2026-06-05 14:16:35 +02:00
9c2e507ccf Improve voice workflows and add user manual 2026-06-04 08:23:18 +02:00
40e42590cc Release v1.6.0: a11y (WCAG AA), i18n (DE), PWA, perf, tests, Cast UX
Cast: card/list views, sort & filter, online voice picker, "Hear a line"
sample button, AI character notes, import auto-save.

Platform: WCAG 2.1 AA accessibility pass; German UI translation + language
picker; installable PWA with offline shell; GZip + content-visibility
virtualization + lazy images + Rehearser PCM memory cap (mobile stability);
Playwright suite (desktop + iPhone); opt-in minified bundle build.

Fixes: screenplay parser false characters; Fish-Speech inline-tag tones;
narrator/voice pickers list full library; clone GUI rework; fish.audio
import dedup; voice-ID rename; bulk-delete modal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 14:23:35 +02:00
d99395480a Add Script Rehearser; clean Connect Apps; About changelog; rework Try It Out
## Script Rehearser (new feature)
- New section s-rehearser.html + rehearser.js + nav/loader wiring
- Phase 1: paste/upload script (.txt), auto-detect characters from
  'CHARACTER: dialog' or ALL-CAPS screenplay format
- Phase 2: assign a TTS voice per character, or mark 'I play this'
- Phase 3: step-through rehearsal — synthesizes other characters via TTS,
  shows level-meter + oscilloscope for your own lines, records them from mic
- Phase 4: session summary with per-line audio playback + download

## Connect Apps
- Removed duplicate standalone MCP/speak/hotkey full-width cards
- Kept the integration-grid cards (they use the real server URL from JS)
- Added Global Hotkey Daemon as a proper integration card with snippet-hotkey
  populated by integrations.js (uses proxyBase URL dynamically)

## About page
- GET /api/changelog endpoint reads CHANGELOG.md and returns it as text
- Collapsible 'Changelog' <details> card fetches and displays it lazily

## Try It Out
- Reorganised into three cards: Voice & backend / Text to synthesize / Generate
- Backend help panel moved below the voice row (not in the same flex row)
- Style instruction field gains a dynamic badge ('style-aware ✓' / 'weak style')
  and a yellow warning when a non-style-aware backend is selected while the
  field is filled — wired to both backend-select change and input events

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 20:09:59 +02:00
bf458283af Show spoken sentence in typing bubble; fix VAD noise sensitivity
Sentence text in typing bubble:
- Backend sends 'text' field with each audio SSE event (the sentence
  being synthesised)
- Frontend audio queue stores {url, text} pairs
- playNextAudio() writes the sentence text into the '...' typing bubble
  when LLM tokens haven't arrived yet (convCurrentSentenceBubble)
- convCurrentSentenceBubble cleared as soon as first LLM token arrives
  so normal streaming takes over seamlessly

VAD noise fixes:
- VAD_THRESHOLD: 0.01 → 0.02 (background noise no longer counts as speech)
- VAD_MIN_REC_MS: 400 → 800ms (8/10s wait before silence detection starts,
  gives user time to begin speaking without initial noise triggering send)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 20:50:44 +02:00
13c79768b4 Fix speech gate, hallucination filter, and latency
Speech gate (silence detection):
- vadHadSpeech flag: VAD auto-stop cancels without calling STT when no
  speech was detected (fixes "[STT] No speech detected → gibberish" loop)
- cancelNextBlob flag: onstop skips processBlob when VAD cancels silently
- vadLastVoiceMs: gates preview transcription on actual detected speech
  (prevents "reich" hallucination on initial silence chunks)

Hallucination filter:
- Client: HALLUCINATION_RE strips known Whisper phantoms from preview
- Server: _is_hallucination() in generate() treats "reich" / "danke" /
  "thank you" etc. as "No speech detected" → never reaches LLM

Latency:
- VAD_SILENCE_MS: 1500 → 1000 ms (sends 500 ms sooner per turn)
- VAD_MIN_REC_MS: 500 → 400 ms
- MediaRecorder timeslice: 2500 → 1500 ms (preview text updates faster)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 20:38:53 +02:00
34870fed27 Pipeline TTS with LLM streaming for lower latency
Replace serial LLM-wait-TTS with overlapped execution:
- LLM streams via background thread → asyncio.Queue (non-blocking event loop)
- _sentence_split() detects sentence boundaries in the token stream
- asyncio.create_task fires TTS for each sentence immediately — TTS for
  sentence 1 runs while LLM is still generating sentences 2, 3, …
- Audio chunks stream to frontend in order as each task completes
- Time-to-first-audio drops from (LLM total + TTS total) to
  roughly (LLM time-to-first-sentence + TTS latency for one sentence)

Frontend audio queue:
- enqueueAudio() / playNextAudio() chain multi-chunk responses seamlessly
- clearAudio() stops playback and cancels queue on new turn or mic click
- scheduleAutoMic() waits for queue to drain before restarting mic
- Error paths clear the queue to avoid stale audio playing after failure

Also fix missing contextlib import (silent bug when audio temp files
needed cleanup in the STT path).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 19:06:07 +02:00
b33829ded5 Add skeleton loading, self-host assets, fix LLM empty response
Perceived startup speed:
- index.html: animated shimmer skeleton (header + toolbar + 8 voice cards)
  visible immediately; fades out when loader.js finishes
- WaveSurfer (57KB) and MDI icon font (394KB woff2) now served from
  static/vendor/ — removes 3 render-blocking external requests from <head>
- Flag-icons CSS loaded async (rel=preload onload trick) — non-blocking

loader.js:
- Fade out skeleton + remove from DOM (300ms transition)
- Reveal page-sections after JS finishes loading

Conversation playground:
- Qwen3 thinking mode fix: fall back to delta.reasoning_content when
  delta.content is empty so think-only LLM turns produce visible output
- Better error message with /no-think hint when LLM returns empty

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 17:28:42 +02:00
686fd61865 Fix NameError: restore File import removed during 422 fix 2026-05-29 14:59:46 +02:00
1474bf1c7d Fix ImportError: _AUDIO_EXTS imported from wrong module in routes/stt.py
_AUDIO_EXTS lives in core.voice, not core.audio. The dead alias
'_VOICE_AUDIO_EXTS' was never used anywhere in the file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 14:57:06 +02:00
b3a408bfd9 Fix 422 on text-only conversation turns
UploadFile | None = File(None) with from __future__ import annotations
caused FastAPI to still treat audio as required when omitted.
Changed to Optional[UploadFile] = None (no File() wrapper) so the
field is genuinely optional for text-input turns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 14:30:06 +02:00
db6302f99d 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>
2026-05-29 13:53:31 +02:00
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
c7a1e35539 Security audit, modular refactor, and container-name field
Security fixes:
- Block /proc /sys /dev /run /boot in /api/browse-dirs (path traversal)
- Verify yt-dlp output stays inside TEMP_DIR before registration
- Remove Access-Control-Allow-Origin: * from /api/proxy-audio
- TTL-based temp file registry (default 2h) to prevent disk fill

Performance:
- Cache settings + routing rules in memory (mtime-checked); eliminates
  per-request disk reads on every TTS call

UI:
- Add container name (optional) field to Docker stack TTS/STT engine
  cards (Qwen3 Voice Clone, Voice Design, Custom Voice, Streaming,
  NVIDIA Magpie, Parakeet) — enables Stop/Start/Restart buttons on
  all engine cards, matching the existing Other Local TTS/STT cards

Refactor — backend:
- server.py: 5560 lines → 43-line entry point
- core/ package: constants, registry, validation, docker_client,
  config, routing, audio, voice, presets, tts_helpers
- routes/ package: admin, settings, library, stt, sources, docker,
  tts, conversation (FastAPI APIRouter modules)
- Dockerfile + docker-compose.yml updated to include core/ and routes/

Refactor — frontend:
- static/app.js: 8744 lines → 16 modules in static/js/
  utils, voice-inspector, voice-sources, integrations, routing,
  settings, voice-clone, voice-library, tts-preview, benchmark,
  stt, init, engines, ai-backends, generation, conversation
- static/loader.js updated to load modules sequentially

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