#!/usr/bin/env bash # Que el verde ESCUCHE, y en local. El complemento del 07 (que hable). # # El TUI de Hermes no tiene microfono, y su STT nativo es para notas de voz de # mensajeria —que saldrian de la maquina—. El puente escucha-verde.sh cierra el # hueco con faster-whisper local (el mismo 'small' en espanol que ya declara la # seccion stt: del config.yaml), en CPU para no pelear por la VRAM con el 4B. # # La prueba no necesita microfono: hace un BUCLE. Genera voz con el mismo TTS del # verde (voz-verde.sh, 07), la transcribe con escucha_transcribe.py, y comprueba # que el texto vuelve entero. Si el oido funciona, lo que entro por el altavoz # sale por el transcriptor. cd "$(dirname "$0")" && . ./comun.sh PY=$RAIZ/nucleo/venv/bin/python [ -x "$PY" ] || PY=$(command -v python3) TRANS=$VERDE/escucha_transcribe.py titulo "Las piezas" afirma "existe escucha_transcribe.py" test -f "$TRANS" afirma "existe el puente escucha-verde.sh" test -x "$VERDE/escucha-verde.sh" afirma "faster-whisper importa" "$PY" -c "import faster_whisper" afirma "el TTS del verde existe (para el bucle)" test -x "$VERDE/voz-verde.sh" # quita acentos y baja a minusculas, para comparar sin depender de la tilde _norm() { "$PY" -c "import sys,unicodedata as u; t=u.normalize('NFD',sys.stdin.read().lower()); print(''.join(c for c in t if u.category(c)!='Mn'))"; } titulo "El bucle voz -> texto" # (frase dicha, palabras clave que TIENEN que volver). Se evita 'jarvis' a # proposito: es un nombre raro y whisper lo oye 'harvis'; eso no mide el oido. probar_frase() { local frase=$1 claves=$2 local wav=$TMP/oir.wav txt=$TMP/oir.txt printf '%s' "$frase" > "$txt" rm -f "$wav" "$VERDE/voz-verde.sh" "$wav" "$txt" >/dev/null 2>&1 if [ ! -s "$wav" ]; then echo " $(rojo FALLO) no se genero el WAV para: $frase"; _fallo=$((_fallo+1)); return fi local ini out norm falta="" ini=$(date +%s.%N) out=$(timeout 120 "$PY" "$TRANS" "$wav" 2>/dev/null) local tardo; tardo=$(awk "BEGIN{printf \"%.1f\", $(date +%s.%N) - $ini}") norm=$(printf '%s' "$out" | _norm) local c for c in $claves; do printf '%s' "$norm" | grep -q "$c" || falta="$falta $c" done if [ -z "$falta" ]; then printf ' %s escucho: "%s" (%ss)\n' "$(verde OK)" "$out" "$tardo"; _ok=$((_ok+1)) else printf ' %s faltan [%s] en: "%s"\n' "$(rojo FALLO)" "$falta" "$out"; _fallo=$((_fallo+1)) fi } probar_frase "cuanto espacio libre queda en el disco" "espacio disco" probar_frase "abre el navegador y busca el tiempo en madrid" "navegador tiempo madrid" probar_frase "apaga las luces del salon a las diez" "luces salon" titulo "Local de verdad" # El transcriptor no debe abrir ningun socket a la nube: se comprueba que el # codigo no importa clientes de APIs de STT de pago. if grep -qiE "openai|groq|mistral|requests\.post|urllib.*http" "$TRANS"; then echo " $(rojo FALLO) el transcriptor referencia una API remota"; _fallo=$((_fallo+1)) else echo " $(verde OK) el transcriptor no llama a ninguna API remota"; _ok=$((_ok+1)) fi resumen