Recognize simple device commands in the transcript and act on them without
a Tatlock round-trip. commands.match() maps volume up/down, mute/unmute,
"set volume to N", and "goes to eleven"/max to a "command" message sent
straight to the device; the utterance never reaches the LLM. Matching is
deliberately precise so real requests ("set an alarm for a quarter to
eleven") are not hijacked. Adds the "command" message to the device
protocol in docs/architecture.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKPbR6DY2JygHbyLjxm7Uu
62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
from desklock_gateway import commands
|
|
|
|
|
|
def test_mute_and_unmute() -> None:
|
|
assert commands.match("mute") == {"type": "command", "action": "mute"}
|
|
assert commands.match("mute the volume") == {"type": "command", "action": "mute"}
|
|
# "unmute" contains "mute" — must resolve to unmute
|
|
assert commands.match("unmute") == {"type": "command", "action": "unmute"}
|
|
|
|
|
|
def test_relative_up_down() -> None:
|
|
assert commands.match("volume up") == {"type": "command", "action": "volume_up"}
|
|
assert commands.match("louder please") == {"type": "command", "action": "volume_up"}
|
|
assert commands.match("turn it up") == {"type": "command", "action": "volume_up"}
|
|
assert commands.match("volume down") == {"type": "command", "action": "volume_down"}
|
|
assert commands.match("a bit quieter") == {"type": "command", "action": "volume_down"}
|
|
assert commands.match("turn it down") == {"type": "command", "action": "volume_down"}
|
|
|
|
|
|
def test_set_to_number_digit_and_word() -> None:
|
|
assert commands.match("set volume to 7") == {
|
|
"type": "command",
|
|
"action": "volume_set",
|
|
"level": 7,
|
|
}
|
|
assert commands.match("volume to seven") == {
|
|
"type": "command",
|
|
"action": "volume_set",
|
|
"level": 7,
|
|
}
|
|
assert commands.match("volume 3") == {"type": "command", "action": "volume_set", "level": 3}
|
|
# clamps into 0..11
|
|
assert commands.match("set volume to 50") == {
|
|
"type": "command",
|
|
"action": "volume_set",
|
|
"level": 11,
|
|
}
|
|
|
|
|
|
def test_goes_to_eleven() -> None:
|
|
assert commands.match("this one goes to eleven") == {
|
|
"type": "command",
|
|
"action": "volume_set",
|
|
"level": 11,
|
|
}
|
|
assert commands.match("set volume to eleven") == {
|
|
"type": "command",
|
|
"action": "volume_set",
|
|
"level": 11,
|
|
}
|
|
assert commands.match("crank it") == {"type": "command", "action": "volume_set", "level": 11}
|
|
assert commands.match("max volume") == {"type": "command", "action": "volume_set", "level": 11}
|
|
|
|
|
|
def test_non_commands_fall_through_to_llm() -> None:
|
|
# these must NOT be hijacked from Tatlock
|
|
assert commands.match("what's the weather tomorrow") is None
|
|
assert commands.match("set an alarm for a quarter to eleven") is None
|
|
assert commands.match("turn up the heating in the lounge") is None
|
|
assert commands.match("") is None
|
|
assert commands.match("tell me a joke") is None
|