Files
mrleo1nidandClaude Opus 5 04029f3750 Этап 8: настраиваемые команды
- commands.yaml с рабочими примерами: медиа, громкость, поиск, папки, блокировка;
  перечитывается автоматически, ошибки не ломают остальные команды
- Действия run / open / http / keys; вывод и ответы возвращаются модели
- Вызов через модель (tool calling) и мгновенно по точным фразам, в том числе с параметрами
- Подтверждение «да/нет» для опасных команд, после голосового вопроса микрофон включается сам
- Безопасность: запуск без оболочки, защита аргументов cmd/PowerShell/.bat,
  переменные окружения раскрываются только в шаблоне
- Вкладка «Команды» в настройках
- Тесты разбора, действий, фраз и полных сценариев через Assistant

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 04:38:57 +03:00

49 lines
1.9 KiB
Python

from agr_assistent.commands.matching import confirmation_decision, match_phrase, normalize
from agr_assistent.commands.model import parse_command
_COMMANDS = [
parse_command(
{
"name": "pause",
"description": "Пауза",
"phrases": ["Поставь на паузу", "пауза"],
"action": {"type": "keys", "keys": "media_play_pause"},
}
),
parse_command(
{
"name": "volume",
"description": "Громкость",
"phrases": ["громкость {level} процентов", "громкость {level}"],
"parameters": {"level": {"type": "integer", "minimum": 0, "maximum": 100}},
"action": {"type": "keys", "keys": "volume_up"},
}
),
]
def test_normalize() -> None:
assert normalize(" Ещё, пожалуйста!! ") == "еще пожалуйста"
def test_whole_phrase_must_match() -> None:
assert match_phrase(_COMMANDS, "Пауза.")[0].name == "pause"
assert match_phrase(_COMMANDS, "поставь на паузу")[0].name == "pause"
assert match_phrase(_COMMANDS, "пауза в работе") is None
assert match_phrase(_COMMANDS, "") is None
def test_phrase_parameters_are_validated() -> None:
command, arguments = match_phrase(_COMMANDS, "Громкость 30 процентов")
assert command.name == "volume" and arguments == {"level": 30}
assert match_phrase(_COMMANDS, "громкость 30")[1] == {"level": 30}
assert match_phrase(_COMMANDS, "громкость 300") is None
assert match_phrase(_COMMANDS, "громкость много") is None
def test_confirmation_decision() -> None:
assert confirmation_decision("Да!") is True
assert confirmation_decision("не надо") is False
assert confirmation_decision("да, но сначала сохрани файл") is None