@switchbot/openapi-cli
Advanced tools
@@ -81,2 +81,33 @@ { | ||
| "items": { "$ref": "#/$defs/rule" } | ||
| }, | ||
| "audit": { | ||
| "type": ["object", "null"], | ||
| "additionalProperties": false, | ||
| "description": "Controls rule-evaluate trace recording.", | ||
| "properties": { | ||
| "evaluate_trace": { | ||
| "enum": ["full", "sampled", "off"], | ||
| "default": "sampled", | ||
| "description": "full=every evaluation; sampled=skip high-freq blocked-by-condition; off=disabled." | ||
| }, | ||
| "evaluate_retention_days": { | ||
| "type": "integer", | ||
| "minimum": 1, | ||
| "default": 7, | ||
| "description": "Days to retain rule-evaluate records." | ||
| } | ||
| } | ||
| }, | ||
| "llm_budget": { | ||
| "type": ["object", "null"], | ||
| "additionalProperties": false, | ||
| "description": "Global LLM call budget applied across all llm conditions.", | ||
| "properties": { | ||
| "max_calls_per_hour": { | ||
| "type": "integer", | ||
| "minimum": 0, | ||
| "default": 60, | ||
| "description": "Maximum LLM condition calls per hour across all rules." | ||
| } | ||
| } | ||
| } | ||
@@ -303,2 +334,30 @@ } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "additionalProperties": false, | ||
| "required": ["llm"], | ||
| "properties": { | ||
| "llm": { | ||
| "type": "object", | ||
| "additionalProperties": false, | ||
| "required": ["prompt"], | ||
| "description": "Evaluate the condition using an LLM decision call.", | ||
| "properties": { | ||
| "prompt": { "type": "string", "minLength": 1, "description": "Prompt template sent to the LLM." }, | ||
| "provider": { "enum": ["auto", "openai", "anthropic"], "default": "auto" }, | ||
| "timeout_ms": { "type": "integer", "minimum": 500, "maximum": 10000, "default": 5000 }, | ||
| "cache_ttl": { "type": "string", "pattern": "^(none|\\d+[smh])$", "default": "5m" }, | ||
| "budget": { | ||
| "type": ["object", "null"], | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "max_calls_per_hour": { "type": "integer", "minimum": 0, "default": 10 } | ||
| } | ||
| }, | ||
| "on_error": { "enum": ["fail", "pass", "skip"], "default": "fail" }, | ||
| "recent_events": { "type": "integer", "minimum": 0, "maximum": 20, "default": 5 } | ||
| } | ||
| } | ||
| } | ||
| } | ||
@@ -305,0 +364,0 @@ ] |
+1
-1
| { | ||
| "name": "@switchbot/openapi-cli", | ||
| "version": "3.3.3", | ||
| "version": "3.4.0", | ||
| "description": "SwitchBot smart home CLI β control devices, run scenes, stream real-time events, and integrate AI agents via MCP. Full API v1.1 coverage.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
+52
-8
@@ -96,3 +96,3 @@ # @switchbot/openapi-cli | ||
| - π **Dry-run mode** β preview every mutating request before it hits the API | ||
| - π§ͺ **Fully tested** β 1959 Vitest tests, mocked axios, zero network in CI | ||
| - π§ͺ **Fully tested** β 2204 Vitest tests, mocked axios, zero network in CI | ||
| - β‘ **Shell completion** β Bash / Zsh / Fish / PowerShell | ||
@@ -277,5 +277,5 @@ | ||
| **cron** (schedule-driven), and **webhook** (local HTTP POST). | ||
| Supported conditions: `time_between` (quiet hours) and `device_state` | ||
| (live API check with per-tick dedup). Every fire is recorded in | ||
| `~/.switchbot/audit.log`. `rules run` is long-running; use | ||
| Supported conditions: `time_between` (quiet hours), `device_state` | ||
| (live API check with per-tick dedup), and `llm` (AI decision β see | ||
| below). Every fire is recorded in `~/.switchbot/audit.log`. `rules run` is long-running; use | ||
| `daemon start` / `daemon reload` for the managed background mode. | ||
@@ -301,2 +301,31 @@ | ||
| **LLM condition** β add an AI judgement step before actions fire. The engine calls the | ||
| configured LLM provider, passes the prompt plus recent event context, and gates execution | ||
| on the model's yes/no answer: | ||
| ```yaml | ||
| conditions: | ||
| - llm: | ||
| prompt: "Is the temperature above normal comfort range?" | ||
| provider: auto # auto | openai | anthropic | ||
| cache_ttl: 5m # skip redundant calls for identical context | ||
| budget: | ||
| max_calls_per_hour: 20 | ||
| on_error: pass # fail | pass | skip | ||
| ``` | ||
| Set `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` (provider `auto` tries Anthropic first). | ||
| `rules lint` flags misconfigured LLM conditions (no provider key, cache TTL too high for | ||
| the trigger frequency, budget zero). Evaluation decisions are recorded in the trace log. | ||
| **Decision trace** β enable `automation.audit.evaluate_trace` in `policy.yaml` to record | ||
| every evaluation decision (why a rule fired or was blocked): | ||
| ```yaml | ||
| automation: | ||
| audit: | ||
| evaluate_trace: sampled # full | sampled | off (default: sampled) | ||
| evaluate_retention_days: 7 | ||
| ``` | ||
| ```bash | ||
@@ -339,2 +368,12 @@ # 1. Author rules under `automation.rules`. See examples/policies/automation.yaml | ||
| # Set OPENAI_API_KEY or ANTHROPIC_API_KEY; auto mode falls back to heuristic on failure | ||
| # 9. Explain why a specific evaluation fired or was blocked (requires evaluate_trace). | ||
| switchbot rules trace-explain --rule "motion on" --last | ||
| switchbot rules trace-explain --rule "motion on" --since 1h --json | ||
| switchbot rules trace-explain <fireId> # single evaluation by ID | ||
| # 10. Simulate a rule against historical events without running the engine. | ||
| switchbot rules simulate "motion on" # replay last 24h from audit log | ||
| switchbot rules simulate "motion on" --since 7d --json | ||
| switchbot rules simulate policy.yaml --rule "night AC" --against events.jsonl | ||
| ``` | ||
@@ -888,3 +927,4 @@ | ||
| `audit_stats`, `policy_diff`, `policy_validate`, `policy_new`, | ||
| `policy_migrate`, `rules_suggest`, `rule_notifications`) plus a | ||
| `policy_migrate`, `rules_suggest`, `rule_notifications`, | ||
| `rules_explain`, `rules_simulate`) plus a | ||
| `switchbot://events` resource for real-time shadow updates. | ||
@@ -895,2 +935,5 @@ `rules_suggest` accepts an optional `llm` parameter (`openai | anthropic | auto`) | ||
| name, time range, channel, and result. | ||
| `rules_explain` returns the decision trace for a specific evaluation (why a rule | ||
| fired or was blocked); `rules_simulate` replays historical events against a rule | ||
| and reports would-fire / blocked / throttled outcomes. | ||
| See [`docs/agent-guide.md`](./docs/agent-guide.md) for the full tool reference and safety rules (destructive-command guard). | ||
@@ -1175,3 +1218,3 @@ | ||
| npm run build # Compile to dist/ | ||
| npm test # Run the Vitest suite (1959 tests) | ||
| npm test # Run the Vitest suite (2204 tests) | ||
| npm run test:watch # Watch mode | ||
@@ -1242,3 +1285,4 @@ npm run test:coverage # Coverage report (v8, HTML + text) | ||
| β βββ rules.ts # `rules suggest/lint/list/explain/run/reload/tail/replay/ | ||
| β β # conflicts/doctor/summary/last-fired/webhook-*` | ||
| β β # conflicts/doctor/summary/last-fired/webhook-*/ | ||
| β β # trace-explain/simulate` | ||
| β βββ scenes.ts | ||
@@ -1267,3 +1311,3 @@ β βββ health.ts # `health check/serve` β report + HTTP endpoints | ||
| βββ quota.ts # Local daily-quota counter | ||
| tests/ # Vitest suite (1959 tests, mocked axios, no network) | ||
| tests/ # Vitest suite (2204 tests, mocked axios, no network) | ||
| ``` | ||
@@ -1270,0 +1314,0 @@ |
Sorry, the diff of this file is too big to display
2356686
1.67%60077
1.54%1328
3.43%