Update assistant features and docs

This commit is contained in:
2026-02-12 14:12:37 +03:00
parent bb3133a1c0
commit ca8ebd6657
19 changed files with 814 additions and 180 deletions

View File

@@ -53,8 +53,9 @@ from .core.config import BASE_DIR
from .core.cleaner import clean_response
from .core.commands import is_stop_command
from .core.smalltalk import get_smalltalk_response
from .features.alarm import get_alarm_clock
from .features.timer import get_timer_manager
from .features.alarm import ASK_ALARM_TIME_PROMPT, get_alarm_clock
from .features.stopwatch import get_stopwatch_manager
from .features.timer import ASK_TIMER_TIME_PROMPT, get_timer_manager
from .features.weather import get_weather_report
from .features.music import get_music_controller
from .features.cities_game import get_cities_game
@@ -256,6 +257,7 @@ def main():
get_recognizer().initialize() # Подключение к Deepgram
init_tts() # Загрузка нейросети для синтеза речи (Silero)
alarm_clock = get_alarm_clock() # Загрузка будильников
stopwatch_manager = get_stopwatch_manager() # Загрузка секундомеров
timer_manager = get_timer_manager() # Загрузка таймеров
cities_game = get_cities_game() # Игра "Города"
print()
@@ -270,6 +272,10 @@ def main():
# (True = режим диалога, слушаем сразу. False = ждем "Alexandr")
skip_wakeword = False
# Контекст уточнения "на какое время поставить ...".
# Может быть: "timer", "alarm".
pending_time_target = None
# Переменная для отслеживания последней проверки здоровья STT
last_stt_check = time.time()
@@ -314,9 +320,10 @@ def main():
if ding_sound:
ding_sound.play()
# Фраза услышана! Слушаем команду пользователя (5 секунд тишины макс)
# Фраза активации услышана:
# до 5с ждём начало речи, после начала завершаем STT по 3с тишины.
try:
user_text = listen(timeout_seconds=5.0)
user_text = listen(timeout_seconds=5.0, fast_stop=True)
except Exception as e:
print(f"Ошибка при прослушивании: {e}")
print("Переинициализация STT...")
@@ -328,10 +335,12 @@ def main():
continue # Продолжаем цикл
else:
# Режим диалога (Follow-up): ждем продолжения речи без "Alexandr"
print("👂 Слушаю продолжение диалога (3 сек)...")
# Ждем начала речи 3 сек. Если начали говорить, слушаем до 7 сек.
print("👂 Слушаю продолжение диалога (5 сек)...")
# Ждем начала речи 5 сек. Если начали говорить, слушаем до 7 сек.
try:
user_text = listen(timeout_seconds=7.0, detection_timeout=3.0)
user_text = listen(
timeout_seconds=7.0, detection_timeout=5.0, fast_stop=True
)
except Exception as e:
print(f"Ошибка при прослушивании: {e}")
print("Переинициализация STT...")
@@ -350,13 +359,21 @@ def main():
# --- Шаг 2: Анализ распознанного текста ---
if not user_text:
# Была активация, но речь не распознана
speak("Извините, я вас не расслышал. Попробуйте ещё раз.")
skip_wakeword = False # Возвращаемся в режим ожидания имени
# Пустой ввод: без лишних ответов возвращаемся к ожиданию wake word.
skip_wakeword = False
continue
# Проверка на команду "Стоп"
if is_stop_command(user_text):
if stopwatch_manager.has_running_stopwatches():
stopwatch_stop_response = stopwatch_manager.pause_stopwatches()
clean_stopwatch_stop_response = clean_response(
stopwatch_stop_response, language="ru"
)
speak(clean_stopwatch_stop_response)
last_response = clean_stopwatch_stop_response
skip_wakeword = False
continue
print("_" * 50)
print("💤 Жду 'Alexandr' для активации...")
skip_wakeword = False
@@ -387,24 +404,52 @@ def main():
skip_wakeword = True
continue
command_text = user_text
command_text_lower = command_text.lower()
if pending_time_target == "timer" and "таймер" not in command_text_lower:
command_text = f"таймер {command_text}"
elif (
pending_time_target == "alarm"
and "будильник" not in command_text_lower
and "разбуди" not in command_text_lower
):
command_text = f"будильник {command_text}"
# Проверка команд таймера ("поставь таймер на 6 минут")
timer_response = timer_manager.parse_command(user_text)
stopwatch_response = stopwatch_manager.parse_command(command_text)
if stopwatch_response:
clean_stopwatch_response = clean_response(
stopwatch_response, language="ru"
)
speak(clean_stopwatch_response)
last_response = clean_stopwatch_response
skip_wakeword = True
continue
# Проверка команд таймера ("поставь таймер на 6 минут")
timer_response = timer_manager.parse_command(command_text)
if timer_response:
clean_timer_response = clean_response(timer_response, language="ru")
completed = speak(
clean_timer_response, check_interrupt=check_wakeword_once
)
last_response = clean_timer_response
pending_time_target = (
"timer" if timer_response == ASK_TIMER_TIME_PROMPT else None
)
skip_wakeword = not completed
continue
# Проверка команд будильника ("поставь будильник на 7")
alarm_response = alarm_clock.parse_command(user_text)
alarm_response = alarm_clock.parse_command(command_text)
if alarm_response:
clean_alarm_response = clean_response(alarm_response, language="ru")
speak(clean_alarm_response)
last_response = clean_alarm_response
skip_wakeword = False
pending_time_target = (
"alarm" if alarm_response == ASK_ALARM_TIME_PROMPT else None
)
skip_wakeword = alarm_response == ASK_ALARM_TIME_PROMPT
continue
# Проверка команды громкости ("громкость 5")