feat: expand Reyna CLI integrations

This commit is contained in:
Adolfo Reyna
2026-06-15 18:59:43 -04:00
parent 97379a1046
commit a0a26565f0
16 changed files with 3626 additions and 19 deletions
+123 -3
View File
@@ -3,7 +3,7 @@ from pathlib import Path
from typer.testing import CliRunner
from reyna_cli.cli import app
from reyna_cli.cli import app, build_tts_payload
from reyna_cli.config import Device, Registry, get_device, load_registry
from reyna_cli.utils import infer_capabilities, resolve_tool_name
@@ -53,8 +53,16 @@ devices:
def test_config_get_device():
registry = Registry(devices=[Device(id="iphone_mcp", url="http://localhost:8080/api/mcp")])
assert get_device("iphone", registry).url == "http://localhost:8080/api/mcp"
registry = Registry(devices=[Device(id="iphone_mcp", url="http://localhost:8080/api/mcp"), Device(id="personal_laptop_screen", url="http://localhost:8081/api/mcp"), Device(id="local_desktop_screen", url="http://127.0.0.1:8080/api/mcp")])
iphone = get_device("iphone", registry)
laptop = get_device("laptop", registry)
computer = get_device("computer", registry)
assert iphone is not None
assert laptop is not None
assert computer is not None
assert iphone.url == "http://localhost:8080/api/mcp"
assert laptop.url == "http://localhost:8081/api/mcp"
assert computer.url == "http://127.0.0.1:8080/api/mcp"
assert get_device("nonexistent", registry) is None
@@ -88,12 +96,74 @@ def test_screen_has_subcommands():
assert "speak" in result.stdout
def test_build_tts_payload_base64_encodes_wav(monkeypatch, tmp_path):
def fake_synthesize(message, wav_path, command_template=None, voice=None, sample_rate=16000):
wav_path.write_bytes(b"RIFFfake-wav")
return wav_path
monkeypatch.setattr("reyna_cli.cli.synthesize_wav", fake_synthesize)
payload = build_tts_payload("hello", tmp_path / "speech.wav", 42, None, None, 16000)
assert payload == {"wav_base64": "UklGRmZha2Utd2F2", "volume": 42}
def test_screen_speak_generates_wav_base64_payload(monkeypatch, tmp_path):
registry_path = tmp_path / "local_devices.yaml"
registry_path.write_text(
"""
devices:
esp32_screen:
display_name: ESP32 Screen
url: http://screen.local/api/mcp
""",
encoding="utf-8",
)
monkeypatch.setenv("REYNA_DEVICES_REGISTRY", str(registry_path))
def fake_get_tools(device, live_only=False, cache_only=False, refresh=False):
return {"ok": True, "tools": [{"name": "play_audio_base64"}]}
calls = []
def fake_call_device_tool(device, tool_name, arguments):
calls.append((device.id, tool_name, arguments))
return {"ok": True, "result": "played"}
def fake_synthesize(message, wav_path, command_template=None, voice=None, sample_rate=16000):
assert message == "hello screen"
wav_path.write_bytes(b"RIFFfake-wav")
return wav_path
monkeypatch.setattr("reyna_cli.cli.get_tools", fake_get_tools)
monkeypatch.setattr("reyna_cli.cli.call_device_tool", fake_call_device_tool)
monkeypatch.setattr("reyna_cli.cli.synthesize_wav", fake_synthesize)
result = runner.invoke(app, ["screen", "speak", "hello screen", "--volume", "42", "--out", str(tmp_path / "speech.wav"), "--json"])
assert result.exit_code == 0
assert calls == [("esp32_screen", "play_audio_base64", {"wav_base64": "UklGRmZha2Utd2F2", "volume": 42})]
def test_devices_screen_has_subcommands():
result = runner.invoke(app, ["devices", "screen", "--help"])
assert result.exit_code == 0
assert "text" in result.stdout
def test_laptop_has_subcommands():
result = runner.invoke(app, ["laptop", "--help"])
assert result.exit_code == 0
assert "text" in result.stdout
assert "speak" in result.stdout
assert "screenshot" in result.stdout
assert "sensors" in result.stdout
def test_devices_laptop_has_subcommands():
result = runner.invoke(app, ["devices", "laptop", "--help"])
assert result.exit_code == 0
assert "text" in result.stdout
assert "battery" in result.stdout
def test_devices_arm_has_subcommands():
result = runner.invoke(app, ["devices", "arm", "--help"])
assert result.exit_code == 0
@@ -116,3 +186,53 @@ def test_mongo_has_subcommands():
assert "dbs" in result.stdout
assert "collections" in result.stdout
assert "find" in result.stdout
def test_deco_has_subcommands():
result = runner.invoke(app, ["deco", "--help"])
assert result.exit_code == 0
assert "overview" in result.stdout
assert "clients" in result.stdout
assert "firmware" in result.stdout
assert "config" in result.stdout
def test_deco_config_is_direct(monkeypatch, tmp_path):
empty_env = tmp_path / ".env"
empty_env.write_text("", encoding="utf-8")
monkeypatch.setenv("HERMES_ENV_PATH", str(empty_env))
monkeypatch.setenv("DECO_HOST", "192.168.68.1")
monkeypatch.delenv("DECO_PASSWORD", raising=False)
result = runner.invoke(app, ["deco", "config", "--json"])
assert result.exit_code == 0
payload = json.loads(result.stdout)
assert payload["ok"] is True
assert payload["source"] == "direct"
assert payload["result"]["host"] == "192.168.68.1"
assert payload["result"]["passwordConfigured"] is False
def test_macmini_has_subcommands():
result = runner.invoke(app, ["macmini", "--help"])
assert result.exit_code == 0
assert "calendar" in result.stdout
assert "contacts" in result.stdout
assert "notes" in result.stdout
assert "reminders" in result.stdout
assert "deco" in result.stdout
def test_macmini_calendar_has_subcommands():
result = runner.invoke(app, ["macmini", "calendar", "--help"])
assert result.exit_code == 0
assert "calendars" in result.stdout
assert "events" in result.stdout
assert "create" in result.stdout
def test_macmini_deco_has_subcommands():
result = runner.invoke(app, ["macmini", "deco", "--help"])
assert result.exit_code == 0
assert "overview" in result.stdout
assert "clients" in result.stdout
assert "firmware" in result.stdout