v2 - STT via Whisper for more precision and if nor available, twist to Vox

This commit is contained in:
pporcheret
2026-10-27 16:44:39 +01:00
parent 5ccb0a48c2
commit 5f82b1bdf2
49 changed files with 4667 additions and 329 deletions
+26
View File
@@ -8,6 +8,8 @@ from services.audio import listen_once, speak_async, tts_backend_detect
from services.wakeword import WakeWordListener
from services import admin_console # ALFRED_ADMIN_PAGES_V1
from services.hermes_client import ask_hermes
from services import alfred_timers, alfred_context_images # ALFRED_TIMERS_CONTEXT_V1
from services import alfred_features # ALFRED_FEATURES_V45
from services import audio_settings # ALFRED_AUDIO_SETTINGS_V1
from services.camera import video_stream
from services import ha_views, alfred_views_controller
@@ -29,6 +31,8 @@ STATE_LOCK = threading.RLock()
IMAGE_REVISION = 0 # Incrémenté à chaque image envoyée par ComfyUI.
conversation_lock=threading.Lock()
mic_stop_event=threading.Event()
# Service temps autonome (survit aux conversations Hermes)
alfred_timer_store = alfred_timers.register(app, socketio, speak_async, audio_settings) # ALFRED_TIMERS_CONTEXT_V1
audio_settings.initialize()
audio_settings.update_settings({"mic_gain": 30})
# Recharge les réglages V4L2 enregistrés, sans interrompre Alfred si la webcam est absente.
@@ -107,6 +111,17 @@ def conversation(score=1.0):
# ComfyUI publie l'image pendant cet appel Hermes.
with STATE_LOCK:
image_revision_before = IMAGE_REVISION
# ALFRED_FEATURES_V45 voice opt-in background mode
if alfred_features.should_run_in_background(r.text):
try:
alfred_features.submit(r.text, source='voice')
emit_state('idle', partial='', content={
'type': 'text',
'text': 'Hermes travaille sur la demande. Le résultat apparaîtra dans les cartes.'
})
except ValueError as exc:
emit_state('error', content={'type': 'text', 'text': str(exc)})
return
answer = ask_hermes(r.text)
print(f"[ALFRED] Réponse Hermes : {answer!r}", flush=True)
if isinstance(answer, dict):
@@ -119,11 +134,19 @@ def conversation(score=1.0):
speech = str(answer or "")
display = {"type": "text", "text": speech}
# Une illustration contextuelle (Wikipédia) peut compléter la réponse Hermes.
# Elle n'interrompt pas la lecture TTS et ne remplace pas la scène centrale.
alfred_context_images.schedule_context_image(
r.text, speech, socketio,
lambda: STATE.get("transcript") == r.text,
) # ALFRED_TIMERS_CONTEXT_V1
# Si le MCP ComfyUI a affiché une image pendant la requête,
# ne pas l'écraser par la réponse textuelle d'Hermes.
with STATE_LOCK:
if IMAGE_REVISION == image_revision_before:
STATE["content"] = display
alfred_features.publish_voice_display(display)
socketio.emit("alfred_render", display)
else:
print("[ALFRED] Image ComfyUI conservée à l'écran", flush=True)
@@ -233,6 +256,9 @@ def camera_stream():
headers={'Cache-Control': 'no-store', 'X-Content-Type-Options': 'nosniff'}
)
# ALFRED_FEATURES_V45 init
alfred_features.init_app(app, ask_hermes, socketio=socketio)
@app.get("/")
def index(): return render_template("index.html",name=os.getenv("ALFRED_NAME","Alfred"))
@app.get("/api/state")