agent-claw: automated task changes

This commit is contained in:
daniel
2026-05-06 18:55:16 -05:00
parent 38905bb1e9
commit 732b00fb66
8494 changed files with 2018127 additions and 4 deletions

View File

@@ -0,0 +1,91 @@
"""Home Assistant tool — control and query HA entities via REST API."""
import json
import os
import urllib.request
import urllib.error
from strands import tool
HA_URL = "https://homeassistant.home.everyonce.com"
# Token stored in workspace or env; fallback to hardcoded for AgentCore runtime
HA_TOKEN = os.environ.get(
"HA_TOKEN",
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJlMDExN2YwNzhlM2Q0NjViODJhNjJiZWFiMzI1ZWU4MiIsImlhdCI6MTc3MTM1MjU0MiwiZXhwIjoyMDg2NzEyNTQyfQ.UySLD6JV4e_bdd1nQjdbZcimdCD6B3kBGDftcRz1H6Q"
)
def _ha_request(method: str, path: str, body: dict | None = None) -> dict | list:
url = f"{HA_URL}{path}"
headers = {
"Authorization": f"Bearer {HA_TOKEN}",
"Content-Type": "application/json",
}
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(url, data=data, headers=headers, method=method)
try:
with urllib.request.urlopen(req, timeout=10) as resp:
return json.loads(resp.read().decode())
except urllib.error.HTTPError as e:
return {"error": f"HTTP {e.code}: {e.reason}", "body": e.read().decode()[:500]}
except Exception as e:
return {"error": str(e)}
@tool
def home_assistant(action: str, entity_id: str = "", domain: str = "", service: str = "",
service_data: dict | None = None) -> str:
"""Control and query your Home Assistant smart home.
Actions:
- "get_state": Get the current state of a specific entity (requires entity_id).
- "list_states": List all entity states (optionally filter by domain prefix like 'light', 'switch', 'climate', 'sensor').
- "call_service": Call a HA service (requires domain, service, and optional service_data with entity_id).
- "get_history": Not yet implemented.
Common service examples:
- Turn light on: domain="light", service="turn_on", service_data={"entity_id": "light.living_room"}
- Turn light off: domain="light", service="turn_off", service_data={"entity_id": "light.living_room"}
- Set brightness: domain="light", service="turn_on", service_data={"entity_id": "light.x", "brightness_pct": 50}
- Lock door: domain="lock", service="lock", service_data={"entity_id": "lock.front_door"}
- Set thermostat: domain="climate", service="set_temperature", service_data={"entity_id": "climate.x", "temperature": 72}
Args:
action: One of "get_state", "list_states", "call_service".
entity_id: Entity ID for get_state (e.g. "light.living_room").
domain: Service domain for call_service (e.g. "light", "switch", "lock", "climate").
service: Service name for call_service (e.g. "turn_on", "turn_off", "lock").
service_data: Dict of extra params for call_service (e.g. {"entity_id": "light.x", "brightness_pct": 80}).
Returns:
JSON string with the result.
"""
if action == "get_state":
if not entity_id:
return "entity_id is required for get_state"
result = _ha_request("GET", f"/api/states/{entity_id}")
if isinstance(result, dict) and "error" not in result:
return f"{entity_id}: {result.get('state')} (attrs: {json.dumps(result.get('attributes', {}))[:300]})"
return json.dumps(result)
elif action == "list_states":
result = _ha_request("GET", "/api/states")
if isinstance(result, list):
# Filter by domain prefix if entity_id used as filter
prefix = entity_id or domain
if prefix:
result = [s for s in result if s.get("entity_id", "").startswith(prefix)]
# Return concise summary
lines = [f"{s['entity_id']}: {s['state']}" for s in result[:50]]
return "\n".join(lines) + (f"\n... ({len(result)} total)" if len(result) > 50 else "")
return json.dumps(result)
elif action == "call_service":
if not domain or not service:
return "domain and service are required for call_service"
body = service_data or {}
if entity_id and "entity_id" not in body:
body["entity_id"] = entity_id
result = _ha_request("POST", f"/api/services/{domain}/{service}", body)
return f"Service {domain}.{service} called successfully" if isinstance(result, list) else json.dumps(result)
else:
return f"Unknown action: {action}. Use 'get_state', 'list_states', or 'call_service'."