Skip to content

feat(tools): home_assistant tool for HA REST API#6464

Open
theonlyhennygod wants to merge 1 commit intomasterfrom
feat/home-assistant-tool
Open

feat(tools): home_assistant tool for HA REST API#6464
theonlyhennygod wants to merge 1 commit intomasterfrom
feat/home-assistant-tool

Conversation

@theonlyhennygod
Copy link
Copy Markdown
Collaborator

Summary

  • Base branch: master
  • What changed and why:
    • Adds a home_assistant Tool that drives a self-hosted Home Assistant instance via its REST API. Until now, crates/zeroclaw-runtime/src/integrations/registry.rs:634-639 declared HA as ComingSoon with no implementation behind it.
    • Read actions (get_state, list_states, list_services) gate on ToolOperation::Read; call_service gates on ToolOperation::Act AND a configurable allowed_domains allowlist so operators control the blast radius.
    • Wires the integration registry's status_fn to flip Available → Active when home_assistant.enabled = true, and the developer page picks it up automatically.
  • Scope boundary:
  • Blast radius: zeroclaw-config (additive [home_assistant] block, default disabled), zeroclaw-tools (new module), zeroclaw-runtime/src/tools/mod.rs (config-gated registration in all_tools_with_runtime), zeroclaw-runtime/src/integrations/{mod,registry}.rs (status flip + setup-hint arm), docs.
  • Linked issue(s): Closes #6448. Sibling tracking issues: [Feature]: Philips Hue integration tool #6449 (Hue), [Feature]: 8Sleep integration tool #6450 (8Sleep).

Validation Evidence (required)

cargo fmt --all -- --check
cargo clippy -p zeroclaw-config -p zeroclaw-tools -p zeroclaw-runtime --all-targets -- -D warnings
cargo test -p zeroclaw-config -p zeroclaw-tools -p zeroclaw-runtime
cargo check -p zeroclaw-gateway
  • Commands run and tail output:
    • cargo fmt --all -- --check → clean (no diff after cargo fmt --all was run).
    • cargo clippy ...Finished dev profile [unoptimized + debuginfo] target(s) in 47.60s. No warnings.
    • cargo test -p zeroclaw-config -p zeroclaw-tools -p zeroclaw-runtime
      • test result: ok. 620 passed; 0 failed; 0 ignored (zeroclaw-config)
      • test result: ok. 1641 passed; 0 failed; 1 ignored (zeroclaw-tools)
      • test result: ok. 1158 passed; 0 failed; 0 ignored (zeroclaw-runtime)
      • Total: 3,420 passed, 0 failed.
    • New tool: 14 tests under home_assistant::tests::* — name, schema shape (action enum, required fields), URL/base normalization, allowlist trimming, missing-action / unknown-action / missing-entity / missing-domain / missing-service / disallowed-domain / empty-allowlist paths, spec() reflection.
    • New registry tests: home_assistant_available_when_not_configured and home_assistant_active_when_enabled — confirm the developer-page card flips when config is set.
    • cargo check -p zeroclaw-gateway → builds; gateway surfaces tools via state.tools_registry from all_tools_with_runtime, so the new tool auto-appears at GET /api/tools when [home_assistant] enabled = true.
  • Beyond CI — what did you manually verify?
    • Developer-page integration card moves from 🔜 Coming Soon to ⚪ Available (and ✅ Active once configured) — the registry test exercises both states.
    • zeroclaw integrations info "Home Assistant" now prints the LLAT setup steps (the new arm in show_integration_info).
    • Not verified live: I did not stand up a real HA instance and execute end-to-end — call_service against an actual light.turn_on is left to follow-up smoke once the PR lands. The unit tests cover error paths (missing fields, disallowed domains) but not the HTTP success path.
  • If any command was intentionally skipped, why: Skipped the full ./dev/ci.sh all because the change is scoped to three crates + docs + a changelog entry; the targeted clippy+test runs already gated those crates with -D warnings.

