File size: 2,640 Bytes
d725335
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a837fd9
 
 
 
 
2a9b8d1
a837fd9
 
2a9b8d1
 
a837fd9
 
 
 
d725335
 
 
 
 
2a9b8d1
a837fd9
 
2a9b8d1
 
d725335
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from __future__ import annotations

import json

from tiny_trigger.automation import load_automation_text
from tiny_trigger.models import ActionEvent
from tiny_trigger.store import (
    RuntimeState,
    append_events,
    load_local_config,
    load_runtime_state,
    load_saved_automations,
    save_automations,
    save_runtime_state,
)


def test_local_config_yaml(tmp_path) -> None:
    path = tmp_path / "config.yaml"
    path.write_text(
        "\n".join(
            [
                "default_device: cuda:0",
                "webhook_url: http://example.test",
                "llm_provider: anthropic",
                "replicate_model: openai/gpt-5.2",
                "replicate_reasoning_effort: medium",
                "openai_model: gpt-5.5",
                "anthropic_model: claude-sonnet-4-6",
            ]
        ),
        encoding="utf-8",
    )

    config = load_local_config(path)

    assert config.default_device == "cuda:0"
    assert config.webhook_url == "http://example.test"
    assert config.llm_provider == "anthropic"
    assert config.replicate_model == "openai/gpt-5.2"
    assert config.replicate_reasoning_effort == "medium"
    assert config.openai_model == "gpt-5.5"
    assert config.anthropic_model == "claude-sonnet-4-6"


def test_save_and_load_automations(tmp_path) -> None:
    path = tmp_path / "automations.json"
    document = load_automation_text(
        json.dumps(
            {
                "rules": [
                    {
                        "name": "notify",
                        "when": {"all": [{"present": {"label": "person"}}]},
                        "then": [{"type": "simulate", "name": "notify"}],
                    }
                ]
            }
        )
    )

    save_automations(document, path)
    loaded = load_saved_automations(path)

    assert loaded is not None
    assert loaded.rules[0].name == "notify"


def test_runtime_state_roundtrip(tmp_path) -> None:
    path = tmp_path / "state.json"
    save_runtime_state(RuntimeState(last_fired={"turn-on-pc": 12.0}), path)

    assert load_runtime_state(path).last_fired == {"turn-on-pc": 12.0}


def test_append_events_jsonl(tmp_path) -> None:
    path = tmp_path / "events.jsonl"
    append_events(
        [
            ActionEvent(
                rule="turn-on-pc",
                action="turn on pc",
                type="simulate",
                frame_index=0,
                timestamp_sec=0.0,
            )
        ],
        path,
    )

    rows = path.read_text(encoding="utf-8").splitlines()
    assert len(rows) == 1
    assert json.loads(rows[0])["rule"] == "turn-on-pc"