- say/Default erkennt den Daemon via GET /status: enqueue + sofort zurück (stdout = Item-ID), --wait pollt bis zur Fertigstellung, --now springt vor - mute/unmute/status/cancel mit plain Output; mute/unmute schreiben ohne Daemon die Mute-Datei direkt (gleiche Quelle, wirkt sofort im Daemon) - Degraded Mode: Lock-Datei talk.lock im Config-Dir (Kollision = warten, verwaist nach 60 s), sequenzielles lokales Abspielen, mute respektiert - Handler-Signatur der Befehlstabelle erhält stdout (say/Steuer-Befehle geben Ergebnisse aus); --priority wird validiert
talk
Status: WIP — aktive Entwicklung (talk 2.0). Binde Spezifikation:
.scratch/talk-2-0/spec.md· Implementierungsplan:.scratch/talk-2-0/plan.md
talk macht Skripte und KI-Agenten hörbar: Ein Aufruf — talk "Build fertig" —
spricht eine kurze Nachricht über eine TTS-Provider-Kette
(ElevenLabs → OpenAI → Edge-TTS → OS-Stimme), serialisiert durch den Daemon
talkd. Cross-platform (Windows/macOS/Linux, amd64/arm64), statische Binaries,
keine Runtime-Abhängigkeiten.
Befehle
| Befehl | Zweck |
|---|---|
talk "Text" |
Ansage — Abkürzung für talk say, non-blocking |
talk say "Text" |
Ansage (Text als Argument oder von stdin) |
talk wrap -- <Befehl> |
Befehl ausführen, Erfolg/Misserfolg + Dauer ansagen |
talk mute / talk unmute |
Ansagen dauerhaft stummschalten / Stummschaltung aufheben |
talk status |
Daemon-Status (Queue, Mute, Provider, Version) |
talk cancel |
laufende und geplante Ansagen abbrechen |
talk voices |
verfügbare Stimmen anzeigen |
talk test |
Test-Ansage ausgeben |
talk doctor |
Selbstdiagnose des Setups |
talk setup |
geführte Ersteinrichtung (Wizard) |
Say-Flags (gelten auch für talk "Text"): --wait, --now, --priority,
--voice, --lang, --provider.
Hinweis: In diesem Stand ist say (und der Default-Aufruf
talk "Text") implementiert — inklusive der kompletten Provider-Kette
(ElevenLabs → OpenAI → Edge-TTS → OS-Stimme, blockierend;
Daemon-Anbindung folgt). Alle anderen Befehle sind Stubs und melden
not implemented yet (Exit-Code ≠ 0).
Provider-Kette (Task 03)
Ohne Pin läuft die Vier-Stufen-Fallback-Kette
ElevenLabs → OpenAI TTS → Edge-TTS → OS built-in: Bei fehlendem Key,
HTTP-Fehler, Timeout oder Netz-Problem fällt die Kette automatisch auf die
nächste Stufe; jeder Fallback wird auf stderr protokolliert (nie still).
Pinnen per --provider=<name> oder provider = "<name>" in der
config.toml.
| Stufe | Key (Env) | Default-Endpunkt | Audio |
|---|---|---|---|
elevenlabs |
TALK_ELEVENLABS_KEY |
https://api.elevenlabs.io |
mp3 |
openai |
TALK_OPENAI_KEY |
https://api.openai.com |
mp3 |
edge |
— (kostenlos) | wss://speech.platform.bing.com/... |
mp3 |
osbuiltin |
— | lokale OS-TTS | WAV/PCM |
Keys laufen ausschließlich über Env-Variablen (nie in die config.toml).
Endpunkte sind konfigurierbar — Datei [providers.<name>] endpoint = "…"
bzw. Env TALK_ELEVENLABS_ENDPOINT / TALK_OPENAI_ENDPOINT /
TALK_EDGE_ENDPOINT (Env schlägt Datei; so zeigen Tests/CI die Kette auf
Fake-Server). Das OpenAI-Modell ist konfigurierbar
([providers.openai] model, Default tts-1).
Stimmen: neutralen Repo-Defaults je Provider+Sprache (ElevenLabs
„Rachel", OpenAI „alloy", Edge de-DE-KatjaNeural/en-US-AriaNeural)
kann man pro Sprache überordnen — config.toml:
[voice.elevenlabs]
de = "21m00Tcm4TlvDq8ikWAM" # eigene Stimme je Sprache
en = "21m00Tcm4TlvDq8ikWAM"
[voice.edge]
de = "de-DE-KatjaNeural"
Rangfolge: --voice-Flag > voice.<provider>.<lang> > Repo-Default.
MP3 wird von der Binärdatei selbst dekodiert (reiner Go-Dekoder, kein
ffmpeg, CGO-frei).
OS-TTS auf Linux (Dev-Abhängigkeit espeak)
Der OS-Provider osbuiltin nutzt auf Linux zwei Wege:
- Audio-Bytes (Wiedergabe über den eingebauten oto-Sink): benötigt
espeak(oderespeak-ng). Auf NixOS als Dev-Abhängigkeit:nix shell nixpkgs#espeak-ng. - Direktansage ohne espeak:
spd-say(speech-dispatcher) — spielt selbst über den Daemon ab, kann aber nachspd-say --helpkeine Bytes in Dateien/Pipes liefern.talknutzt diesen Weg automatisch, wenn kein espeak vorhanden ist.
TALK_AUDIO_SINK=null (oder audio.sink = "null" in der config.toml)
schaltet jede Tongabe ab — für CI und Server.
Entwicklung
go build ./... # bauen
go test ./... # Tests
go vet ./... # statische Analyse
gofmt -l . # Formatierung prüfen (leerer Output = ok)
CI: .gitea/workflows/test.yml (Gitea Actions) läuft vet, gofmt-Check, Tests
und Build bei jedem Push und Pull Request.
Lizenz
MIT — siehe LICENSE.