Security & Privacy Impact (required)

  • New permissions, capabilities, or file system access scope? No. The tool uses HTTP only.
  • New external network calls? Yes. The tool POSTs/GETs home_assistant.base_url. Disabled by default; the operator opts in.
  • Secrets / tokens / credentials handling changed? Yes. A new access_token field on HomeAssistantConfig carries #[secret], so it's encrypted at rest when [secrets] encrypt = true. Token also resolves from HOME_ASSISTANT_TOKEN env var as a fallback.
  • PII, real identities, or personal data in diff, tests, fixtures, or docs? No. Tests use neutral placeholders (http://homeassistant.local:8123, test-token, light.kitchen).
  • Risk and mitigation: A misconfigured allowed_domains could let the agent trigger unexpected automations. Mitigation: allowed_domains is enforced server-side in the tool's execute (not just in the schema); empty allowlist blocks all call_service calls; defaults are conservative (no lock, no cover, no notify).

Compatibility (required)

  • Backward compatible? Yes. Additive config, default enabled: false. Config::default() includes home_assistant: HomeAssistantConfig::default(), so existing configs missing [home_assistant] continue to deserialize unchanged.
  • Config / env / CLI surface changed? Yes — new [home_assistant] block; new HOME_ASSISTANT_TOKEN env var fallback. No CLI changes.
  • Upgrade steps for existing users: None required. To opt in, add [home_assistant] enabled = true, base_url, and either access_token or HOME_ASSISTANT_TOKEN.

Rollback (required for risk: medium and risk: high)

  • Fast rollback command/path: Set [home_assistant] enabled = false in ~/.zeroclaw/config.toml (or remove the block) and restart the agent. The tool is unregistered on next boot.
  • Feature flags or config toggles: home_assistant.enabled (boolean) is the master switch. home_assistant.allowed_domains is the per-action throttle.
  • Observable failure symptoms:
    • Logs: home_assistant: enabled but no access token found ... or ... base_url is empty — skipping registration indicate config issues.
    • Logs: Home Assistant {action} failed (4xx/5xx) indicates upstream HA problems (token revoked, instance unreachable).
    • Metric: tools registry size at gateway boot will not include home_assistant if either token or base_url is missing.

@github-actions github-actions Bot added the docs Auto scope: docs/markdown/template files changed. label May 6, 2026
Adds a `home_assistant` Tool that talks to a self-hosted Home Assistant
instance via its REST API. Read actions (`get_state`, `list_states`,
`list_services`) require `ToolOperation::Read`; the mutating
`call_service` action requires `ToolOperation::Act` and is further
restricted by an operator-controlled `allowed_domains` allowlist.

`HomeAssistantConfig` is disabled by default. The access token is
marked `#[secret]` (encrypted at rest when `[secrets] encrypt = true`)
and falls back to the `HOME_ASSISTANT_TOKEN` env var. The registry
status flips Available -> Active when `home_assistant.enabled` is set.

Adds a setup-guide doc, a `zeroclaw integrations info "Home Assistant"`
hint arm, and a CHANGELOG-next entry.

Closes #6448
@theonlyhennygod theonlyhennygod force-pushed the feat/home-assistant-tool branch from 0084e27 to 2e9d172 Compare May 6, 2026 18:47
@theonlyhennygod
Copy link
Copy Markdown
Collaborator Author

Rebased onto current master (was conflicting against #6386 which moved the integrations registry to a schema-driven, single-loop catalog).

What changed in the diff vs. the original push:

  • Dropped the hand-rolled status_fn flip in crates/zeroclaw-runtime/src/integrations/registry.rs:634-651 — that code path no longer exists.
  • Dropped the two registry-level tests (home_assistant_available_when_not_configured, home_assistant_active_when_enabled) for the same reason; the new registry asserts integrity of the catalog itself, not per-row entries.
  • Added #[integration(category = "ToolsAutomation", display_name = "Home Assistant", description = "Home automation hub", status_field = "enabled")] on HomeAssistantConfig. This is the new contract — the Configurable derive emits the integration_descriptor() method that the registry's single loop consumes.
  • Kept the setup-hint arm in show_integration_info, the runtime tool registration, the home_assistant.rs tool (and its 14 unit tests), config schema, docs page, SUMMARY.md link, and CHANGELOG entry — all unchanged.

Note: under the new registry, IntegrationCategory::SmartHome was removed (no live entries). Home Assistant now categorises as ToolsAutomation, alongside Browser, Cron, Google Workspace.

Re-validated locally: cargo fmt, cargo clippy -p zeroclaw-config -p zeroclaw-tools -p zeroclaw-runtime --all-targets -- -D warnings, full tests for those three crates — 3,409 passed, 0 failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Auto scope: docs/markdown/template files changed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant