feat: Audio-Streaming als Default (Admin abschaltbar via AUDIO_STREAM_DEFAULT)

- Config audio_stream_default=True; _run_turn nutzt es, wenn die Anfrage audio_stream
  nicht explizit setzt (explizite Anfrage gewinnt)
- voice_loop: immer durchgehender Player (spielt 1 oder N Haeppchen luekenlos);
  --stream-audio / --no-stream-audio als Tri-State (sonst entscheidet der Server-Default)
- conftest: audio_stream_default=False fuer deterministische Tests; neuer Test fuer
  Default-an-Streaming ueber /ws/voice; 67 Tests gruen
- Doku + .env.example aktualisiert (AUDIO_STREAM_DEFAULT, --no-stream-audio)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-17 18:07:36 +02:00
commit 7c1f00662c
7 changed files with 52 additions and 28 deletions

View file

@ -136,6 +136,19 @@ def test_ws_voice_stream_text_emits_token_events(monkeypatch):
assert ws.receive_json()["type"] == "token" # Antworttext kommt als token-Event(e)
def test_ws_voice_audio_stream_default_on(monkeypatch):
# Server-Default an -> Audio wird gestreamt, auch ohne expliziten audio_stream-Flag.
monkeypatch.setattr(settings, "audio_stream_default", True)
opts = _install_voice_stubs(monkeypatch)
with client.websocket_connect("/ws/voice") as ws:
ws.send_json({"type": "start", "format": "wav", **opts}) # kein audio_stream gesetzt
ws.send_bytes(b"PCMDATA")
ws.send_json({"type": "end"})
assert ws.receive_json()["type"] == "transcript"
assert ws.receive_json()["type"] == "ack"
assert ws.receive_json()["type"] == "audio" # Audio VOR semantic -> Streaming aktiv
def test_ws_voice_empty_buffer_errors(monkeypatch):
opts = _install_voice_stubs(monkeypatch)
with client.websocket_connect("/ws/voice") as ws: