first commit
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
"""Тест Модуля 5: горячие клавиши + машина состояний = ЖИВОЙ ассистент.
|
||||
|
||||
Запуск:
|
||||
python modules/assistant/test_assistant.py # console-бэкенд (Linux, без root)
|
||||
python modules/assistant/test_assistant.py --backend keys # глобальные клавиши (Windows; Linux — root)
|
||||
|
||||
Консольный режим (имитация трёх клавиш):
|
||||
Enter — нажать «Слушай» (первый раз), отпустить (второй раз) — аналог удержания
|
||||
s + Enter — «Замолчи»
|
||||
r + Enter — «Повтори»
|
||||
q + Enter — выход
|
||||
|
||||
Критерии приёмки Модуля 5:
|
||||
1. Пустой вопрос: Enter → молчание → Enter → «Слишком коротко».
|
||||
2. Обычный цикл: Enter → вопрос → Enter → ответ голосом (диалог помнит контекст).
|
||||
3. «Замолчи» во время речи — звук стихает мгновенно (цель < 100 мс).
|
||||
4. «Повтори» — последняя фраза звучит снова.
|
||||
5. Нажать «Слушай» ВО ВРЕМЯ речи — речь стихла, запись началась.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from modules.assistant import Assistant
|
||||
from modules.audio_io import Player, Recorder
|
||||
from modules.brain import get_provider as get_brain
|
||||
from modules.hotkeys import KeyEvents, get_backend
|
||||
from modules.stt import get_provider as get_stt
|
||||
from modules.tts import make_tts
|
||||
except ImportError:
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
|
||||
from modules.assistant import Assistant
|
||||
from modules.audio_io import Player, Recorder
|
||||
from modules.brain import get_provider as get_brain
|
||||
from modules.hotkeys import KeyEvents, get_backend
|
||||
from modules.stt import get_provider as get_stt
|
||||
from modules.tts import make_tts
|
||||
|
||||
STATES_RU = {
|
||||
"idle": "⏸ ожидание",
|
||||
"listening": "🎙 слушаю",
|
||||
"thinking": "🧠 думаю…",
|
||||
"speaking": "🔊 говорю",
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Живой ассистент (Модуль 5)")
|
||||
parser.add_argument("--backend", default="console", choices=["console", "keys"])
|
||||
parser.add_argument("--stt-model", default="small")
|
||||
args = parser.parse_args()
|
||||
|
||||
print("Загружаю модули…")
|
||||
stt = get_stt("faster-whisper", model_size=args.stt_model)
|
||||
brain = get_brain("openrouter") # модель из .env
|
||||
tts = make_tts() # провайдер/скорость из .env (TTS_PROVIDER, TTS_RATE)
|
||||
recorder = Recorder()
|
||||
player = Player()
|
||||
|
||||
def on_state(state: str, note: str) -> None:
|
||||
line = STATES_RU.get(state, state)
|
||||
print(f"\n[{line}]" + (f" {note}" if note else ""))
|
||||
|
||||
assistant = Assistant(stt, brain, tts, recorder, player, on_state_change=on_state)
|
||||
|
||||
quit_event = threading.Event()
|
||||
|
||||
events = KeyEvents(
|
||||
on_talk_down=assistant.on_talk_down,
|
||||
on_talk_up=assistant.on_talk_up,
|
||||
on_stop=assistant.on_stop,
|
||||
on_repeat=assistant.on_repeat,
|
||||
on_quit=lambda: quit_event.set(),
|
||||
)
|
||||
|
||||
if args.backend == "keys":
|
||||
print("\nГлобальные клавиши: «Слушай» = space (удерживать), "
|
||||
"«Замолчи» = esc, «Повтори» = enter. Ctrl+C — выход.")
|
||||
print("(На Linux этот режим требует root: sudo -E .venv/bin/python …)")
|
||||
else:
|
||||
print("\nКонсольные клавиши (имитация удержания):")
|
||||
print(" Enter — нажать «Слушай», ещё Enter — отпустить (начать обработку)")
|
||||
print(" s + Enter — «Замолчи» | r + Enter — «Повтори» | q + Enter — выход")
|
||||
|
||||
backend = get_backend(args.backend, events)
|
||||
backend.start()
|
||||
|
||||
try:
|
||||
while not quit_event.wait(timeout=0.2):
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
print("\n(Ctrl+C)")
|
||||
finally:
|
||||
backend.stop()
|
||||
try:
|
||||
player.stop() # тишина при выходе
|
||||
except Exception:
|
||||
pass
|
||||
print("Выход.")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user