Этап 8: настраиваемые команды
- commands.yaml с рабочими примерами: медиа, громкость, поиск, папки, блокировка; перечитывается автоматически, ошибки не ломают остальные команды - Действия run / open / http / keys; вывод и ответы возвращаются модели - Вызов через модель (tool calling) и мгновенно по точным фразам, в том числе с параметрами - Подтверждение «да/нет» для опасных команд, после голосового вопроса микрофон включается сам - Безопасность: запуск без оболочки, защита аргументов cmd/PowerShell/.bat, переменные окружения раскрываются только в шаблоне - Вкладка «Команды» в настройках - Тесты разбора, действий, фраз и полных сценариев через Assistant Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
84d8aaa848
commit
04029f3750
@@ -0,0 +1,48 @@
|
||||
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
|
||||
Reference in New Issue
Block a user