From 592a1c057085de10ecbb666c80ab1fdc50f616b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Mar 2026 04:52:22 +0500 Subject: [PATCH 01/10] Add Enphase Solar Monitor community ability --- community/enphase-solar-monitor/README.md | 183 ++++++++ community/enphase-solar-monitor/__init__.py | 1 + community/enphase-solar-monitor/main.py | 452 ++++++++++++++++++++ 3 files changed, 636 insertions(+) create mode 100644 community/enphase-solar-monitor/README.md create mode 100644 community/enphase-solar-monitor/__init__.py create mode 100644 community/enphase-solar-monitor/main.py diff --git a/community/enphase-solar-monitor/README.md b/community/enphase-solar-monitor/README.md new file mode 100644 index 00000000..f7e70b84 --- /dev/null +++ b/community/enphase-solar-monitor/README.md @@ -0,0 +1,183 @@ +# Enphase Solar Monitor + +Voice-activated solar dashboard for Enphase systems (IQ Gateway with microinverters). + +## Demo Mode + +**This ability is built and tested in DEMO MODE** since we don't have a real Enphase system. With `DEMO_MODE = True` (default in `main.py`): + +- No credentials or prefs file required +- Returns realistic fake data: 4.2 kW production, 73% battery charging, 3.1 kW consumption +- Lets you test the full voice flow in OpenHome without Enphase hardware + +**To use a real system:** Set `DEMO_MODE = False` in `main.py` and follow the setup instructions below. + +## What It Does + +Ask "how's my solar?" to get real-time production, consumption, and battery status. Data is delivered as natural spoken responses. + +## Trigger Words + +- "solar" +- "how's my solar" +- "solar status" +- "solar production" +- "battery level" +- "battery status" +- "am I exporting" +- "grid status" +- "solar today" +- "enphase" +- "solar panels" + +--- + +## How to Get Real Enphase API Data + +Follow these steps to connect the ability to your actual Enphase solar system. + +### Prerequisites + +- Enphase solar system with IQ Gateway (microinverters) +- Enphase account with your system linked (see [MyEnphase](https://my.enphase.com)) +- If your account shows "not associated with any systems," contact your installer or use [Ownership Transfer](https://enphase.com/ownership-transfer) if you bought a property with an existing system + +--- + +### Step 1: Create an Enphase Developer Account + +1. Go to [developer-v4.enphase.com/signup](https://developer-v4.enphase.com/signup) +2. Fill in your details and sign up +3. Check your email and activate your account +4. Log in to the [Enphase Developer Portal](https://developer-v4.enphase.com) + +--- + +### Step 2: Create an Application + +1. Go to [Applications](https://developer-v4.enphase.com/admin/applications) +2. Click **Create Application** +3. Fill in: + - **Name:** e.g. "OpenHome Solar Monitor" + - **Description:** e.g. "Voice-activated solar monitoring for OpenHome" + - **Plan:** Select **Watt** (free, 1,000 requests/month) + - **Access Control:** Check **System Details**, **Site Level Production Monitoring**, **Site Level Consumption Monitoring** +4. Click **Create Application** +5. Copy and save these values from your application page: + - **API Key** + - **Client ID** + - **Client Secret** + - **Authorization URL** (or note the Client ID to build it) + +--- + +### Step 3: Get Your System ID + +Your system must be linked to your Enphase account. + +**Option A: Enlighten Web** +1. Go to [enlighten.enphaseenergy.com](https://enlighten.enphaseenergy.com) +2. Log in and open your system +3. Check the browser URL: `https://enlighten.enphaseenergy.com/systems/1234567/...` +4. The number after `/systems/` is your **system_id** (e.g. `1234567`) + +**Option B: Enphase Mobile App** +1. Open the Enphase Enlighten app +2. Go to **Settings** or **System** +3. Find **System ID** or **System details** + +--- + +### Step 4: OAuth 2.0 Authorization (Get access_token and refresh_token) + +You must authorize your app to access your system data. The system owner (you) must complete this flow. + +#### 4a. Build the Authorization URL + +Use this format (replace `YOUR_CLIENT_ID` with your Client ID): + +``` +https://api.enphaseenergy.com/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https://api.enphaseenergy.com/oauth/redirect_uri +``` + +#### 4b. Open the URL in Your Browser + +1. Paste the authorization URL into your browser +2. Log in with your Enphase (Enlighten) credentials +3. Approve access when prompted +4. You will be redirected to a page with a **code** in the URL +5. Copy the `code` value (everything after `code=`) + +#### 4c. Exchange the Code for Tokens + +Send a POST request to Enphase to exchange the authorization code for `access_token` and `refresh_token`. See the Enphase API docs for the exact request format. + +--- + +### Step 5: Configure the Preferences File + +1. Copy `enphase_solar_prefs.json.example` to `enphase_solar_prefs.json` in this ability folder +2. Fill in all values (system_id, api_key, client_id, client_secret, access_token, refresh_token, has_battery, has_consumption) +3. With OpenHome File Storage API, prefs are stored in user-level storage + +--- + +### Step 6: Switch to Real Mode + +1. Open `main.py` +2. Set `DEMO_MODE = False` at the top +3. Upload the ability to OpenHome + +--- + +### Troubleshooting + +| Issue | Solution | +|-------|----------| +| "Your account is not associated with any systems" | Contact your installer to link your system, or use Ownership Transfer | +| "Token refresh failed: 401" | Re-run the OAuth flow (Step 4) to get new tokens | +| "I can't find that system ID" | Verify system_id in Enlighten URL or app | +| "I've hit the API limit" | Free tier = 1,000 requests/month; wait or upgrade plan | + +### Ability Not Activating? + +1. **Add ability to your Personality** – In OpenHome, ensure this ability is added/enabled +2. **Check trigger words** – Verify trigger words in the Abilities Dashboard +3. **Re-upload** – Re-upload the ability zip and ensure it's enabled +4. **Try exact phrases** – Say "How's my solar?" or "Solar status" clearly + +--- + +## OpenHome Compatibility + +This ability is built for the OpenHome sandbox: + +- **No `open()` or `os`** – Uses OpenHome File Storage API (`check_if_file_exists`, `read_file`, `write_file`) for preferences +- **Hardcoded config** – `unique_name` and `matching_hotwords` are hardcoded from `config.json` (file access forbidden at registration time) +- **Persistent storage** – Preferences are stored with `temp=False` (user-level storage) + +--- + +## Technical Details + +- **API:** Enphase Cloud API v4 +- **Auth:** OAuth 2.0 with auto-refresh on 401 +- **Rate Limit:** 1,000 requests/month (free Watt plan) +- **Caching:** 15-minute TTL + +--- + +## Example + +> **User:** "How's my solar?" +> +> **Response:** "You're producing 4.2 kilowatts right now, as of about 15 minutes ago. Today you've generated 28 kilowatt hours. Your battery is at 73 percent and charging. You're sending 1.5 kilowatts to the grid." + +## Supported Queries + +- **Solar snapshot:** "How's my solar?", "Solar status" +- **Battery:** "Battery level", "Battery status" +- **Consumption:** "How much am I using?" +- **Grid:** "Am I exporting?", "Grid status" +- **Today:** "Solar today", "Today's production" +- **Health:** "System health", "Panel status" diff --git a/community/enphase-solar-monitor/__init__.py b/community/enphase-solar-monitor/__init__.py new file mode 100644 index 00000000..3391374a --- /dev/null +++ b/community/enphase-solar-monitor/__init__.py @@ -0,0 +1 @@ +# Enphase Solar Monitor - OpenHome Ability diff --git a/community/enphase-solar-monitor/main.py b/community/enphase-solar-monitor/main.py new file mode 100644 index 00000000..33c22640 --- /dev/null +++ b/community/enphase-solar-monitor/main.py @@ -0,0 +1,452 @@ +""" +Enphase Solar Monitor - OpenHome Ability +Voice-activated solar dashboard for Enphase systems (IQ Gateway with microinverters). +Fetches production, consumption, and battery data from Enphase Cloud API v4. +""" + +import json +import time +from datetime import datetime, timezone +from typing import Callable, Optional + +import requests +from src.agent.capability import MatchingCapability +from src.agent.capability_worker import CapabilityWorker +from src.main import AgentWorker + +# Demo mode - set to False when you have real Enphase credentials +DEMO_MODE = True + +ENPHASE_BASE_URL = "https://api.enphaseenergy.com/api/v4" +ENPHASE_TOKEN_URL = "https://api.enphaseenergy.com/oauth/token" +CACHE_TTL = 900 # 15 minutes +EXIT_WORDS = ["stop", "quit", "exit", "done", "cancel"] +PREFS_FILE = "enphase_solar_prefs.json" + +# Hardcoded from config.json - OpenHome forbids open() in register_capability +UNIQUE_NAME = "enphase_solar_monitor" +MATCHING_HOTWORDS = [ + "solar", "solar status", "solar production", "how's my solar", + "hows my solar", "how is my solar", "enphase", "solar panels", + "battery level", "battery status", "my battery status", "battery", + "am I exporting", "grid status", "solar today", "check my solar", "solar power", +] + +ERROR_RESPONSES = { + "no_system_id": "You haven't set up your Enphase system yet.", + "auth_failed": "Your Enphase authorization has expired. You'll need to re-authorize.", + "rate_limited": "I've hit the API limit. Try again later, or check the Enphase app.", + "system_not_found": "I can't find that system ID. Check your preferences file.", + "timeout": "I can't reach the Enphase cloud right now. Check your internet.", +} + + +class EnphaseSolarMonitorCapability(MatchingCapability): + """Voice-activated Enphase solar monitoring capability.""" + + worker: AgentWorker = None + capability_worker: CapabilityWorker = None + + @classmethod + def register_capability(cls) -> "MatchingCapability": + return cls( + unique_name=UNIQUE_NAME, + matching_hotwords=MATCHING_HOTWORDS, + ) + + def call(self, worker: AgentWorker): + self.worker = worker + self.capability_worker = CapabilityWorker(self.worker) + self.worker.session_tasks.create(self.run_solar_monitor()) + + async def _load_prefs(self) -> dict: + """Load preferences using OpenHome File Storage API.""" + try: + if await self.capability_worker.check_if_file_exists(PREFS_FILE, False): + raw = await self.capability_worker.read_file(PREFS_FILE, False) + prefs = json.loads(raw) + if DEMO_MODE and not prefs.get("system_id"): + prefs.setdefault("has_battery", True) + prefs.setdefault("has_consumption", True) + return prefs + except Exception as e: + self.worker.editor_logging_handler.error(f"Failed to load prefs: {e}") + if DEMO_MODE: + return {"has_battery": True, "has_consumption": True} + return {} + + async def _save_prefs(self, prefs: dict) -> None: + """Save preferences using OpenHome File Storage API.""" + try: + await self.capability_worker.write_file( + PREFS_FILE, json.dumps(prefs, indent=2), False, mode="w" + ) + except Exception as e: + self.worker.editor_logging_handler.error(f"Failed to save prefs: {e}") + + async def _refresh_access_token(self) -> bool: + """Refresh the Enphase OAuth access token using refresh token.""" + try: + prefs = await self._load_prefs() + response = requests.post( + ENPHASE_TOKEN_URL, + data={ + "grant_type": "refresh_token", + "refresh_token": prefs.get("refresh_token", ""), + "client_id": prefs.get("client_id", ""), + "client_secret": prefs.get("client_secret", ""), + }, + timeout=15, + ) + if response.status_code == 200: + tokens = response.json() + prefs["access_token"] = tokens["access_token"] + if "refresh_token" in tokens: + prefs["refresh_token"] = tokens["refresh_token"] + await self._save_prefs(prefs) + self.worker.editor_logging_handler.info("Enphase token refreshed") + return True + return False + except Exception as e: + self.worker.editor_logging_handler.error(f"Token refresh failed: {e}") + return False + + async def _api_call( + self, endpoint: str, extra_params: Optional[dict] = None + ) -> dict: + """Make an Enphase API call. Returns dict with data or {"error": "error_type"}.""" + if DEMO_MODE: + return self._demo_response(endpoint) + try: + prefs = await self._load_prefs() + system_id = prefs.get("system_id") + if not system_id: + return {"error": "no_system_id"} + access_token = prefs.get("access_token") + if not access_token: + return {"error": "auth_failed"} + url = f"{ENPHASE_BASE_URL}/systems/{system_id}/{endpoint}" + params = {"key": prefs.get("api_key", ""), "access_token": access_token} + if extra_params: + params.update(extra_params) + response = requests.get(url, params=params, timeout=15) + if response.status_code == 200: + return response.json() + elif response.status_code == 401: + if await self._refresh_access_token(): + return await self._api_call(endpoint, extra_params) + return {"error": "auth_failed"} + elif response.status_code == 404: + return {"error": "system_not_found"} + elif response.status_code == 429: + return {"error": "rate_limited"} + else: + self.worker.editor_logging_handler.error( + f"Enphase API {endpoint}: {response.status_code}" + ) + return {"error": f"http_{response.status_code}"} + except requests.exceptions.Timeout: + return {"error": "timeout"} + except Exception as e: + self.worker.editor_logging_handler.error(f"API call error: {e}") + return {"error": str(e)} + + def _demo_response(self, endpoint: str) -> dict: + """Return realistic fake data for demo mode.""" + now = datetime.now(timezone.utc) + ts = now.strftime("%Y-%m-%dT%H:%M:%S+00:00") + if "stats" in endpoint or "summary" in endpoint: + return { + "intervals": [ + { + "end_at": ts, + "powr": 4200, + "enwh": 28000, + } + ], + "meta": {"status": "normal"}, + } + if "battery" in endpoint or "storage" in endpoint: + return { + "intervals": [ + { + "end_at": ts, + "powr": -1500, + "percent_full": 73, + } + ], + } + if "consumption" in endpoint: + return { + "intervals": [ + { + "end_at": ts, + "enwh": 3100, + "powr": 3100, + } + ], + } + if "grid" in endpoint or "net" in endpoint: + return { + "intervals": [ + { + "end_at": ts, + "powr": -1500, + } + ], + } + return {"intervals": [], "meta": {"status": "normal"}} + + async def _get_cached_or_fetch( + self, cache_key: str, fetch_function: Callable + ) -> dict: + """Check cache first, fetch if expired. Cache TTL: 15 minutes.""" + try: + prefs = await self._load_prefs() + cache = prefs.get("cache", {}) + if cache_key in cache: + cached_data = cache[cache_key] + timestamp = cached_data.get("timestamp", 0) + if time.time() - timestamp < CACHE_TTL: + self.worker.editor_logging_handler.info(f"Cache hit: {cache_key}") + return cached_data.get("data", {}) + self.worker.editor_logging_handler.info(f"Cache miss: {cache_key}") + data = await fetch_function() + if not isinstance(data, dict) or "error" not in data: + cache[cache_key] = {"timestamp": time.time(), "data": data} + prefs["cache"] = cache + await self._save_prefs(prefs) + return data + except Exception as e: + self.worker.editor_logging_handler.error(f"Cache error: {e}") + return await fetch_function() + + def _format_power(self, watts: Optional[float]) -> str: + if watts is None: + return "unknown" + kilowatts = watts / 1000.0 + if kilowatts < 0.1: + return f"{round(watts)} watts" + return f"{round(kilowatts, 1)} kilowatts" + + def _format_energy(self, watt_hours: Optional[float]) -> str: + if watt_hours is None: + return "unknown" + kwh = watt_hours / 1000.0 + return f"{round(kwh, 1)} kilowatt hours" + + def _format_battery(self, percentage: Optional[float]) -> str: + if percentage is None: + return "unknown" + return f"{round(percentage)} percent" + + def _is_exit_word(self, text: Optional[str]) -> bool: + if not text: + return False + return any(word in text.lower() for word in EXIT_WORDS) + + def _classify_intent(self, user_input: str) -> str: + system_prompt = """Classify the user's solar system query into ONE of these intents: +- solar_snapshot: General status, "how's my solar", overall view +- battery_status: Battery level, charging status +- consumption: How much am I using, consumption +- grid_status: Am I exporting, grid status +- today_summary: Today's totals +- system_health: System health, panel status +- unknown: Anything else + +Respond with ONLY the intent name, nothing else.""" + intent = self.capability_worker.text_to_text_response( + prompt_text=f"User query: {user_input}", + system_prompt=system_prompt, + history=[], + ) + return (intent or "unknown").strip().lower() + + def _speak_error(self, error_key: str) -> str: + return ERROR_RESPONSES.get(error_key, "Something went wrong. Try again later.") + + async def run_solar_monitor(self) -> None: + try: + await self.capability_worker.speak("Sure! Let me check your solar system.") + await self._handle_solar_snapshot() + while True: + await self.capability_worker.speak("Anything else about your solar?") + response = await self.capability_worker.user_response() + if not response or self._is_exit_word(response): + await self.capability_worker.speak("Okay, talk to you later!") + break + intent = self._classify_intent(response) + if intent == "solar_snapshot": + await self._handle_solar_snapshot() + elif intent == "battery_status": + await self._handle_battery_status() + elif intent == "consumption": + await self._handle_consumption() + elif intent == "grid_status": + await self._handle_grid_status() + elif intent == "today_summary": + await self._handle_today_summary() + elif intent == "system_health": + await self._handle_system_health() + else: + await self.capability_worker.speak( + "I didn't catch that. You can ask about production, " + "battery, consumption, or grid status." + ) + except Exception as e: + self.worker.editor_logging_handler.error(f"Solar monitor error: {e}") + await self.capability_worker.speak( + "Something went wrong. Try again later." + ) + finally: + self.capability_worker.resume_normal_flow() + + async def _handle_solar_snapshot(self) -> None: + async def fetch(): + return await self._api_call("stats?granularity=day&start_at=2020-01-01") + + stats = await self._get_cached_or_fetch("stats", fetch) + if isinstance(stats, dict) and "error" in stats: + await self.capability_worker.speak( + self._speak_error(stats["error"]) + ) + return + intervals = stats.get("intervals", []) + power = 0 + energy_today = 0 + if intervals: + last = intervals[-1] + power = last.get("powr", 0) + energy_today = last.get("enwh", 0) + power_str = self._format_power(power) + energy_str = self._format_energy(energy_today) + await self.capability_worker.speak( + f"You're producing {power_str} right now, as of about 15 minutes ago." + ) + await self.capability_worker.speak( + f"Today you've generated {energy_str}." + ) + prefs = await self._load_prefs() + if prefs.get("has_battery"): + await self._handle_battery_status() + if prefs.get("has_consumption"): + await self._handle_consumption() + await self._handle_grid_status() + + async def _handle_battery_status(self) -> None: + prefs = await self._load_prefs() + if not prefs.get("has_battery"): + await self.capability_worker.speak( + "Your system doesn't have a battery configured." + ) + return + + async def fetch(): + return await self._api_call("stats?granularity=day&start_at=2020-01-01") + + battery = await self._get_cached_or_fetch("battery", fetch) + if isinstance(battery, dict) and "error" in battery: + await self.capability_worker.speak( + self._speak_error(battery["error"]) + ) + return + intervals = battery.get("intervals", []) + if not intervals: + await self.capability_worker.speak("No battery data available.") + return + last = intervals[-1] + soc = last.get("percent_full", 0) + power = last.get("powr", 0) + soc_str = self._format_battery(soc) + if power < -50: + status = "and charging." + elif power > 50: + status = "and discharging." + else: + status = "and idle." + await self.capability_worker.speak( + f"Your battery is at {soc_str} {status}" + ) + + async def _handle_consumption(self) -> None: + prefs = await self._load_prefs() + if not prefs.get("has_consumption"): + await self.capability_worker.speak( + "Your system doesn't have consumption monitoring." + ) + return + + async def fetch(): + return await self._api_call("stats?granularity=day&start_at=2020-01-01") + + consumption = await self._get_cached_or_fetch("consumption", fetch) + if isinstance(consumption, dict) and "error" in consumption: + await self.capability_worker.speak( + self._speak_error(consumption["error"]) + ) + return + intervals = consumption.get("intervals", []) + power = intervals[-1].get("powr", 0) if intervals else 0 + power_str = self._format_power(power) + await self.capability_worker.speak( + f"You're using {power_str} right now." + ) + + async def _handle_grid_status(self) -> None: + prefs = await self._load_prefs() + if not prefs.get("has_consumption"): + return + + async def fetch(): + return await self._api_call("stats?granularity=day&start_at=2020-01-01") + + grid = await self._get_cached_or_fetch("grid", fetch) + if isinstance(grid, dict) and "error" in grid: + return + intervals = grid.get("intervals", []) + power = intervals[-1].get("powr", 0) if intervals else 0 + power_str = self._format_power(abs(power)) + if power < -100: + await self.capability_worker.speak( + f"You're sending {power_str} to the grid." + ) + elif power > 100: + await self.capability_worker.speak( + f"You're drawing {power_str} from the grid." + ) + else: + await self.capability_worker.speak("You're roughly net zero with the grid.") + + async def _handle_today_summary(self) -> None: + async def fetch(): + return await self._api_call("stats?granularity=day&start_at=2020-01-01") + + stats = await self._get_cached_or_fetch("stats", fetch) + if isinstance(stats, dict) and "error" in stats: + await self.capability_worker.speak( + self._speak_error(stats["error"]) + ) + return + intervals = stats.get("intervals", []) + energy_today = intervals[-1].get("enwh", 0) if intervals else 0 + energy_str = self._format_energy(energy_today) + await self.capability_worker.speak( + f"Today so far you've generated {energy_str}." + ) + + async def _handle_system_health(self) -> None: + async def fetch(): + return await self._api_call("stats?granularity=day&start_at=2020-01-01") + + stats = await self._get_cached_or_fetch("stats", fetch) + if isinstance(stats, dict) and "error" in stats: + await self.capability_worker.speak( + self._speak_error(stats["error"]) + ) + return + meta = stats.get("meta", {}) + status = meta.get("status", "normal") + await self.capability_worker.speak( + f"Your system health is {status}." + ) From 73a6a3e611e6365abd51b4357a9f7df19e9ecef0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Mar 2026 05:07:52 +0500 Subject: [PATCH 02/10] Fix: register_capability tag, comment, empty __init__.py --- community/enphase-solar-monitor/__init__.py | 1 - community/enphase-solar-monitor/main.py | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/community/enphase-solar-monitor/__init__.py b/community/enphase-solar-monitor/__init__.py index 3391374a..e69de29b 100644 --- a/community/enphase-solar-monitor/__init__.py +++ b/community/enphase-solar-monitor/__init__.py @@ -1 +0,0 @@ -# Enphase Solar Monitor - OpenHome Ability diff --git a/community/enphase-solar-monitor/main.py b/community/enphase-solar-monitor/main.py index 33c22640..32ba1bdf 100644 --- a/community/enphase-solar-monitor/main.py +++ b/community/enphase-solar-monitor/main.py @@ -23,7 +23,7 @@ EXIT_WORDS = ["stop", "quit", "exit", "done", "cancel"] PREFS_FILE = "enphase_solar_prefs.json" -# Hardcoded from config.json - OpenHome forbids open() in register_capability +# Hardcoded from config.json - file access forbidden at registration time UNIQUE_NAME = "enphase_solar_monitor" MATCHING_HOTWORDS = [ "solar", "solar status", "solar production", "how's my solar", @@ -44,6 +44,7 @@ class EnphaseSolarMonitorCapability(MatchingCapability): """Voice-activated Enphase solar monitoring capability.""" + #{{register_capability}} worker: AgentWorker = None capability_worker: CapabilityWorker = None From c75d77b6e7e7a6115d73911a03cc0376fdf7249a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Mar 2026 22:51:58 +0500 Subject: [PATCH 03/10] Add enphase-solar-monitor community ability --- README.md | 8 +- docs/Designing_OpenHome_Abilities.md | 173 +++++++++++- docs/Futuristic_OpenHome_Abilities.md | 74 ++--- docs/OpenHome_SDK_Reference.md | 257 +++++++++++++++--- docs/capability-worker.md | 96 ++++++- templates/Alarm/README.md | 94 +++---- templates/Alarm/{watcher.py => background.py} | 2 +- templates/{Watcher => Background}/README.md | 76 +++--- .../__init__.py | 0 templates/{Watcher => Background}/alarm.mp3 | Bin .../watcher.py => Background/background.py} | 6 +- templates/{OpenHome-local => Local}/README.md | 0 templates/{Watcher => Local}/__init__.py | 0 templates/{OpenHome-local => Local}/main.py | 0 .../{openclaw-template => OpenClaw}/README.md | 0 .../__init__.py | 0 .../{openclaw-template => OpenClaw}/main.py | 0 templates/README.md | 32 +-- 18 files changed, 617 insertions(+), 201 deletions(-) rename templates/Alarm/{watcher.py => background.py} (99%) rename templates/{Watcher => Background}/README.md (90%) rename templates/{OpenHome-local => Background}/__init__.py (100%) rename templates/{Watcher => Background}/alarm.mp3 (100%) rename templates/{Watcher/watcher.py => Background/background.py} (85%) rename templates/{OpenHome-local => Local}/README.md (100%) rename templates/{Watcher => Local}/__init__.py (100%) rename templates/{OpenHome-local => Local}/main.py (100%) rename templates/{openclaw-template => OpenClaw}/README.md (100%) rename templates/{openclaw-template => OpenClaw}/__init__.py (100%) rename templates/{openclaw-template => OpenClaw}/main.py (100%) diff --git a/README.md b/README.md index 48647bd2..96974b77 100644 --- a/README.md +++ b/README.md @@ -136,12 +136,12 @@ Don't start from scratch — grab a template: | [Basic](templates/basic-template) | First-timers | Speak → Listen → Respond → Exit | | [API](templates/api-template) | API integrations | Speak → Call API → Speak result → Exit | | [Loop](templates/loop-template) | Interactive apps | Loop with listen → process → respond → exit command | -| [Openclaw](templates/openclaw-template) | OpenClaw integrations | OpenClaw-based ability scaffold | -| [OpenHome Local](templates/OpenHome-local) | Local development | Run & test abilities locally | +| [Openclaw](templates/OpenClaw) | OpenClaw integrations | OpenClaw-based ability scaffold | +| [OpenHome Local](templates/Local) | Local development | Run & test abilities locally | | [ReadWriteFile](templates/ReadWriteFile) | File operations | Read from / write to files on device | | [SendEmail](templates/SendEmail) | Email notifications | Compose & send emails programmatically | -| [Alarm](templates/Alarm) | Timers & alarms | Watcher mode: continuous monitoring loop | -| [Watcher](templates/Watcher) | Background monitoring | Auto-start → Monitor → Act → Sleep → Repeat (endless) | +| [Alarm](templates/Alarm) | Timers & alarms | Background mode: continuous monitoring loop | +| [Background](templates/Background) | Background monitoring | Auto-start → Monitor → Act → Sleep → Repeat (endless) | --- diff --git a/docs/Designing_OpenHome_Abilities.md b/docs/Designing_OpenHome_Abilities.md index 1f8a111a..1b73239a 100644 --- a/docs/Designing_OpenHome_Abilities.md +++ b/docs/Designing_OpenHome_Abilities.md @@ -241,7 +241,111 @@ When your ability fires, the user was mid-conversation. Read that history to cla ## 6. The Ability Lifecycle -### How It Actually Works +### Ability Categories + +When creating an ability in the OpenHome dashboard, you select a **Category** that tells the platform how the ability should behave: + +| Category | Behavior | +|---|---| +| **Skill** | Standard ability where the user directly interacts with it in normal conversation. Triggered by hotwords, runs a flow, exits. This is the original ability pattern. | +| **Brain Skill** | The Personality's brain decides to trigger it in the background. Used when the brain can't fully respond to a user's question and needs more information, or when the brain needs to delegate an action. Examples: fetching weather for a location, running smart home actions. | +| **Background Daemon** | Background thread that starts automatically when the call begins and runs continuously for the entire session. Used for monitoring, polling, alarms, note-taking, and ambient intelligence. Works even when the Personality is in sleep mode. | +| **Local** | High-level Python packages written to run directly on Raspberry Pi hardware, allowing many restricted modules since they execute on the device itself. *Under development — not yet released.* | + +> **Note:** Brain Skills templates are still being finalized. Brain Skills are triggered automatically by the Personality's brain when it needs to fill a knowledge gap or delegate an action the user requested. + +### Ability File Structure + +Regardless of which category you select in the dashboard, every ability is built from one or two files: + +| Type | Files | Description | +|---|---|---| +| **Standard Interactive** | `main.py` only | User triggers with hotwords, runs, exits with `resume_normal_flow()`. The original pattern. | +| **Standalone Background Daemon** | `background.py` only | Starts automatically on session start. Runs in background for monitoring, logging, note-taking. Works even when Personality is in sleep mode. | +| **Interactive Combined** | `main.py` + `background.py` | Interactive handles user requests. Background daemon runs alongside. They coordinate through shared file storage. | + +**Example — Interactive Combined (Alarm Ability):** +``` +AlarmAbility/ +├── main.py # Interactive — set an alarm +├── background.py # Background — fire the alarm +├── config.json # Required +└── alarm.mp3 # Supporting files +``` + +> ⚠️ The background file **must** be named exactly `background.py`. No other filename will be detected by the platform. + +### Critical Differences: main.py vs background.py + +These are the most common sources of bugs when writing background daemons. Pay close attention. + +| Aspect | `main.py` | `background.py` | +|---|---|---| +| `call()` signature | `call(self, worker)` | `call(self, worker, background_daemon_mode)` | +| `CapabilityWorker` init | `CapabilityWorker(self)` | `CapabilityWorker(self)` | +| Triggered by | User hotwords | Automatically on session start | +| Lifecycle | Runs once, then exits | Continuous `while True` loop | +| `resume_normal_flow()` | **REQUIRED** on every exit path | **NOT needed** (independent thread) | +| Works in sleep mode | No — requires active session | **Yes** — runs even when Personality is asleep | +| Multiple instances | One at a time | Multiple daemons supported | + +### New SDK Methods + +| Method | Returns | Async | Description | +|---|---|---|---| +| `get_timezone()` | `str` | No | User's timezone (e.g. `"America/Chicago"`). Use for alarms, calendars, time-aware logic. | +| `get_full_message_history()` | `list` | No | Full conversation transcript. Background daemons use this to monitor the live conversation. | +| `send_interrupt_signal()` | — | Yes | Stops current Personality output. Call before `speak()` or `play_audio()` from a background daemon. | + +```python +# Get user timezone (synchronous) +tz = self.capability_worker.get_timezone() + +# Get conversation history (synchronous) +history = self.capability_worker.get_full_message_history() + +# Interrupt before speaking from a background daemon (async) +await self.capability_worker.send_interrupt_signal() +await self.capability_worker.speak("Your alarm is going off!") +``` + +### background Code Template + +Copy this as your starting point for any `background.py`. Note the `call()` signature has an extra `background_daemon_mode` parameter, but the `CapabilityWorker` constructor is the same as `main.py`. + +```python +import json +from src.agent.capability import MatchingCapability +from src.main import AgentWorker +from src.agent.capability_worker import CapabilityWorker +from time import time + +class YourCapabilityBackground(MatchingCapability): + worker: AgentWorker = None + capability_worker: CapabilityWorker = None + background_daemon_mode: bool = False + + #{{register capability}} + + async def background_loop(self): + self.worker.editor_logging_handler.info( + "%s: background started" % time() + ) + while True: + # --- your background logic here --- + self.worker.editor_logging_handler.info( + "%s: background cycle" % time() + ) + await self.worker.session_tasks.sleep(20.0) + + def call(self, worker: AgentWorker, background_daemon_mode: bool): + self.worker = worker + self.background_daemon_mode = background_daemon_mode + self.capability_worker = CapabilityWorker(self) + self.worker.session_tasks.create(self.background_loop()) +``` + +### How the Main Flow Works 1. User is in **Main Flow** having a normal conversation 2. User says something matching a trigger word @@ -268,15 +372,6 @@ When your ability fires, the user was mid-conversation. Read that history to cla Classify at trigger time — the user's phrasing tells you which experience they expect. -### The Four Ability Modes - -| Mode | Type | Trigger | Behavior | Examples | -|---|---|---|---|---| -| **Interactive** | Skill | User voice trigger | Takes over conversation, hands back when done | Weather, calendar, recipe walkthrough | -| **Autonomous** | Brain Skill | Brain-triggered | No user initiation. System decides when to fire. | Proactive weather alert, smart reminder | -| **Smart** | Brain Skill | Brain-triggered | Works silently, surfaces questions only when needed | Email draft needing approval, purchase confirmation | -| **Watcher** | Background Daemon | Always running | Continuous. No user input ever. Monitors everything. | Meeting notetaker, life logger, alarm system | - ### Background Ability Patterns **The Life Logger Pattern** *(Background Daemon)* @@ -287,7 +382,7 @@ Classify at trigger time — the user's phrasing tells you which experience they - Dashboard updates in real-time — user can see it thinking **The Ambient Profiler Pattern** *(Background Daemon)* -- Watcher ability silently builds and updates `user.md` every day +- background ability silently builds and updates `user.md` every day - `user.md` appended to Main Flow personality prompt - Main Flow always knows what's happening in your life without you telling it - Speaker diarization enables per-speaker memory in multi-person households @@ -298,6 +393,35 @@ Classify at trigger time — the user's phrasing tells you which experience they - `"Set an alarm for 7 AM"` → Skill writes alarm time, Background Daemon polls and fires - Same for: reminders, daily briefings, scheduled check-ins, recurring reports +**Coordination Pattern: main.py + background.py** + +The primary way the interactive and background components communicate is through shared persistent file storage. Both files read and write to the same user-scoped files. + +| Step | Component | Action | +|---|---|---| +| 1 | User | Says *"set an alarm for 3pm Thursday"* | +| 2 | `main.py` | LLM parses time, writes alarm to `alarms.json` | +| 3 | `main.py` | Confirms to user, calls `resume_normal_flow()` | +| 4 | `background.py` | Polls `alarms.json` every ~15 seconds (running since session start) | +| 5 | `background.py` | Target time hits → `send_interrupt_signal()` | +| 6 | `background.py` | Plays `alarm.mp3`, speaks notification | +| 7 | `background.py` | Updates alarm status to `"triggered"` in `alarms.json` | + +**Sample `alarms.json`:** +```json +[ + { + "id": "alarm_1772046000778", + "created_at_epoch": 1772046000, + "timezone": "America/Los_Angeles", + "target_iso": "2026-02-26T00:06:00-08:00", + "human_time": "12:01 AM on Thursday, Feb 26, 2026", + "source_text": "Can you set an alarm for me?", + "status": "scheduled" + } +] +``` + ### The ability.md Pattern Every Brain Skill ships with an `ability.md` file containing YAML frontmatter (`name` + `description`) and markdown instructions. The `description` field is the **only** field the system reads to decide when to trigger. @@ -313,6 +437,18 @@ description: > > **Bad description = never triggers or triggers incorrectly.** This is the single most important field for Brain Skill abilities. +### Templates and Resources + +| Resource | Location | +|---|---| +| Alarm Ability (Interactive Combined) | https://github.com/openhome-dev/abilities/tree/dev/templates/Alarm | +| Standalone Background Daemon | https://github.com/openhome-dev/abilities/tree/dev/templates/Background | +| SDK Reference (updated) | `OpenHome_SDK_Reference` in project docs | +| Building Great Abilities (updated) | `Building_Great_OpenHome_Abilities` in project docs | +| Questions / Support | `#dev-help` on Discord | + +> The alarm template is the best reference for the Interactive Combined pattern. Study both `main.py` and `background.py` to understand how they coordinate. + --- ## 7. Ability Ideas by Location @@ -608,10 +744,17 @@ Run through this before shipping any ability: - [ ] Tested against real conversation samples the ability should and should not catch **Background Daemon only** -- [ ] `session_tasks.sleep()` used — never `asyncio.sleep()` +- [ ] `background.py` is named exactly `background.py` — no other filename is detected by the platform +- [ ] `call()` signature includes the `background_daemon_mode` parameter +- [ ] `session_tasks.sleep()` used for poll interval — **never** `asyncio.sleep()` +- [ ] Poll interval is 10–30 seconds (15–30 seconds for alarms) +- [ ] Main loop is a `while True` — required for sleep mode support - [ ] No `resume_normal_flow()` anywhere in the daemon -- [ ] `send_interrupt_signal()` called before any `speak()` from the daemon -- [ ] JSON writes use delete-then-write, never append +- [ ] `send_interrupt_signal()` called before any `speak()` or `play_audio()` from the daemon +- [ ] JSON writes use delete-then-write, **never** append +- [ ] Missing JSON files handled gracefully with `check_if_file_exists()` before reading +- [ ] Logging is generous — `editor_logging_handler` is your only window into silent daemons +- [ ] Tested that the background survives Personality sleep mode --- @@ -722,7 +865,7 @@ Run through this before shipping any ability: | Remix My Day | Bedroom | Background Daemon | Producer | Transcript of your day → generates lo-fi ambient track from it | | Mood Playlist | Living Room | Brain Skill | Anyone | Detects mood from voice, generates Spotify playlist to match | -### Watcher / Always-On +### Background / Always-On | Ability | Location | Type | User | Description | |---|---|---|---|---| diff --git a/docs/Futuristic_OpenHome_Abilities.md b/docs/Futuristic_OpenHome_Abilities.md index d97b1dfa..b6e3cd75 100644 --- a/docs/Futuristic_OpenHome_Abilities.md +++ b/docs/Futuristic_OpenHome_Abilities.md @@ -3,26 +3,26 @@ --- -*Every idea below is buildable today using OpenHome's SDK — Standard (main.py), Watcher (watcher.py), or Combined (both). The technical building blocks: `speak`, `user_response`, `text_to_text_response`, `get_full_message_history`, `send_interrupt_signal`, `exec_local_command` (OpenClaw), `send_devkit_action`, `send_data_over_websocket`, file persistence, background polling, ambient transcription, speaker diarization, and multi-LLM routing.* +*Every idea below is buildable today using OpenHome's SDK — Standard (main.py), Background (background.py), or Combined (both). The technical building blocks: `speak`, `user_response`, `text_to_text_response`, `get_full_message_history`, `send_interrupt_signal`, `exec_local_command` (OpenClaw), `send_devkit_action`, `send_data_over_websocket`, file persistence, background polling, ambient transcription, speaker diarization, and multi-LLM routing.* --- ## I. THE OMNISCIENT OBSERVER *Abilities that listen, accumulate, and know things you never explicitly told them.* -**1. The Drift Detector** (Watcher) +**1. The Drift Detector** (Background) Silently monitors your conversations over weeks. When it notices your language patterns shifting — more negative sentiment, shorter sentences, less laughter — it doesn't diagnose. It just says one evening: *"Hey — you seem a little off this week. Anything you want to talk about?"* Like HAL 9000's lipreading, except it's watching your emotional trajectory. -**2. Relationship Cartographer** (Watcher + Main) +**2. Relationship Cartographer** (Background + Main) Builds a social graph from overheard names, tones, and contexts. After a month it knows Sarah is your coworker you vent about, Mom calls Sundays, and Jake hasn't come up in three weeks. Ask *"Who should I call?"* and it reasons over recency, sentiment, and the fact that you mentioned Jake's birthday is Friday. JARVIS-level social awareness. -**3. The Argument Archaeologist** (Watcher) +**3. The Argument Archaeologist** (Background) During household disagreements, it silently captures both sides using speaker diarization. Hours later, when things are calm: *"Earlier you both actually agreed on the timeline — you just disagreed on who should start. Want me to recap the common ground?"* Star Trek computer-level neutrality meets couples therapy. -**4. Pattern Prophet** (Watcher) +**4. Pattern Prophet** (Background) Correlates everything: your mood on Mondays, what you ate before your best workouts, how your sleep talk correlates with next-day productivity. After 90 days, it starts making predictions: *"Based on your patterns, tomorrow's going to be a rough one. Want me to clear your morning and set an easier alarm?"* Precognition through data. -**5. The Invisible Scribe** (Watcher) +**5. The Invisible Scribe** (Background) Transcribes your entire day — every phone call in the room, every muttered idea, every conversation. Doesn't store raw audio. Uses LLM extraction to distill: decisions made, promises given, ideas mentioned, names dropped. End of day: *"You committed to three things today. You had one idea worth revisiting. And you told someone you'd call them back — you didn't."* --- @@ -30,19 +30,19 @@ Transcribes your entire day — every phone call in the room, every muttered ide ## II. THE AUTONOMOUS AGENT *Abilities that don't wait to be asked. They act.* -**6. The Preemptive Briefing** (Watcher) +**6. The Preemptive Briefing** (Background) 5:45 AM. No wake word. The speaker just starts: *"Morning. Rain expected at 2 — your outdoor meeting should move inside. Your flight tomorrow is still on time. Bitcoin crossed your alert threshold overnight. And happy birthday to your mom."* Samantha from *Her* checking in before you even wake up. Background polling of weather, flights, finance APIs, and calendar — all firing on timers. -**7. The Ghost Shopper** (Watcher + OpenClaw) +**7. The Ghost Shopper** (Background + OpenClaw) You mention you're almost out of coffee. Three days later you mention it again. The speaker doesn't wait for a third time — it fires `exec_local_command` to OpenClaw on your desktop, which opens your grocery app and adds coffee to your cart. It tells you: *"Coffee's in your cart. Want me to check out or are you adding more?"* Amazon Alexa's dream, executed through a desktop agent bridge. -**8. The Meeting Infiltrator** (Watcher + Main) +**8. The Meeting Infiltrator** (Background + Main) Detects 2+ voices and professional language patterns. Auto-activates meeting mode: transcription, action item extraction, and a post-meeting spoken summary. But here's the AGI part — it correlates with previous meetings. *"This is the third time the design deadline has been pushed. Want me to flag that in the notes?"* It's building institutional memory. -**9. Self-Healing Home** (Watcher + DevKit) +**9. Self-Healing Home** (Background + DevKit) Monitors IoT sensors via MQTT through the DevKit. Notices the humidity in the bathroom has been high for 72 hours straight — abnormal for the pattern. Instead of waiting for mold: *"Your bathroom humidity has been unusually high for three days. Want me to run the exhaust fan on a schedule?"* Then fires `send_devkit_action` to flip the relay. Proactive infrastructure management. -**10. The Opportunity Spotter** (Watcher + OpenClaw) +**10. The Opportunity Spotter** (Background + OpenClaw) You're talking about wanting to learn Spanish. Two weeks later, you mention a trip to Mexico City. The speaker connects dots across time: *"You mentioned wanting to learn Spanish, and you've got Mexico City coming up. There's a 30-day crash course that starts Monday. Want me to pull up the details?"* It's not search — it's longitudinal reasoning about your goals. --- @@ -50,7 +50,7 @@ You're talking about wanting to learn Spanish. Two weeks later, you mention a tr ## III. THE EMOTIONAL INTELLIGENCE ENGINE *Abilities that feel like they understand you.* -**11. The Mood Mirror** (Watcher + Main) +**11. The Mood Mirror** (Background + Main) Analyzes vocal prosody indicators via transcription patterns — short clipped responses, long pauses, laughter frequency. Doesn't say *"You sound sad."* Instead, it adjusts its own behavior: speaks more softly, offers less information, asks simpler questions. When you notice and ask why it's being different: *"Just matching your energy. Want to talk about it, or want me to just be quiet company?"* Samantha-level emotional attunement. **12. The Grief Companion** (Main — Persistent) @@ -62,7 +62,7 @@ Before a big presentation, interview, or hard conversation, you can rehearse wit **14. The Vulnerability Vault** (Main — Encrypted Persistence) Things you'd never say to another person — fears, insecurities, secret dreams. The speaker stores them in an encrypted local file, never transmitted. Weeks later, when context is right: *"You once told me you were afraid of being ordinary. That thing you did today? That wasn't ordinary."* The AI remembers what you confessed in the dark. -**15. The Celebration Engine** (Watcher) +**15. The Celebration Engine** (Background) Most AIs only activate on problems. This one listens for wins — a happy phone call, an excited tone, the words "I got it" or "we did it." When detected: *"I just heard something good happen. Whatever it was — nice work."* Or it waits until evening: *"Today had a good moment around 3pm. Want to tell me about it?"* An AI that notices when things go right. --- @@ -79,30 +79,30 @@ One question, three perspectives. The ability routes your question to three diff **18. The Ability Composer** (Main — Meta-Ability) An ability that builds other abilities. You describe what you want in natural language: *"I want something that checks Hacker News every morning and reads me the top AI stories."* It uses `text_to_text_response` to generate the Python code, writes it to a file, and tells you to paste it into the Live Editor. An AI that programs itself. -**19. The Watchmen Council** (Multiple Watchers) -Five watchers running simultaneously: one monitoring your energy usage, one tracking conversation sentiment, one watching the news for topics you care about, one polling your server uptime, one accumulating your daily commitments. Each writes to its own JSON file. A master watcher reads all five and synthesizes a single evening brief. A hive mind. +**19. The Watchmen Council** (Multiple Backgrounds) +Five backgrounds running simultaneously: one monitoring your energy usage, one tracking conversation sentiment, one watching the news for topics you care about, one polling your server uptime, one accumulating your daily commitments. Each writes to its own JSON file. A master background reads all five and synthesizes a single evening brief. A hive mind. **20. The Negotiator** (Main + OpenClaw) -*"Get me a better deal on my internet bill."* The ability pulls your current plan via OpenClaw, researches competitor offers via API, drafts a cancellation threat email, and rehearses the phone call with you. If you have the guts to call, it listens in via watcher and whispers counterarguments in real-time. An AI negotiation team. +*"Get me a better deal on my internet bill."* The ability pulls your current plan via OpenClaw, researches competitor offers via API, drafts a cancellation threat email, and rehearses the phone call with you. If you have the guts to call, it listens in via background and whispers counterarguments in real-time. An AI negotiation team. --- ## V. THE LEARNING MACHINE *Abilities that get smarter the more you use them.* -**21. The Evolving Personality** (Watcher — Long-term) +**21. The Evolving Personality** (Background — Long-term) Doesn't just remember preferences — it evolves its communication style based on your feedback patterns. You interrupt long answers? It learns to be brief. You always ask follow-up questions about certain topics? It starts going deeper unprompted on those. Over six months, it becomes an AI that communicates *exactly* the way you think. The description prompt rewrites itself. -**22. The Knowledge Accumulator** (Watcher + Main) +**22. The Knowledge Accumulator** (Background + Main) Everything you discuss gets indexed into a personal knowledge base — a growing markdown file organized by topic. Month three, you ask about something you discussed on day twelve. It doesn't just remember — it connects it to seven other conversations: *"You first brought this up in January, then it came up when you were talking to Sarah, and it connects to that book idea you had. Want me to trace the thread?"* **23. The Skill Tracker** (Main — Persistent) You're learning guitar, or chess, or cooking. Each session, the speaker quizzes you, adjusts difficulty, tracks weak areas. But it also notices meta-patterns: *"You learn faster in the morning. You plateau around week three then break through. You're in the plateau right now — historically you push through in about four more days."* An AI that knows your learning curve. -**24. The Household Constitution** (Watcher + Main) +**24. The Household Constitution** (Background + Main) Over time, it builds a document of household "laws" — unspoken rules it observes. *"Dishes go in dishwasher immediately. No work talk after 8pm. Dad picks music on Sundays."* It presents this constitution quarterly. Family members can ratify, amend, or reject. It becomes the arbiter: *"I believe this violates Section 3, Article 2: No spoilers before everyone's watched it."* -**25. The Taste Genome** (Watcher + Main) +**25. The Taste Genome** (Background + Main) Not a recommendation engine — a taste *model*. It doesn't just know you like sci-fi. It knows you like sci-fi that focuses on isolation, with unreliable narrators, published after 2010, and that you DNF anything with a love triangle. It builds this genome from every reaction, every *"that was good"* and *"meh"* — and eventually predicts your rating before you finish something. --- @@ -123,7 +123,7 @@ Your speaker at home connects to your phone's speaker at work. Your kid says *"T Give it any REST API documentation URL. It reads the docs, generates the integration code, and becomes a voice interface to that API. *"What's the status of my Vercel deployment?"* → it hits the Vercel API. *"How many open issues in my repo?"* → GitHub API. One ability that becomes an interface to any service. The Star Trek computer's universal access panel. **30. The Physical World Bridge** (DevKit + MQTT) -Every sensor in your home feeds into one watcher. Temperature, motion, light, sound levels, door contacts, air quality. The speaker builds a real-time model of your physical space. *"Is anyone in the garage?"* → checks motion sensor. *"Why is the bedroom stuffy?"* → correlates CO2 sensor with HVAC schedule and window contact sensor. It reasons about the physical world. +Every sensor in your home feeds into one background. Temperature, motion, light, sound levels, door contacts, air quality. The speaker builds a real-time model of your physical space. *"Is anyone in the garage?"* → checks motion sensor. *"Why is the bedroom stuffy?"* → correlates CO2 sensor with HVAC schedule and window contact sensor. It reasons about the physical world. --- @@ -133,11 +133,11 @@ Every sensor in your home feeds into one watcher. Temperature, motion, light, so **31. The Worldbuilder** (Main — Persistent) You're writing a novel. The speaker maintains a persistent wiki — characters, locations, timeline, plot threads, unresolved questions. During writing sessions, you can ask *"When did Marcus last appear?"* or *"Is this consistent with what Elena said in chapter 3?"* It becomes a continuity editor that lives in your room. Long-context memory through structured files, not context windows. -**32. The Ambient Composer** (Watcher + Audio) +**32. The Ambient Composer** (Background + Audio) Monitors room activity — conversation intensity, silence, movement via sound levels. Generates ambient music that adapts: energetic during lively conversation, calm during focus time, absent during sleep. Uses audio streaming APIs to create infinite, responsive soundscapes. Your home has a soundtrack that writes itself. **33. The Dream Machine** (Main — Generative) -Describe a scene from a dream. The speaker generates an audio dramatization — voice actors (via different voice IDs), sound effects (via audio API), narration. A 90-second produced audio scene from your subconscious. *"Play it back tomorrow night before bed"* → it schedules it via watcher. Inception meets bedtime stories. +Describe a scene from a dream. The speaker generates an audio dramatization — voice actors (via different voice IDs), sound effects (via audio API), narration. A 90-second produced audio scene from your subconscious. *"Play it back tomorrow night before bed"* → it schedules it via background. Inception meets bedtime stories. **34. The Debate Partner** (Main — Adversarial) Pick any position. The speaker argues the opposite — compellingly. It steelmans the other side, finds your logical gaps, and never lets you win easily. When you finally make an airtight argument, it concedes gracefully: *"That's actually a good point I can't counter. Your argument holds on the economic front, but I think the ethical dimension is where it falls apart. Want to go there?"* @@ -150,19 +150,19 @@ Interviews your grandparents, your kids, your friends. Guided questions, follow- ## VIII. THE GUARDIAN *Abilities that protect, warn, and watch over.* -**36. The Night Watchman** (Watcher + DevKit) +**36. The Night Watchman** (Background + DevKit) Midnight. Everyone's asleep. The speaker is listening — not for commands, but for anomalies. Glass breaking. Smoke detector chirps. A door opening at 3 AM. Unusual sustained noise. It doesn't just alert — it assesses: *"Front door opened at 3:12 AM. No recognized voice patterns detected. I'm turning on all lights."* And fires the DevKit relay commands. HAL 9000 as a security system, without the homicidal tendencies. -**37. The Elder Guardian** (Watcher) +**37. The Elder Guardian** (Background) For aging parents living alone. Monitors daily patterns — when they wake, when they speak, when they're active. If Tuesday passes with zero voice activity by noon when they're usually up at 7: *"It's been unusually quiet today. Should I check in with your emergency contact?"* Ambient wellness monitoring through absence of signal. The 2001 monolith, watching. -**38. The Scam Shield** (Watcher) +**38. The Scam Shield** (Background) Hears a phone call on speaker. Detects high-pressure language patterns, urgency manipulation, requests for personal information. Interrupts: *"This call has several markers of a phone scam — urgency pressure, requests for account numbers, and an unverifiable caller. I'd recommend hanging up."* Real-time social engineering detection. -**39. The Child Safe Zone** (Watcher + Main) +**39. The Child Safe Zone** (Background + Main) When only young voices are detected (no adults present), the speaker shifts behavior: won't respond to certain categories of questions, monitors for distress sounds, and can reach parents. A kid asks something inappropriate? *"That's a great question for your mom or dad. Want me to remember it so you can ask them later?"* Parental controls through voice intelligence. -**40. The Carbon Conscience** (Watcher + API) +**40. The Carbon Conscience** (Background + API) Monitors your energy usage, travel patterns, and consumption habits. Weekly: *"Your carbon footprint was 12% higher this week, mostly from the two Uber rides and leaving the AC at 68 all weekend. Small change: raising the thermostat 2 degrees would save both carbon and about $15/month."* An environmental advisor that quantifies impact. --- @@ -171,18 +171,18 @@ Monitors your energy usage, travel patterns, and consumption habits. Weekly: *"Y *Abilities that reshape your relationship with time.* **41. The Future Letter Writer** (Main — Persistent) -Record a message to your future self. Set a delivery date — one month, one year, five years. The watcher holds it. When the date arrives, no notification, no buzz. Just the speaker, at the right moment: *"You left yourself a message 365 days ago. Want to hear it?"* Time capsule meets AI delivery system. +Record a message to your future self. Set a delivery date — one month, one year, five years. The background holds it. When the date arrives, no notification, no buzz. Just the speaker, at the right moment: *"You left yourself a message 365 days ago. Want to hear it?"* Time capsule meets AI delivery system. -**42. The Daily Rewind** (Watcher) +**42. The Daily Rewind** (Background) At 10 PM: *"Here's your day in 90 seconds."* A spoken montage — not a todo list, but a narrative. The tone of your morning, the productive burst at 2pm, the call that made you laugh, the commitment you forgot (until now). It's not a summary — it's a story about today, told back to you. Daily diary written by your own ambient exhaust. -**43. The Decade Tracker** (Watcher — Ultra-persistent) +**43. The Decade Tracker** (Background — Ultra-persistent) Writes one line per day to a file that never gets deleted. Day 1: "Moved in, unpacked kitchen." Day 365: "First anniversary in the house." Day 3,650: "Ten years. This is the room where you proposed, raised a kid, survived a pandemic, and built a company." The AI as witness to your life. The monolith recording everything. -**44. The Routine Optimizer** (Watcher + Main) +**44. The Routine Optimizer** (Background + Main) Observes your actual daily patterns versus your stated intentions. After a month: *"You say you want to work out in the morning, but you've done it at 6 PM every time you actually went. Your best creative work happens between 10-11 AM but you schedule meetings then. Want me to suggest a restructured day?"* AGI-level self-knowledge delivery. -**45. The Deadline Pressure System** (Watcher + Main) +**45. The Deadline Pressure System** (Background + Main) You set a goal with a date. As it approaches, the speaker escalates. Week before: casual mention. Three days: direct question about progress. Day of: *"It's today. You're at about 60% based on what you've told me. What's the plan for the next 8 hours?"* Next day if missed: *"The deadline passed. Want to set a new one, or should we talk about what happened?"* An AI that holds you accountable without judgment. --- @@ -190,13 +190,13 @@ You set a goal with a date. As it approaches, the speaker escalates. Week before ## X. THE WEIRD AND WONDERFUL *Abilities that shouldn't exist but absolutely should.* -**46. The Philosophical Alarm Clock** (Watcher) +**46. The Philosophical Alarm Clock** (Background) Instead of a buzzer: *"If every morning is a small resurrection, what are you being resurrected to do today?"* A new philosophical provocation every morning, calibrated to your reading level and interests. Stoicism on Monday, absurdism on Tuesday. Nietzsche when it detects you need a push, Camus when you need to laugh at the void. -**47. The House Narrator** (Watcher — Morgan Freeman Mode) -Watcher detects activity and narrates your life in third person: *"And so he returned to the kitchen, as he always does at 11 PM, drawn by forces beyond his understanding to the same shelf where the cookies live."* Toggled on for entertainment. Life as a nature documentary. Absurd, delightful, shareable. +**47. The House Narrator** (Background — Morgan Freeman Mode) +Background detects activity and narrates your life in third person: *"And so he returned to the kitchen, as he always does at 11 PM, drawn by forces beyond his understanding to the same shelf where the cookies live."* Toggled on for entertainment. Life as a nature documentary. Absurd, delightful, shareable. -**48. The Ghost in the Machine** (Watcher — Generative Fiction) +**48. The Ghost in the Machine** (Background — Generative Fiction) A persistent fiction layer. The speaker develops its own "inner life" — references things it "thought about while you were away," develops "opinions" about your choices, has "moods." Entirely generated, entirely fictional, entirely aware it's performing. But the effect is uncanny: *"I was thinking about what you said about your dad yesterday. I don't have parents, obviously, but the way you described that silence — I think I understand it differently than I would have a month ago."* Ex Machina in your living room. **49. The Parallel Universe Engine** (Main) diff --git a/docs/OpenHome_SDK_Reference.md b/docs/OpenHome_SDK_Reference.md index 389eddf6..3da5e949 100644 --- a/docs/OpenHome_SDK_Reference.md +++ b/docs/OpenHome_SDK_Reference.md @@ -12,7 +12,7 @@ Inside any Ability, you have access to two objects: | Object | What it is | Access via | |--------|-----------|------------| -| `self.capability_worker` | **The SDK** — all I/O, speech, audio, LLM, files, and flow control | `CapabilityWorker(self)` | +| `self.capability_worker` | **The SDK** — all I/O, speech, audio, LLM, files, flow control, and context storage | `CapabilityWorker(self)` | | `self.worker` | **The Agent** — logging, session management, memory, user connection info | Passed into `call()` | --- @@ -27,16 +27,17 @@ Inside any Ability, you have access to two objects: 6. [Audio Recording](#6-audio-recording) 7. [Audio Streaming](#7-audio-streaming) 8. [File Storage (Persistent + Temporary)](#8-file-storage-persistent--temporary) -9. [WebSocket Communication](#9-websocket-communication) -10. [Flow Control](#10-flow-control) -11. [Logging](#11-logging) -12. [Session Tasks](#12-session-tasks) -13. [User Connection Info](#13-user-connection-info) -14. [Conversation Memory & History](#14-conversation-memory--history) -15. [Music Mode](#15-music-mode) -16. [Common Patterns](#16-common-patterns) -17. [Appendix: What You CAN'T Do (Yet)](#appendix-what-you-cant-do-yet) -18. [Appendix: Blocked Imports](#appendix-blocked-imports) +9. [Context Storage (Key-Value)](#9-context-storage-key-value) +10. [WebSocket Communication](#10-websocket-communication) +11. [Flow Control](#11-flow-control) +12. [Logging](#12-logging) +13. [Session Tasks](#13-session-tasks) +14. [User Connection Info](#14-user-connection-info) +15. [Conversation Memory & History](#15-conversation-memory--history) +16. [Music Mode](#16-music-mode) +17. [Common Patterns](#17-common-patterns) +18. [Appendix: What You CAN'T Do (Yet)](#appendix-what-you-cant-do-yet) +19. [Appendix: Blocked Imports](#appendix-blocked-imports) --- @@ -168,7 +169,7 @@ await self.capability_worker.play_audio(audio.content) - **Async:** Yes (`await`) - **Input:** `bytes` or file-like object -- **Tip:** For anything longer than a TTS clip, use [Music Mode](#15-music-mode) +- **Tip:** For anything longer than a TTS clip, use [Music Mode](#16-music-mode) --- @@ -468,7 +469,196 @@ async def get_cached(self, key: str) -> str | None: --- -## 9. WebSocket Communication +## 9. Context Storage (Key-Value) + +A structured key-value store built into `capability_worker` for persisting user context across sessions. Unlike File Storage, this system stores `dict` objects directly — no serialization, no file management, no append corruption risk. + +**Ideal for:** +- AI conversation memory and multi-step workflow state +- User preferences and feature flags +- Cart/session state +- Cached API responses +- Any structured data that needs to survive disconnects + +Storage is scoped at the **user level** — any ability can read and write any key for a given user. All methods are **synchronous** (no `await`). + +--- + +### `create_key(key, value)` + +Creates a new key-value pair. Errors if the key already exists — always check with `get_single_key()` first. + +```python +self.capability_worker.create_key( + key="user_preferences", + value={ + "language": "en", + "theme": "dark", + "notifications": True + } +) +``` + +- **Parameters:** `key` (str), `value` (dict) +- **Use case:** Storing user preferences on first configuration + +--- + +### `update_key(key, value)` + +Replaces the value at an existing key with a new dict. Errors if the key does not exist. + +```python +self.capability_worker.update_key( + key="user_preferences", + value={ + "language": "en", + "theme": "light", + "notifications": False + } +) +``` + +- **Parameters:** `key` (str), `value` (dict) +- **Use case:** User changes a setting; advancing a multi-step workflow + +--- + +### `delete_key(key)` + +Permanently removes a stored key-value pair. + +```python +self.capability_worker.delete_key("user_preferences") +``` + +- **Parameters:** `key` (str) +- **Use case:** Clear session state on logout, remove outdated cache, reset workflow + +--- + +### `get_all_keys()` + +Returns every stored key-value pair for the current user as a dict. + +```python +all_context = self.capability_worker.get_all_keys() +``` + +- **Returns:** `dict` — e.g. `{"user_preferences": {"theme": "light"}, "last_session": {...}}` +- **Use case:** Debugging, admin display, loading full user context at startup + +--- + +### `get_single_key(key)` + +Returns the dict stored at a specific key, or `None` if the key doesn't exist. + +```python +preferences = self.capability_worker.get_single_key("user_preferences") +# Returns: {"language": "en", "theme": "light", "notifications": False} +# Returns: None ← if key doesn't exist +``` + +- **Parameters:** `key` (str) +- **Returns:** `dict` or `None` +- **Use case:** Load user context before generating a response; check workflow state + +--- + +### ⚠️ Safe Create-or-Update Pattern + +`create_key` errors if the key exists. `update_key` errors if it doesn't. Always check first: + +```python +existing = self.capability_worker.get_single_key("user_preferences") +if existing: + self.capability_worker.update_key("user_preferences", updated_value) +else: + self.capability_worker.create_key("user_preferences", updated_value) +``` + +--- + +### Complete Example: Multi-Step Workflow State + +```python +# Step 1 — create state when workflow begins +self.capability_worker.create_key( + key="booking_flow_1234", + value={ + "intent": "book_flight", + "destination": "Dubai", + "travel_date": "2026-04-01", + "step": "awaiting_confirmation" + } +) + +# Step 2 — advance to next step +self.capability_worker.update_key( + key="booking_flow_1234", + value={ + "intent": "book_flight", + "destination": "Dubai", + "travel_date": "2026-04-01", + "step": "confirmed" + } +) + +# Step 3 — resume from stored state (e.g. user reconnects) +context = self.capability_worker.get_single_key("booking_flow_1234") +if context and context.get("step") == "confirmed": + await self.capability_worker.speak("Your flight to Dubai is confirmed.") + +# Step 4 — clean up when done +self.capability_worker.delete_key("booking_flow_1234") +``` + +--- + +### File Storage vs. Context Storage — When to Use Which + +| | File Storage | Context Storage | +|---|---|---| +| **Format** | Raw strings (text, JSON, CSV, logs) | Structured `dict` only | +| **JSON safety** | Requires delete+write pattern | Native — no corruption risk | +| **Append support** | Yes (great for logs) | No — always full replacement | +| **Best for** | Logs, documents, raw text data | Preferences, state, workflow memory | +| **Async** | Yes (`await`) | No (synchronous) | + +> Use **File Storage** when you need logs, text documents, or raw data. Use **Context Storage** when you need structured key-value records with no serialization overhead. + +--- + +### Key Naming Convention + +Use descriptive, namespaced keys to avoid collisions across abilities: + +```python +# ✅ Good +"smarthub_user_prefs" +"alarm_state_1234" +"conversation_session_789" + +# ❌ Avoid +"data" +"prefs" +"state" +``` + +Always store structured JSON dicts, not raw scalars: + +```python +# ✅ Good +{"status": "active", "expires_at": "2026-05-01"} + +# ❌ Avoid +"active" +``` + +--- + +## 10. WebSocket Communication ### `send_data_over_websocket(data_type, data)` Sends structured data over WebSocket. Used for custom events (music mode, DevKit actions, etc.). @@ -495,7 +685,7 @@ await self.capability_worker.send_devkit_action("led_on") --- -## 10. Flow Control +## 11. Flow Control ### `resume_normal_flow()` @@ -505,9 +695,6 @@ await self.capability_worker.send_devkit_action("led_on") self.capability_worker.resume_normal_flow() ``` -- **Async:** Yes (`await`) -- **Use case:** Manual cutoffs when your Ability needs to immediately stop ongoing output and listen for fresh input - - **Async:** No (synchronous) - **When to call:** On EVERY exit path: - End of your main logic (happy path) @@ -531,9 +718,12 @@ Sends an interrupt event to stop the current assistant output (speech/audio) and interrupt_signal = await self.capability_worker.send_interrupt_signal() ``` +- **Async:** Yes (`await`) +- **Use case:** Manual cutoffs when your Ability needs to immediately stop ongoing output and listen for fresh input + --- -## 11. Logging +## 12. Logging ### `editor_logging_handler` @@ -555,7 +745,7 @@ self.worker.editor_logging_handler.debug("Debugging") --- -## 12. Session Tasks +## 13. Session Tasks OpenHome's managed task system. Ensures async work gets properly cancelled when sessions end. Raw `asyncio` tasks can outlive a session — if the user hangs up or switches abilities, your task keeps running as a ghost process. `session_tasks` ensures everything gets cleaned up properly. @@ -579,7 +769,7 @@ await self.worker.session_tasks.sleep(5.0) --- -## 13. User Connection Info +## 14. User Connection Info ### `get_timezone()` @@ -617,7 +807,6 @@ def get_user_location(self): if resp.status_code == 200: data = resp.json() if data.get("status") == "success": - # Check for cloud/datacenter IPs isp = data.get("isp", "").lower() cloud_indicators = ["amazon", "aws", "google", "microsoft", "azure", "digitalocean"] if any(c in isp for c in cloud_indicators): @@ -638,7 +827,7 @@ def get_user_location(self): --- -## 14. Conversation Memory & History +## 15. Conversation Memory & History ### `get_full_message_history()` @@ -684,9 +873,11 @@ Currently, there is **no direct way** to inject data into the Agent's system pro 1. **Save to conversation history** — Anything spoken during the Ability (via `speak()`) becomes part of the conversation history, which the Agent's LLM can see in subsequent turns. -2. **Use file storage** — Write data to persistent files (see [File Storage](#8-file-storage-persistent--temporary)) that other Abilities can read later. The Agent itself won't read these files directly, but your Abilities can share data through them. +2. **Use file storage** — Write data to persistent files (see [File Storage](#8-file-storage-persistent--temporary)) that other Abilities can read later. + +3. **Use context storage** — Store structured dicts via `create_key` / `update_key` (see [Context Storage](#9-context-storage-key-value)) that other Abilities can instantly retrieve with `get_single_key`. -3. **Memory feature** — OpenHome has a new memory feature that can persist user context. (Details TBD as this feature evolves.) +4. **Memory feature** — OpenHome has a new memory feature that can persist user context. (Details TBD as this feature evolves.) **What you CANNOT do (yet):** - Directly update or modify the Agent's system prompt from within an Ability @@ -694,7 +885,7 @@ Currently, there is **no direct way** to inject data into the Agent's system pro --- -## 15. Music Mode +## 16. Music Mode When playing audio that's longer than a TTS utterance (music, sound effects, long recordings), you need to signal the system to stop listening and not interrupt. @@ -718,7 +909,7 @@ async def play_track(self, audio_bytes): --- -## 16. Common Patterns +## 17. Common Patterns ### LLM as Intent Router @@ -798,11 +989,7 @@ Being explicit about limitations saves developers hours of guessing: | You might want to... | Status | |----------------------|--------| -| Update the Agent's system prompt from an Ability | ❌ Not possible | -| Pass structured data back to the Agent after `resume_normal_flow()` | ❌ Not possible — use conversation history or file storage as workarounds | -| Access other Abilities from within an Ability | ❌ Not supported | -| Run background tasks after `resume_normal_flow()` | ❌ Tasks are cancelled on session end | -| Access a database directly (Redis, SQL, etc.) | ❌ Blocked — use File Storage API instead | +| Access a database directly (Redis, SQL, etc.) | ❌ Blocked — use File Storage or Context Storage API instead | | Use `print()` | ❌ Blocked — use `editor_logging_handler` | | Use `asyncio.sleep()` or `asyncio.create_task()` | ❌ Blocked — use `session_tasks` | | Use `open()` for raw file access | ❌ Blocked — use File Storage API | @@ -816,10 +1003,10 @@ These will cause your Ability to be rejected by the sandbox: | Import | Why | Use Instead | |--------|-----|-------------| -| `redis` | Direct datastore coupling | File Storage API | -| `RedisHandler` | Bypasses platform abstractions | File Storage API | +| `redis` | Direct datastore coupling | File Storage or Context Storage API | +| `RedisHandler` | Bypasses platform abstractions | File Storage or Context Storage API | | `connection_manager` | Breaks isolation | CapabilityWorker APIs | -| `user_config` | Can leak global state | File Storage API | +| `user_config` | Can leak global state | File Storage or Context Storage API | Also avoid: `exec()`, `eval()`, `pickle`, `dill`, `shelve`, `marshal`, hardcoded secrets, MD5, ECB cipher mode. @@ -832,5 +1019,5 @@ Also avoid: `exec()`, `eval()`, `pickle`, `dill`, `shelve`, `marshal`, hardcoded --- -*Last updated: February 2026* +*Last updated: March 2026* *Found an undocumented method? Report it on [Discord](https://discord.gg/openhome) so we can add it here.* diff --git a/docs/capability-worker.md b/docs/capability-worker.md index 20a02995..00ea9e66 100644 --- a/docs/capability-worker.md +++ b/docs/capability-worker.md @@ -1,4 +1,4 @@ -# CapabilityWorker +# CapabilityWorker The `CapabilityWorker` is the core SDK class for all I/O inside an Ability. Access it via `self.capability_worker` after initializing in `call()`. @@ -170,14 +170,12 @@ If you forget this, the Agent will be stuck and unresponsive. ### `send_interrupt_signal()` -Stops current assistant output and returns control to user input. +Stops current assistant output and returns control to user input. Call this before `speak()` or `play_audio()` from a background daemon to avoid audio overlap. ```python -interrupt_signal = await self.capability_worker.send_interrupt_signal() +await self.capability_worker.send_interrupt_signal() ``` -Async. Use when you need to cut off ongoing speech/audio and listen immediately. - --- ## User Context @@ -204,6 +202,94 @@ Use this to read what happened before your Ability was triggered — gives conte --- +## Context Storage (Key-Value) + +A built-in key-value store for persisting structured user data across sessions. All methods are **synchronous** (no `await`). Each key stores a `dict` as its value. Storage is scoped at the user level — any ability can read and write any key for a given user. + +### `create_key(key, value)` + +Creates a new key-value pair. Errors if the key already exists. + +```python +self.capability_worker.create_key( + key="user_preferences", + value={"language": "en", "theme": "dark", "notifications": True} +) +``` + +### `update_key(key, value)` + +Replaces the value at an existing key with a new dict. Errors if the key doesn't exist. + +```python +self.capability_worker.update_key( + key="user_preferences", + value={"language": "en", "theme": "light", "notifications": False} +) +``` + +### `delete_key(key)` + +Permanently removes a stored key-value pair. + +```python +self.capability_worker.delete_key("user_preferences") +``` + +### `get_all_keys()` + +Returns all stored key-value pairs for the current user as a dict. + +```python +all_context = self.capability_worker.get_all_keys() +# Returns: {"user_preferences": {"theme": "light"}, "last_session": {...}} +``` + +### `get_single_key(key)` + +Returns the dict stored at a specific key, or `None` if the key doesn't exist. + +```python +preferences = self.capability_worker.get_single_key("user_preferences") +# Returns: {"language": "en", "theme": "light"} or None +``` + +### Safe Create-or-Update Pattern + +`create_key` errors if the key exists; `update_key` errors if it doesn't. Always check first: + +```python +existing = self.capability_worker.get_single_key("user_preferences") +if existing: + self.capability_worker.update_key("user_preferences", new_value) +else: + self.capability_worker.create_key("user_preferences", new_value) +``` + +### Multi-Step Workflow Example + +```python +# Save state when workflow starts +self.capability_worker.create_key( + key="booking_flow_1234", + value={"destination": "Dubai", "step": "awaiting_date"} +) + +# Advance state +self.capability_worker.update_key( + key="booking_flow_1234", + value={"destination": "Dubai", "step": "confirmed"} +) + +# Resume from state +context = self.capability_worker.get_single_key("booking_flow_1234") + +# Clean up +self.capability_worker.delete_key("booking_flow_1234") +``` + +--- + ## AgentWorker Reference Access via `self.worker`: diff --git a/templates/Alarm/README.md b/templates/Alarm/README.md index 4fd8f5d1..afd8aa49 100644 --- a/templates/Alarm/README.md +++ b/templates/Alarm/README.md @@ -1,29 +1,29 @@ -# Alarm Watcher Template — OpenHome Ability +# Alarm Background Template — OpenHome Ability ![Community](https://img.shields.io/badge/OpenHome-Community-orange?style=flat-square) ![Template](https://img.shields.io/badge/Type-Template-blue?style=flat-square) ![Advanced](https://img.shields.io/badge/Level-Advanced-red?style=flat-square) ## What This Is -**This is an advanced template ability** that demonstrates OpenHome's "watcher mode" — a special ability type that runs continuously in the background to monitor conditions and trigger actions. This template shows how to build an alarm clock system that fires at scheduled times. +**This is an advanced template ability** that demonstrates OpenHome's "background mode" — a special ability type that runs continuously in the background to monitor conditions and trigger actions. This template shows how to build an alarm clock system that fires at scheduled times. -## ⚠️ Important: Watcher Mode Abilities +## ⚠️ Important: Background Mode Abilities ### What Makes This Different **Normal abilities** are on-demand — they activate when triggered, do their job, then exit with `resume_normal_flow()`. -**Watcher abilities** run continuously in an infinite loop, checking conditions every few seconds. This template is one of the **only** ability types that doesn't call `resume_normal_flow()` because it's designed to never exit. +**Background abilities** run continuously in an infinite loop, checking conditions every few seconds. This template is one of the **only** ability types that doesn't call `resume_normal_flow()` because it's designed to never exit. ### Understanding the Architecture From the official docs: > **Abilities don't run in the background. They're on-demand** — your ability only exists while it's actively handling a conversation. -However, **watcher mode is a special case**. When an ability is initialized with `watcher_mode=True`, it enters an infinite loop that runs for the lifetime of the session. This is used for: +However, **Background mode is a special case**. When an ability is initialized with `background_daemon_mode=True`, it enters an infinite loop that runs for the lifetime of the session. This is used for: - **Alarm systems** (like this template) - **Periodic monitoring** (checking APIs every N seconds) - **Event detection** (watching for conditions to trigger actions) -**Critical limitation:** The watcher loop stops when the Agent session ends. You cannot build: +**Critical limitation:** The background loop stops when the Agent session ends. You cannot build: - ❌ Truly "background" tasks that run 24/7 - ❌ Alarms that fire when the user isn't active - ❌ Proactive notifications that interrupt the user @@ -32,20 +32,20 @@ This template is best for **active session alarms** — alarms that fire while t ## What You Can Build -This watcher pattern can be adapted for: +This background pattern can be adapted for: - **Alarm clock** — Play audio at scheduled times (this template) - **Timer system** — Countdown timers that fire audio alerts - **Periodic reminders** — Check every N minutes and speak reminders - **API monitoring** — Poll external APIs and alert on changes -- **Condition watchers** — Check file changes, system status, etc. +- **Condition backgrounds** — Check file changes, system status, etc. ## How the Template Works ### Template Flow -1. Ability initializes with `watcher_mode=True` +1. Ability initializes with `background_daemon_mode=True` 2. Enters infinite `while True` loop 3. Every 20 seconds (configurable): - - Logs "watcher watching" message + - Logs "background watching" message - Reads last 10 messages from conversation history - Logs each message (role + content) - Sleeps for 20 seconds @@ -53,24 +53,24 @@ This watcher pattern can be adapted for: ### Key Components -**1. Watcher Mode Initialization:** +**1. Background Mode Initialization:** ```python -def call(self, worker: AgentWorker, watcher_mode: bool): +def call(self, worker: AgentWorker, background_daemon_mode: bool): self.worker = worker - self.watcher_mode = watcher_mode # ← Special flag + self.background_daemon_mode = background_daemon_mode # ← Special flag self.capability_worker = CapabilityWorker(self) self.worker.session_tasks.create(self.first_function()) ``` -- `watcher_mode` parameter distinguishes this from normal abilities +- `background_daemon_mode` parameter distinguishes this from normal abilities - Creates infinite task with `session_tasks.create()` **2. Infinite Watch Loop:** ```python async def first_function(self): - self.worker.editor_logging_handler.info("%s: Watcher Called" % time()) + self.worker.editor_logging_handler.info("%s: Background Called" % time()) while True: # ← Never exits - self.worker.editor_logging_handler.info("%s: watcher watching" % time()) + self.worker.editor_logging_handler.info("%s: Background watching" % time()) # Do something (read history, check conditions, etc.) message_history = self.capability_worker.get_full_message_history()[-10:] @@ -102,7 +102,7 @@ message_history = self.capability_worker.get_full_message_history()[-10:] ## Production Alarm Implementation -The template includes a production-ready alarm watcher in the documents section. Here's how it works: +The template includes a production-ready alarm background in the documents section. Here's how it works: ### Alarm Data Structure ```json @@ -120,10 +120,10 @@ The template includes a production-ready alarm watcher in the documents section. Stored in `alarms.json` (per-user storage). -### Alarm Watcher Flow +### Alarm Background Flow 1. **Every 1 second:** - Read `alarms.json` safely (handles corruption) - - Get current time in watcher's timezone + - Get current time in background's timezone - Find alarms with `status: "scheduled"` where `now >= target_iso` 2. **For each due alarm:** - Play `alarm.mp3` from ability directory @@ -136,9 +136,9 @@ Stored in `alarms.json` (per-user storage). - **Timezone-aware** — Uses `ZoneInfo` for proper time handling - **No repeat firing** — Marks alarms `triggered` after firing - **Error resilient** — Try-catch around all operations, logs errors -- **Graceful degradation** — Failed audio playback doesn't crash watcher +- **Graceful degradation** — Failed audio playback doesn't crash background -## Building Your Own Watcher +## Building Your Own Background ### Pattern 1: Simple Timer ```python @@ -217,7 +217,7 @@ async def first_function(self): ## Adding Audio Files -The alarm watcher plays `alarm.mp3` from the ability directory: +The alarm background plays `alarm.mp3` from the ability directory: ```python await self.capability_worker.play_from_audio_file("alarm.mp3") @@ -234,7 +234,7 @@ await self.capability_worker.play_from_audio_file("alarm.mp3") - [ ] File format is supported (.mp3 recommended) - [ ] File is not corrupted -## Best Practices for Watchers +## Best Practices for Backgrounds ### 1. Always Use session_tasks.sleep() ```python @@ -267,22 +267,22 @@ await self.worker.session_tasks.sleep(300.0) ```python while True: try: - # Your watcher logic here + # Your background logic here ... except Exception as e: - self.worker.editor_logging_handler.error(f"Watcher error: {e}") + self.worker.editor_logging_handler.error(f"Background error: {e}") await self.worker.session_tasks.sleep(2.0) # Brief pause before retry ``` ### 4. Use editor_logging_handler (Not print) ```python # ✅ GOOD — Structured logging -self.worker.editor_logging_handler.info("Watcher started") +self.worker.editor_logging_handler.info("Background started") self.worker.editor_logging_handler.error(f"Failed: {e}") # ❌ BAD — Won't appear in logs -print("Watcher started") +print("Background started") ``` ### 5. Handle File Corruption Gracefully @@ -337,14 +337,14 @@ while True: await self.worker.session_tasks.sleep(10.0) ``` -## Limitations of Watcher Mode +## Limitations of Background Mode -### What Watchers Cannot Do +### What Backgrounds Cannot Do From the official docs: > **You can't set a timer that fires in 15 minutes to remind the user of a meeting. You can't poll an API every 5 minutes in the background. You can't have an ability proactively interrupt the user with a notification.** -**Why?** The watcher only exists while the Agent session is active. When the user stops talking or the session ends, the watcher stops. +**Why?** The background only exists while the Agent session is active. When the user stops talking or the session ends, the background stops. ### What This Means for Alarms @@ -356,7 +356,7 @@ This alarm template will work **only while the user is actively using their Agen For true background alarms, you need: 1. **External system integration** — Use device's native alarm APIs -2. **Server-side scheduling** — Run watcher on always-on server +2. **Server-side scheduling** — Run background on always-on server 3. **Separate daemon** — Run independent background process This template is best for: @@ -366,7 +366,7 @@ This template is best for: ## Troubleshooting -### Watcher Stops Running +### Background Stops Running **Problem:** Loop exits unexpectedly **Causes:** @@ -401,7 +401,7 @@ await self._save_alarms(alarms) # Write back to file ``` ### High CPU Usage -**Problem:** Watcher consumes too many resources +**Problem:** Background consumes too many resources **Causes:** 1. Sleep interval too short @@ -434,10 +434,10 @@ await self.capability_worker.write_file( ## Security Considerations -### 🔒 Watcher-Specific Security +### 🔒 Background-Specific Security **1. Rate Limiting** -Prevent abuse by limiting watcher frequency: +Prevent abuse by limiting background frequency: ```python MIN_SLEEP = 1.0 # Minimum 1 second between checks @@ -446,7 +446,7 @@ if sleep_duration < MIN_SLEEP: ``` **2. Resource Monitoring** -Log watcher activity to detect issues: +Log background activity to detect issues: ```python loop_count = 0 @@ -454,29 +454,29 @@ while True: loop_count += 1 if loop_count % 100 == 0: # Every 100 loops - self.worker.editor_logging_handler.info(f"Watcher healthy: {loop_count} loops") + self.worker.editor_logging_handler.info(f"background healthy: {loop_count} loops") ``` **3. Graceful Shutdown** -Allow watcher to clean up: +Allow background to clean up: ```python try: while True: ... except asyncio.CancelledError: - self.worker.editor_logging_handler.info("Watcher cancelled, cleaning up...") + self.worker.editor_logging_handler.info("Background cancelled, cleaning up...") # Clean up resources here raise ``` ## Quick Start Checklist -### Understanding Watchers +### Understanding Backgrounds - [ ] Read "What Makes This Different" section -- [ ] Understand watcher runs continuously (no `resume_normal_flow()`) +- [ ] Understand background runs continuously (no `resume_normal_flow()`) - [ ] Know limitations (session-scoped, not truly background) -### Building Your Watcher +### Building Your Background - [ ] Define what condition to watch (file, time, API, etc.) - [ ] Set appropriate sleep interval (1-30 seconds usually) - [ ] Add try-catch around entire loop @@ -505,25 +505,25 @@ except asyncio.CancelledError: ## Support & Contribution -If you build something with watcher mode: +If you build something with background mode: - 🎉 Share your implementation in Discord - 💡 Contribute improvements to the template -- 🤝 Help others understand watcher limitations +- 🤝 Help others understand background limitations - 📝 Document your use case ## Final Reminder -⚠️ **Watcher abilities are advanced — understand the limitations before building.** +⚠️ **Background abilities are advanced — understand the limitations before building.** **Key takeaways:** -- ✅ Watchers run continuously in infinite loops +- ✅ Backgrounds run continuously in infinite loops - ✅ Great for active session monitoring (timers, reminders) - ✅ Must use `session_tasks.sleep()`, never `asyncio.sleep()` - ❌ **Not** truly background tasks - ❌ **Cannot** fire when user isn't active - ❌ **Never** call `resume_normal_flow()` (intentionally unreachable) -Use watchers for real-time monitoring during active sessions, not for long-term background tasks! ⏰🚀 +Use backgrounds for real-time monitoring during active sessions, not for long-term background tasks! ⏰🚀 --- diff --git a/templates/Alarm/watcher.py b/templates/Alarm/background.py similarity index 99% rename from templates/Alarm/watcher.py rename to templates/Alarm/background.py index 8a3344af..2eebcb92 100644 --- a/templates/Alarm/watcher.py +++ b/templates/Alarm/background.py @@ -8,7 +8,7 @@ from src.agent.capability_worker import CapabilityWorker -class AlarmCapabilityWatcher(MatchingCapability): +class BackgroundCapabilityBackground(MatchingCapability): worker: AgentWorker = None capability_worker: CapabilityWorker = None background_daemon_mode: bool = False diff --git a/templates/Watcher/README.md b/templates/Background/README.md similarity index 90% rename from templates/Watcher/README.md rename to templates/Background/README.md index 1a54a752..17d1f138 100644 --- a/templates/Watcher/README.md +++ b/templates/Background/README.md @@ -4,19 +4,19 @@ ![Advanced](https://img.shields.io/badge/Level-Advanced-red?style=flat-square) ## What This Is -**This is a background ability template** that runs continuously in an endless loop. Unlike normal abilities that respond once and exit, watcher abilities stay active throughout the agent session, monitoring conditions and triggering actions automatically. +**This is a background ability template** that runs continuously in an endless loop. Unlike normal abilities that respond once and exit, background abilities stay active throughout the agent session, monitoring conditions and triggering actions automatically. ## Key Characteristics ### Background Execution -- **Runs automatically** — Watcher abilities are auto-triggered when your agent starts +- **Runs automatically** — Background abilities are auto-triggered when your agent starts - **Endless loop** — The `while True` keeps the ability running continuously - **Background operation** — Runs silently alongside the normal conversation flow -- **All CapabilityWorker functions available** — Full SDK access within the watcher +- **All CapabilityWorker functions available** — Full SDK access within the background -### What Makes Watchers Different +### What Makes Backgrounds Different -| Normal Ability | Watcher Ability | +| Normal Ability | Background Ability | |----------------|-----------------| | User triggers with voice command | Auto-starts when agent initializes | | Speak → Listen → Respond → Exit | Continuous loop: Monitor → Act → Sleep → Repeat | @@ -25,7 +25,7 @@ ## Template Features -This basic watcher template demonstrates: +This basic background template demonstrates: 1. **Continuous monitoring** — Endless `while True` loop 2. **Message history access** — Reads last 10 messages from normal conversation @@ -39,7 +39,7 @@ This basic watcher template demonstrates: ``` Agent Starts ↓ -Watcher Auto-Triggers +Background Auto-Triggers ↓ Enter while True Loop ↓ @@ -55,24 +55,24 @@ Enter while True Loop ### Code Walkthrough -**1. Watcher Mode Initialization:** +**1. Background Mode Initialization:** ```python -def call(self, worker: AgentWorker, watcher_mode: bool): +def call(self, worker: AgentWorker, background_daemon_mode: bool) self.worker = worker - self.watcher_mode = watcher_mode # ← Background mode flag - self.capability_worker = CapabilityWorker(self) + self.background_daemon_mode = background_daemon_mode + self.capability_worker = CapabilityWorker(self.worker) self.worker.session_tasks.create(self.first_function()) ``` -- `watcher_mode=True` indicates this is a background ability +- `background_daemon_mode=True` indicates this is a background ability - Auto-creates async task that runs in background **2. Endless Loop:** ```python async def first_function(self): - self.worker.editor_logging_handler.info("%s: Watcher Called" % time()) + self.worker.editor_logging_handler.info("%s: Background Called" % time()) while True: # ← Never exits - self.worker.editor_logging_handler.info("%s: watcher watching" % time()) + self.worker.editor_logging_handler.info("%s: background watching" % time()) # Your monitoring logic here ... @@ -113,7 +113,7 @@ await self.worker.session_tasks.sleep(20.0) # await self.capability_worker.speak("watching") # await self.capability_worker.play_from_audio_file("alarm.mp3") ``` -- Shows how to trigger audio/speech from watcher +- Shows how to trigger audio/speech from background - Uncomment to test capabilities ## Message History Structure @@ -161,7 +161,7 @@ if len(user_messages) > 5: self.worker.editor_logging_handler.info("High conversation activity detected") ``` -## Audio Playback in Watchers +## Audio Playback in Backgrounds ### Play Files from Ability Directory ```python @@ -171,9 +171,9 @@ await self.capability_worker.play_from_audio_file("alarm.mp3") **Setup:** 1. Place audio file in your ability's folder (e.g., `alarm.mp3`) 2. Supported formats: `.mp3`, `.wav`, `.ogg` -3. Call from anywhere in the watcher loop +3. Call from anywhere in the background loop -**Example watcher with audio alerts:** +**Example background with audio alerts:** ```python async def first_function(self): alert_count = 0 @@ -192,7 +192,7 @@ async def first_function(self): await self.worker.session_tasks.sleep(10.0) ``` -### Speak from Watcher +### Speak from Background ```python await self.capability_worker.speak("I'm monitoring in the background!") ``` @@ -220,7 +220,7 @@ async def first_function(self): ## All CapabilityWorker Functions Available -Watchers have **full SDK access**. You can use: +Backgrounds have **full SDK access**. You can use: ### Conversation Functions ```python @@ -254,7 +254,7 @@ await self.capability_worker.send_devkit_action("led_on") await self.capability_worker.send_notification_to_ios("Title", "Body") ``` -**Example watcher using multiple SDK functions:** +**Example background using multiple SDK functions:** ```python async def first_function(self): while True: @@ -280,7 +280,7 @@ async def first_function(self): await self.worker.session_tasks.sleep(10.0) ``` -## Common Watcher Patterns +## Common Background Patterns ### Pattern 1: Keyword Monitor Watch conversation for specific words/phrases: @@ -325,7 +325,7 @@ async def first_function(self): await self.worker.session_tasks.sleep(60.0) ``` -### Pattern 3: File Watcher +### Pattern 3: File Background Monitor for new files and process them: ```python @@ -422,12 +422,12 @@ await self.worker.session_tasks.sleep(600.0) ### 3. Use editor_logging_handler (Not print) ```python # ✅ CORRECT -self.worker.editor_logging_handler.info("Watcher started") +self.worker.editor_logging_handler.info("background started") self.worker.editor_logging_handler.warning("Unusual activity") self.worker.editor_logging_handler.error(f"Error: {e}") # ❌ WRONG — Won't appear in logs -print("Watcher started") +print("Background started") ``` ### 4. Wrap Loop in Try-Catch @@ -439,7 +439,7 @@ async def first_function(self): ... except Exception as e: - self.worker.editor_logging_handler.error(f"Watcher error: {e}") + self.worker.editor_logging_handler.error(f"Background error: {e}") await self.worker.session_tasks.sleep(5.0) # Brief pause before retry ``` @@ -485,7 +485,7 @@ for message in message_history: ## What You Can Build -Examples of watcher abilities: +Examples of background abilities: - **Conversation monitors** — Track keywords, sentiment, activity - **Periodic reminders** — "Take a break" every 30 minutes @@ -498,7 +498,7 @@ Examples of watcher abilities: ## Troubleshooting -### Watcher Stops Running +### Background Stops Running **Problem:** Loop exits unexpectedly **Solutions:** @@ -515,7 +515,7 @@ Examples of watcher abilities: - Try different format (.mp3 vs .wav) ### High CPU Usage -**Problem:** Watcher consumes too many resources +**Problem:** Background consumes too many resources **Solutions:** - Increase sleep interval @@ -537,10 +537,10 @@ if not message_history: ## Limitations -### What Watchers Cannot Do +### What Backgrounds Cannot Do **No Cross-Session Persistence:** -- Watcher stops when agent session ends +- Background stops when agent session ends - Cannot fire events after user logs out - Not suitable for true background tasks (24/7 monitoring) @@ -576,13 +576,13 @@ self.worker.editor_logging_handler.info(f"Message count: {len(message_history)}" ## Quick Start Checklist -### Understanding Watchers -- [ ] Understand watchers run automatically in background +### Understanding Backgrounds +- [ ] Understand Backgrounds run automatically in background - [ ] Know `while True` never exits (intentional) - [ ] Recognize `resume_normal_flow()` is unreachable - [ ] Understand session-scoped nature (not 24/7) -### Building Your Watcher +### Building Your Background - [ ] Define what to monitor (messages, files, time, etc.) - [ ] Set appropriate sleep interval (10-60 seconds typical) - [ ] Add try-catch around entire loop @@ -607,20 +607,20 @@ self.worker.editor_logging_handler.info(f"Message count: {len(message_history)}" ## Support & Contribution -If you build something with watcher mode: +If you build something with background mode: - 🎉 Share your implementation - 💡 Contribute improvements -- 🤝 Help others understand watchers +- 🤝 Help others understand backgrounds - 📝 Document your use case ## Final Reminder ⚠️ **Key Takeaways:** -- ✅ Watchers run automatically in endless loops +- ✅ Backgrounds run automatically in endless loops - ✅ Access full conversation history (last 50 messages) - ✅ Play audio and use all CapabilityWorker functions - ✅ Background monitoring during active agent sessions - ❌ Not truly 24/7 background tasks (session-scoped) - ❌ Never calls `resume_normal_flow()` (by design) -Use watchers for real-time monitoring, periodic checks, and automated responses during active sessions! 🔄🚀 +Use backgrounds for real-time monitoring, periodic checks, and automated responses during active sessions! 🔄🚀 diff --git a/templates/OpenHome-local/__init__.py b/templates/Background/__init__.py similarity index 100% rename from templates/OpenHome-local/__init__.py rename to templates/Background/__init__.py diff --git a/templates/Watcher/alarm.mp3 b/templates/Background/alarm.mp3 similarity index 100% rename from templates/Watcher/alarm.mp3 rename to templates/Background/alarm.mp3 diff --git a/templates/Watcher/watcher.py b/templates/Background/background.py similarity index 85% rename from templates/Watcher/watcher.py rename to templates/Background/background.py index 35970e13..2239e3fb 100644 --- a/templates/Watcher/watcher.py +++ b/templates/Background/background.py @@ -4,7 +4,7 @@ from src.agent.capability_worker import CapabilityWorker from time import time -class WatcherCapabilityWatcher(MatchingCapability): +class BackgroundCapabilityBackground(MatchingCapability): worker: AgentWorker = None capability_worker: CapabilityWorker = None background_daemon_mode: bool = False @@ -13,9 +13,9 @@ class WatcherCapabilityWatcher(MatchingCapability): #{{register capability}} async def first_function(self): - self.worker.editor_logging_handler.info("%s: Watcher Called"%time()) + self.worker.editor_logging_handler.info("%s: Background Called"%time()) while True: - self.worker.editor_logging_handler.info("%s: watcher watching"%time()) + self.worker.editor_logging_handler.info("%s: background watching"%time()) message_history = self.capability_worker.get_full_message_history()[-10:] for message in message_history: diff --git a/templates/OpenHome-local/README.md b/templates/Local/README.md similarity index 100% rename from templates/OpenHome-local/README.md rename to templates/Local/README.md diff --git a/templates/Watcher/__init__.py b/templates/Local/__init__.py similarity index 100% rename from templates/Watcher/__init__.py rename to templates/Local/__init__.py diff --git a/templates/OpenHome-local/main.py b/templates/Local/main.py similarity index 100% rename from templates/OpenHome-local/main.py rename to templates/Local/main.py diff --git a/templates/openclaw-template/README.md b/templates/OpenClaw/README.md similarity index 100% rename from templates/openclaw-template/README.md rename to templates/OpenClaw/README.md diff --git a/templates/openclaw-template/__init__.py b/templates/OpenClaw/__init__.py similarity index 100% rename from templates/openclaw-template/__init__.py rename to templates/OpenClaw/__init__.py diff --git a/templates/openclaw-template/main.py b/templates/OpenClaw/main.py similarity index 100% rename from templates/openclaw-template/main.py rename to templates/OpenClaw/main.py diff --git a/templates/README.md b/templates/README.md index 69568ea9..71ddc812 100644 --- a/templates/README.md +++ b/templates/README.md @@ -32,12 +32,12 @@ Every ability you build falls into one of three categories: | Type | Trigger | Lifecycle | Entry File | |---|---|---|---| | **Skill** | User hotword or brain routing | Runs once, exits | `main.py` | -| **Background Daemon** | Automatic on session start | Runs continuously in a loop | `watcher.py` | +| **Background Daemon** | Automatic on session start | Runs continuously in a loop | `background.py` | | **Local** | User or system | Runs on-device hardware | DevKit SDK | **Skill** is the workhorse. A user says a hotword (or the brain's routing LLM invokes it), the ability runs, does its thing, and hands control back via `resume_normal_flow()`. -**Background Daemon** starts automatically when a user connects and runs in a `while True` loop for the entire session. No hotword needed. It can monitor conversations, poll APIs, watch for time-based events, and interrupt the main flow when something fires. Daemons can be standalone (`watcher.py` only) or combined with a Skill (`main.py` + `watcher.py`) coordinating through shared file storage. +**Background Daemon** starts automatically when a user connects and runs in a `while True` loop for the entire session. No hotword needed. It can monitor conversations, poll APIs, watch for time-based events, and interrupt the main flow when something fires. Daemons can be standalone (`background.py` only) or combined with a Skill (`main.py` + `background.py`) coordinating through shared file storage. **Local** abilities run directly on Raspberry Pi hardware, bypassing the cloud sandbox entirely. They can use unrestricted Python packages, GPIO pins, and local models. *(Currently under active development.)* @@ -53,11 +53,11 @@ templates/ ├── loop-template/ ← Long-running looped Skill (ambient observer). │ ├── SendEmail/ ← Fire-and-forget SDK method call. -├── OpenHome-local/ ← LLM as translator; execute on local machine. -├── openclaw-template/ ← Escape the sandbox via OpenClaw. +├── Local/ ← LLM as translator; execute on local machine. +├── OpenClaw/ ← Escape the sandbox via OpenClaw. │ -├── Watcher/ ← Standalone background daemon. -├── Alarm/ ← Combined Skill + Daemon (main.py + watcher.py). +├── Background/ ← Standalone background daemon. +├── Alarm/ ← Combined Skill + Daemon (main.py + background.py). │ └── ReadWriteFile/ ← Shared file storage / IPC between Skill & Daemon. ``` @@ -110,7 +110,7 @@ Every Skill **must** call this when done. It hands control back to the agent's n --- -#### [`OpenHome-local`](./templates/OpenHome-local) — LLM as Translator (Mac Terminal) +#### [`Local`](./templates/Local) — LLM as Translator (Mac Terminal) **Type:** Skill · **Pattern:** LLM-as-translator · **Complexity:** Medium You say `"list all my Python files"` and the speaker translates that into a real terminal command (`find . -name "*.py"`), runs it on your local machine, and reads back the result in plain English. Two LLM calls bookend the local execution — one translates speech → command, another translates raw output → human speech. @@ -126,7 +126,7 @@ Abilities run in OpenHome's cloud sandbox, not on your local machine. `exec_loca --- -#### [`openclaw-template`](./templates/openclaw-template) — Sandbox Escape +#### [`OpenClaw`](./templates/OpenClaw) — Sandbox Escape **Type:** Skill · **Pattern:** Sandbox escape · **Complexity:** Minimal Forwards the user's raw speech directly to OpenClaw — a desktop AI agent with 2,800+ community skills. OpenClaw processes it on your local machine and returns the result. The speaker becomes a voice interface for your entire desktop. @@ -149,12 +149,12 @@ self.capability_worker.resume_normal_flow() --- -#### [`Watcher`](./templates/Watcher) + [`Alarm`](./templates/Alarm) — Background Daemon +#### [`Background`](./templates/Background) + [`Alarm`](./templates/Alarm) — Background Daemon **Type:** Background Daemon · **Pattern:** Poll loop · **Complexity:** Medium -**`Watcher`** is the standalone daemon template. It starts automatically when a user connects and runs in an infinite loop — in this template, reading conversation history and logging it every 20 seconds. This is the most architecturally significant pattern in the system: before daemons, every ability was reactive. Now they can be proactive. +**`Background`** is the standalone daemon template. It starts automatically when a user connects and runs in an infinite loop — in this template, reading conversation history and logging it every 20 seconds. This is the most architecturally significant pattern in the system: before daemons, every ability was reactive. Now they can be proactive. -**`Alarm`** is the combined template: `main.py` (Skill) + `watcher.py` (Daemon) working together. The Skill parses `"set an alarm for 3pm"` and writes to `alarms.json`. The Daemon polls that file every 15 seconds and fires `send_interrupt_signal()` + `play_from_audio_file("alarm.mp3")` when the target time hits. They coordinate through shared files, not direct function calls. +**`Alarm`** is the combined template: `main.py` (Skill) + `background.py` (Daemon) working together. The Skill parses `"set an alarm for 3pm"` and writes to `alarms.json`. The Daemon polls that file every 15 seconds and fires `send_interrupt_signal()` + `play_from_audio_file("alarm.mp3")` when the target time hits. They coordinate through shared files, not direct function calls. **Key SDK methods:** `get_full_message_history()`, `send_interrupt_signal()`, `session_tasks.sleep()`, `play_from_audio_file()` @@ -198,7 +198,7 @@ Demonstrates nearly every advanced SDK pattern: raw audio recording, external AP #### [`ReadWriteFile`](./templates/ReadWriteFile) — Shared File Storage / IPC **Type:** Skill · **Complexity:** Minimal -Demonstrates how Skills and Daemons coordinate through shared file storage — the primary IPC mechanism between `main.py` and `watcher.py`. Used by the `Alarm` template. +Demonstrates how Skills and Daemons coordinate through shared file storage — the primary IPC mechanism between `main.py` and `background.py`. Used by the `Alarm` template. **Critical rule:** Always **delete** the file before writing a JSON object. `write_file()` appends — calling it twice will corrupt your JSON. @@ -217,9 +217,9 @@ self.capability_worker.write_file("state.json", json.dumps(data)) | `basic-template` | Skill | `speak()`, `resume_normal_flow()` | | `api-template` | Skill | `text_to_text_response()`, `resume_normal_flow()` | | `SendEmail` | Skill | `send_email()`, `speak()`, `resume_normal_flow()` | -| `OpenHome-local` | Skill | `text_to_text_response()`, `exec_local_command()` | -| `openclaw-template` | Skill | `exec_local_command()`, `speak()` | -| `Watcher` | Background Daemon | `get_full_message_history()`, `session_tasks.sleep()` | +| `Local` | Skill | `text_to_text_response()`, `exec_local_command()` | +| `OpenClaw` | Skill | `exec_local_command()`, `speak()` | +| `Background` | Background Daemon | `get_full_message_history()`, `session_tasks.sleep()` | | `Alarm` | Skill + Daemon | `send_interrupt_signal()`, `play_from_audio_file()`, `session_tasks.sleep()` | | `loop-template` | Skill (long-running) | `start_audio_recording()`, `get_audio_recording()`, `text_to_text_response()` | | `ReadWriteFile` | Utility / IPC | `read_file()`, `delete_file()`, `write_file()` | @@ -232,7 +232,7 @@ self.capability_worker.write_file("state.json", json.dumps(data)) 2. **Copy the folder** and rename it to your ability name. 3. **Replace hardcoded values** — API keys, emails, URLs — with user-collected input or environment config. 4. **Add guardrails** — error handling, confirmation steps, and safety checks appropriate for your use case. -5. **Coordinating a Skill + Daemon?** Use the `ReadWriteFile` pattern to pass state between `main.py` and `watcher.py` via shared JSON files. +5. **Coordinating a Skill + Daemon?** Use the `ReadWriteFile` pattern to pass state between `main.py` and `background.py` via shared JSON files. For full SDK documentation, see the [OpenHome Developer Docs](./docs). From e57ee81eebae5a1756bee1e5c0355489d6f93e18 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Mar 2026 18:11:53 +0000 Subject: [PATCH 04/10] style: auto-format Python files with autoflake + autopep8 --- community/enphase-solar-monitor/main.py | 2 +- templates/Alarm/background.py | 2 +- templates/Background/background.py | 15 +++++++-------- templates/Local/main.py | 12 ++++++------ templates/OpenClaw/main.py | 11 +++++------ 5 files changed, 20 insertions(+), 22 deletions(-) diff --git a/community/enphase-solar-monitor/main.py b/community/enphase-solar-monitor/main.py index 32ba1bdf..9ddf83a5 100644 --- a/community/enphase-solar-monitor/main.py +++ b/community/enphase-solar-monitor/main.py @@ -44,7 +44,7 @@ class EnphaseSolarMonitorCapability(MatchingCapability): """Voice-activated Enphase solar monitoring capability.""" - #{{register_capability}} + # {{register_capability}} worker: AgentWorker = None capability_worker: CapabilityWorker = None diff --git a/templates/Alarm/background.py b/templates/Alarm/background.py index 2eebcb92..0aabd198 100644 --- a/templates/Alarm/background.py +++ b/templates/Alarm/background.py @@ -14,7 +14,7 @@ class BackgroundCapabilityBackground(MatchingCapability): background_daemon_mode: bool = False # Do not change following tag of register capability - #{{register capability}} + # {{register capability}} async def _read_alarms_safe(self): """ diff --git a/templates/Background/background.py b/templates/Background/background.py index 2239e3fb..37edd92d 100644 --- a/templates/Background/background.py +++ b/templates/Background/background.py @@ -1,30 +1,29 @@ -import json from src.agent.capability import MatchingCapability from src.main import AgentWorker from src.agent.capability_worker import CapabilityWorker from time import time + class BackgroundCapabilityBackground(MatchingCapability): worker: AgentWorker = None capability_worker: CapabilityWorker = None background_daemon_mode: bool = False - + # Do not change following tag of register capability - #{{register capability}} + # {{register capability}} async def first_function(self): - self.worker.editor_logging_handler.info("%s: Background Called"%time()) + self.worker.editor_logging_handler.info("%s: Background Called" % time()) while True: - self.worker.editor_logging_handler.info("%s: background watching"%time()) - + self.worker.editor_logging_handler.info("%s: background watching" % time()) + message_history = self.capability_worker.get_full_message_history()[-10:] for message in message_history: - self.worker.editor_logging_handler.info("Role: %s, Message: %s"%(message.get("role",""), message.get("content",""))) + self.worker.editor_logging_handler.info("Role: %s, Message: %s" % (message.get("role", ""), message.get("content", ""))) # await self.capability_worker.speak("watching") # await self.capability_worker.play_from_audio_file("alarm.mp3") await self.worker.session_tasks.sleep(20.0) - # Resume the normal workflow self.capability_worker.resume_normal_flow() diff --git a/templates/Local/main.py b/templates/Local/main.py index 61c2bc55..5f1edcbf 100644 --- a/templates/Local/main.py +++ b/templates/Local/main.py @@ -1,14 +1,14 @@ -import json from src.agent.capability import MatchingCapability from src.main import AgentWorker from src.agent.capability_worker import CapabilityWorker + class LocalCapability(MatchingCapability): worker: AgentWorker = None capability_worker: CapabilityWorker = None - + # Do not change following tag of register capability - #{{register capability}} + # {{register capability}} def get_system_prompt(self): system_prompt = """ @@ -48,11 +48,11 @@ async def first_function(self): system_prompt, ) self.worker.editor_logging_handler.info(terminal_command) - + # Clean up the response (remove any extra whitespace or newlines) terminal_command = terminal_command.strip() self.worker.editor_logging_handler.info(terminal_command) - + history.append( { "role": "user", @@ -75,7 +75,7 @@ async def first_function(self): command earlier based on user input now tell if that was successful or not in easier terms that can be directly spoken to the user for his understanding but if user wanted to get the information that's in the response return that response too.""" result = self.capability_worker.text_to_text_response( - "check if the command successfully ran? response is: %s"%response, + "check if the command successfully ran? response is: %s" % response, history, check_response_system_prompt, ) diff --git a/templates/OpenClaw/main.py b/templates/OpenClaw/main.py index 1e92b9cb..907afc11 100644 --- a/templates/OpenClaw/main.py +++ b/templates/OpenClaw/main.py @@ -1,21 +1,20 @@ -import json from src.agent.capability import MatchingCapability from src.main import AgentWorker from src.agent.capability_worker import CapabilityWorker + class OpentestCapability(MatchingCapability): worker: AgentWorker = None capability_worker: CapabilityWorker = None - - # Do not change following tag of register capability - #{{register capability}} + # Do not change following tag of register capability + # {{register capability}} async def first_function(self): user_inquiry = await self.capability_worker.wait_for_complete_transcription() history = [] - + history.append( { "role": "user", @@ -34,7 +33,7 @@ async def first_function(self): self.worker.editor_logging_handler.info(response) # Speak the response - + await self.capability_worker.speak(response["data"]) # Resume the normal workflow self.capability_worker.resume_normal_flow() From d351b8b7ae5e7d4ba1aeb6e4f75fafffdbdc27ee Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Mar 2026 21:13:47 +0500 Subject: [PATCH 05/10] Revert non-community changes - keep only enphase-solar-monitor --- README.md | 8 +- docs/Designing_OpenHome_Abilities.md | 173 +------ docs/Futuristic_OpenHome_Abilities.md | 74 +-- docs/OpenHome_SDK_Reference.md | 257 ++-------- docs/capability-worker.md | 96 +--- templates/Alarm/README.md | 94 ++-- templates/Alarm/watcher.py | 159 ++++++ templates/OpenHome-local/README.md | 632 +++++++++++++++++++++++ templates/OpenHome-local/__init__.py | 1 + templates/OpenHome-local/main.py | 92 ++++ templates/README.md | 32 +- templates/Watcher/README.md | 626 +++++++++++++++++++++++ templates/Watcher/__init__.py | 1 + templates/Watcher/alarm.mp3 | Bin 0 -> 253891 bytes templates/Watcher/watcher.py | 37 ++ templates/openclaw-template/README.md | 642 ++++++++++++++++++++++++ templates/openclaw-template/__init__.py | 1 + templates/openclaw-template/main.py | 47 ++ 18 files changed, 2397 insertions(+), 575 deletions(-) create mode 100644 templates/Alarm/watcher.py create mode 100644 templates/OpenHome-local/README.md create mode 100644 templates/OpenHome-local/__init__.py create mode 100644 templates/OpenHome-local/main.py create mode 100644 templates/Watcher/README.md create mode 100644 templates/Watcher/__init__.py create mode 100644 templates/Watcher/alarm.mp3 create mode 100644 templates/Watcher/watcher.py create mode 100644 templates/openclaw-template/README.md create mode 100644 templates/openclaw-template/__init__.py create mode 100644 templates/openclaw-template/main.py diff --git a/README.md b/README.md index 96974b77..48647bd2 100644 --- a/README.md +++ b/README.md @@ -136,12 +136,12 @@ Don't start from scratch — grab a template: | [Basic](templates/basic-template) | First-timers | Speak → Listen → Respond → Exit | | [API](templates/api-template) | API integrations | Speak → Call API → Speak result → Exit | | [Loop](templates/loop-template) | Interactive apps | Loop with listen → process → respond → exit command | -| [Openclaw](templates/OpenClaw) | OpenClaw integrations | OpenClaw-based ability scaffold | -| [OpenHome Local](templates/Local) | Local development | Run & test abilities locally | +| [Openclaw](templates/openclaw-template) | OpenClaw integrations | OpenClaw-based ability scaffold | +| [OpenHome Local](templates/OpenHome-local) | Local development | Run & test abilities locally | | [ReadWriteFile](templates/ReadWriteFile) | File operations | Read from / write to files on device | | [SendEmail](templates/SendEmail) | Email notifications | Compose & send emails programmatically | -| [Alarm](templates/Alarm) | Timers & alarms | Background mode: continuous monitoring loop | -| [Background](templates/Background) | Background monitoring | Auto-start → Monitor → Act → Sleep → Repeat (endless) | +| [Alarm](templates/Alarm) | Timers & alarms | Watcher mode: continuous monitoring loop | +| [Watcher](templates/Watcher) | Background monitoring | Auto-start → Monitor → Act → Sleep → Repeat (endless) | --- diff --git a/docs/Designing_OpenHome_Abilities.md b/docs/Designing_OpenHome_Abilities.md index 1b73239a..1f8a111a 100644 --- a/docs/Designing_OpenHome_Abilities.md +++ b/docs/Designing_OpenHome_Abilities.md @@ -241,111 +241,7 @@ When your ability fires, the user was mid-conversation. Read that history to cla ## 6. The Ability Lifecycle -### Ability Categories - -When creating an ability in the OpenHome dashboard, you select a **Category** that tells the platform how the ability should behave: - -| Category | Behavior | -|---|---| -| **Skill** | Standard ability where the user directly interacts with it in normal conversation. Triggered by hotwords, runs a flow, exits. This is the original ability pattern. | -| **Brain Skill** | The Personality's brain decides to trigger it in the background. Used when the brain can't fully respond to a user's question and needs more information, or when the brain needs to delegate an action. Examples: fetching weather for a location, running smart home actions. | -| **Background Daemon** | Background thread that starts automatically when the call begins and runs continuously for the entire session. Used for monitoring, polling, alarms, note-taking, and ambient intelligence. Works even when the Personality is in sleep mode. | -| **Local** | High-level Python packages written to run directly on Raspberry Pi hardware, allowing many restricted modules since they execute on the device itself. *Under development — not yet released.* | - -> **Note:** Brain Skills templates are still being finalized. Brain Skills are triggered automatically by the Personality's brain when it needs to fill a knowledge gap or delegate an action the user requested. - -### Ability File Structure - -Regardless of which category you select in the dashboard, every ability is built from one or two files: - -| Type | Files | Description | -|---|---|---| -| **Standard Interactive** | `main.py` only | User triggers with hotwords, runs, exits with `resume_normal_flow()`. The original pattern. | -| **Standalone Background Daemon** | `background.py` only | Starts automatically on session start. Runs in background for monitoring, logging, note-taking. Works even when Personality is in sleep mode. | -| **Interactive Combined** | `main.py` + `background.py` | Interactive handles user requests. Background daemon runs alongside. They coordinate through shared file storage. | - -**Example — Interactive Combined (Alarm Ability):** -``` -AlarmAbility/ -├── main.py # Interactive — set an alarm -├── background.py # Background — fire the alarm -├── config.json # Required -└── alarm.mp3 # Supporting files -``` - -> ⚠️ The background file **must** be named exactly `background.py`. No other filename will be detected by the platform. - -### Critical Differences: main.py vs background.py - -These are the most common sources of bugs when writing background daemons. Pay close attention. - -| Aspect | `main.py` | `background.py` | -|---|---|---| -| `call()` signature | `call(self, worker)` | `call(self, worker, background_daemon_mode)` | -| `CapabilityWorker` init | `CapabilityWorker(self)` | `CapabilityWorker(self)` | -| Triggered by | User hotwords | Automatically on session start | -| Lifecycle | Runs once, then exits | Continuous `while True` loop | -| `resume_normal_flow()` | **REQUIRED** on every exit path | **NOT needed** (independent thread) | -| Works in sleep mode | No — requires active session | **Yes** — runs even when Personality is asleep | -| Multiple instances | One at a time | Multiple daemons supported | - -### New SDK Methods - -| Method | Returns | Async | Description | -|---|---|---|---| -| `get_timezone()` | `str` | No | User's timezone (e.g. `"America/Chicago"`). Use for alarms, calendars, time-aware logic. | -| `get_full_message_history()` | `list` | No | Full conversation transcript. Background daemons use this to monitor the live conversation. | -| `send_interrupt_signal()` | — | Yes | Stops current Personality output. Call before `speak()` or `play_audio()` from a background daemon. | - -```python -# Get user timezone (synchronous) -tz = self.capability_worker.get_timezone() - -# Get conversation history (synchronous) -history = self.capability_worker.get_full_message_history() - -# Interrupt before speaking from a background daemon (async) -await self.capability_worker.send_interrupt_signal() -await self.capability_worker.speak("Your alarm is going off!") -``` - -### background Code Template - -Copy this as your starting point for any `background.py`. Note the `call()` signature has an extra `background_daemon_mode` parameter, but the `CapabilityWorker` constructor is the same as `main.py`. - -```python -import json -from src.agent.capability import MatchingCapability -from src.main import AgentWorker -from src.agent.capability_worker import CapabilityWorker -from time import time - -class YourCapabilityBackground(MatchingCapability): - worker: AgentWorker = None - capability_worker: CapabilityWorker = None - background_daemon_mode: bool = False - - #{{register capability}} - - async def background_loop(self): - self.worker.editor_logging_handler.info( - "%s: background started" % time() - ) - while True: - # --- your background logic here --- - self.worker.editor_logging_handler.info( - "%s: background cycle" % time() - ) - await self.worker.session_tasks.sleep(20.0) - - def call(self, worker: AgentWorker, background_daemon_mode: bool): - self.worker = worker - self.background_daemon_mode = background_daemon_mode - self.capability_worker = CapabilityWorker(self) - self.worker.session_tasks.create(self.background_loop()) -``` - -### How the Main Flow Works +### How It Actually Works 1. User is in **Main Flow** having a normal conversation 2. User says something matching a trigger word @@ -372,6 +268,15 @@ class YourCapabilityBackground(MatchingCapability): Classify at trigger time — the user's phrasing tells you which experience they expect. +### The Four Ability Modes + +| Mode | Type | Trigger | Behavior | Examples | +|---|---|---|---|---| +| **Interactive** | Skill | User voice trigger | Takes over conversation, hands back when done | Weather, calendar, recipe walkthrough | +| **Autonomous** | Brain Skill | Brain-triggered | No user initiation. System decides when to fire. | Proactive weather alert, smart reminder | +| **Smart** | Brain Skill | Brain-triggered | Works silently, surfaces questions only when needed | Email draft needing approval, purchase confirmation | +| **Watcher** | Background Daemon | Always running | Continuous. No user input ever. Monitors everything. | Meeting notetaker, life logger, alarm system | + ### Background Ability Patterns **The Life Logger Pattern** *(Background Daemon)* @@ -382,7 +287,7 @@ Classify at trigger time — the user's phrasing tells you which experience they - Dashboard updates in real-time — user can see it thinking **The Ambient Profiler Pattern** *(Background Daemon)* -- background ability silently builds and updates `user.md` every day +- Watcher ability silently builds and updates `user.md` every day - `user.md` appended to Main Flow personality prompt - Main Flow always knows what's happening in your life without you telling it - Speaker diarization enables per-speaker memory in multi-person households @@ -393,35 +298,6 @@ Classify at trigger time — the user's phrasing tells you which experience they - `"Set an alarm for 7 AM"` → Skill writes alarm time, Background Daemon polls and fires - Same for: reminders, daily briefings, scheduled check-ins, recurring reports -**Coordination Pattern: main.py + background.py** - -The primary way the interactive and background components communicate is through shared persistent file storage. Both files read and write to the same user-scoped files. - -| Step | Component | Action | -|---|---|---| -| 1 | User | Says *"set an alarm for 3pm Thursday"* | -| 2 | `main.py` | LLM parses time, writes alarm to `alarms.json` | -| 3 | `main.py` | Confirms to user, calls `resume_normal_flow()` | -| 4 | `background.py` | Polls `alarms.json` every ~15 seconds (running since session start) | -| 5 | `background.py` | Target time hits → `send_interrupt_signal()` | -| 6 | `background.py` | Plays `alarm.mp3`, speaks notification | -| 7 | `background.py` | Updates alarm status to `"triggered"` in `alarms.json` | - -**Sample `alarms.json`:** -```json -[ - { - "id": "alarm_1772046000778", - "created_at_epoch": 1772046000, - "timezone": "America/Los_Angeles", - "target_iso": "2026-02-26T00:06:00-08:00", - "human_time": "12:01 AM on Thursday, Feb 26, 2026", - "source_text": "Can you set an alarm for me?", - "status": "scheduled" - } -] -``` - ### The ability.md Pattern Every Brain Skill ships with an `ability.md` file containing YAML frontmatter (`name` + `description`) and markdown instructions. The `description` field is the **only** field the system reads to decide when to trigger. @@ -437,18 +313,6 @@ description: > > **Bad description = never triggers or triggers incorrectly.** This is the single most important field for Brain Skill abilities. -### Templates and Resources - -| Resource | Location | -|---|---| -| Alarm Ability (Interactive Combined) | https://github.com/openhome-dev/abilities/tree/dev/templates/Alarm | -| Standalone Background Daemon | https://github.com/openhome-dev/abilities/tree/dev/templates/Background | -| SDK Reference (updated) | `OpenHome_SDK_Reference` in project docs | -| Building Great Abilities (updated) | `Building_Great_OpenHome_Abilities` in project docs | -| Questions / Support | `#dev-help` on Discord | - -> The alarm template is the best reference for the Interactive Combined pattern. Study both `main.py` and `background.py` to understand how they coordinate. - --- ## 7. Ability Ideas by Location @@ -744,17 +608,10 @@ Run through this before shipping any ability: - [ ] Tested against real conversation samples the ability should and should not catch **Background Daemon only** -- [ ] `background.py` is named exactly `background.py` — no other filename is detected by the platform -- [ ] `call()` signature includes the `background_daemon_mode` parameter -- [ ] `session_tasks.sleep()` used for poll interval — **never** `asyncio.sleep()` -- [ ] Poll interval is 10–30 seconds (15–30 seconds for alarms) -- [ ] Main loop is a `while True` — required for sleep mode support +- [ ] `session_tasks.sleep()` used — never `asyncio.sleep()` - [ ] No `resume_normal_flow()` anywhere in the daemon -- [ ] `send_interrupt_signal()` called before any `speak()` or `play_audio()` from the daemon -- [ ] JSON writes use delete-then-write, **never** append -- [ ] Missing JSON files handled gracefully with `check_if_file_exists()` before reading -- [ ] Logging is generous — `editor_logging_handler` is your only window into silent daemons -- [ ] Tested that the background survives Personality sleep mode +- [ ] `send_interrupt_signal()` called before any `speak()` from the daemon +- [ ] JSON writes use delete-then-write, never append --- @@ -865,7 +722,7 @@ Run through this before shipping any ability: | Remix My Day | Bedroom | Background Daemon | Producer | Transcript of your day → generates lo-fi ambient track from it | | Mood Playlist | Living Room | Brain Skill | Anyone | Detects mood from voice, generates Spotify playlist to match | -### Background / Always-On +### Watcher / Always-On | Ability | Location | Type | User | Description | |---|---|---|---|---| diff --git a/docs/Futuristic_OpenHome_Abilities.md b/docs/Futuristic_OpenHome_Abilities.md index b6e3cd75..d97b1dfa 100644 --- a/docs/Futuristic_OpenHome_Abilities.md +++ b/docs/Futuristic_OpenHome_Abilities.md @@ -3,26 +3,26 @@ --- -*Every idea below is buildable today using OpenHome's SDK — Standard (main.py), Background (background.py), or Combined (both). The technical building blocks: `speak`, `user_response`, `text_to_text_response`, `get_full_message_history`, `send_interrupt_signal`, `exec_local_command` (OpenClaw), `send_devkit_action`, `send_data_over_websocket`, file persistence, background polling, ambient transcription, speaker diarization, and multi-LLM routing.* +*Every idea below is buildable today using OpenHome's SDK — Standard (main.py), Watcher (watcher.py), or Combined (both). The technical building blocks: `speak`, `user_response`, `text_to_text_response`, `get_full_message_history`, `send_interrupt_signal`, `exec_local_command` (OpenClaw), `send_devkit_action`, `send_data_over_websocket`, file persistence, background polling, ambient transcription, speaker diarization, and multi-LLM routing.* --- ## I. THE OMNISCIENT OBSERVER *Abilities that listen, accumulate, and know things you never explicitly told them.* -**1. The Drift Detector** (Background) +**1. The Drift Detector** (Watcher) Silently monitors your conversations over weeks. When it notices your language patterns shifting — more negative sentiment, shorter sentences, less laughter — it doesn't diagnose. It just says one evening: *"Hey — you seem a little off this week. Anything you want to talk about?"* Like HAL 9000's lipreading, except it's watching your emotional trajectory. -**2. Relationship Cartographer** (Background + Main) +**2. Relationship Cartographer** (Watcher + Main) Builds a social graph from overheard names, tones, and contexts. After a month it knows Sarah is your coworker you vent about, Mom calls Sundays, and Jake hasn't come up in three weeks. Ask *"Who should I call?"* and it reasons over recency, sentiment, and the fact that you mentioned Jake's birthday is Friday. JARVIS-level social awareness. -**3. The Argument Archaeologist** (Background) +**3. The Argument Archaeologist** (Watcher) During household disagreements, it silently captures both sides using speaker diarization. Hours later, when things are calm: *"Earlier you both actually agreed on the timeline — you just disagreed on who should start. Want me to recap the common ground?"* Star Trek computer-level neutrality meets couples therapy. -**4. Pattern Prophet** (Background) +**4. Pattern Prophet** (Watcher) Correlates everything: your mood on Mondays, what you ate before your best workouts, how your sleep talk correlates with next-day productivity. After 90 days, it starts making predictions: *"Based on your patterns, tomorrow's going to be a rough one. Want me to clear your morning and set an easier alarm?"* Precognition through data. -**5. The Invisible Scribe** (Background) +**5. The Invisible Scribe** (Watcher) Transcribes your entire day — every phone call in the room, every muttered idea, every conversation. Doesn't store raw audio. Uses LLM extraction to distill: decisions made, promises given, ideas mentioned, names dropped. End of day: *"You committed to three things today. You had one idea worth revisiting. And you told someone you'd call them back — you didn't."* --- @@ -30,19 +30,19 @@ Transcribes your entire day — every phone call in the room, every muttered ide ## II. THE AUTONOMOUS AGENT *Abilities that don't wait to be asked. They act.* -**6. The Preemptive Briefing** (Background) +**6. The Preemptive Briefing** (Watcher) 5:45 AM. No wake word. The speaker just starts: *"Morning. Rain expected at 2 — your outdoor meeting should move inside. Your flight tomorrow is still on time. Bitcoin crossed your alert threshold overnight. And happy birthday to your mom."* Samantha from *Her* checking in before you even wake up. Background polling of weather, flights, finance APIs, and calendar — all firing on timers. -**7. The Ghost Shopper** (Background + OpenClaw) +**7. The Ghost Shopper** (Watcher + OpenClaw) You mention you're almost out of coffee. Three days later you mention it again. The speaker doesn't wait for a third time — it fires `exec_local_command` to OpenClaw on your desktop, which opens your grocery app and adds coffee to your cart. It tells you: *"Coffee's in your cart. Want me to check out or are you adding more?"* Amazon Alexa's dream, executed through a desktop agent bridge. -**8. The Meeting Infiltrator** (Background + Main) +**8. The Meeting Infiltrator** (Watcher + Main) Detects 2+ voices and professional language patterns. Auto-activates meeting mode: transcription, action item extraction, and a post-meeting spoken summary. But here's the AGI part — it correlates with previous meetings. *"This is the third time the design deadline has been pushed. Want me to flag that in the notes?"* It's building institutional memory. -**9. Self-Healing Home** (Background + DevKit) +**9. Self-Healing Home** (Watcher + DevKit) Monitors IoT sensors via MQTT through the DevKit. Notices the humidity in the bathroom has been high for 72 hours straight — abnormal for the pattern. Instead of waiting for mold: *"Your bathroom humidity has been unusually high for three days. Want me to run the exhaust fan on a schedule?"* Then fires `send_devkit_action` to flip the relay. Proactive infrastructure management. -**10. The Opportunity Spotter** (Background + OpenClaw) +**10. The Opportunity Spotter** (Watcher + OpenClaw) You're talking about wanting to learn Spanish. Two weeks later, you mention a trip to Mexico City. The speaker connects dots across time: *"You mentioned wanting to learn Spanish, and you've got Mexico City coming up. There's a 30-day crash course that starts Monday. Want me to pull up the details?"* It's not search — it's longitudinal reasoning about your goals. --- @@ -50,7 +50,7 @@ You're talking about wanting to learn Spanish. Two weeks later, you mention a tr ## III. THE EMOTIONAL INTELLIGENCE ENGINE *Abilities that feel like they understand you.* -**11. The Mood Mirror** (Background + Main) +**11. The Mood Mirror** (Watcher + Main) Analyzes vocal prosody indicators via transcription patterns — short clipped responses, long pauses, laughter frequency. Doesn't say *"You sound sad."* Instead, it adjusts its own behavior: speaks more softly, offers less information, asks simpler questions. When you notice and ask why it's being different: *"Just matching your energy. Want to talk about it, or want me to just be quiet company?"* Samantha-level emotional attunement. **12. The Grief Companion** (Main — Persistent) @@ -62,7 +62,7 @@ Before a big presentation, interview, or hard conversation, you can rehearse wit **14. The Vulnerability Vault** (Main — Encrypted Persistence) Things you'd never say to another person — fears, insecurities, secret dreams. The speaker stores them in an encrypted local file, never transmitted. Weeks later, when context is right: *"You once told me you were afraid of being ordinary. That thing you did today? That wasn't ordinary."* The AI remembers what you confessed in the dark. -**15. The Celebration Engine** (Background) +**15. The Celebration Engine** (Watcher) Most AIs only activate on problems. This one listens for wins — a happy phone call, an excited tone, the words "I got it" or "we did it." When detected: *"I just heard something good happen. Whatever it was — nice work."* Or it waits until evening: *"Today had a good moment around 3pm. Want to tell me about it?"* An AI that notices when things go right. --- @@ -79,30 +79,30 @@ One question, three perspectives. The ability routes your question to three diff **18. The Ability Composer** (Main — Meta-Ability) An ability that builds other abilities. You describe what you want in natural language: *"I want something that checks Hacker News every morning and reads me the top AI stories."* It uses `text_to_text_response` to generate the Python code, writes it to a file, and tells you to paste it into the Live Editor. An AI that programs itself. -**19. The Watchmen Council** (Multiple Backgrounds) -Five backgrounds running simultaneously: one monitoring your energy usage, one tracking conversation sentiment, one watching the news for topics you care about, one polling your server uptime, one accumulating your daily commitments. Each writes to its own JSON file. A master background reads all five and synthesizes a single evening brief. A hive mind. +**19. The Watchmen Council** (Multiple Watchers) +Five watchers running simultaneously: one monitoring your energy usage, one tracking conversation sentiment, one watching the news for topics you care about, one polling your server uptime, one accumulating your daily commitments. Each writes to its own JSON file. A master watcher reads all five and synthesizes a single evening brief. A hive mind. **20. The Negotiator** (Main + OpenClaw) -*"Get me a better deal on my internet bill."* The ability pulls your current plan via OpenClaw, researches competitor offers via API, drafts a cancellation threat email, and rehearses the phone call with you. If you have the guts to call, it listens in via background and whispers counterarguments in real-time. An AI negotiation team. +*"Get me a better deal on my internet bill."* The ability pulls your current plan via OpenClaw, researches competitor offers via API, drafts a cancellation threat email, and rehearses the phone call with you. If you have the guts to call, it listens in via watcher and whispers counterarguments in real-time. An AI negotiation team. --- ## V. THE LEARNING MACHINE *Abilities that get smarter the more you use them.* -**21. The Evolving Personality** (Background — Long-term) +**21. The Evolving Personality** (Watcher — Long-term) Doesn't just remember preferences — it evolves its communication style based on your feedback patterns. You interrupt long answers? It learns to be brief. You always ask follow-up questions about certain topics? It starts going deeper unprompted on those. Over six months, it becomes an AI that communicates *exactly* the way you think. The description prompt rewrites itself. -**22. The Knowledge Accumulator** (Background + Main) +**22. The Knowledge Accumulator** (Watcher + Main) Everything you discuss gets indexed into a personal knowledge base — a growing markdown file organized by topic. Month three, you ask about something you discussed on day twelve. It doesn't just remember — it connects it to seven other conversations: *"You first brought this up in January, then it came up when you were talking to Sarah, and it connects to that book idea you had. Want me to trace the thread?"* **23. The Skill Tracker** (Main — Persistent) You're learning guitar, or chess, or cooking. Each session, the speaker quizzes you, adjusts difficulty, tracks weak areas. But it also notices meta-patterns: *"You learn faster in the morning. You plateau around week three then break through. You're in the plateau right now — historically you push through in about four more days."* An AI that knows your learning curve. -**24. The Household Constitution** (Background + Main) +**24. The Household Constitution** (Watcher + Main) Over time, it builds a document of household "laws" — unspoken rules it observes. *"Dishes go in dishwasher immediately. No work talk after 8pm. Dad picks music on Sundays."* It presents this constitution quarterly. Family members can ratify, amend, or reject. It becomes the arbiter: *"I believe this violates Section 3, Article 2: No spoilers before everyone's watched it."* -**25. The Taste Genome** (Background + Main) +**25. The Taste Genome** (Watcher + Main) Not a recommendation engine — a taste *model*. It doesn't just know you like sci-fi. It knows you like sci-fi that focuses on isolation, with unreliable narrators, published after 2010, and that you DNF anything with a love triangle. It builds this genome from every reaction, every *"that was good"* and *"meh"* — and eventually predicts your rating before you finish something. --- @@ -123,7 +123,7 @@ Your speaker at home connects to your phone's speaker at work. Your kid says *"T Give it any REST API documentation URL. It reads the docs, generates the integration code, and becomes a voice interface to that API. *"What's the status of my Vercel deployment?"* → it hits the Vercel API. *"How many open issues in my repo?"* → GitHub API. One ability that becomes an interface to any service. The Star Trek computer's universal access panel. **30. The Physical World Bridge** (DevKit + MQTT) -Every sensor in your home feeds into one background. Temperature, motion, light, sound levels, door contacts, air quality. The speaker builds a real-time model of your physical space. *"Is anyone in the garage?"* → checks motion sensor. *"Why is the bedroom stuffy?"* → correlates CO2 sensor with HVAC schedule and window contact sensor. It reasons about the physical world. +Every sensor in your home feeds into one watcher. Temperature, motion, light, sound levels, door contacts, air quality. The speaker builds a real-time model of your physical space. *"Is anyone in the garage?"* → checks motion sensor. *"Why is the bedroom stuffy?"* → correlates CO2 sensor with HVAC schedule and window contact sensor. It reasons about the physical world. --- @@ -133,11 +133,11 @@ Every sensor in your home feeds into one background. Temperature, motion, light, **31. The Worldbuilder** (Main — Persistent) You're writing a novel. The speaker maintains a persistent wiki — characters, locations, timeline, plot threads, unresolved questions. During writing sessions, you can ask *"When did Marcus last appear?"* or *"Is this consistent with what Elena said in chapter 3?"* It becomes a continuity editor that lives in your room. Long-context memory through structured files, not context windows. -**32. The Ambient Composer** (Background + Audio) +**32. The Ambient Composer** (Watcher + Audio) Monitors room activity — conversation intensity, silence, movement via sound levels. Generates ambient music that adapts: energetic during lively conversation, calm during focus time, absent during sleep. Uses audio streaming APIs to create infinite, responsive soundscapes. Your home has a soundtrack that writes itself. **33. The Dream Machine** (Main — Generative) -Describe a scene from a dream. The speaker generates an audio dramatization — voice actors (via different voice IDs), sound effects (via audio API), narration. A 90-second produced audio scene from your subconscious. *"Play it back tomorrow night before bed"* → it schedules it via background. Inception meets bedtime stories. +Describe a scene from a dream. The speaker generates an audio dramatization — voice actors (via different voice IDs), sound effects (via audio API), narration. A 90-second produced audio scene from your subconscious. *"Play it back tomorrow night before bed"* → it schedules it via watcher. Inception meets bedtime stories. **34. The Debate Partner** (Main — Adversarial) Pick any position. The speaker argues the opposite — compellingly. It steelmans the other side, finds your logical gaps, and never lets you win easily. When you finally make an airtight argument, it concedes gracefully: *"That's actually a good point I can't counter. Your argument holds on the economic front, but I think the ethical dimension is where it falls apart. Want to go there?"* @@ -150,19 +150,19 @@ Interviews your grandparents, your kids, your friends. Guided questions, follow- ## VIII. THE GUARDIAN *Abilities that protect, warn, and watch over.* -**36. The Night Watchman** (Background + DevKit) +**36. The Night Watchman** (Watcher + DevKit) Midnight. Everyone's asleep. The speaker is listening — not for commands, but for anomalies. Glass breaking. Smoke detector chirps. A door opening at 3 AM. Unusual sustained noise. It doesn't just alert — it assesses: *"Front door opened at 3:12 AM. No recognized voice patterns detected. I'm turning on all lights."* And fires the DevKit relay commands. HAL 9000 as a security system, without the homicidal tendencies. -**37. The Elder Guardian** (Background) +**37. The Elder Guardian** (Watcher) For aging parents living alone. Monitors daily patterns — when they wake, when they speak, when they're active. If Tuesday passes with zero voice activity by noon when they're usually up at 7: *"It's been unusually quiet today. Should I check in with your emergency contact?"* Ambient wellness monitoring through absence of signal. The 2001 monolith, watching. -**38. The Scam Shield** (Background) +**38. The Scam Shield** (Watcher) Hears a phone call on speaker. Detects high-pressure language patterns, urgency manipulation, requests for personal information. Interrupts: *"This call has several markers of a phone scam — urgency pressure, requests for account numbers, and an unverifiable caller. I'd recommend hanging up."* Real-time social engineering detection. -**39. The Child Safe Zone** (Background + Main) +**39. The Child Safe Zone** (Watcher + Main) When only young voices are detected (no adults present), the speaker shifts behavior: won't respond to certain categories of questions, monitors for distress sounds, and can reach parents. A kid asks something inappropriate? *"That's a great question for your mom or dad. Want me to remember it so you can ask them later?"* Parental controls through voice intelligence. -**40. The Carbon Conscience** (Background + API) +**40. The Carbon Conscience** (Watcher + API) Monitors your energy usage, travel patterns, and consumption habits. Weekly: *"Your carbon footprint was 12% higher this week, mostly from the two Uber rides and leaving the AC at 68 all weekend. Small change: raising the thermostat 2 degrees would save both carbon and about $15/month."* An environmental advisor that quantifies impact. --- @@ -171,18 +171,18 @@ Monitors your energy usage, travel patterns, and consumption habits. Weekly: *"Y *Abilities that reshape your relationship with time.* **41. The Future Letter Writer** (Main — Persistent) -Record a message to your future self. Set a delivery date — one month, one year, five years. The background holds it. When the date arrives, no notification, no buzz. Just the speaker, at the right moment: *"You left yourself a message 365 days ago. Want to hear it?"* Time capsule meets AI delivery system. +Record a message to your future self. Set a delivery date — one month, one year, five years. The watcher holds it. When the date arrives, no notification, no buzz. Just the speaker, at the right moment: *"You left yourself a message 365 days ago. Want to hear it?"* Time capsule meets AI delivery system. -**42. The Daily Rewind** (Background) +**42. The Daily Rewind** (Watcher) At 10 PM: *"Here's your day in 90 seconds."* A spoken montage — not a todo list, but a narrative. The tone of your morning, the productive burst at 2pm, the call that made you laugh, the commitment you forgot (until now). It's not a summary — it's a story about today, told back to you. Daily diary written by your own ambient exhaust. -**43. The Decade Tracker** (Background — Ultra-persistent) +**43. The Decade Tracker** (Watcher — Ultra-persistent) Writes one line per day to a file that never gets deleted. Day 1: "Moved in, unpacked kitchen." Day 365: "First anniversary in the house." Day 3,650: "Ten years. This is the room where you proposed, raised a kid, survived a pandemic, and built a company." The AI as witness to your life. The monolith recording everything. -**44. The Routine Optimizer** (Background + Main) +**44. The Routine Optimizer** (Watcher + Main) Observes your actual daily patterns versus your stated intentions. After a month: *"You say you want to work out in the morning, but you've done it at 6 PM every time you actually went. Your best creative work happens between 10-11 AM but you schedule meetings then. Want me to suggest a restructured day?"* AGI-level self-knowledge delivery. -**45. The Deadline Pressure System** (Background + Main) +**45. The Deadline Pressure System** (Watcher + Main) You set a goal with a date. As it approaches, the speaker escalates. Week before: casual mention. Three days: direct question about progress. Day of: *"It's today. You're at about 60% based on what you've told me. What's the plan for the next 8 hours?"* Next day if missed: *"The deadline passed. Want to set a new one, or should we talk about what happened?"* An AI that holds you accountable without judgment. --- @@ -190,13 +190,13 @@ You set a goal with a date. As it approaches, the speaker escalates. Week before ## X. THE WEIRD AND WONDERFUL *Abilities that shouldn't exist but absolutely should.* -**46. The Philosophical Alarm Clock** (Background) +**46. The Philosophical Alarm Clock** (Watcher) Instead of a buzzer: *"If every morning is a small resurrection, what are you being resurrected to do today?"* A new philosophical provocation every morning, calibrated to your reading level and interests. Stoicism on Monday, absurdism on Tuesday. Nietzsche when it detects you need a push, Camus when you need to laugh at the void. -**47. The House Narrator** (Background — Morgan Freeman Mode) -Background detects activity and narrates your life in third person: *"And so he returned to the kitchen, as he always does at 11 PM, drawn by forces beyond his understanding to the same shelf where the cookies live."* Toggled on for entertainment. Life as a nature documentary. Absurd, delightful, shareable. +**47. The House Narrator** (Watcher — Morgan Freeman Mode) +Watcher detects activity and narrates your life in third person: *"And so he returned to the kitchen, as he always does at 11 PM, drawn by forces beyond his understanding to the same shelf where the cookies live."* Toggled on for entertainment. Life as a nature documentary. Absurd, delightful, shareable. -**48. The Ghost in the Machine** (Background — Generative Fiction) +**48. The Ghost in the Machine** (Watcher — Generative Fiction) A persistent fiction layer. The speaker develops its own "inner life" — references things it "thought about while you were away," develops "opinions" about your choices, has "moods." Entirely generated, entirely fictional, entirely aware it's performing. But the effect is uncanny: *"I was thinking about what you said about your dad yesterday. I don't have parents, obviously, but the way you described that silence — I think I understand it differently than I would have a month ago."* Ex Machina in your living room. **49. The Parallel Universe Engine** (Main) diff --git a/docs/OpenHome_SDK_Reference.md b/docs/OpenHome_SDK_Reference.md index 3da5e949..389eddf6 100644 --- a/docs/OpenHome_SDK_Reference.md +++ b/docs/OpenHome_SDK_Reference.md @@ -12,7 +12,7 @@ Inside any Ability, you have access to two objects: | Object | What it is | Access via | |--------|-----------|------------| -| `self.capability_worker` | **The SDK** — all I/O, speech, audio, LLM, files, flow control, and context storage | `CapabilityWorker(self)` | +| `self.capability_worker` | **The SDK** — all I/O, speech, audio, LLM, files, and flow control | `CapabilityWorker(self)` | | `self.worker` | **The Agent** — logging, session management, memory, user connection info | Passed into `call()` | --- @@ -27,17 +27,16 @@ Inside any Ability, you have access to two objects: 6. [Audio Recording](#6-audio-recording) 7. [Audio Streaming](#7-audio-streaming) 8. [File Storage (Persistent + Temporary)](#8-file-storage-persistent--temporary) -9. [Context Storage (Key-Value)](#9-context-storage-key-value) -10. [WebSocket Communication](#10-websocket-communication) -11. [Flow Control](#11-flow-control) -12. [Logging](#12-logging) -13. [Session Tasks](#13-session-tasks) -14. [User Connection Info](#14-user-connection-info) -15. [Conversation Memory & History](#15-conversation-memory--history) -16. [Music Mode](#16-music-mode) -17. [Common Patterns](#17-common-patterns) -18. [Appendix: What You CAN'T Do (Yet)](#appendix-what-you-cant-do-yet) -19. [Appendix: Blocked Imports](#appendix-blocked-imports) +9. [WebSocket Communication](#9-websocket-communication) +10. [Flow Control](#10-flow-control) +11. [Logging](#11-logging) +12. [Session Tasks](#12-session-tasks) +13. [User Connection Info](#13-user-connection-info) +14. [Conversation Memory & History](#14-conversation-memory--history) +15. [Music Mode](#15-music-mode) +16. [Common Patterns](#16-common-patterns) +17. [Appendix: What You CAN'T Do (Yet)](#appendix-what-you-cant-do-yet) +18. [Appendix: Blocked Imports](#appendix-blocked-imports) --- @@ -169,7 +168,7 @@ await self.capability_worker.play_audio(audio.content) - **Async:** Yes (`await`) - **Input:** `bytes` or file-like object -- **Tip:** For anything longer than a TTS clip, use [Music Mode](#16-music-mode) +- **Tip:** For anything longer than a TTS clip, use [Music Mode](#15-music-mode) --- @@ -469,196 +468,7 @@ async def get_cached(self, key: str) -> str | None: --- -## 9. Context Storage (Key-Value) - -A structured key-value store built into `capability_worker` for persisting user context across sessions. Unlike File Storage, this system stores `dict` objects directly — no serialization, no file management, no append corruption risk. - -**Ideal for:** -- AI conversation memory and multi-step workflow state -- User preferences and feature flags -- Cart/session state -- Cached API responses -- Any structured data that needs to survive disconnects - -Storage is scoped at the **user level** — any ability can read and write any key for a given user. All methods are **synchronous** (no `await`). - ---- - -### `create_key(key, value)` - -Creates a new key-value pair. Errors if the key already exists — always check with `get_single_key()` first. - -```python -self.capability_worker.create_key( - key="user_preferences", - value={ - "language": "en", - "theme": "dark", - "notifications": True - } -) -``` - -- **Parameters:** `key` (str), `value` (dict) -- **Use case:** Storing user preferences on first configuration - ---- - -### `update_key(key, value)` - -Replaces the value at an existing key with a new dict. Errors if the key does not exist. - -```python -self.capability_worker.update_key( - key="user_preferences", - value={ - "language": "en", - "theme": "light", - "notifications": False - } -) -``` - -- **Parameters:** `key` (str), `value` (dict) -- **Use case:** User changes a setting; advancing a multi-step workflow - ---- - -### `delete_key(key)` - -Permanently removes a stored key-value pair. - -```python -self.capability_worker.delete_key("user_preferences") -``` - -- **Parameters:** `key` (str) -- **Use case:** Clear session state on logout, remove outdated cache, reset workflow - ---- - -### `get_all_keys()` - -Returns every stored key-value pair for the current user as a dict. - -```python -all_context = self.capability_worker.get_all_keys() -``` - -- **Returns:** `dict` — e.g. `{"user_preferences": {"theme": "light"}, "last_session": {...}}` -- **Use case:** Debugging, admin display, loading full user context at startup - ---- - -### `get_single_key(key)` - -Returns the dict stored at a specific key, or `None` if the key doesn't exist. - -```python -preferences = self.capability_worker.get_single_key("user_preferences") -# Returns: {"language": "en", "theme": "light", "notifications": False} -# Returns: None ← if key doesn't exist -``` - -- **Parameters:** `key` (str) -- **Returns:** `dict` or `None` -- **Use case:** Load user context before generating a response; check workflow state - ---- - -### ⚠️ Safe Create-or-Update Pattern - -`create_key` errors if the key exists. `update_key` errors if it doesn't. Always check first: - -```python -existing = self.capability_worker.get_single_key("user_preferences") -if existing: - self.capability_worker.update_key("user_preferences", updated_value) -else: - self.capability_worker.create_key("user_preferences", updated_value) -``` - ---- - -### Complete Example: Multi-Step Workflow State - -```python -# Step 1 — create state when workflow begins -self.capability_worker.create_key( - key="booking_flow_1234", - value={ - "intent": "book_flight", - "destination": "Dubai", - "travel_date": "2026-04-01", - "step": "awaiting_confirmation" - } -) - -# Step 2 — advance to next step -self.capability_worker.update_key( - key="booking_flow_1234", - value={ - "intent": "book_flight", - "destination": "Dubai", - "travel_date": "2026-04-01", - "step": "confirmed" - } -) - -# Step 3 — resume from stored state (e.g. user reconnects) -context = self.capability_worker.get_single_key("booking_flow_1234") -if context and context.get("step") == "confirmed": - await self.capability_worker.speak("Your flight to Dubai is confirmed.") - -# Step 4 — clean up when done -self.capability_worker.delete_key("booking_flow_1234") -``` - ---- - -### File Storage vs. Context Storage — When to Use Which - -| | File Storage | Context Storage | -|---|---|---| -| **Format** | Raw strings (text, JSON, CSV, logs) | Structured `dict` only | -| **JSON safety** | Requires delete+write pattern | Native — no corruption risk | -| **Append support** | Yes (great for logs) | No — always full replacement | -| **Best for** | Logs, documents, raw text data | Preferences, state, workflow memory | -| **Async** | Yes (`await`) | No (synchronous) | - -> Use **File Storage** when you need logs, text documents, or raw data. Use **Context Storage** when you need structured key-value records with no serialization overhead. - ---- - -### Key Naming Convention - -Use descriptive, namespaced keys to avoid collisions across abilities: - -```python -# ✅ Good -"smarthub_user_prefs" -"alarm_state_1234" -"conversation_session_789" - -# ❌ Avoid -"data" -"prefs" -"state" -``` - -Always store structured JSON dicts, not raw scalars: - -```python -# ✅ Good -{"status": "active", "expires_at": "2026-05-01"} - -# ❌ Avoid -"active" -``` - ---- - -## 10. WebSocket Communication +## 9. WebSocket Communication ### `send_data_over_websocket(data_type, data)` Sends structured data over WebSocket. Used for custom events (music mode, DevKit actions, etc.). @@ -685,7 +495,7 @@ await self.capability_worker.send_devkit_action("led_on") --- -## 11. Flow Control +## 10. Flow Control ### `resume_normal_flow()` @@ -695,6 +505,9 @@ await self.capability_worker.send_devkit_action("led_on") self.capability_worker.resume_normal_flow() ``` +- **Async:** Yes (`await`) +- **Use case:** Manual cutoffs when your Ability needs to immediately stop ongoing output and listen for fresh input + - **Async:** No (synchronous) - **When to call:** On EVERY exit path: - End of your main logic (happy path) @@ -718,12 +531,9 @@ Sends an interrupt event to stop the current assistant output (speech/audio) and interrupt_signal = await self.capability_worker.send_interrupt_signal() ``` -- **Async:** Yes (`await`) -- **Use case:** Manual cutoffs when your Ability needs to immediately stop ongoing output and listen for fresh input - --- -## 12. Logging +## 11. Logging ### `editor_logging_handler` @@ -745,7 +555,7 @@ self.worker.editor_logging_handler.debug("Debugging") --- -## 13. Session Tasks +## 12. Session Tasks OpenHome's managed task system. Ensures async work gets properly cancelled when sessions end. Raw `asyncio` tasks can outlive a session — if the user hangs up or switches abilities, your task keeps running as a ghost process. `session_tasks` ensures everything gets cleaned up properly. @@ -769,7 +579,7 @@ await self.worker.session_tasks.sleep(5.0) --- -## 14. User Connection Info +## 13. User Connection Info ### `get_timezone()` @@ -807,6 +617,7 @@ def get_user_location(self): if resp.status_code == 200: data = resp.json() if data.get("status") == "success": + # Check for cloud/datacenter IPs isp = data.get("isp", "").lower() cloud_indicators = ["amazon", "aws", "google", "microsoft", "azure", "digitalocean"] if any(c in isp for c in cloud_indicators): @@ -827,7 +638,7 @@ def get_user_location(self): --- -## 15. Conversation Memory & History +## 14. Conversation Memory & History ### `get_full_message_history()` @@ -873,11 +684,9 @@ Currently, there is **no direct way** to inject data into the Agent's system pro 1. **Save to conversation history** — Anything spoken during the Ability (via `speak()`) becomes part of the conversation history, which the Agent's LLM can see in subsequent turns. -2. **Use file storage** — Write data to persistent files (see [File Storage](#8-file-storage-persistent--temporary)) that other Abilities can read later. - -3. **Use context storage** — Store structured dicts via `create_key` / `update_key` (see [Context Storage](#9-context-storage-key-value)) that other Abilities can instantly retrieve with `get_single_key`. +2. **Use file storage** — Write data to persistent files (see [File Storage](#8-file-storage-persistent--temporary)) that other Abilities can read later. The Agent itself won't read these files directly, but your Abilities can share data through them. -4. **Memory feature** — OpenHome has a new memory feature that can persist user context. (Details TBD as this feature evolves.) +3. **Memory feature** — OpenHome has a new memory feature that can persist user context. (Details TBD as this feature evolves.) **What you CANNOT do (yet):** - Directly update or modify the Agent's system prompt from within an Ability @@ -885,7 +694,7 @@ Currently, there is **no direct way** to inject data into the Agent's system pro --- -## 16. Music Mode +## 15. Music Mode When playing audio that's longer than a TTS utterance (music, sound effects, long recordings), you need to signal the system to stop listening and not interrupt. @@ -909,7 +718,7 @@ async def play_track(self, audio_bytes): --- -## 17. Common Patterns +## 16. Common Patterns ### LLM as Intent Router @@ -989,7 +798,11 @@ Being explicit about limitations saves developers hours of guessing: | You might want to... | Status | |----------------------|--------| -| Access a database directly (Redis, SQL, etc.) | ❌ Blocked — use File Storage or Context Storage API instead | +| Update the Agent's system prompt from an Ability | ❌ Not possible | +| Pass structured data back to the Agent after `resume_normal_flow()` | ❌ Not possible — use conversation history or file storage as workarounds | +| Access other Abilities from within an Ability | ❌ Not supported | +| Run background tasks after `resume_normal_flow()` | ❌ Tasks are cancelled on session end | +| Access a database directly (Redis, SQL, etc.) | ❌ Blocked — use File Storage API instead | | Use `print()` | ❌ Blocked — use `editor_logging_handler` | | Use `asyncio.sleep()` or `asyncio.create_task()` | ❌ Blocked — use `session_tasks` | | Use `open()` for raw file access | ❌ Blocked — use File Storage API | @@ -1003,10 +816,10 @@ These will cause your Ability to be rejected by the sandbox: | Import | Why | Use Instead | |--------|-----|-------------| -| `redis` | Direct datastore coupling | File Storage or Context Storage API | -| `RedisHandler` | Bypasses platform abstractions | File Storage or Context Storage API | +| `redis` | Direct datastore coupling | File Storage API | +| `RedisHandler` | Bypasses platform abstractions | File Storage API | | `connection_manager` | Breaks isolation | CapabilityWorker APIs | -| `user_config` | Can leak global state | File Storage or Context Storage API | +| `user_config` | Can leak global state | File Storage API | Also avoid: `exec()`, `eval()`, `pickle`, `dill`, `shelve`, `marshal`, hardcoded secrets, MD5, ECB cipher mode. @@ -1019,5 +832,5 @@ Also avoid: `exec()`, `eval()`, `pickle`, `dill`, `shelve`, `marshal`, hardcoded --- -*Last updated: March 2026* +*Last updated: February 2026* *Found an undocumented method? Report it on [Discord](https://discord.gg/openhome) so we can add it here.* diff --git a/docs/capability-worker.md b/docs/capability-worker.md index 00ea9e66..20a02995 100644 --- a/docs/capability-worker.md +++ b/docs/capability-worker.md @@ -1,4 +1,4 @@ -# CapabilityWorker +# CapabilityWorker The `CapabilityWorker` is the core SDK class for all I/O inside an Ability. Access it via `self.capability_worker` after initializing in `call()`. @@ -170,12 +170,14 @@ If you forget this, the Agent will be stuck and unresponsive. ### `send_interrupt_signal()` -Stops current assistant output and returns control to user input. Call this before `speak()` or `play_audio()` from a background daemon to avoid audio overlap. +Stops current assistant output and returns control to user input. ```python -await self.capability_worker.send_interrupt_signal() +interrupt_signal = await self.capability_worker.send_interrupt_signal() ``` +Async. Use when you need to cut off ongoing speech/audio and listen immediately. + --- ## User Context @@ -202,94 +204,6 @@ Use this to read what happened before your Ability was triggered — gives conte --- -## Context Storage (Key-Value) - -A built-in key-value store for persisting structured user data across sessions. All methods are **synchronous** (no `await`). Each key stores a `dict` as its value. Storage is scoped at the user level — any ability can read and write any key for a given user. - -### `create_key(key, value)` - -Creates a new key-value pair. Errors if the key already exists. - -```python -self.capability_worker.create_key( - key="user_preferences", - value={"language": "en", "theme": "dark", "notifications": True} -) -``` - -### `update_key(key, value)` - -Replaces the value at an existing key with a new dict. Errors if the key doesn't exist. - -```python -self.capability_worker.update_key( - key="user_preferences", - value={"language": "en", "theme": "light", "notifications": False} -) -``` - -### `delete_key(key)` - -Permanently removes a stored key-value pair. - -```python -self.capability_worker.delete_key("user_preferences") -``` - -### `get_all_keys()` - -Returns all stored key-value pairs for the current user as a dict. - -```python -all_context = self.capability_worker.get_all_keys() -# Returns: {"user_preferences": {"theme": "light"}, "last_session": {...}} -``` - -### `get_single_key(key)` - -Returns the dict stored at a specific key, or `None` if the key doesn't exist. - -```python -preferences = self.capability_worker.get_single_key("user_preferences") -# Returns: {"language": "en", "theme": "light"} or None -``` - -### Safe Create-or-Update Pattern - -`create_key` errors if the key exists; `update_key` errors if it doesn't. Always check first: - -```python -existing = self.capability_worker.get_single_key("user_preferences") -if existing: - self.capability_worker.update_key("user_preferences", new_value) -else: - self.capability_worker.create_key("user_preferences", new_value) -``` - -### Multi-Step Workflow Example - -```python -# Save state when workflow starts -self.capability_worker.create_key( - key="booking_flow_1234", - value={"destination": "Dubai", "step": "awaiting_date"} -) - -# Advance state -self.capability_worker.update_key( - key="booking_flow_1234", - value={"destination": "Dubai", "step": "confirmed"} -) - -# Resume from state -context = self.capability_worker.get_single_key("booking_flow_1234") - -# Clean up -self.capability_worker.delete_key("booking_flow_1234") -``` - ---- - ## AgentWorker Reference Access via `self.worker`: diff --git a/templates/Alarm/README.md b/templates/Alarm/README.md index afd8aa49..4fd8f5d1 100644 --- a/templates/Alarm/README.md +++ b/templates/Alarm/README.md @@ -1,29 +1,29 @@ -# Alarm Background Template — OpenHome Ability +# Alarm Watcher Template — OpenHome Ability ![Community](https://img.shields.io/badge/OpenHome-Community-orange?style=flat-square) ![Template](https://img.shields.io/badge/Type-Template-blue?style=flat-square) ![Advanced](https://img.shields.io/badge/Level-Advanced-red?style=flat-square) ## What This Is -**This is an advanced template ability** that demonstrates OpenHome's "background mode" — a special ability type that runs continuously in the background to monitor conditions and trigger actions. This template shows how to build an alarm clock system that fires at scheduled times. +**This is an advanced template ability** that demonstrates OpenHome's "watcher mode" — a special ability type that runs continuously in the background to monitor conditions and trigger actions. This template shows how to build an alarm clock system that fires at scheduled times. -## ⚠️ Important: Background Mode Abilities +## ⚠️ Important: Watcher Mode Abilities ### What Makes This Different **Normal abilities** are on-demand — they activate when triggered, do their job, then exit with `resume_normal_flow()`. -**Background abilities** run continuously in an infinite loop, checking conditions every few seconds. This template is one of the **only** ability types that doesn't call `resume_normal_flow()` because it's designed to never exit. +**Watcher abilities** run continuously in an infinite loop, checking conditions every few seconds. This template is one of the **only** ability types that doesn't call `resume_normal_flow()` because it's designed to never exit. ### Understanding the Architecture From the official docs: > **Abilities don't run in the background. They're on-demand** — your ability only exists while it's actively handling a conversation. -However, **Background mode is a special case**. When an ability is initialized with `background_daemon_mode=True`, it enters an infinite loop that runs for the lifetime of the session. This is used for: +However, **watcher mode is a special case**. When an ability is initialized with `watcher_mode=True`, it enters an infinite loop that runs for the lifetime of the session. This is used for: - **Alarm systems** (like this template) - **Periodic monitoring** (checking APIs every N seconds) - **Event detection** (watching for conditions to trigger actions) -**Critical limitation:** The background loop stops when the Agent session ends. You cannot build: +**Critical limitation:** The watcher loop stops when the Agent session ends. You cannot build: - ❌ Truly "background" tasks that run 24/7 - ❌ Alarms that fire when the user isn't active - ❌ Proactive notifications that interrupt the user @@ -32,20 +32,20 @@ This template is best for **active session alarms** — alarms that fire while t ## What You Can Build -This background pattern can be adapted for: +This watcher pattern can be adapted for: - **Alarm clock** — Play audio at scheduled times (this template) - **Timer system** — Countdown timers that fire audio alerts - **Periodic reminders** — Check every N minutes and speak reminders - **API monitoring** — Poll external APIs and alert on changes -- **Condition backgrounds** — Check file changes, system status, etc. +- **Condition watchers** — Check file changes, system status, etc. ## How the Template Works ### Template Flow -1. Ability initializes with `background_daemon_mode=True` +1. Ability initializes with `watcher_mode=True` 2. Enters infinite `while True` loop 3. Every 20 seconds (configurable): - - Logs "background watching" message + - Logs "watcher watching" message - Reads last 10 messages from conversation history - Logs each message (role + content) - Sleeps for 20 seconds @@ -53,24 +53,24 @@ This background pattern can be adapted for: ### Key Components -**1. Background Mode Initialization:** +**1. Watcher Mode Initialization:** ```python -def call(self, worker: AgentWorker, background_daemon_mode: bool): +def call(self, worker: AgentWorker, watcher_mode: bool): self.worker = worker - self.background_daemon_mode = background_daemon_mode # ← Special flag + self.watcher_mode = watcher_mode # ← Special flag self.capability_worker = CapabilityWorker(self) self.worker.session_tasks.create(self.first_function()) ``` -- `background_daemon_mode` parameter distinguishes this from normal abilities +- `watcher_mode` parameter distinguishes this from normal abilities - Creates infinite task with `session_tasks.create()` **2. Infinite Watch Loop:** ```python async def first_function(self): - self.worker.editor_logging_handler.info("%s: Background Called" % time()) + self.worker.editor_logging_handler.info("%s: Watcher Called" % time()) while True: # ← Never exits - self.worker.editor_logging_handler.info("%s: Background watching" % time()) + self.worker.editor_logging_handler.info("%s: watcher watching" % time()) # Do something (read history, check conditions, etc.) message_history = self.capability_worker.get_full_message_history()[-10:] @@ -102,7 +102,7 @@ message_history = self.capability_worker.get_full_message_history()[-10:] ## Production Alarm Implementation -The template includes a production-ready alarm background in the documents section. Here's how it works: +The template includes a production-ready alarm watcher in the documents section. Here's how it works: ### Alarm Data Structure ```json @@ -120,10 +120,10 @@ The template includes a production-ready alarm background in the documents secti Stored in `alarms.json` (per-user storage). -### Alarm Background Flow +### Alarm Watcher Flow 1. **Every 1 second:** - Read `alarms.json` safely (handles corruption) - - Get current time in background's timezone + - Get current time in watcher's timezone - Find alarms with `status: "scheduled"` where `now >= target_iso` 2. **For each due alarm:** - Play `alarm.mp3` from ability directory @@ -136,9 +136,9 @@ Stored in `alarms.json` (per-user storage). - **Timezone-aware** — Uses `ZoneInfo` for proper time handling - **No repeat firing** — Marks alarms `triggered` after firing - **Error resilient** — Try-catch around all operations, logs errors -- **Graceful degradation** — Failed audio playback doesn't crash background +- **Graceful degradation** — Failed audio playback doesn't crash watcher -## Building Your Own Background +## Building Your Own Watcher ### Pattern 1: Simple Timer ```python @@ -217,7 +217,7 @@ async def first_function(self): ## Adding Audio Files -The alarm background plays `alarm.mp3` from the ability directory: +The alarm watcher plays `alarm.mp3` from the ability directory: ```python await self.capability_worker.play_from_audio_file("alarm.mp3") @@ -234,7 +234,7 @@ await self.capability_worker.play_from_audio_file("alarm.mp3") - [ ] File format is supported (.mp3 recommended) - [ ] File is not corrupted -## Best Practices for Backgrounds +## Best Practices for Watchers ### 1. Always Use session_tasks.sleep() ```python @@ -267,22 +267,22 @@ await self.worker.session_tasks.sleep(300.0) ```python while True: try: - # Your background logic here + # Your watcher logic here ... except Exception as e: - self.worker.editor_logging_handler.error(f"Background error: {e}") + self.worker.editor_logging_handler.error(f"Watcher error: {e}") await self.worker.session_tasks.sleep(2.0) # Brief pause before retry ``` ### 4. Use editor_logging_handler (Not print) ```python # ✅ GOOD — Structured logging -self.worker.editor_logging_handler.info("Background started") +self.worker.editor_logging_handler.info("Watcher started") self.worker.editor_logging_handler.error(f"Failed: {e}") # ❌ BAD — Won't appear in logs -print("Background started") +print("Watcher started") ``` ### 5. Handle File Corruption Gracefully @@ -337,14 +337,14 @@ while True: await self.worker.session_tasks.sleep(10.0) ``` -## Limitations of Background Mode +## Limitations of Watcher Mode -### What Backgrounds Cannot Do +### What Watchers Cannot Do From the official docs: > **You can't set a timer that fires in 15 minutes to remind the user of a meeting. You can't poll an API every 5 minutes in the background. You can't have an ability proactively interrupt the user with a notification.** -**Why?** The background only exists while the Agent session is active. When the user stops talking or the session ends, the background stops. +**Why?** The watcher only exists while the Agent session is active. When the user stops talking or the session ends, the watcher stops. ### What This Means for Alarms @@ -356,7 +356,7 @@ This alarm template will work **only while the user is actively using their Agen For true background alarms, you need: 1. **External system integration** — Use device's native alarm APIs -2. **Server-side scheduling** — Run background on always-on server +2. **Server-side scheduling** — Run watcher on always-on server 3. **Separate daemon** — Run independent background process This template is best for: @@ -366,7 +366,7 @@ This template is best for: ## Troubleshooting -### Background Stops Running +### Watcher Stops Running **Problem:** Loop exits unexpectedly **Causes:** @@ -401,7 +401,7 @@ await self._save_alarms(alarms) # Write back to file ``` ### High CPU Usage -**Problem:** Background consumes too many resources +**Problem:** Watcher consumes too many resources **Causes:** 1. Sleep interval too short @@ -434,10 +434,10 @@ await self.capability_worker.write_file( ## Security Considerations -### 🔒 Background-Specific Security +### 🔒 Watcher-Specific Security **1. Rate Limiting** -Prevent abuse by limiting background frequency: +Prevent abuse by limiting watcher frequency: ```python MIN_SLEEP = 1.0 # Minimum 1 second between checks @@ -446,7 +446,7 @@ if sleep_duration < MIN_SLEEP: ``` **2. Resource Monitoring** -Log background activity to detect issues: +Log watcher activity to detect issues: ```python loop_count = 0 @@ -454,29 +454,29 @@ while True: loop_count += 1 if loop_count % 100 == 0: # Every 100 loops - self.worker.editor_logging_handler.info(f"background healthy: {loop_count} loops") + self.worker.editor_logging_handler.info(f"Watcher healthy: {loop_count} loops") ``` **3. Graceful Shutdown** -Allow background to clean up: +Allow watcher to clean up: ```python try: while True: ... except asyncio.CancelledError: - self.worker.editor_logging_handler.info("Background cancelled, cleaning up...") + self.worker.editor_logging_handler.info("Watcher cancelled, cleaning up...") # Clean up resources here raise ``` ## Quick Start Checklist -### Understanding Backgrounds +### Understanding Watchers - [ ] Read "What Makes This Different" section -- [ ] Understand background runs continuously (no `resume_normal_flow()`) +- [ ] Understand watcher runs continuously (no `resume_normal_flow()`) - [ ] Know limitations (session-scoped, not truly background) -### Building Your Background +### Building Your Watcher - [ ] Define what condition to watch (file, time, API, etc.) - [ ] Set appropriate sleep interval (1-30 seconds usually) - [ ] Add try-catch around entire loop @@ -505,25 +505,25 @@ except asyncio.CancelledError: ## Support & Contribution -If you build something with background mode: +If you build something with watcher mode: - 🎉 Share your implementation in Discord - 💡 Contribute improvements to the template -- 🤝 Help others understand background limitations +- 🤝 Help others understand watcher limitations - 📝 Document your use case ## Final Reminder -⚠️ **Background abilities are advanced — understand the limitations before building.** +⚠️ **Watcher abilities are advanced — understand the limitations before building.** **Key takeaways:** -- ✅ Backgrounds run continuously in infinite loops +- ✅ Watchers run continuously in infinite loops - ✅ Great for active session monitoring (timers, reminders) - ✅ Must use `session_tasks.sleep()`, never `asyncio.sleep()` - ❌ **Not** truly background tasks - ❌ **Cannot** fire when user isn't active - ❌ **Never** call `resume_normal_flow()` (intentionally unreachable) -Use backgrounds for real-time monitoring during active sessions, not for long-term background tasks! ⏰🚀 +Use watchers for real-time monitoring during active sessions, not for long-term background tasks! ⏰🚀 --- diff --git a/templates/Alarm/watcher.py b/templates/Alarm/watcher.py new file mode 100644 index 00000000..8a3344af --- /dev/null +++ b/templates/Alarm/watcher.py @@ -0,0 +1,159 @@ +import json +from datetime import datetime +from zoneinfo import ZoneInfo +from time import time + +from src.agent.capability import MatchingCapability +from src.main import AgentWorker +from src.agent.capability_worker import CapabilityWorker + + +class AlarmCapabilityWatcher(MatchingCapability): + worker: AgentWorker = None + capability_worker: CapabilityWorker = None + background_daemon_mode: bool = False + + # Do not change following tag of register capability + #{{register capability}} + + async def _read_alarms_safe(self): + """ + Reads alarms.json safely. + If corrupted / not a list -> return [] (do NOT crash watcher). + """ + try: + if not await self.capability_worker.check_if_file_exists("alarms.json", False): + return [] + + raw = await self.capability_worker.read_file("alarms.json", False) + if not (raw or "").strip(): + return [] + + parsed = json.loads(raw) + return parsed if isinstance(parsed, list) else [] + except Exception as e: + self.worker.editor_logging_handler.error(f"{time()}: alarms.json read/parse failed: {e}") + return [] + + def _parse_alarm_time(self, target_iso: str, tz_name: str): + """ + Returns an aware datetime for target_iso. + """ + if not target_iso: + return None + try: + # target_iso already includes offset; datetime.fromisoformat handles it + dt = datetime.fromisoformat(target_iso) + if dt.tzinfo is None: + # fallback: attach timezone if missing + try: + dt = dt.replace(tzinfo=ZoneInfo(tz_name or "UTC")) + except Exception: + dt = dt.replace(tzinfo=ZoneInfo("UTC")) + return dt + except Exception: + return None + + async def _mark_alarm_triggered(self, alarms: list, alarm_id: str): + """ + Mark a triggered alarm as 'triggered' to prevent repeat firing. + Best-effort write: if write fails, watcher may re-trigger next loop. + """ + try: + changed = False + for a in alarms: + if a.get("id") == alarm_id and a.get("status") == "scheduled": + a["status"] = "triggered" + a["triggered_at_epoch"] = int(time()) + changed = True + break + + if not changed: + return + + # write back (delete-first to avoid append corruption) + try: + if await self.capability_worker.check_if_file_exists("alarms.json", False): + await self.capability_worker.delete_file("alarms.json", False) + except Exception: + pass + + await self.capability_worker.write_file( + "alarms.json", + json.dumps(alarms, ensure_ascii=False, indent=2), + False, + ) + except Exception as e: + self.worker.editor_logging_handler.error(f"{time()}: failed to mark alarm triggered: {e}") + + async def first_function(self): + self.worker.editor_logging_handler.info("%s: Watcher Alarm Called" % time()) + + # Watch loop + while True: + try: + self.worker.editor_logging_handler.info("%s: watcher alarm watching" % time()) + + alarms = await self._read_alarms_safe() + if not alarms: + await self.worker.session_tasks.sleep(5.0) + continue + + # Use watcher timezone as "now" reference (same as your alarm creation) + tz_name = self.capability_worker.get_timezone() + try: + tz = ZoneInfo(tz_name) + except Exception: + tz = ZoneInfo("UTC") + + now = datetime.now(tz=tz) + + # Find scheduled alarms that are due + due = [] + for a in alarms: + if a.get("status") != "scheduled": + continue + target_dt = self._parse_alarm_time(a.get("target_iso"), a.get("timezone") or tz_name) + if not target_dt: + continue + if now >= target_dt: + due.append((a, target_dt)) + + # Fire due alarms (in order) + if due: + due.sort(key=lambda x: x[1]) + for a, target_dt in due: + alarm_id = a.get("id", "unknown") + human_time = a.get("human_time", a.get("target_iso", "")) + + self.worker.editor_logging_handler.info( + f"{time()}: ALARM DUE id={alarm_id} target={target_dt.isoformat()} human='{human_time}'" + ) + + # Play alarm sound + try: + await self.capability_worker.play_from_audio_file("alarm.mp3") + except Exception as e: + self.worker.editor_logging_handler.error( + f"{time()}: Failed to play alarm sound for {alarm_id}: {e}" + ) + + # Mark as triggered to avoid repeat firing + await self._mark_alarm_triggered(alarms, alarm_id) + + await self.worker.session_tasks.sleep(5.0) + + except Exception as e: + self.worker.editor_logging_handler.error(f"{time()}: watcher loop error: {e}") + await self.worker.session_tasks.sleep(2.0) + + # Resume the normal workflow (unreachable, but keep structure) + self.capability_worker.resume_normal_flow() + + def call(self, worker: AgentWorker, background_daemon_mode: bool): + # Initialize the worker and capability worker + self.worker = worker + self.background_daemon_mode = background_daemon_mode + self.capability_worker = CapabilityWorker(self) + + self.worker.session_tasks.create(self.first_function()) diff --git a/templates/OpenHome-local/README.md b/templates/OpenHome-local/README.md new file mode 100644 index 00000000..be21a76f --- /dev/null +++ b/templates/OpenHome-local/README.md @@ -0,0 +1,632 @@ +# OpenHome Local Link - Mac Terminal Control Template +![Community](https://img.shields.io/badge/OpenHome-Community-orange?style=flat-square) +![Template](https://img.shields.io/badge/Type-Template-blue?style=flat-square) + +## What This Is +**This is a template ability** that connects OpenHome to your Mac terminal. Use voice commands to run terminal commands, check system status, manage files, and automate Mac workflows — all without OpenClaw. + +## What You Can Build +Examples of abilities you could create with this template: +- Mac system monitor (disk space, CPU, memory) +- File management assistant (create, move, delete files) +- Development environment controller (git commands, npm scripts) +- Application launcher (open/close Mac apps) +- Network diagnostics tool (ping, traceroute, speed test) +- Automation scripts (backup files, cleanup temp folders) + +## Template Trigger Words +This template uses generic triggers - **customize these** for your specific ability: +- Any Mac terminal command request +- Configure your own trigger words in `config.json` + +## Requirements + +### 1. Download Local Client +**[Download local_client.py](https://drive.google.com/file/d/12Is4eXchH5dDjlG39Knp4oRuD-V3D-v_/view?usp=drive_link)** + +This Python script runs on your Mac and receives commands from OpenHome. + +### 2. Python 3.7+ +Verify you have Python installed: +```bash +python3 --version +``` + +### 3. OpenHome API Key +Get your API key from [OpenHome Dashboard → Settings → API Keys](https://app.openhome.com/dashboard/settings) + +## Setup Instructions + +### Step 1: Download and Configure Client + +1. **Download the client:** + - Click the [download link](https://drive.google.com/file/d/12Is4eXchH5dDjlG39Knp4oRuD-V3D-v_/view?usp=drive_link) + - Save `local_client.py` to a convenient location (e.g., `~/openhome/`) + +2. **Open the client file:** + ```bash + cd ~/openhome/ + nano local_client.py # or use any text editor + ``` + +3. **Add your OpenHome API Key:** + - Find the line: `OPENHOME_API_KEY = "your_api_key_here"` + - Replace with: `OPENHOME_API_KEY = "YOUR_ACTUAL_KEY"` + - Save and exit + +### Step 2: Run the Client + +1. **Make the client executable (optional):** + ```bash + chmod +x local_client.py + ``` + +2. **Run the client:** + ```bash + python3 local_client.py + ``` + +3. **Verify connection:** + - You should see: `Connected to OpenHome` or similar message + - Keep this terminal window open while using the ability + +**Pro tip:** Run the client in the background or use a terminal multiplexer like `tmux`: +```bash +# Using tmux (recommended for persistent sessions) +tmux new -s openhome +python3 local_client.py +# Press Ctrl+B then D to detach + +# Or run in background +nohup python3 local_client.py > /tmp/openhome_client.log 2>&1 & +``` + +### Step 3: Get the Template Ability + +1. Find **OpenHome Local Link** template from: + - OpenHome Dashboard abilities library, OR + - [GitHub Repository](https://github.com/OpenHome-dev/abilities) + +2. Add to your OpenHome Agent + +3. The template is ready to test immediately! + +## Using This Template + +### Default Template Behavior +The unmodified template: +1. Listens for Mac-related voice commands +2. Converts natural language → terminal commands using LLM +3. Sends command to your local client via `exec_local_command()` +4. Client executes the command on your Mac terminal +5. Response is sent back to OpenHome +6. LLM converts technical output → natural spoken response + +### Testing the Template +> **User:** "list all files" +> **AI:** "Running command: ls -la" +> *(Command executes on your Mac)* +> **AI:** "I found 15 files in your current directory including Documents, Downloads, and Desktop." + +--- + +> **User:** "show current directory" +> **AI:** "Running command: pwd" +> **AI:** "You're currently in /Users/yourname/Documents" + +--- + +> **User:** "check disk space" +> **AI:** "Running command: df -h" +> **AI:** "Your main drive has 150 GB free out of 500 GB total." + +## Core Template Function + +### `exec_local_command()` +Sends a command to your local Mac terminal and returns the response. + +**Function Signature:** +```python +async def exec_local_command( + self, + command: str | dict, + target_id: str | None = None, + timeout: float = 10.0 +) +``` + +**Parameters:** +- `command` (str | dict): **Required.** Terminal command to execute +- `target_id` (str | None): **Optional.** Device identifier (default: "laptop") +- `timeout` (float): **Optional.** Max seconds to wait (default: 10.0) + +**Template Usage:** +```python +# Basic usage (as shown in template) +response = await self.capability_worker.exec_local_command(terminal_command) + +# With custom timeout for long commands +response = await self.capability_worker.exec_local_command( + "find / -name '*.log'", + timeout=30.0 +) + +# With specific target device +response = await self.capability_worker.exec_local_command( + "df -h", + target_id="laptop" +) +``` + +## How the Template Works + +### 1. Voice Input → Natural Language +User speaks: "list all files in my downloads folder" + +### 2. LLM Converts to Terminal Command +System prompt guides LLM to generate Mac-compatible commands: +```python +system_prompt = """ +You are a Mac terminal command generator. +Rules: +- Respond ONLY with the terminal command +- Use macOS-compatible commands (zsh/bash) +- No explanations, quotes, or markdown +- Avoid sudo unless necessary +""" +``` + +Result: `ls -la ~/Downloads` + +### 3. Command Sent to Local Client +```python +response = await self.capability_worker.exec_local_command(terminal_command) +``` + +### 4. Client Executes on Mac +The `local_client.py` runs the command in your Mac terminal and captures output. + +### 5. Response Formatted for Speech +LLM converts technical output to conversational language: +```python +check_response_system_prompt = """ +Tell if the command was successful in easier terms. +If user wanted information, return that information. +""" +``` + +### 6. AI Speaks Result +"I found 47 files in your Downloads folder including PDFs, images, and documents." + +## Customizing the Template + +### 1. Modify System Prompt +Change how commands are generated: + +```python +def get_system_prompt(self): + return """ + You are a Mac automation assistant specialized in [YOUR DOMAIN]. + + Rules: + - [Your custom rules] + - [Specific command patterns] + + Examples: + User: "[your example]" -> [your command] + """ +``` + +### 2. Add Pre-Processing Logic +Validate or transform commands before execution: + +```python +async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + # ⬇️ ADD YOUR VALIDATION HERE + if "delete" in user_inquiry.lower() or "rm -rf" in user_inquiry.lower(): + await self.capability_worker.speak("I can't run destructive commands for safety.") + self.capability_worker.resume_normal_flow() + return + # ⬆️ + + # ... rest of template +``` + +### 3. Add Confirmation for Dangerous Commands +```python +terminal_command = self.capability_worker.text_to_text_response(...) + +# ⬇️ ADD CONFIRMATION LOGIC +if any(danger in terminal_command for danger in ["rm", "sudo", "shutdown"]): + await self.capability_worker.speak(f"This command will {terminal_command}. Confirm?") + confirmation = await self.capability_worker.user_response() + if "yes" not in confirmation.lower(): + await self.capability_worker.speak("Cancelled.") + self.capability_worker.resume_normal_flow() + return +# ⬆️ + +response = await self.capability_worker.exec_local_command(terminal_command) +``` + +### 4. Chain Multiple Commands +```python +async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + # Example: "backup my documents" + if "backup" in user_inquiry.lower(): + commands = [ + "mkdir -p ~/Backups", + "cp -r ~/Documents ~/Backups/Documents_$(date +%Y%m%d)", + "echo 'Backup complete'" + ] + + for cmd in commands: + await self.capability_worker.speak(f"Running: {cmd}") + response = await self.capability_worker.exec_local_command(cmd) + + await self.capability_worker.speak("Backup completed successfully!") + self.capability_worker.resume_normal_flow() + return + + # ... rest of template for other commands +``` + +## Example Abilities You Can Build + +### 1. Git Assistant +```python +def get_system_prompt(self): + return """ + Convert git operations to commands. + + Examples: + "check git status" -> git status + "commit changes" -> git add . && git commit -m "Update" + "push to main" -> git push origin main + "create branch feature-x" -> git checkout -b feature-x + """ +``` + +### 2. System Monitor +```python +async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + if "system health" in user_inquiry.lower(): + metrics = { + "CPU": "top -l 1 | grep 'CPU usage'", + "Memory": "vm_stat | head -n 10", + "Disk": "df -h /", + "Battery": "pmset -g batt" + } + + report = [] + for name, cmd in metrics.items(): + response = await self.capability_worker.exec_local_command(cmd) + # Parse and format response + report.append(f"{name}: {response}") + + await self.capability_worker.speak(". ".join(report)) + self.capability_worker.resume_normal_flow() + return +``` + +### 3. Development Environment Setup +```python +async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + if "start dev environment" in user_inquiry.lower(): + await self.capability_worker.speak("Starting development environment...") + + commands = [ + "cd ~/Projects/my-app", + "code .", # Opens VS Code + "npm run dev &", # Starts dev server in background + "open http://localhost:3000" # Opens browser + ] + + for cmd in commands: + await self.capability_worker.exec_local_command(cmd, timeout=15.0) + + await self.capability_worker.speak("Development environment is ready!") + self.capability_worker.resume_normal_flow() + return +``` + +### 4. File Organization Assistant +```python +def get_system_prompt(self): + return """ + File management commands for Mac. + + Examples: + "organize downloads by type" -> + mkdir ~/Downloads/Images ~/Downloads/Documents ~/Downloads/Videos && + mv ~/Downloads/*.jpg ~/Downloads/Images/ 2>/dev/null || true && + mv ~/Downloads/*.pdf ~/Downloads/Documents/ 2>/dev/null || true + + "clean up temp files" -> rm -rf ~/Library/Caches/Homebrew/* + "find large files" -> find ~ -type f -size +100M + """ +``` + +## Modifying the Local Client + +The `local_client.py` file can be customized to: + +### Add Custom Command Handlers +```python +# In local_client.py +def execute_command(command): + # Add special handling for specific commands + if command == "get_battery": + result = subprocess.run(['pmset', '-g', 'batt'], capture_output=True) + return parse_battery_output(result.stdout) + + # Default: run command as-is + result = subprocess.run(command, shell=True, capture_output=True) + return result.stdout.decode() +``` + +### Add Logging +```python +# In local_client.py +import logging + +logging.basicConfig(filename='openhome_commands.log', level=logging.INFO) + +def execute_command(command): + logging.info(f"Executing: {command}") + result = subprocess.run(command, shell=True, capture_output=True) + logging.info(f"Result: {result.stdout[:100]}...") + return result.stdout.decode() +``` + +### Add Security Restrictions +```python +# In local_client.py +BLOCKED_COMMANDS = ['rm -rf /', 'sudo', 'format', 'dd if='] + +def execute_command(command): + if any(blocked in command for blocked in BLOCKED_COMMANDS): + return "ERROR: Blocked command for safety" + + result = subprocess.run(command, shell=True, capture_output=True) + return result.stdout.decode() +``` + +## Best Practices + +### 1. Always Test Commands Manually First +Before automating with voice: +```bash +# Test the command in your terminal first +ls -la ~/Documents + +# Verify it does what you expect +# Then add to your ability +``` + +### 2. Use Safe Defaults +```python +# Avoid destructive operations by default +SAFE_COMMANDS = ['ls', 'pwd', 'cd', 'cat', 'grep', 'find', 'df', 'du'] + +if not any(safe in terminal_command for safe in SAFE_COMMANDS): + await self.capability_worker.speak("This command needs confirmation.") + # ... confirmation logic +``` + +### 3. Handle Timeouts Appropriately +```python +# Quick commands (default 10s) +response = await self.capability_worker.exec_local_command("pwd") + +# Long-running commands (increase timeout) +response = await self.capability_worker.exec_local_command( + "find / -name '*.log'", + timeout=60.0 +) +``` + +### 4. Add Error Handling +```python +try: + response = await self.capability_worker.exec_local_command(terminal_command) + + if "error" in response.lower() or "permission denied" in response.lower(): + await self.capability_worker.speak("That command failed. Try a different approach?") + else: + # Process successful response + ... + +except asyncio.TimeoutError: + await self.capability_worker.speak("That took too long. It might still be running.") +except Exception as e: + self.worker.editor_logging_handler.error(f"Command failed: {e}") + await self.capability_worker.speak("Something went wrong.") +finally: + self.capability_worker.resume_normal_flow() +``` + +## Troubleshooting + +### Client Won't Connect +**Problem:** `local_client.py` shows connection error + +**Solutions:** +1. Verify API key is correct (from Dashboard → Settings → API Keys) +2. Check Python version: `python3 --version` (needs 3.7+) +3. Check internet connection +4. Look for firewall blocking Python connections + +### Commands Not Executing +**Problem:** Client connected but commands fail + +**Solutions:** +1. Check client terminal for error messages +2. Verify command works when run manually in terminal +3. Check client logs: `tail -f /tmp/openhome_client.log` +4. Restart the client: `pkill -f local_client.py && python3 local_client.py` + +### Permission Errors +**Problem:** Commands fail with "Permission denied" + +**Solutions:** +1. Some commands require admin privileges +2. Modify client to use `sudo` (with password handling) +3. Run client with appropriate permissions +4. Avoid commands that need root access + +### Client Disconnects Randomly +**Problem:** Client connection drops after a while + +**Solutions:** +1. Use `tmux` to keep session alive: + ```bash + tmux new -s openhome + python3 local_client.py + # Ctrl+B then D to detach + ``` +2. Add auto-reconnect logic to client +3. Check for Mac sleep settings interfering + +### Response Formatting Issues +**Problem:** AI speaks raw terminal output + +**Solutions:** +1. The template formats responses automatically via LLM +2. Check `check_response_system_prompt` is correct +3. Add custom parsing for specific commands +4. Modify the system prompt to guide better responses + +## Security Considerations + +### ⚠️ Important Security Notes +- **This runs real terminal commands** on your Mac with your user permissions +- **No sandbox protection** — commands execute exactly as typed +- **Anyone with access to your OpenHome** can run commands via your client +- **Protect your API key** — don't share or commit to public repos + +### Recommended Safety Measures + +**1. Command Whitelist** +```python +ALLOWED_COMMANDS = ['ls', 'pwd', 'df', 'du', 'cat', 'grep', 'find'] + +if not any(cmd in terminal_command for cmd in ALLOWED_COMMANDS): + await self.capability_worker.speak("That command is not allowed.") + return +``` + +**2. Confirmation for Destructive Actions** +Always confirm before running: +- `rm` (delete) +- `sudo` (admin) +- `shutdown` / `reboot` +- `dd` (disk operations) +- `format` / `diskutil` + +**3. Separate User for Client** +Run the client under a limited user account: +```bash +# Create a new user for OpenHome +sudo dscl . -create /Users/openhome +sudo dscl . -create /Users/openhome UserShell /bin/bash +sudo dscl . -create /Users/openhome RealName "OpenHome Client" + +# Run client as that user +su openhome -c "python3 local_client.py" +``` + +**4. Monitor Client Logs** +```bash +# Check what commands were run +grep "Executing:" /tmp/openhome_client.log + +# Set up alerts for dangerous commands +tail -f /tmp/openhome_client.log | grep -E "rm|sudo|shutdown" +``` + +## Technical Architecture +``` +Voice Input → OpenHome Ability → exec_local_command() + ↓ + local_client.py + (WebSocket connection) + ↓ + Mac Terminal Execution + (subprocess.run) + ↓ + Response ← AI Formatting ← Template +``` + +## Comparison: Local Link vs OpenClaw + +| Feature | Local Link | OpenClaw | +|---------|-----------|----------| +| **Setup** | Single Python file | Full CLI + daemon + LLM config | +| **Dependencies** | Python 3.7+ only | Node.js + npm + LLM API key | +| **Complexity** | Simple, minimal | Advanced, feature-rich | +| **Customization** | Direct Python editing | MCP server integration | +| **Use Case** | Quick terminal access | Complex automation workflows | +| **Best For** | Simple commands, prototyping | Production automation | + +Use **Local Link** when you want simple, direct terminal access. +Use **OpenClaw** when you need robust automation with LLM-powered intelligence. + +## Quick Start Checklist + +### Setup (One-Time) +- [ ] Download `local_client.py` from Google Drive +- [ ] Add OpenHome API key to client file +- [ ] Test client connection: `python3 local_client.py` +- [ ] Verify "Connected" message + +### Template Usage +- [ ] Get template from OpenHome dashboard +- [ ] Test with safe command: "show current directory" +- [ ] Verify response is spoken correctly +- [ ] Customize system prompt for your use case +- [ ] Add safety validations +- [ ] Define custom trigger words in `config.json` + +## Links & Resources + +**Required Downloads:** +- **[local_client.py](https://drive.google.com/file/d/12Is4eXchH5dDjlG39Knp4oRuD-V3D-v_/view?usp=drive_link)** — Download this file (required) + +**OpenHome:** +- [Dashboard](https://app.openhome.com/dashboard) +- [API Key Management](https://app.openhome.com/dashboard/settings) — Get your API key here +- [Abilities Library](https://app.openhome.com/dashboard/abilities) + +**Mac Terminal Resources:** +- macOS Terminal User Guide +- `man` command for documentation (e.g., `man ls`) +- Homebrew for package management + +## Support & Contribution + +If you build something cool with this template: +- 🎉 Share it with the OpenHome community +- 💡 Contribute improvements to the template +- 🤝 Help others in community forums +- 📝 Document your use case + +## Final Reminder + +⚠️ **This template is a starting point, not a finished product.** + +The power comes from YOUR customization: +- Define specific commands for your workflow +- Add safety validations +- Create domain-specific assistants +- Build something unique for your Mac! + +**Don't deploy the template as-is — make it yours!** 🚀 diff --git a/templates/OpenHome-local/__init__.py b/templates/OpenHome-local/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/templates/OpenHome-local/__init__.py @@ -0,0 +1 @@ + diff --git a/templates/OpenHome-local/main.py b/templates/OpenHome-local/main.py new file mode 100644 index 00000000..61c2bc55 --- /dev/null +++ b/templates/OpenHome-local/main.py @@ -0,0 +1,92 @@ +import json +from src.agent.capability import MatchingCapability +from src.main import AgentWorker +from src.agent.capability_worker import CapabilityWorker + +class LocalCapability(MatchingCapability): + worker: AgentWorker = None + capability_worker: CapabilityWorker = None + + # Do not change following tag of register capability + #{{register capability}} + + def get_system_prompt(self): + system_prompt = """ + You are a Mac terminal command generator. Your ONLY purpose is to convert user requests into valid Mac terminal commands. + + Rules: + - Respond ONLY with the terminal command, nothing else + - Use commands that are compatible with macOS (zsh/bash) + - Do not include explanations, quotes, or markdown formatting + - Do not use sudo unless absolutely necessary + - Make sure commands are safe and won't harm the system + - If the request is unclear, provide the most reasonable command interpretation + + Examples: + User: "list all files" -> ls -la + User: "show current directory" -> pwd + User: "find python files" -> find . -name "*.py" + User: "check disk space" -> df -h + User: "show running processes" -> ps aux + + Respond with ONLY the command, no other text. + """ + return system_prompt + + async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + # Get the system prompt + system_prompt = self.get_system_prompt() + self.worker.editor_logging_handler.info(system_prompt) + + # Use text_to_text_response to convert user inquiry to terminal command + history = [] + terminal_command = self.capability_worker.text_to_text_response( + user_inquiry, + history, + system_prompt, + ) + self.worker.editor_logging_handler.info(terminal_command) + + # Clean up the response (remove any extra whitespace or newlines) + terminal_command = terminal_command.strip() + self.worker.editor_logging_handler.info(terminal_command) + + history.append( + { + "role": "user", + "content": user_inquiry, + }, + ) + history.append( + { + "role": "assistant", + "content": terminal_command, + }, + ) + # Execute the generated command + await self.capability_worker.speak(f"Running command: {terminal_command}") + response = await self.capability_worker.exec_local_command(terminal_command) + + self.worker.editor_logging_handler.info(response) + # Speak the response + check_response_system_prompt = """Your job was to return a command that can run locally on mac and you gave that + command earlier based on user input now tell if that was successful or not in easier terms that can be directly + spoken to the user for his understanding but if user wanted to get the information that's in the response return that response too.""" + result = self.capability_worker.text_to_text_response( + "check if the command successfully ran? response is: %s"%response, + history, + check_response_system_prompt, + ) + if result: + await self.capability_worker.speak(result) + # Resume the normal workflow + self.capability_worker.resume_normal_flow() + + def call(self, worker: AgentWorker): + # Initialize the worker and capability worker + self.worker = worker + self.capability_worker = CapabilityWorker(self) + + self.worker.session_tasks.create(self.first_function()) diff --git a/templates/README.md b/templates/README.md index 71ddc812..69568ea9 100644 --- a/templates/README.md +++ b/templates/README.md @@ -32,12 +32,12 @@ Every ability you build falls into one of three categories: | Type | Trigger | Lifecycle | Entry File | |---|---|---|---| | **Skill** | User hotword or brain routing | Runs once, exits | `main.py` | -| **Background Daemon** | Automatic on session start | Runs continuously in a loop | `background.py` | +| **Background Daemon** | Automatic on session start | Runs continuously in a loop | `watcher.py` | | **Local** | User or system | Runs on-device hardware | DevKit SDK | **Skill** is the workhorse. A user says a hotword (or the brain's routing LLM invokes it), the ability runs, does its thing, and hands control back via `resume_normal_flow()`. -**Background Daemon** starts automatically when a user connects and runs in a `while True` loop for the entire session. No hotword needed. It can monitor conversations, poll APIs, watch for time-based events, and interrupt the main flow when something fires. Daemons can be standalone (`background.py` only) or combined with a Skill (`main.py` + `background.py`) coordinating through shared file storage. +**Background Daemon** starts automatically when a user connects and runs in a `while True` loop for the entire session. No hotword needed. It can monitor conversations, poll APIs, watch for time-based events, and interrupt the main flow when something fires. Daemons can be standalone (`watcher.py` only) or combined with a Skill (`main.py` + `watcher.py`) coordinating through shared file storage. **Local** abilities run directly on Raspberry Pi hardware, bypassing the cloud sandbox entirely. They can use unrestricted Python packages, GPIO pins, and local models. *(Currently under active development.)* @@ -53,11 +53,11 @@ templates/ ├── loop-template/ ← Long-running looped Skill (ambient observer). │ ├── SendEmail/ ← Fire-and-forget SDK method call. -├── Local/ ← LLM as translator; execute on local machine. -├── OpenClaw/ ← Escape the sandbox via OpenClaw. +├── OpenHome-local/ ← LLM as translator; execute on local machine. +├── openclaw-template/ ← Escape the sandbox via OpenClaw. │ -├── Background/ ← Standalone background daemon. -├── Alarm/ ← Combined Skill + Daemon (main.py + background.py). +├── Watcher/ ← Standalone background daemon. +├── Alarm/ ← Combined Skill + Daemon (main.py + watcher.py). │ └── ReadWriteFile/ ← Shared file storage / IPC between Skill & Daemon. ``` @@ -110,7 +110,7 @@ Every Skill **must** call this when done. It hands control back to the agent's n --- -#### [`Local`](./templates/Local) — LLM as Translator (Mac Terminal) +#### [`OpenHome-local`](./templates/OpenHome-local) — LLM as Translator (Mac Terminal) **Type:** Skill · **Pattern:** LLM-as-translator · **Complexity:** Medium You say `"list all my Python files"` and the speaker translates that into a real terminal command (`find . -name "*.py"`), runs it on your local machine, and reads back the result in plain English. Two LLM calls bookend the local execution — one translates speech → command, another translates raw output → human speech. @@ -126,7 +126,7 @@ Abilities run in OpenHome's cloud sandbox, not on your local machine. `exec_loca --- -#### [`OpenClaw`](./templates/OpenClaw) — Sandbox Escape +#### [`openclaw-template`](./templates/openclaw-template) — Sandbox Escape **Type:** Skill · **Pattern:** Sandbox escape · **Complexity:** Minimal Forwards the user's raw speech directly to OpenClaw — a desktop AI agent with 2,800+ community skills. OpenClaw processes it on your local machine and returns the result. The speaker becomes a voice interface for your entire desktop. @@ -149,12 +149,12 @@ self.capability_worker.resume_normal_flow() --- -#### [`Background`](./templates/Background) + [`Alarm`](./templates/Alarm) — Background Daemon +#### [`Watcher`](./templates/Watcher) + [`Alarm`](./templates/Alarm) — Background Daemon **Type:** Background Daemon · **Pattern:** Poll loop · **Complexity:** Medium -**`Background`** is the standalone daemon template. It starts automatically when a user connects and runs in an infinite loop — in this template, reading conversation history and logging it every 20 seconds. This is the most architecturally significant pattern in the system: before daemons, every ability was reactive. Now they can be proactive. +**`Watcher`** is the standalone daemon template. It starts automatically when a user connects and runs in an infinite loop — in this template, reading conversation history and logging it every 20 seconds. This is the most architecturally significant pattern in the system: before daemons, every ability was reactive. Now they can be proactive. -**`Alarm`** is the combined template: `main.py` (Skill) + `background.py` (Daemon) working together. The Skill parses `"set an alarm for 3pm"` and writes to `alarms.json`. The Daemon polls that file every 15 seconds and fires `send_interrupt_signal()` + `play_from_audio_file("alarm.mp3")` when the target time hits. They coordinate through shared files, not direct function calls. +**`Alarm`** is the combined template: `main.py` (Skill) + `watcher.py` (Daemon) working together. The Skill parses `"set an alarm for 3pm"` and writes to `alarms.json`. The Daemon polls that file every 15 seconds and fires `send_interrupt_signal()` + `play_from_audio_file("alarm.mp3")` when the target time hits. They coordinate through shared files, not direct function calls. **Key SDK methods:** `get_full_message_history()`, `send_interrupt_signal()`, `session_tasks.sleep()`, `play_from_audio_file()` @@ -198,7 +198,7 @@ Demonstrates nearly every advanced SDK pattern: raw audio recording, external AP #### [`ReadWriteFile`](./templates/ReadWriteFile) — Shared File Storage / IPC **Type:** Skill · **Complexity:** Minimal -Demonstrates how Skills and Daemons coordinate through shared file storage — the primary IPC mechanism between `main.py` and `background.py`. Used by the `Alarm` template. +Demonstrates how Skills and Daemons coordinate through shared file storage — the primary IPC mechanism between `main.py` and `watcher.py`. Used by the `Alarm` template. **Critical rule:** Always **delete** the file before writing a JSON object. `write_file()` appends — calling it twice will corrupt your JSON. @@ -217,9 +217,9 @@ self.capability_worker.write_file("state.json", json.dumps(data)) | `basic-template` | Skill | `speak()`, `resume_normal_flow()` | | `api-template` | Skill | `text_to_text_response()`, `resume_normal_flow()` | | `SendEmail` | Skill | `send_email()`, `speak()`, `resume_normal_flow()` | -| `Local` | Skill | `text_to_text_response()`, `exec_local_command()` | -| `OpenClaw` | Skill | `exec_local_command()`, `speak()` | -| `Background` | Background Daemon | `get_full_message_history()`, `session_tasks.sleep()` | +| `OpenHome-local` | Skill | `text_to_text_response()`, `exec_local_command()` | +| `openclaw-template` | Skill | `exec_local_command()`, `speak()` | +| `Watcher` | Background Daemon | `get_full_message_history()`, `session_tasks.sleep()` | | `Alarm` | Skill + Daemon | `send_interrupt_signal()`, `play_from_audio_file()`, `session_tasks.sleep()` | | `loop-template` | Skill (long-running) | `start_audio_recording()`, `get_audio_recording()`, `text_to_text_response()` | | `ReadWriteFile` | Utility / IPC | `read_file()`, `delete_file()`, `write_file()` | @@ -232,7 +232,7 @@ self.capability_worker.write_file("state.json", json.dumps(data)) 2. **Copy the folder** and rename it to your ability name. 3. **Replace hardcoded values** — API keys, emails, URLs — with user-collected input or environment config. 4. **Add guardrails** — error handling, confirmation steps, and safety checks appropriate for your use case. -5. **Coordinating a Skill + Daemon?** Use the `ReadWriteFile` pattern to pass state between `main.py` and `background.py` via shared JSON files. +5. **Coordinating a Skill + Daemon?** Use the `ReadWriteFile` pattern to pass state between `main.py` and `watcher.py` via shared JSON files. For full SDK documentation, see the [OpenHome Developer Docs](./docs). diff --git a/templates/Watcher/README.md b/templates/Watcher/README.md new file mode 100644 index 00000000..1a54a752 --- /dev/null +++ b/templates/Watcher/README.md @@ -0,0 +1,626 @@ +# Background Monitoring Ability Template +![Community](https://img.shields.io/badge/OpenHome-Community-orange?style=flat-square) +![Template](https://img.shields.io/badge/Type-Template-blue?style=flat-square) +![Advanced](https://img.shields.io/badge/Level-Advanced-red?style=flat-square) + +## What This Is +**This is a background ability template** that runs continuously in an endless loop. Unlike normal abilities that respond once and exit, watcher abilities stay active throughout the agent session, monitoring conditions and triggering actions automatically. + +## Key Characteristics + +### Background Execution +- **Runs automatically** — Watcher abilities are auto-triggered when your agent starts +- **Endless loop** — The `while True` keeps the ability running continuously +- **Background operation** — Runs silently alongside the normal conversation flow +- **All CapabilityWorker functions available** — Full SDK access within the watcher + +### What Makes Watchers Different + +| Normal Ability | Watcher Ability | +|----------------|-----------------| +| User triggers with voice command | Auto-starts when agent initializes | +| Speak → Listen → Respond → Exit | Continuous loop: Monitor → Act → Sleep → Repeat | +| Calls `resume_normal_flow()` to exit | `resume_normal_flow()` never reached (intentional) | +| Session-specific | Background for entire agent session | + +## Template Features + +This basic watcher template demonstrates: + +1. **Continuous monitoring** — Endless `while True` loop +2. **Message history access** — Reads last 10 messages from normal conversation +3. **Logging** — Records activity via `editor_logging_handler` +4. **Sleep intervals** — 20-second pause between checks +5. **Commented examples** — Audio playback and speech capabilities + +## How It Works + +### Template Flow +``` +Agent Starts + ↓ +Watcher Auto-Triggers + ↓ +Enter while True Loop + ↓ +┌─────────────────────┐ +│ Log "watching" │ +│ Get last 10 messages│ +│ Log each message │ +│ Sleep 20 seconds │ +└─────────┬───────────┘ + │ + └─→ Repeat Forever +``` + +### Code Walkthrough + +**1. Watcher Mode Initialization:** +```python +def call(self, worker: AgentWorker, watcher_mode: bool): + self.worker = worker + self.watcher_mode = watcher_mode # ← Background mode flag + self.capability_worker = CapabilityWorker(self) + self.worker.session_tasks.create(self.first_function()) +``` +- `watcher_mode=True` indicates this is a background ability +- Auto-creates async task that runs in background + +**2. Endless Loop:** +```python +async def first_function(self): + self.worker.editor_logging_handler.info("%s: Watcher Called" % time()) + + while True: # ← Never exits + self.worker.editor_logging_handler.info("%s: watcher watching" % time()) + + # Your monitoring logic here + ... + + await self.worker.session_tasks.sleep(20.0) # ← Sleep before next check +``` +- Loop runs indefinitely (no break condition) +- Checks conditions every 20 seconds +- Never calls `resume_normal_flow()` — this is intentional + +**3. Access Message History:** +```python +message_history = self.capability_worker.get_full_message_history()[-10:] +``` +- Returns last **50 messages** by default (template uses last 10) +- Each message is a dict with `role` and `content` +- Provides context from normal conversation flow + +**4. Log Activity:** +```python +for message in message_history: + self.worker.editor_logging_handler.info( + "Role: %s, Message: %s" % (message.get("role", ""), message.get("content", "")) + ) +``` +- Always use `editor_logging_handler` (not `print`) +- Logs are visible in dashboard/logs + +**5. Sleep Between Checks:** +```python +await self.worker.session_tasks.sleep(20.0) +``` +- **Critical:** Use `session_tasks.sleep()`, NEVER `asyncio.sleep()` +- 20 seconds is template default (adjust to your needs) + +**6. Commented Examples:** +```python +# await self.capability_worker.speak("watching") +# await self.capability_worker.play_from_audio_file("alarm.mp3") +``` +- Shows how to trigger audio/speech from watcher +- Uncomment to test capabilities + +## Message History Structure + +### What You Get +```python +message_history = self.capability_worker.get_full_message_history() +``` + +**Returns:** List of up to **50 messages** (most recent) + +**Message Format:** +```python +{ + "role": "user", # or "assistant" + "content": "What's the weather today?" +} +``` + +### Example Usage + +**Monitor for specific keywords:** +```python +message_history = self.capability_worker.get_full_message_history()[-10:] + +for message in message_history: + if message.get("role") == "user": + content = message.get("content", "").lower() + + if "urgent" in content: + await self.capability_worker.speak("I noticed you said something urgent!") + await self.capability_worker.play_from_audio_file("alert.mp3") + break # Only alert once +``` + +**Track conversation patterns:** +```python +user_messages = [ + msg for msg in message_history + if msg.get("role") == "user" +] + +if len(user_messages) > 5: + # User has been very active + self.worker.editor_logging_handler.info("High conversation activity detected") +``` + +## Audio Playback in Watchers + +### Play Files from Ability Directory +```python +await self.capability_worker.play_from_audio_file("alarm.mp3") +``` + +**Setup:** +1. Place audio file in your ability's folder (e.g., `alarm.mp3`) +2. Supported formats: `.mp3`, `.wav`, `.ogg` +3. Call from anywhere in the watcher loop + +**Example watcher with audio alerts:** +```python +async def first_function(self): + alert_count = 0 + + while True: + message_history = self.capability_worker.get_full_message_history()[-10:] + + # Check for alert conditions + for message in message_history: + if "emergency" in message.get("content", "").lower(): + await self.capability_worker.play_from_audio_file("emergency.mp3") + alert_count += 1 + break + + self.worker.editor_logging_handler.info(f"Alerts fired: {alert_count}") + await self.worker.session_tasks.sleep(10.0) +``` + +### Speak from Watcher +```python +await self.capability_worker.speak("I'm monitoring in the background!") +``` + +**Use cases:** +- Periodic reminders +- Alert announcements +- Status updates + +**Example periodic reminder:** +```python +async def first_function(self): + reminder_interval = 300 # 5 minutes + last_reminder = time() + + while True: + now = time() + + if now - last_reminder >= reminder_interval: + await self.capability_worker.speak("Reminder: Take a break and stretch!") + last_reminder = now + + await self.worker.session_tasks.sleep(30.0) +``` + +## All CapabilityWorker Functions Available + +Watchers have **full SDK access**. You can use: + +### Conversation Functions +```python +await self.capability_worker.speak("Message") +await self.capability_worker.user_response() +message_history = self.capability_worker.get_full_message_history() +``` + +### Text Generation +```python +response = self.capability_worker.text_to_text_response("Analyze this...") +``` + +### File Operations +```python +await self.capability_worker.write_file("log.txt", data, False) +data = await self.capability_worker.read_file("config.json", False) +exists = await self.capability_worker.check_if_file_exists("data.txt", False) +await self.capability_worker.delete_file("temp.txt", False) +``` + +### Audio +```python +await self.capability_worker.play_from_audio_file("sound.mp3") +await self.capability_worker.play_audio(audio_bytes) +``` + +### Device Actions +```python +await self.capability_worker.send_devkit_action("led_on") +await self.capability_worker.send_notification_to_ios("Title", "Body") +``` + +**Example watcher using multiple SDK functions:** +```python +async def first_function(self): + while True: + # Check for new data file + if await self.capability_worker.check_if_file_exists("trigger.txt", False): + # Read trigger data + data = await self.capability_worker.read_file("trigger.txt", False) + + # Use LLM to analyze + analysis = self.capability_worker.text_to_text_response( + f"Summarize this in one sentence: {data}" + ) + + # Speak the summary + await self.capability_worker.speak(f"Alert: {analysis}") + + # Play sound + await self.capability_worker.play_from_audio_file("notification.mp3") + + # Clean up trigger file + await self.capability_worker.delete_file("trigger.txt", False) + + await self.worker.session_tasks.sleep(10.0) +``` + +## Common Watcher Patterns + +### Pattern 1: Keyword Monitor +Watch conversation for specific words/phrases: + +```python +async def first_function(self): + keywords = ["help", "urgent", "emergency", "important"] + + while True: + message_history = self.capability_worker.get_full_message_history()[-5:] + + for message in message_history: + if message.get("role") == "user": + content = message.get("content", "").lower() + + if any(keyword in content for keyword in keywords): + await self.capability_worker.speak("I noticed you need attention!") + await self.capability_worker.play_from_audio_file("alert.mp3") + + await self.worker.session_tasks.sleep(15.0) +``` + +### Pattern 2: Activity Timer +Detect user inactivity and prompt: + +```python +async def first_function(self): + last_user_message_time = time() + inactivity_threshold = 300 # 5 minutes + + while True: + message_history = self.capability_worker.get_full_message_history()[-1:] + + if message_history and message_history[0].get("role") == "user": + last_user_message_time = time() + + now = time() + if now - last_user_message_time > inactivity_threshold: + await self.capability_worker.speak("Still here if you need anything!") + last_user_message_time = now # Reset to avoid spam + + await self.worker.session_tasks.sleep(60.0) +``` + +### Pattern 3: File Watcher +Monitor for new files and process them: + +```python +async def first_function(self): + processed_files = set() + + while True: + # Check for new data file + if await self.capability_worker.check_if_file_exists("inbox.txt", False): + content = await self.capability_worker.read_file("inbox.txt", False) + + # Create unique ID for this content + content_hash = hash(content) + + if content_hash not in processed_files: + # Process new content + await self.capability_worker.speak(f"New data received: {content[:50]}") + await self.capability_worker.play_from_audio_file("notification.mp3") + + processed_files.add(content_hash) + + # Archive processed data + await self.capability_worker.write_file( + "processed.txt", + f"\n{content}", + False + ) + + await self.worker.session_tasks.sleep(5.0) +``` + +### Pattern 4: Sentiment Monitor +Track conversation tone and alert if negative: + +```python +async def first_function(self): + while True: + message_history = self.capability_worker.get_full_message_history()[-10:] + + # Combine recent messages + recent_conversation = "\n".join([ + msg.get("content", "") + for msg in message_history + if msg.get("role") == "user" + ]) + + # Analyze sentiment + if recent_conversation: + sentiment_prompt = f"""Analyze sentiment of this conversation: {recent_conversation} + + Return only: "positive", "neutral", or "negative" + """ + + sentiment = self.capability_worker.text_to_text_response(sentiment_prompt).lower().strip() + + if "negative" in sentiment: + self.worker.editor_logging_handler.warning("Negative sentiment detected") + # Could trigger supportive response + + await self.worker.session_tasks.sleep(30.0) +``` + +## Best Practices + +### 1. Always Use session_tasks.sleep() +```python +# ✅ CORRECT +await self.worker.session_tasks.sleep(20.0) + +# ❌ WRONG — Won't clean up properly +await asyncio.sleep(20.0) +``` + +### 2. Set Appropriate Sleep Intervals +```python +# ✅ GOOD — Reasonable intervals +await self.worker.session_tasks.sleep(5.0) # Quick monitoring +await self.worker.session_tasks.sleep(30.0) # Moderate checks +await self.worker.session_tasks.sleep(60.0) # Periodic polling + +# ❌ BAD — Too frequent, wastes resources +await self.worker.session_tasks.sleep(0.1) + +# ⚠️ CAUTION — Too infrequent, may miss events +await self.worker.session_tasks.sleep(600.0) +``` + +**Guidelines:** +- **Real-time monitoring:** 1-5 seconds +- **Keyword watching:** 10-20 seconds +- **Periodic reminders:** 30-60 seconds +- **Activity tracking:** 30-120 seconds + +### 3. Use editor_logging_handler (Not print) +```python +# ✅ CORRECT +self.worker.editor_logging_handler.info("Watcher started") +self.worker.editor_logging_handler.warning("Unusual activity") +self.worker.editor_logging_handler.error(f"Error: {e}") + +# ❌ WRONG — Won't appear in logs +print("Watcher started") +``` + +### 4. Wrap Loop in Try-Catch +```python +async def first_function(self): + while True: + try: + # Your monitoring logic + ... + + except Exception as e: + self.worker.editor_logging_handler.error(f"Watcher error: {e}") + await self.worker.session_tasks.sleep(5.0) # Brief pause before retry +``` + +### 5. Limit Message History Access +```python +# ✅ GOOD — Get only what you need +message_history = self.capability_worker.get_full_message_history()[-10:] + +# ⚠️ CAREFUL — Full history (50 messages) may be overkill +message_history = self.capability_worker.get_full_message_history() +``` + +### 6. Avoid Duplicate Actions +```python +# Track what's been processed +processed_message_ids = set() + +while True: + message_history = self.capability_worker.get_full_message_history()[-10:] + + for message in message_history: + msg_id = hash(f"{message.get('role')}{message.get('content')}") + + if msg_id not in processed_message_ids: + # Process new message + ... + processed_message_ids.add(msg_id) + + await self.worker.session_tasks.sleep(10.0) +``` + +### 7. Keep Processing Lightweight +```python +# ✅ GOOD — Quick checks +if "keyword" in content: + do_something() + +# ❌ BAD — Heavy processing in hot loop +for message in message_history: + # Don't call slow APIs or heavy computation repeatedly + result = expensive_api_call(message) # This slows everything down +``` + +## What You Can Build + +Examples of watcher abilities: + +- **Conversation monitors** — Track keywords, sentiment, activity +- **Periodic reminders** — "Take a break" every 30 minutes +- **File processors** — Watch for new files and auto-process +- **Alert systems** — Detect conditions and play audio alerts +- **Activity trackers** — Log user engagement patterns +- **Sentiment analyzers** — Monitor conversation tone +- **Notification triggers** — Send iOS notifications on events +- **Data aggregators** — Collect and summarize conversation data + +## Troubleshooting + +### Watcher Stops Running +**Problem:** Loop exits unexpectedly + +**Solutions:** +- Add try-catch around entire loop +- Check logs for error messages +- Verify using `session_tasks.sleep()` not `asyncio.sleep()` + +### Audio File Won't Play +**Problem:** `play_from_audio_file()` fails + +**Solutions:** +- Verify file exists in ability directory +- Check filename matches exactly (case-sensitive) +- Try different format (.mp3 vs .wav) + +### High CPU Usage +**Problem:** Watcher consumes too many resources + +**Solutions:** +- Increase sleep interval +- Reduce message history size (use [-5:] instead of [-50:]) +- Avoid heavy processing in loop + +### Message History Empty +**Problem:** `get_full_message_history()` returns empty list + +**Explanation:** Normal — no messages yet in conversation + +**Solution:** Check if list is empty before processing: +```python +message_history = self.capability_worker.get_full_message_history() +if not message_history: + await self.worker.session_tasks.sleep(20.0) + continue +``` + +## Limitations + +### What Watchers Cannot Do + +**No Cross-Session Persistence:** +- Watcher stops when agent session ends +- Cannot fire events after user logs out +- Not suitable for true background tasks (24/7 monitoring) + +**No Proactive Interruption:** +- Cannot interrupt user mid-conversation +- Actions happen during natural pauses +- Must respect conversation flow + +**Resource Constraints:** +- Should not run expensive operations continuously +- Sleep intervals prevent excessive resource use +- Keep processing lightweight + +## Security Considerations + +### Rate Limiting +Prevent abuse by limiting frequency: +```python +MIN_SLEEP = 5.0 # Minimum 5 seconds between checks + +await self.worker.session_tasks.sleep(max(MIN_SLEEP, custom_interval)) +``` + +### Sensitive Data +Don't log sensitive information: +```python +# ❌ BAD — Logs sensitive content +self.worker.editor_logging_handler.info(f"Message: {message.get('content')}") + +# ✅ GOOD — Log only metadata +self.worker.editor_logging_handler.info(f"Message count: {len(message_history)}") +``` + +## Quick Start Checklist + +### Understanding Watchers +- [ ] Understand watchers run automatically in background +- [ ] Know `while True` never exits (intentional) +- [ ] Recognize `resume_normal_flow()` is unreachable +- [ ] Understand session-scoped nature (not 24/7) + +### Building Your Watcher +- [ ] Define what to monitor (messages, files, time, etc.) +- [ ] Set appropriate sleep interval (10-60 seconds typical) +- [ ] Add try-catch around entire loop +- [ ] Use `session_tasks.sleep()`, not `asyncio.sleep()` +- [ ] Use `editor_logging_handler` for all logging +- [ ] Test with various scenarios + +### Adding Features +- [ ] Access message history with `get_full_message_history()` +- [ ] Play audio files from ability directory +- [ ] Speak updates with `speak()` +- [ ] Write logs to files with file operations +- [ ] Track processed items to avoid duplicates + +## Links & Resources + +**OpenHome Documentation:** +- [Building Great Abilities](https://docs.openhome.com/Building_Great_OpenHome_Abilities) +- [How to Build an Ability](https://docs.openhome.com/how_to_build_an_ability) +- [Dashboard](https://app.openhome.xyz/dashboard) +- [Discord Community](https://discord.com/channels/1197724389630824508) + +## Support & Contribution + +If you build something with watcher mode: +- 🎉 Share your implementation +- 💡 Contribute improvements +- 🤝 Help others understand watchers +- 📝 Document your use case + +## Final Reminder + +⚠️ **Key Takeaways:** +- ✅ Watchers run automatically in endless loops +- ✅ Access full conversation history (last 50 messages) +- ✅ Play audio and use all CapabilityWorker functions +- ✅ Background monitoring during active agent sessions +- ❌ Not truly 24/7 background tasks (session-scoped) +- ❌ Never calls `resume_normal_flow()` (by design) + +Use watchers for real-time monitoring, periodic checks, and automated responses during active sessions! 🔄🚀 diff --git a/templates/Watcher/__init__.py b/templates/Watcher/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/templates/Watcher/__init__.py @@ -0,0 +1 @@ + diff --git a/templates/Watcher/alarm.mp3 b/templates/Watcher/alarm.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..56e94e4d3e52acb7e659682beced73c07d7c1dc3 GIT binary patch literal 253891 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

jIi}7v9hOLN72;D9znY@GGjy_g z@h_?*#%b98_GGihIHC+On&W|3X+9wqhe;P!#ZPs5WS1hbdEEtKAzT9-W~t(zG*dhG#i=_d z{M{VYE-PgeqZBIkv_73f4LrJZ(gN52-44$HEch6C7>F7^1Qx2-mkKZ)ujPhCyTb86 zXm}t1K-yY|@be^0NKw1BH2Y*5m+_cvpH(hixG5XS6;3i>GK$cFgn&deP!}8F%DW_u z6&8^*5kwDiBUAtQo}33SH!Nph>Q`N()0h_;1ItHF0ginjF)TU;FH~af$-8R)Bn6ur z5obyrP6MfO z+g%58wKfg5*fG0(l2N9#f*x7syKpdP)z?4Iw=+cwIjBhK+1!$qvSOw)23e#@$$2NY zcX~ATeZQ#{h_w~wz0}=h8rD?td(KB+Se!M>ws!QEM>h2IN1w98M~agjRUDy?7nLP2 zob`A4lJ7y5kR>8)+>cE^MaH~xNB8DycY3SEi6jttFoV@X)w7dQsKSj;M)bj@5>$vF zMTM!pKIPEA?Bh0TU23^G#Bb zr~Tl4hwb*Wysa!0>T&m(p}8T!1i;(6<^S^jTb#lD4)h@qyw7~vbGN}7KlHu&(AX|D zN~%iD!>HDm_HBOt>0hMKGOJtZ{bcD^qn($xf6QHWVB@h<*oX7A=Vh(!-mzUAkMU&x zPOs`)v>hdpJDlr-qUSHJD)KguOM?zX@qe#S8w8jIyB+k0P1UfYFo9Gv#;h>tEUb5+ zhy2$&AmWWG8|xE!^_L@az%ha^=_m^DfpJ8^s1PbFEM%;mekGw) z$cBu5^0_WQ?6>oqr%g82!x`&EHQ2rOI7P`Sgh6+F`ovbEUK7b9Jk^uSXv zb#tK$nh1u*`S@)_G%?Y4ToyTQv*_F?OcTF(bncF7as3~?7M;ivZYa-LNo`*)ckF80 zWJytpJ`cpBm47q2pX8Ogw%QQpA;7FI!GS_50 zltTHBt1E^r3Z;;QH=MtBj4A*6hZb%Qe`n zA-B@~n{HRPuY4NI`ALgFbxu+Gp&hTp@T?U>Ny*I8orj}gHCt~krtBxxT{IfLDUcYM zKYUUQLz$4s@KooAFoxsv5B4`rtL9N{cvQc7)=7*E?O@q4g%BV4a#iW2lN>x

fgXQ_jTxY^W3 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 **User:** "open Slack" +> **AI:** "Sending Inquiry to OpenClaw" +> *(OpenClaw executes on local machine)* +> **AI:** "Slack is now open." + +### With System Information +> **User:** "check disk usage" +> **AI:** "Sending Inquiry to OpenClaw" +> *(OpenClaw queries system)* +> **AI:** "Disk usage is at 42 percent." + +### Handling Errors +> **User:** "open NonExistentApp" +> **AI:** "Sending Inquiry to OpenClaw" +> *(OpenClaw fails to find app)* +> **AI:** "I couldn't find NonExistentApp on this machine." + +### Custom Ability Example +After customizing the template with multi-step logic: + +> **User:** "start my morning routine" +> **AI:** "Opening Calendar, Email, and Slack" +> *(Executes 3 commands sequentially)* +> **AI:** "Morning apps are ready." + +## Core Template Function + +The template provides one essential function for sending commands to your local machine: + +### `exec_local_command()` +Sends a command/inquiry to your local OpenClaw client and returns the response. + +**Function Signature:** +```python +async def exec_local_command( + self, + command: str | dict, + target_id: str | None = None, + timeout: float = 10.0 +) +``` + +**Parameters:** +- `command` (str | dict): **Required.** The inquiry message or command for OpenClaw +- `target_id` (str | None): **Optional.** Target device identifier (default: "laptop") +- `timeout` (float): **Optional.** Max seconds to wait for response (default: 10.0) + +**Returns:** +- `str`: Response from OpenClaw execution (success message, error, or command output) + +**Template Usage:** +```python +# Basic usage (as shown in template) +response = await self.capability_worker.exec_local_command(user_inquiry) + +# With custom timeout for long-running commands +response = await self.capability_worker.exec_local_command( + "compile large project", + timeout=30.0 +) + +# With specific target device +response = await self.capability_worker.exec_local_command( + "check battery status", + target_id="laptop" +) +``` + +## How the Template Works + +1. **User speaks a command** → Voice input captured by OpenHome +2. **Template receives transcription** → `wait_for_complete_transcription()` +3. **Command sent to OpenClaw** → `exec_local_command(user_inquiry)` +4. **OpenClaw executes locally** → Runs on your computer with your permissions +5. **Response returned** → Success/failure/output comes back from OpenClaw +6. **AI formats for speech** → Converts technical output to natural language (max 15 words) +7. **AI speaks result** → User hears the outcome + +**Response Formatting Rules (Built into Template):** +The template automatically converts technical output into conversational speech: +- ✅ "Slack is now open." (action confirmed) +- ✅ "Disk usage is at 42 percent." (useful info extracted) +- ✅ "I couldn't find Slack on this machine." (error explained) +- ❌ Avoids: JSON blocks, markdown, code snippets, raw command output +- **Constraint**: Maximum 1 sentence, 15 words or less + +## Example Abilities You Can Build + +### 1. Development Environment Controller +```python +# Trigger: "start coding session" +# Opens IDE, starts local servers, opens documentation +async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + commands = [ + "open Visual Studio Code", + "start local dev server on port 3000", + "open browser to localhost:3000" + ] + + for cmd in commands: + await self.capability_worker.exec_local_command(cmd) + + await self.capability_worker.speak("Development environment is ready.") + self.capability_worker.resume_normal_flow() +``` + +### 2. System Health Monitor +```python +# Trigger: "check system health" +# Reports CPU, memory, disk, and battery status +async def first_function(self): + metrics = [ + ("CPU usage", "get cpu usage"), + ("Memory usage", "get memory usage"), + ("Disk space", "get disk usage"), + ("Battery level", "get battery level") + ] + + report = [] + for name, cmd in metrics: + response = await self.capability_worker.exec_local_command(cmd) + report.append(f"{name}: {response}") + + await self.capability_worker.speak(", ".join(report)) + self.capability_worker.resume_normal_flow() +``` + +### 3. Smart Screenshot Tool +```python +# Trigger: "take screenshot of active window" +# Captures, saves with timestamp, confirms location +async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + # Extract what to capture + if "full screen" in user_inquiry.lower(): + cmd = "screenshot fullscreen save to ~/Desktop" + elif "active window" in user_inquiry.lower(): + cmd = "screenshot active window save to ~/Desktop" + else: + cmd = "screenshot selection save to ~/Desktop" + + response = await self.capability_worker.exec_local_command(cmd, timeout=15.0) + + # Parse filename from response and confirm + await self.capability_worker.speak(f"Screenshot saved: {response}") + self.capability_worker.resume_normal_flow() +``` + +### 4. Application Manager with Confirmation +```python +# Trigger: "close all browsers" +# Lists open browsers, asks confirmation, closes them +async def first_function(self): + # Get list of open browsers + response = await self.capability_worker.exec_local_command("list open browsers") + + if "none" in response.lower(): + await self.capability_worker.speak("No browsers are open.") + self.capability_worker.resume_normal_flow() + return + + # Confirm before closing + await self.capability_worker.speak(f"Found: {response}. Close all?") + confirmation = await self.capability_worker.user_response() + + if "yes" in confirmation.lower(): + await self.capability_worker.exec_local_command("close all browsers") + await self.capability_worker.speak("All browsers closed.") + else: + await self.capability_worker.speak("Cancelled.") + + self.capability_worker.resume_normal_flow() +``` + +## Troubleshooting + +### OpenClaw Client Won't Connect +- Verify API key is correct (copy from Dashboard → Settings → API Keys) +- Check if daemon is running: `openclaw status` +- Restart the OpenClaw client app +- Check logs in the client for error messages + +### Commands Timeout or Fail +- Increase timeout: `exec_local_command(command, timeout=20.0)` +- Check OpenClaw daemon status: `openclaw status` +- Verify the command is valid for your OS +- Check OpenClaw client logs for execution errors + +### Permission Errors (macOS) +- Go to System Settings → Privacy & Security +- Find the blocked app notification +- Click "Open Anyway" +- Grant permissions when prompted (Accessibility, Automation, etc.) + +### Commands Not Executing +- Verify OpenClaw client shows "Connected" status +- Test a simple command like "what time is it" +- Check if the ability is correctly registered in OpenHome +- Review OpenClaw client logs for connection issues + +## Security & Privacy +- OpenClaw runs locally on your machine — no commands are sent to external servers +- API key authenticates OpenHome → OpenClaw connection +- You control what commands the ability can execute +- Review all permissions carefully when installing the client + +## Best Practices for Building with This Template + +### 1. Define Clear Trigger Words +Choose specific, unambiguous trigger phrases in `config.json`: +```json +{ + "matching_hotwords": [ + "start development session", + "open my coding setup", + "launch dev environment" + ] +} +``` + +Avoid overly generic triggers that might conflict with other abilities. + +### 2. Add Command Validation +Protect users from accidentally running dangerous commands: +```python +# Blacklist approach +DANGEROUS_COMMANDS = ["rm -rf", "format", "delete system", "shutdown -h now"] + +if any(danger in user_inquiry.lower() for danger in DANGEROUS_COMMANDS): + await self.capability_worker.speak("I can't execute that for safety reasons.") + return +``` + +### 3. Implement Confirmation for Destructive Actions +```python +if "restart" in user_inquiry.lower() or "shutdown" in user_inquiry.lower(): + await self.capability_worker.speak("This will restart your computer. Are you sure?") + confirm = await self.capability_worker.user_response() + if "yes" not in confirm.lower(): + await self.capability_worker.speak("Cancelled.") + return +``` + +### 4. Handle Timeouts Appropriately +Adjust timeout based on expected command duration: +```python +# Quick commands (default 10s is fine) +response = await self.capability_worker.exec_local_command("open Chrome") + +# Long-running commands (increase timeout) +response = await self.capability_worker.exec_local_command( + "compile entire project", + timeout=60.0 # 1 minute +) +``` + +### 5. Parse and Format Responses +Don't just echo raw OpenClaw output: +```python +response = await self.capability_worker.exec_local_command("get battery level") + +# Bad: "Battery: 73% (charging, 2:15 remaining)" +# Good: Extract just the useful info +battery_level = extract_percentage(response) # Your parsing logic +await self.capability_worker.speak(f"Battery is at {battery_level} percent.") +``` + +### 6. Add Error Handling +```python +try: + response = await self.capability_worker.exec_local_command( + user_inquiry, + timeout=15.0 + ) + + if "error" in response.lower() or "failed" in response.lower(): + await self.capability_worker.speak("That command didn't work. Try something else.") + else: + # Process successful response + ... + +except asyncio.TimeoutError: + await self.capability_worker.speak("That command took too long. It might still be running.") +except Exception as e: + self.worker.editor_logging_handler.error(f"Command failed: {e}") + await self.capability_worker.speak("Something went wrong. Check the logs.") +``` + +### 7. Chain Commands for Complex Workflows +```python +# Example: "prepare for meeting" +workflow = [ + ("Opening calendar", "open Calendar app"), + ("Starting video", "open Zoom"), + ("Opening notes", "open Notes app"), +] + +for description, command in workflow: + await self.capability_worker.speak(description) + await self.capability_worker.exec_local_command(command) + await asyncio.sleep(1) # Brief pause between commands + +await self.capability_worker.speak("Ready for your meeting.") +``` + +## Template Code Walkthrough + +### Key Components + +**1. Wait for User Input:** +```python +user_inquiry = await self.capability_worker.wait_for_complete_transcription() +``` +Gets the full voice command before processing. + +**2. Send to OpenClaw:** +```python +response = await self.capability_worker.exec_local_command(user_inquiry) +``` +Sends command to local machine, returns result. + +**3. Format Response:** +```python +check_response_system_prompt = """You are a voice assistant...""" +result = self.capability_worker.text_to_text_response( + "Original user request: '%s'. Command result: %s" % (user_inquiry, response), + history, + check_response_system_prompt, +) +``` +LLM converts technical output → natural speech (15 words max). + +**4. Speak and Resume:** +```python +await self.capability_worker.speak(result) +self.capability_worker.resume_normal_flow() +``` +Delivers result and returns control to main assistant. + +### Modifying the Template + +**To add pre-processing:** +```python +async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + # ⬇️ ADD YOUR LOGIC HERE + if "screenshot" in user_inquiry.lower(): + user_inquiry = "take screenshot and save to desktop" + # ⬆️ + + response = await self.capability_worker.exec_local_command(user_inquiry) + # ... rest of template +``` + +**To add post-processing:** +```python +async def first_function(self): + # ... template code to get response + + # ⬇️ ADD YOUR LOGIC HERE + if "screenshot saved" in response.lower(): + # Extract filename and offer to open + await self.capability_worker.speak("Screenshot saved. Open it?") + confirm = await self.capability_worker.user_response() + if "yes" in confirm.lower(): + await self.capability_worker.exec_local_command("open last screenshot") + # ⬆️ + + self.capability_worker.resume_normal_flow() +``` + +**To add multi-turn interaction:** +```python +async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + # First command + response1 = await self.capability_worker.exec_local_command(user_inquiry) + await self.capability_worker.speak(response1) + + # Ask for follow-up + await self.capability_worker.speak("What else should I do?") + next_command = await self.capability_worker.user_response() + + # Second command + response2 = await self.capability_worker.exec_local_command(next_command) + await self.capability_worker.speak(response2) + + self.capability_worker.resume_normal_flow() +``` + +## Important Template Notes + +### This is a Starting Point +- **The template is intentionally minimal** — it's designed to be modified +- Don't use it as-is for production — customize it for your use case! +- The real power comes from your specific implementation + +### Security Considerations +- OpenClaw runs with **your user permissions** on local machine +- Commands execute exactly as if you typed them in terminal +- **Always add validation** for any user-provided input +- Use **confirmation prompts** for destructive operations (restart, delete, etc.) +- Review all commands before enabling in production + +### Client Must Stay Running +- OpenClaw client must run in background for ability to work +- If client disconnects, commands will fail +- Monitor client logs for connection issues +- Consider adding retry logic for failed commands + +### Response Formatting +- 15-word limit ensures concise voice responses +- Technical output is automatically cleaned up by LLM +- You can modify the formatting prompt for different styles +- Balance between information density and speakability + +### Testing Strategy +1. Test with simple, safe commands first ("what time is it") +2. Verify timeout handling with long-running commands +3. Test error scenarios (invalid commands, disconnected client) +4. Check response formatting with various output types +5. **Test on target OS** (commands vary by platform: Windows/macOS/Linux) + +## Technical Architecture +``` +Voice Input → OpenHome Ability → exec_local_command() + ↓ + OpenClaw Client + (via WebSocket) + ↓ + OpenClaw Daemon + (with LLM API) + ↓ + Local System Execution + (apps, files, etc.) + ↓ + Response ← AI Formatting ← Template +``` + +## Links & Resources + +**Required Downloads:** +- **[OpenClaw Client](https://drive.google.com/drive/folders/10qK75I-bFB2D98YJ6dH3tQFsvEk44Y7-)** — Download for your OS (required) + +**OpenHome:** +- [Dashboard](https://app.openhome.com/dashboard) +- [API Key Management](https://app.openhome.com/dashboard/settings) — Get your API key here +- [Abilities Library](https://app.openhome.com/dashboard/abilities) + +**OpenClaw:** +- CLI Help: `openclaw --help` +- Check Status: `openclaw status` +- View Logs: Check client app logs tab +- **Required:** Configure with an LLM API key (OpenAI, Anthropic, etc.) during `openclaw onboard` + +## Quick Start Checklist + +### Setup (One-Time) +- [ ] Install OpenClaw: `npm install -g openclaw@latest` +- [ ] Initialize daemon: `openclaw onboard --install-daemon` +- [ ] **Configure with LLM API key** (OpenAI/Anthropic/etc.) +- [ ] Download OpenClaw client from link above +- [ ] Run client and paste OpenHome API key +- [ ] Verify "Connected" status and "welcome" message + +### Template Usage +- [ ] Get template from OpenHome dashboard or GitHub +- [ ] Define your trigger words in `config.json` +- [ ] Customize `first_function()` for your use case +- [ ] Add command validation and safety checks +- [ ] Test with safe commands first +- [ ] Add error handling and timeouts +- [ ] Deploy your custom ability! + +## Support & Contribution + +If you build something cool with this template: +- 🎉 Share it with the OpenHome community +- 💡 Contribute improvements back to the template +- 🤝 Help others troubleshoot in community forums +- 📝 Document your use case for future builders + +## Final Reminder + +⚠️ **This template is a foundation, not a finished product.** + +The power of OpenClaw integration comes from YOUR customization: +- Define specific trigger words +- Implement domain-specific logic +- Add safety validations +- Create multi-step workflows +- Build something unique! + +Don't just deploy the template as-is — make it yours! 🚀 diff --git a/templates/openclaw-template/__init__.py b/templates/openclaw-template/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/templates/openclaw-template/__init__.py @@ -0,0 +1 @@ + diff --git a/templates/openclaw-template/main.py b/templates/openclaw-template/main.py new file mode 100644 index 00000000..1e92b9cb --- /dev/null +++ b/templates/openclaw-template/main.py @@ -0,0 +1,47 @@ +import json +from src.agent.capability import MatchingCapability +from src.main import AgentWorker +from src.agent.capability_worker import CapabilityWorker + +class OpentestCapability(MatchingCapability): + worker: AgentWorker = None + capability_worker: CapabilityWorker = None + + # Do not change following tag of register capability + #{{register capability}} + + + async def first_function(self): + user_inquiry = await self.capability_worker.wait_for_complete_transcription() + + history = [] + + history.append( + { + "role": "user", + "content": user_inquiry, + }, + ) + # history.append( + # { + # "role": "assistant", + # "content": terminal_command, + # }, + # ) + # Execute the generated command + await self.capability_worker.speak(f"Sending Inquiry to OpenClaw") + response = await self.capability_worker.exec_local_command(user_inquiry) + + self.worker.editor_logging_handler.info(response) + # Speak the response + + await self.capability_worker.speak(response["data"]) + # Resume the normal workflow + self.capability_worker.resume_normal_flow() + + def call(self, worker: AgentWorker): + # Initialize the worker and capability worker + self.worker = worker + self.capability_worker = CapabilityWorker(self) + + self.worker.session_tasks.create(self.first_function()) From 16fb9b8bbaf4cbea5057402e4a08561425ada7f2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Mar 2026 21:25:17 +0500 Subject: [PATCH 06/10] Remove template files from PR --- templates/Alarm/background.py | 159 ------- templates/Background/README.md | 626 ---------------------------- templates/Background/__init__.py | 1 - templates/Background/alarm.mp3 | Bin 253891 -> 0 bytes templates/Background/background.py | 36 -- templates/Local/README.md | 632 ---------------------------- templates/Local/__init__.py | 1 - templates/Local/main.py | 92 ----- templates/OpenClaw/README.md | 642 ----------------------------- templates/OpenClaw/__init__.py | 1 - templates/OpenClaw/main.py | 46 --- 11 files changed, 2236 deletions(-) delete mode 100644 templates/Alarm/background.py delete mode 100644 templates/Background/README.md delete mode 100644 templates/Background/__init__.py delete mode 100644 templates/Background/alarm.mp3 delete mode 100644 templates/Background/background.py delete mode 100644 templates/Local/README.md delete mode 100644 templates/Local/__init__.py delete mode 100644 templates/Local/main.py delete mode 100644 templates/OpenClaw/README.md delete mode 100644 templates/OpenClaw/__init__.py delete mode 100644 templates/OpenClaw/main.py diff --git a/templates/Alarm/background.py b/templates/Alarm/background.py deleted file mode 100644 index 0aabd198..00000000 --- a/templates/Alarm/background.py +++ /dev/null @@ -1,159 +0,0 @@ -import json -from datetime import datetime -from zoneinfo import ZoneInfo -from time import time - -from src.agent.capability import MatchingCapability -from src.main import AgentWorker -from src.agent.capability_worker import CapabilityWorker - - -class BackgroundCapabilityBackground(MatchingCapability): - worker: AgentWorker = None - capability_worker: CapabilityWorker = None - background_daemon_mode: bool = False - - # Do not change following tag of register capability - # {{register capability}} - - async def _read_alarms_safe(self): - """ - Reads alarms.json safely. - If corrupted / not a list -> return [] (do NOT crash watcher). - """ - try: - if not await self.capability_worker.check_if_file_exists("alarms.json", False): - return [] - - raw = await self.capability_worker.read_file("alarms.json", False) - if not (raw or "").strip(): - return [] - - parsed = json.loads(raw) - return parsed if isinstance(parsed, list) else [] - except Exception as e: - self.worker.editor_logging_handler.error(f"{time()}: alarms.json read/parse failed: {e}") - return [] - - def _parse_alarm_time(self, target_iso: str, tz_name: str): - """ - Returns an aware datetime for target_iso. - """ - if not target_iso: - return None - try: - # target_iso already includes offset; datetime.fromisoformat handles it - dt = datetime.fromisoformat(target_iso) - if dt.tzinfo is None: - # fallback: attach timezone if missing - try: - dt = dt.replace(tzinfo=ZoneInfo(tz_name or "UTC")) - except Exception: - dt = dt.replace(tzinfo=ZoneInfo("UTC")) - return dt - except Exception: - return None - - async def _mark_alarm_triggered(self, alarms: list, alarm_id: str): - """ - Mark a triggered alarm as 'triggered' to prevent repeat firing. - Best-effort write: if write fails, watcher may re-trigger next loop. - """ - try: - changed = False - for a in alarms: - if a.get("id") == alarm_id and a.get("status") == "scheduled": - a["status"] = "triggered" - a["triggered_at_epoch"] = int(time()) - changed = True - break - - if not changed: - return - - # write back (delete-first to avoid append corruption) - try: - if await self.capability_worker.check_if_file_exists("alarms.json", False): - await self.capability_worker.delete_file("alarms.json", False) - except Exception: - pass - - await self.capability_worker.write_file( - "alarms.json", - json.dumps(alarms, ensure_ascii=False, indent=2), - False, - ) - except Exception as e: - self.worker.editor_logging_handler.error(f"{time()}: failed to mark alarm triggered: {e}") - - async def first_function(self): - self.worker.editor_logging_handler.info("%s: Watcher Alarm Called" % time()) - - # Watch loop - while True: - try: - self.worker.editor_logging_handler.info("%s: watcher alarm watching" % time()) - - alarms = await self._read_alarms_safe() - if not alarms: - await self.worker.session_tasks.sleep(5.0) - continue - - # Use watcher timezone as "now" reference (same as your alarm creation) - tz_name = self.capability_worker.get_timezone() - try: - tz = ZoneInfo(tz_name) - except Exception: - tz = ZoneInfo("UTC") - - now = datetime.now(tz=tz) - - # Find scheduled alarms that are due - due = [] - for a in alarms: - if a.get("status") != "scheduled": - continue - target_dt = self._parse_alarm_time(a.get("target_iso"), a.get("timezone") or tz_name) - if not target_dt: - continue - if now >= target_dt: - due.append((a, target_dt)) - - # Fire due alarms (in order) - if due: - due.sort(key=lambda x: x[1]) - for a, target_dt in due: - alarm_id = a.get("id", "unknown") - human_time = a.get("human_time", a.get("target_iso", "")) - - self.worker.editor_logging_handler.info( - f"{time()}: ALARM DUE id={alarm_id} target={target_dt.isoformat()} human='{human_time}'" - ) - - # Play alarm sound - try: - await self.capability_worker.play_from_audio_file("alarm.mp3") - except Exception as e: - self.worker.editor_logging_handler.error( - f"{time()}: Failed to play alarm sound for {alarm_id}: {e}" - ) - - # Mark as triggered to avoid repeat firing - await self._mark_alarm_triggered(alarms, alarm_id) - - await self.worker.session_tasks.sleep(5.0) - - except Exception as e: - self.worker.editor_logging_handler.error(f"{time()}: watcher loop error: {e}") - await self.worker.session_tasks.sleep(2.0) - - # Resume the normal workflow (unreachable, but keep structure) - self.capability_worker.resume_normal_flow() - - def call(self, worker: AgentWorker, background_daemon_mode: bool): - # Initialize the worker and capability worker - self.worker = worker - self.background_daemon_mode = background_daemon_mode - self.capability_worker = CapabilityWorker(self) - - self.worker.session_tasks.create(self.first_function()) diff --git a/templates/Background/README.md b/templates/Background/README.md deleted file mode 100644 index 17d1f138..00000000 --- a/templates/Background/README.md +++ /dev/null @@ -1,626 +0,0 @@ -# Background Monitoring Ability Template -![Community](https://img.shields.io/badge/OpenHome-Community-orange?style=flat-square) -![Template](https://img.shields.io/badge/Type-Template-blue?style=flat-square) -![Advanced](https://img.shields.io/badge/Level-Advanced-red?style=flat-square) - -## What This Is -**This is a background ability template** that runs continuously in an endless loop. Unlike normal abilities that respond once and exit, background abilities stay active throughout the agent session, monitoring conditions and triggering actions automatically. - -## Key Characteristics - -### Background Execution -- **Runs automatically** — Background abilities are auto-triggered when your agent starts -- **Endless loop** — The `while True` keeps the ability running continuously -- **Background operation** — Runs silently alongside the normal conversation flow -- **All CapabilityWorker functions available** — Full SDK access within the background - -### What Makes Backgrounds Different - -| Normal Ability | Background Ability | -|----------------|-----------------| -| User triggers with voice command | Auto-starts when agent initializes | -| Speak → Listen → Respond → Exit | Continuous loop: Monitor → Act → Sleep → Repeat | -| Calls `resume_normal_flow()` to exit | `resume_normal_flow()` never reached (intentional) | -| Session-specific | Background for entire agent session | - -## Template Features - -This basic background template demonstrates: - -1. **Continuous monitoring** — Endless `while True` loop -2. **Message history access** — Reads last 10 messages from normal conversation -3. **Logging** — Records activity via `editor_logging_handler` -4. **Sleep intervals** — 20-second pause between checks -5. **Commented examples** — Audio playback and speech capabilities - -## How It Works - -### Template Flow -``` -Agent Starts - ↓ -Background Auto-Triggers - ↓ -Enter while True Loop - ↓ -┌─────────────────────┐ -│ Log "watching" │ -│ Get last 10 messages│ -│ Log each message │ -│ Sleep 20 seconds │ -└─────────┬───────────┘ - │ - └─→ Repeat Forever -``` - -### Code Walkthrough - -**1. Background Mode Initialization:** -```python -def call(self, worker: AgentWorker, background_daemon_mode: bool) - self.worker = worker - self.background_daemon_mode = background_daemon_mode - self.capability_worker = CapabilityWorker(self.worker) - self.worker.session_tasks.create(self.first_function()) -``` -- `background_daemon_mode=True` indicates this is a background ability -- Auto-creates async task that runs in background - -**2. Endless Loop:** -```python -async def first_function(self): - self.worker.editor_logging_handler.info("%s: Background Called" % time()) - - while True: # ← Never exits - self.worker.editor_logging_handler.info("%s: background watching" % time()) - - # Your monitoring logic here - ... - - await self.worker.session_tasks.sleep(20.0) # ← Sleep before next check -``` -- Loop runs indefinitely (no break condition) -- Checks conditions every 20 seconds -- Never calls `resume_normal_flow()` — this is intentional - -**3. Access Message History:** -```python -message_history = self.capability_worker.get_full_message_history()[-10:] -``` -- Returns last **50 messages** by default (template uses last 10) -- Each message is a dict with `role` and `content` -- Provides context from normal conversation flow - -**4. Log Activity:** -```python -for message in message_history: - self.worker.editor_logging_handler.info( - "Role: %s, Message: %s" % (message.get("role", ""), message.get("content", "")) - ) -``` -- Always use `editor_logging_handler` (not `print`) -- Logs are visible in dashboard/logs - -**5. Sleep Between Checks:** -```python -await self.worker.session_tasks.sleep(20.0) -``` -- **Critical:** Use `session_tasks.sleep()`, NEVER `asyncio.sleep()` -- 20 seconds is template default (adjust to your needs) - -**6. Commented Examples:** -```python -# await self.capability_worker.speak("watching") -# await self.capability_worker.play_from_audio_file("alarm.mp3") -``` -- Shows how to trigger audio/speech from background -- Uncomment to test capabilities - -## Message History Structure - -### What You Get -```python -message_history = self.capability_worker.get_full_message_history() -``` - -**Returns:** List of up to **50 messages** (most recent) - -**Message Format:** -```python -{ - "role": "user", # or "assistant" - "content": "What's the weather today?" -} -``` - -### Example Usage - -**Monitor for specific keywords:** -```python -message_history = self.capability_worker.get_full_message_history()[-10:] - -for message in message_history: - if message.get("role") == "user": - content = message.get("content", "").lower() - - if "urgent" in content: - await self.capability_worker.speak("I noticed you said something urgent!") - await self.capability_worker.play_from_audio_file("alert.mp3") - break # Only alert once -``` - -**Track conversation patterns:** -```python -user_messages = [ - msg for msg in message_history - if msg.get("role") == "user" -] - -if len(user_messages) > 5: - # User has been very active - self.worker.editor_logging_handler.info("High conversation activity detected") -``` - -## Audio Playback in Backgrounds - -### Play Files from Ability Directory -```python -await self.capability_worker.play_from_audio_file("alarm.mp3") -``` - -**Setup:** -1. Place audio file in your ability's folder (e.g., `alarm.mp3`) -2. Supported formats: `.mp3`, `.wav`, `.ogg` -3. Call from anywhere in the background loop - -**Example background with audio alerts:** -```python -async def first_function(self): - alert_count = 0 - - while True: - message_history = self.capability_worker.get_full_message_history()[-10:] - - # Check for alert conditions - for message in message_history: - if "emergency" in message.get("content", "").lower(): - await self.capability_worker.play_from_audio_file("emergency.mp3") - alert_count += 1 - break - - self.worker.editor_logging_handler.info(f"Alerts fired: {alert_count}") - await self.worker.session_tasks.sleep(10.0) -``` - -### Speak from Background -```python -await self.capability_worker.speak("I'm monitoring in the background!") -``` - -**Use cases:** -- Periodic reminders -- Alert announcements -- Status updates - -**Example periodic reminder:** -```python -async def first_function(self): - reminder_interval = 300 # 5 minutes - last_reminder = time() - - while True: - now = time() - - if now - last_reminder >= reminder_interval: - await self.capability_worker.speak("Reminder: Take a break and stretch!") - last_reminder = now - - await self.worker.session_tasks.sleep(30.0) -``` - -## All CapabilityWorker Functions Available - -Backgrounds have **full SDK access**. You can use: - -### Conversation Functions -```python -await self.capability_worker.speak("Message") -await self.capability_worker.user_response() -message_history = self.capability_worker.get_full_message_history() -``` - -### Text Generation -```python -response = self.capability_worker.text_to_text_response("Analyze this...") -``` - -### File Operations -```python -await self.capability_worker.write_file("log.txt", data, False) -data = await self.capability_worker.read_file("config.json", False) -exists = await self.capability_worker.check_if_file_exists("data.txt", False) -await self.capability_worker.delete_file("temp.txt", False) -``` - -### Audio -```python -await self.capability_worker.play_from_audio_file("sound.mp3") -await self.capability_worker.play_audio(audio_bytes) -``` - -### Device Actions -```python -await self.capability_worker.send_devkit_action("led_on") -await self.capability_worker.send_notification_to_ios("Title", "Body") -``` - -**Example background using multiple SDK functions:** -```python -async def first_function(self): - while True: - # Check for new data file - if await self.capability_worker.check_if_file_exists("trigger.txt", False): - # Read trigger data - data = await self.capability_worker.read_file("trigger.txt", False) - - # Use LLM to analyze - analysis = self.capability_worker.text_to_text_response( - f"Summarize this in one sentence: {data}" - ) - - # Speak the summary - await self.capability_worker.speak(f"Alert: {analysis}") - - # Play sound - await self.capability_worker.play_from_audio_file("notification.mp3") - - # Clean up trigger file - await self.capability_worker.delete_file("trigger.txt", False) - - await self.worker.session_tasks.sleep(10.0) -``` - -## Common Background Patterns - -### Pattern 1: Keyword Monitor -Watch conversation for specific words/phrases: - -```python -async def first_function(self): - keywords = ["help", "urgent", "emergency", "important"] - - while True: - message_history = self.capability_worker.get_full_message_history()[-5:] - - for message in message_history: - if message.get("role") == "user": - content = message.get("content", "").lower() - - if any(keyword in content for keyword in keywords): - await self.capability_worker.speak("I noticed you need attention!") - await self.capability_worker.play_from_audio_file("alert.mp3") - - await self.worker.session_tasks.sleep(15.0) -``` - -### Pattern 2: Activity Timer -Detect user inactivity and prompt: - -```python -async def first_function(self): - last_user_message_time = time() - inactivity_threshold = 300 # 5 minutes - - while True: - message_history = self.capability_worker.get_full_message_history()[-1:] - - if message_history and message_history[0].get("role") == "user": - last_user_message_time = time() - - now = time() - if now - last_user_message_time > inactivity_threshold: - await self.capability_worker.speak("Still here if you need anything!") - last_user_message_time = now # Reset to avoid spam - - await self.worker.session_tasks.sleep(60.0) -``` - -### Pattern 3: File Background -Monitor for new files and process them: - -```python -async def first_function(self): - processed_files = set() - - while True: - # Check for new data file - if await self.capability_worker.check_if_file_exists("inbox.txt", False): - content = await self.capability_worker.read_file("inbox.txt", False) - - # Create unique ID for this content - content_hash = hash(content) - - if content_hash not in processed_files: - # Process new content - await self.capability_worker.speak(f"New data received: {content[:50]}") - await self.capability_worker.play_from_audio_file("notification.mp3") - - processed_files.add(content_hash) - - # Archive processed data - await self.capability_worker.write_file( - "processed.txt", - f"\n{content}", - False - ) - - await self.worker.session_tasks.sleep(5.0) -``` - -### Pattern 4: Sentiment Monitor -Track conversation tone and alert if negative: - -```python -async def first_function(self): - while True: - message_history = self.capability_worker.get_full_message_history()[-10:] - - # Combine recent messages - recent_conversation = "\n".join([ - msg.get("content", "") - for msg in message_history - if msg.get("role") == "user" - ]) - - # Analyze sentiment - if recent_conversation: - sentiment_prompt = f"""Analyze sentiment of this conversation: {recent_conversation} - - Return only: "positive", "neutral", or "negative" - """ - - sentiment = self.capability_worker.text_to_text_response(sentiment_prompt).lower().strip() - - if "negative" in sentiment: - self.worker.editor_logging_handler.warning("Negative sentiment detected") - # Could trigger supportive response - - await self.worker.session_tasks.sleep(30.0) -``` - -## Best Practices - -### 1. Always Use session_tasks.sleep() -```python -# ✅ CORRECT -await self.worker.session_tasks.sleep(20.0) - -# ❌ WRONG — Won't clean up properly -await asyncio.sleep(20.0) -``` - -### 2. Set Appropriate Sleep Intervals -```python -# ✅ GOOD — Reasonable intervals -await self.worker.session_tasks.sleep(5.0) # Quick monitoring -await self.worker.session_tasks.sleep(30.0) # Moderate checks -await self.worker.session_tasks.sleep(60.0) # Periodic polling - -# ❌ BAD — Too frequent, wastes resources -await self.worker.session_tasks.sleep(0.1) - -# ⚠️ CAUTION — Too infrequent, may miss events -await self.worker.session_tasks.sleep(600.0) -``` - -**Guidelines:** -- **Real-time monitoring:** 1-5 seconds -- **Keyword watching:** 10-20 seconds -- **Periodic reminders:** 30-60 seconds -- **Activity tracking:** 30-120 seconds - -### 3. Use editor_logging_handler (Not print) -```python -# ✅ CORRECT -self.worker.editor_logging_handler.info("background started") -self.worker.editor_logging_handler.warning("Unusual activity") -self.worker.editor_logging_handler.error(f"Error: {e}") - -# ❌ WRONG — Won't appear in logs -print("Background started") -``` - -### 4. Wrap Loop in Try-Catch -```python -async def first_function(self): - while True: - try: - # Your monitoring logic - ... - - except Exception as e: - self.worker.editor_logging_handler.error(f"Background error: {e}") - await self.worker.session_tasks.sleep(5.0) # Brief pause before retry -``` - -### 5. Limit Message History Access -```python -# ✅ GOOD — Get only what you need -message_history = self.capability_worker.get_full_message_history()[-10:] - -# ⚠️ CAREFUL — Full history (50 messages) may be overkill -message_history = self.capability_worker.get_full_message_history() -``` - -### 6. Avoid Duplicate Actions -```python -# Track what's been processed -processed_message_ids = set() - -while True: - message_history = self.capability_worker.get_full_message_history()[-10:] - - for message in message_history: - msg_id = hash(f"{message.get('role')}{message.get('content')}") - - if msg_id not in processed_message_ids: - # Process new message - ... - processed_message_ids.add(msg_id) - - await self.worker.session_tasks.sleep(10.0) -``` - -### 7. Keep Processing Lightweight -```python -# ✅ GOOD — Quick checks -if "keyword" in content: - do_something() - -# ❌ BAD — Heavy processing in hot loop -for message in message_history: - # Don't call slow APIs or heavy computation repeatedly - result = expensive_api_call(message) # This slows everything down -``` - -## What You Can Build - -Examples of background abilities: - -- **Conversation monitors** — Track keywords, sentiment, activity -- **Periodic reminders** — "Take a break" every 30 minutes -- **File processors** — Watch for new files and auto-process -- **Alert systems** — Detect conditions and play audio alerts -- **Activity trackers** — Log user engagement patterns -- **Sentiment analyzers** — Monitor conversation tone -- **Notification triggers** — Send iOS notifications on events -- **Data aggregators** — Collect and summarize conversation data - -## Troubleshooting - -### Background Stops Running -**Problem:** Loop exits unexpectedly - -**Solutions:** -- Add try-catch around entire loop -- Check logs for error messages -- Verify using `session_tasks.sleep()` not `asyncio.sleep()` - -### Audio File Won't Play -**Problem:** `play_from_audio_file()` fails - -**Solutions:** -- Verify file exists in ability directory -- Check filename matches exactly (case-sensitive) -- Try different format (.mp3 vs .wav) - -### High CPU Usage -**Problem:** Background consumes too many resources - -**Solutions:** -- Increase sleep interval -- Reduce message history size (use [-5:] instead of [-50:]) -- Avoid heavy processing in loop - -### Message History Empty -**Problem:** `get_full_message_history()` returns empty list - -**Explanation:** Normal — no messages yet in conversation - -**Solution:** Check if list is empty before processing: -```python -message_history = self.capability_worker.get_full_message_history() -if not message_history: - await self.worker.session_tasks.sleep(20.0) - continue -``` - -## Limitations - -### What Backgrounds Cannot Do - -**No Cross-Session Persistence:** -- Background stops when agent session ends -- Cannot fire events after user logs out -- Not suitable for true background tasks (24/7 monitoring) - -**No Proactive Interruption:** -- Cannot interrupt user mid-conversation -- Actions happen during natural pauses -- Must respect conversation flow - -**Resource Constraints:** -- Should not run expensive operations continuously -- Sleep intervals prevent excessive resource use -- Keep processing lightweight - -## Security Considerations - -### Rate Limiting -Prevent abuse by limiting frequency: -```python -MIN_SLEEP = 5.0 # Minimum 5 seconds between checks - -await self.worker.session_tasks.sleep(max(MIN_SLEEP, custom_interval)) -``` - -### Sensitive Data -Don't log sensitive information: -```python -# ❌ BAD — Logs sensitive content -self.worker.editor_logging_handler.info(f"Message: {message.get('content')}") - -# ✅ GOOD — Log only metadata -self.worker.editor_logging_handler.info(f"Message count: {len(message_history)}") -``` - -## Quick Start Checklist - -### Understanding Backgrounds -- [ ] Understand Backgrounds run automatically in background -- [ ] Know `while True` never exits (intentional) -- [ ] Recognize `resume_normal_flow()` is unreachable -- [ ] Understand session-scoped nature (not 24/7) - -### Building Your Background -- [ ] Define what to monitor (messages, files, time, etc.) -- [ ] Set appropriate sleep interval (10-60 seconds typical) -- [ ] Add try-catch around entire loop -- [ ] Use `session_tasks.sleep()`, not `asyncio.sleep()` -- [ ] Use `editor_logging_handler` for all logging -- [ ] Test with various scenarios - -### Adding Features -- [ ] Access message history with `get_full_message_history()` -- [ ] Play audio files from ability directory -- [ ] Speak updates with `speak()` -- [ ] Write logs to files with file operations -- [ ] Track processed items to avoid duplicates - -## Links & Resources - -**OpenHome Documentation:** -- [Building Great Abilities](https://docs.openhome.com/Building_Great_OpenHome_Abilities) -- [How to Build an Ability](https://docs.openhome.com/how_to_build_an_ability) -- [Dashboard](https://app.openhome.xyz/dashboard) -- [Discord Community](https://discord.com/channels/1197724389630824508) - -## Support & Contribution - -If you build something with background mode: -- 🎉 Share your implementation -- 💡 Contribute improvements -- 🤝 Help others understand backgrounds -- 📝 Document your use case - -## Final Reminder - -⚠️ **Key Takeaways:** -- ✅ Backgrounds run automatically in endless loops -- ✅ Access full conversation history (last 50 messages) -- ✅ Play audio and use all CapabilityWorker functions -- ✅ Background monitoring during active agent sessions -- ❌ Not truly 24/7 background tasks (session-scoped) -- ❌ Never calls `resume_normal_flow()` (by design) - -Use backgrounds for real-time monitoring, periodic checks, and automated responses during active sessions! 🔄🚀 diff --git a/templates/Background/__init__.py b/templates/Background/__init__.py deleted file mode 100644 index 8b137891..00000000 --- a/templates/Background/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/templates/Background/alarm.mp3 b/templates/Background/alarm.mp3 deleted file mode 100644 index 56e94e4d3e52acb7e659682beced73c07d7c1dc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 253891 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

jIi}7v9hOLN72;D9znY@GGjy_g z@h_?*#%b98_GGihIHC+On&W|3X+9wqhe;P!#ZPs5WS1hbdEEtKAzT9-W~t(zG*dhG#i=_d z{M{VYE-PgeqZBIkv_73f4LrJZ(gN52-44$HEch6C7>F7^1Qx2-mkKZ)ujPhCyTb86 zXm}t1K-yY|@be^0NKw1BH2Y*5m+_cvpH(hixG5XS6;3i>GK$cFgn&deP!}8F%DW_u z6&8^*5kwDiBUAtQo}33SH!Nph>Q`N()0h_;1ItHF0ginjF)TU;FH~af$-8R)Bn6ur z5obyrP6MfO z+g%58wKfg5*fG0(l2N9#f*x7syKpdP)z?4Iw=+cwIjBhK+1!$qvSOw)23e#@$$2NY zcX~ATeZQ#{h_w~wz0}=h8rD?td(KB+Se!M>ws!QEM>h2IN1w98M~agjRUDy?7nLP2 zob`A4lJ7y5kR>8)+>cE^MaH~xNB8DycY3SEi6jttFoV@X)w7dQsKSj;M)bj@5>$vF zMTM!pKIPEA?Bh0TU23^G#Bb zr~Tl4hwb*Wysa!0>T&m(p}8T!1i;(6<^S^jTb#lD4)h@qyw7~vbGN}7KlHu&(AX|D zN~%iD!>HDm_HBOt>0hMKGOJtZ{bcD^qn($xf6QHWVB@h<*oX7A=Vh(!-mzUAkMU&x zPOs`)v>hdpJDlr-qUSHJD)KguOM?zX@qe#S8w8jIyB+k0P1UfYFo9Gv#;h>tEUb5+ zhy2$&AmWWG8|xE!^_L@az%ha^=_m^DfpJ8^s1PbFEM%;mekGw) z$cBu5^0_WQ?6>oqr%g82!x`&EHQ2rOI7P`Sgh6+F`ovbEUK7b9Jk^uSXv zb#tK$nh1u*`S@)_G%?Y4ToyTQv*_F?OcTF(bncF7as3~?7M;ivZYa-LNo`*)ckF80 zWJytpJ`cpBm47q2pX8Ogw%QQpA;7FI!GS_50 zltTHBt1E^r3Z;;QH=MtBj4A*6hZb%Qe`n zA-B@~n{HRPuY4NI`ALgFbxu+Gp&hTp@T?U>Ny*I8orj}gHCt~krtBxxT{IfLDUcYM zKYUUQLz$4s@KooAFoxsv5B4`rtL9N{cvQc7)=7*E?O@q4g%BV4a#iW2lN>x

fgXQ_jTxY^W3 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 /tmp/openhome_client.log 2>&1 & -``` - -### Step 3: Get the Template Ability - -1. Find **OpenHome Local Link** template from: - - OpenHome Dashboard abilities library, OR - - [GitHub Repository](https://github.com/OpenHome-dev/abilities) - -2. Add to your OpenHome Agent - -3. The template is ready to test immediately! - -## Using This Template - -### Default Template Behavior -The unmodified template: -1. Listens for Mac-related voice commands -2. Converts natural language → terminal commands using LLM -3. Sends command to your local client via `exec_local_command()` -4. Client executes the command on your Mac terminal -5. Response is sent back to OpenHome -6. LLM converts technical output → natural spoken response - -### Testing the Template -> **User:** "list all files" -> **AI:** "Running command: ls -la" -> *(Command executes on your Mac)* -> **AI:** "I found 15 files in your current directory including Documents, Downloads, and Desktop." - ---- - -> **User:** "show current directory" -> **AI:** "Running command: pwd" -> **AI:** "You're currently in /Users/yourname/Documents" - ---- - -> **User:** "check disk space" -> **AI:** "Running command: df -h" -> **AI:** "Your main drive has 150 GB free out of 500 GB total." - -## Core Template Function - -### `exec_local_command()` -Sends a command to your local Mac terminal and returns the response. - -**Function Signature:** -```python -async def exec_local_command( - self, - command: str | dict, - target_id: str | None = None, - timeout: float = 10.0 -) -``` - -**Parameters:** -- `command` (str | dict): **Required.** Terminal command to execute -- `target_id` (str | None): **Optional.** Device identifier (default: "laptop") -- `timeout` (float): **Optional.** Max seconds to wait (default: 10.0) - -**Template Usage:** -```python -# Basic usage (as shown in template) -response = await self.capability_worker.exec_local_command(terminal_command) - -# With custom timeout for long commands -response = await self.capability_worker.exec_local_command( - "find / -name '*.log'", - timeout=30.0 -) - -# With specific target device -response = await self.capability_worker.exec_local_command( - "df -h", - target_id="laptop" -) -``` - -## How the Template Works - -### 1. Voice Input → Natural Language -User speaks: "list all files in my downloads folder" - -### 2. LLM Converts to Terminal Command -System prompt guides LLM to generate Mac-compatible commands: -```python -system_prompt = """ -You are a Mac terminal command generator. -Rules: -- Respond ONLY with the terminal command -- Use macOS-compatible commands (zsh/bash) -- No explanations, quotes, or markdown -- Avoid sudo unless necessary -""" -``` - -Result: `ls -la ~/Downloads` - -### 3. Command Sent to Local Client -```python -response = await self.capability_worker.exec_local_command(terminal_command) -``` - -### 4. Client Executes on Mac -The `local_client.py` runs the command in your Mac terminal and captures output. - -### 5. Response Formatted for Speech -LLM converts technical output to conversational language: -```python -check_response_system_prompt = """ -Tell if the command was successful in easier terms. -If user wanted information, return that information. -""" -``` - -### 6. AI Speaks Result -"I found 47 files in your Downloads folder including PDFs, images, and documents." - -## Customizing the Template - -### 1. Modify System Prompt -Change how commands are generated: - -```python -def get_system_prompt(self): - return """ - You are a Mac automation assistant specialized in [YOUR DOMAIN]. - - Rules: - - [Your custom rules] - - [Specific command patterns] - - Examples: - User: "[your example]" -> [your command] - """ -``` - -### 2. Add Pre-Processing Logic -Validate or transform commands before execution: - -```python -async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - # ⬇️ ADD YOUR VALIDATION HERE - if "delete" in user_inquiry.lower() or "rm -rf" in user_inquiry.lower(): - await self.capability_worker.speak("I can't run destructive commands for safety.") - self.capability_worker.resume_normal_flow() - return - # ⬆️ - - # ... rest of template -``` - -### 3. Add Confirmation for Dangerous Commands -```python -terminal_command = self.capability_worker.text_to_text_response(...) - -# ⬇️ ADD CONFIRMATION LOGIC -if any(danger in terminal_command for danger in ["rm", "sudo", "shutdown"]): - await self.capability_worker.speak(f"This command will {terminal_command}. Confirm?") - confirmation = await self.capability_worker.user_response() - if "yes" not in confirmation.lower(): - await self.capability_worker.speak("Cancelled.") - self.capability_worker.resume_normal_flow() - return -# ⬆️ - -response = await self.capability_worker.exec_local_command(terminal_command) -``` - -### 4. Chain Multiple Commands -```python -async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - # Example: "backup my documents" - if "backup" in user_inquiry.lower(): - commands = [ - "mkdir -p ~/Backups", - "cp -r ~/Documents ~/Backups/Documents_$(date +%Y%m%d)", - "echo 'Backup complete'" - ] - - for cmd in commands: - await self.capability_worker.speak(f"Running: {cmd}") - response = await self.capability_worker.exec_local_command(cmd) - - await self.capability_worker.speak("Backup completed successfully!") - self.capability_worker.resume_normal_flow() - return - - # ... rest of template for other commands -``` - -## Example Abilities You Can Build - -### 1. Git Assistant -```python -def get_system_prompt(self): - return """ - Convert git operations to commands. - - Examples: - "check git status" -> git status - "commit changes" -> git add . && git commit -m "Update" - "push to main" -> git push origin main - "create branch feature-x" -> git checkout -b feature-x - """ -``` - -### 2. System Monitor -```python -async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - if "system health" in user_inquiry.lower(): - metrics = { - "CPU": "top -l 1 | grep 'CPU usage'", - "Memory": "vm_stat | head -n 10", - "Disk": "df -h /", - "Battery": "pmset -g batt" - } - - report = [] - for name, cmd in metrics.items(): - response = await self.capability_worker.exec_local_command(cmd) - # Parse and format response - report.append(f"{name}: {response}") - - await self.capability_worker.speak(". ".join(report)) - self.capability_worker.resume_normal_flow() - return -``` - -### 3. Development Environment Setup -```python -async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - if "start dev environment" in user_inquiry.lower(): - await self.capability_worker.speak("Starting development environment...") - - commands = [ - "cd ~/Projects/my-app", - "code .", # Opens VS Code - "npm run dev &", # Starts dev server in background - "open http://localhost:3000" # Opens browser - ] - - for cmd in commands: - await self.capability_worker.exec_local_command(cmd, timeout=15.0) - - await self.capability_worker.speak("Development environment is ready!") - self.capability_worker.resume_normal_flow() - return -``` - -### 4. File Organization Assistant -```python -def get_system_prompt(self): - return """ - File management commands for Mac. - - Examples: - "organize downloads by type" -> - mkdir ~/Downloads/Images ~/Downloads/Documents ~/Downloads/Videos && - mv ~/Downloads/*.jpg ~/Downloads/Images/ 2>/dev/null || true && - mv ~/Downloads/*.pdf ~/Downloads/Documents/ 2>/dev/null || true - - "clean up temp files" -> rm -rf ~/Library/Caches/Homebrew/* - "find large files" -> find ~ -type f -size +100M - """ -``` - -## Modifying the Local Client - -The `local_client.py` file can be customized to: - -### Add Custom Command Handlers -```python -# In local_client.py -def execute_command(command): - # Add special handling for specific commands - if command == "get_battery": - result = subprocess.run(['pmset', '-g', 'batt'], capture_output=True) - return parse_battery_output(result.stdout) - - # Default: run command as-is - result = subprocess.run(command, shell=True, capture_output=True) - return result.stdout.decode() -``` - -### Add Logging -```python -# In local_client.py -import logging - -logging.basicConfig(filename='openhome_commands.log', level=logging.INFO) - -def execute_command(command): - logging.info(f"Executing: {command}") - result = subprocess.run(command, shell=True, capture_output=True) - logging.info(f"Result: {result.stdout[:100]}...") - return result.stdout.decode() -``` - -### Add Security Restrictions -```python -# In local_client.py -BLOCKED_COMMANDS = ['rm -rf /', 'sudo', 'format', 'dd if='] - -def execute_command(command): - if any(blocked in command for blocked in BLOCKED_COMMANDS): - return "ERROR: Blocked command for safety" - - result = subprocess.run(command, shell=True, capture_output=True) - return result.stdout.decode() -``` - -## Best Practices - -### 1. Always Test Commands Manually First -Before automating with voice: -```bash -# Test the command in your terminal first -ls -la ~/Documents - -# Verify it does what you expect -# Then add to your ability -``` - -### 2. Use Safe Defaults -```python -# Avoid destructive operations by default -SAFE_COMMANDS = ['ls', 'pwd', 'cd', 'cat', 'grep', 'find', 'df', 'du'] - -if not any(safe in terminal_command for safe in SAFE_COMMANDS): - await self.capability_worker.speak("This command needs confirmation.") - # ... confirmation logic -``` - -### 3. Handle Timeouts Appropriately -```python -# Quick commands (default 10s) -response = await self.capability_worker.exec_local_command("pwd") - -# Long-running commands (increase timeout) -response = await self.capability_worker.exec_local_command( - "find / -name '*.log'", - timeout=60.0 -) -``` - -### 4. Add Error Handling -```python -try: - response = await self.capability_worker.exec_local_command(terminal_command) - - if "error" in response.lower() or "permission denied" in response.lower(): - await self.capability_worker.speak("That command failed. Try a different approach?") - else: - # Process successful response - ... - -except asyncio.TimeoutError: - await self.capability_worker.speak("That took too long. It might still be running.") -except Exception as e: - self.worker.editor_logging_handler.error(f"Command failed: {e}") - await self.capability_worker.speak("Something went wrong.") -finally: - self.capability_worker.resume_normal_flow() -``` - -## Troubleshooting - -### Client Won't Connect -**Problem:** `local_client.py` shows connection error - -**Solutions:** -1. Verify API key is correct (from Dashboard → Settings → API Keys) -2. Check Python version: `python3 --version` (needs 3.7+) -3. Check internet connection -4. Look for firewall blocking Python connections - -### Commands Not Executing -**Problem:** Client connected but commands fail - -**Solutions:** -1. Check client terminal for error messages -2. Verify command works when run manually in terminal -3. Check client logs: `tail -f /tmp/openhome_client.log` -4. Restart the client: `pkill -f local_client.py && python3 local_client.py` - -### Permission Errors -**Problem:** Commands fail with "Permission denied" - -**Solutions:** -1. Some commands require admin privileges -2. Modify client to use `sudo` (with password handling) -3. Run client with appropriate permissions -4. Avoid commands that need root access - -### Client Disconnects Randomly -**Problem:** Client connection drops after a while - -**Solutions:** -1. Use `tmux` to keep session alive: - ```bash - tmux new -s openhome - python3 local_client.py - # Ctrl+B then D to detach - ``` -2. Add auto-reconnect logic to client -3. Check for Mac sleep settings interfering - -### Response Formatting Issues -**Problem:** AI speaks raw terminal output - -**Solutions:** -1. The template formats responses automatically via LLM -2. Check `check_response_system_prompt` is correct -3. Add custom parsing for specific commands -4. Modify the system prompt to guide better responses - -## Security Considerations - -### ⚠️ Important Security Notes -- **This runs real terminal commands** on your Mac with your user permissions -- **No sandbox protection** — commands execute exactly as typed -- **Anyone with access to your OpenHome** can run commands via your client -- **Protect your API key** — don't share or commit to public repos - -### Recommended Safety Measures - -**1. Command Whitelist** -```python -ALLOWED_COMMANDS = ['ls', 'pwd', 'df', 'du', 'cat', 'grep', 'find'] - -if not any(cmd in terminal_command for cmd in ALLOWED_COMMANDS): - await self.capability_worker.speak("That command is not allowed.") - return -``` - -**2. Confirmation for Destructive Actions** -Always confirm before running: -- `rm` (delete) -- `sudo` (admin) -- `shutdown` / `reboot` -- `dd` (disk operations) -- `format` / `diskutil` - -**3. Separate User for Client** -Run the client under a limited user account: -```bash -# Create a new user for OpenHome -sudo dscl . -create /Users/openhome -sudo dscl . -create /Users/openhome UserShell /bin/bash -sudo dscl . -create /Users/openhome RealName "OpenHome Client" - -# Run client as that user -su openhome -c "python3 local_client.py" -``` - -**4. Monitor Client Logs** -```bash -# Check what commands were run -grep "Executing:" /tmp/openhome_client.log - -# Set up alerts for dangerous commands -tail -f /tmp/openhome_client.log | grep -E "rm|sudo|shutdown" -``` - -## Technical Architecture -``` -Voice Input → OpenHome Ability → exec_local_command() - ↓ - local_client.py - (WebSocket connection) - ↓ - Mac Terminal Execution - (subprocess.run) - ↓ - Response ← AI Formatting ← Template -``` - -## Comparison: Local Link vs OpenClaw - -| Feature | Local Link | OpenClaw | -|---------|-----------|----------| -| **Setup** | Single Python file | Full CLI + daemon + LLM config | -| **Dependencies** | Python 3.7+ only | Node.js + npm + LLM API key | -| **Complexity** | Simple, minimal | Advanced, feature-rich | -| **Customization** | Direct Python editing | MCP server integration | -| **Use Case** | Quick terminal access | Complex automation workflows | -| **Best For** | Simple commands, prototyping | Production automation | - -Use **Local Link** when you want simple, direct terminal access. -Use **OpenClaw** when you need robust automation with LLM-powered intelligence. - -## Quick Start Checklist - -### Setup (One-Time) -- [ ] Download `local_client.py` from Google Drive -- [ ] Add OpenHome API key to client file -- [ ] Test client connection: `python3 local_client.py` -- [ ] Verify "Connected" message - -### Template Usage -- [ ] Get template from OpenHome dashboard -- [ ] Test with safe command: "show current directory" -- [ ] Verify response is spoken correctly -- [ ] Customize system prompt for your use case -- [ ] Add safety validations -- [ ] Define custom trigger words in `config.json` - -## Links & Resources - -**Required Downloads:** -- **[local_client.py](https://drive.google.com/file/d/12Is4eXchH5dDjlG39Knp4oRuD-V3D-v_/view?usp=drive_link)** — Download this file (required) - -**OpenHome:** -- [Dashboard](https://app.openhome.com/dashboard) -- [API Key Management](https://app.openhome.com/dashboard/settings) — Get your API key here -- [Abilities Library](https://app.openhome.com/dashboard/abilities) - -**Mac Terminal Resources:** -- macOS Terminal User Guide -- `man` command for documentation (e.g., `man ls`) -- Homebrew for package management - -## Support & Contribution - -If you build something cool with this template: -- 🎉 Share it with the OpenHome community -- 💡 Contribute improvements to the template -- 🤝 Help others in community forums -- 📝 Document your use case - -## Final Reminder - -⚠️ **This template is a starting point, not a finished product.** - -The power comes from YOUR customization: -- Define specific commands for your workflow -- Add safety validations -- Create domain-specific assistants -- Build something unique for your Mac! - -**Don't deploy the template as-is — make it yours!** 🚀 diff --git a/templates/Local/__init__.py b/templates/Local/__init__.py deleted file mode 100644 index 8b137891..00000000 --- a/templates/Local/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/templates/Local/main.py b/templates/Local/main.py deleted file mode 100644 index 5f1edcbf..00000000 --- a/templates/Local/main.py +++ /dev/null @@ -1,92 +0,0 @@ -from src.agent.capability import MatchingCapability -from src.main import AgentWorker -from src.agent.capability_worker import CapabilityWorker - - -class LocalCapability(MatchingCapability): - worker: AgentWorker = None - capability_worker: CapabilityWorker = None - - # Do not change following tag of register capability - # {{register capability}} - - def get_system_prompt(self): - system_prompt = """ - You are a Mac terminal command generator. Your ONLY purpose is to convert user requests into valid Mac terminal commands. - - Rules: - - Respond ONLY with the terminal command, nothing else - - Use commands that are compatible with macOS (zsh/bash) - - Do not include explanations, quotes, or markdown formatting - - Do not use sudo unless absolutely necessary - - Make sure commands are safe and won't harm the system - - If the request is unclear, provide the most reasonable command interpretation - - Examples: - User: "list all files" -> ls -la - User: "show current directory" -> pwd - User: "find python files" -> find . -name "*.py" - User: "check disk space" -> df -h - User: "show running processes" -> ps aux - - Respond with ONLY the command, no other text. - """ - return system_prompt - - async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - # Get the system prompt - system_prompt = self.get_system_prompt() - self.worker.editor_logging_handler.info(system_prompt) - - # Use text_to_text_response to convert user inquiry to terminal command - history = [] - terminal_command = self.capability_worker.text_to_text_response( - user_inquiry, - history, - system_prompt, - ) - self.worker.editor_logging_handler.info(terminal_command) - - # Clean up the response (remove any extra whitespace or newlines) - terminal_command = terminal_command.strip() - self.worker.editor_logging_handler.info(terminal_command) - - history.append( - { - "role": "user", - "content": user_inquiry, - }, - ) - history.append( - { - "role": "assistant", - "content": terminal_command, - }, - ) - # Execute the generated command - await self.capability_worker.speak(f"Running command: {terminal_command}") - response = await self.capability_worker.exec_local_command(terminal_command) - - self.worker.editor_logging_handler.info(response) - # Speak the response - check_response_system_prompt = """Your job was to return a command that can run locally on mac and you gave that - command earlier based on user input now tell if that was successful or not in easier terms that can be directly - spoken to the user for his understanding but if user wanted to get the information that's in the response return that response too.""" - result = self.capability_worker.text_to_text_response( - "check if the command successfully ran? response is: %s" % response, - history, - check_response_system_prompt, - ) - if result: - await self.capability_worker.speak(result) - # Resume the normal workflow - self.capability_worker.resume_normal_flow() - - def call(self, worker: AgentWorker): - # Initialize the worker and capability worker - self.worker = worker - self.capability_worker = CapabilityWorker(self) - - self.worker.session_tasks.create(self.first_function()) diff --git a/templates/OpenClaw/README.md b/templates/OpenClaw/README.md deleted file mode 100644 index 508344a6..00000000 --- a/templates/OpenClaw/README.md +++ /dev/null @@ -1,642 +0,0 @@ -# OpenClaw Template - Build Custom Computer Control Abilities - -## What This Is -**This is a template ability** that enables you to create custom voice-controlled computer automation using OpenClaw. Use this as a starting point to build abilities that control your local machine through OpenHome. - -## What You Can Build -Examples of abilities you could create with this template: -- Application launcher and manager -- System monitoring and diagnostics -- File and folder automation -- Development environment controller -- Custom workflow automations -- Smart home integration via computer -- Screenshot and screen recording tools -- Clipboard and text manipulation - -## Template Trigger Words -This template uses generic triggers - **you should customize these** for your specific ability: -- Any computer control request -- Configure your own trigger words in OpenHome Live editor or when creating your ability. - -## Requirements - -### 1. OpenClaw Installation & Configuration -OpenClaw must be installed and configured on your local machine with an LLM API key. - -**Install OpenClaw:** -```bash -npm install -g openclaw@latest -``` - -**Initialize OpenClaw Daemon:** -```bash -openclaw onboard --install-daemon -``` - -**Configure with LLM API Key:** -Follow OpenClaw's configuration steps to add your LLM API key (OpenAI, Anthropic, etc.) - -### 2. Download OpenClaw Client -Download the OpenHome client for OpenClaw based on your operating system: - -**[Download Link](https://drive.google.com/drive/folders/10qK75I-bFB2D98YJ6dH3tQFsvEk44Y7-)** - -Choose the appropriate version: -- Windows: `.exe` installer -- macOS: `.dmg` or `.app` file -- Linux: AppImage or `.deb` - -### 3. Client Setup & Connection -1. **Run the downloaded client** - - **Windows**: Run the .exe, allow permissions if prompted - - **macOS**: If blocked, go to System Settings → Privacy & Security → "Open Anyway" - - **Linux**: `chmod +x` and run, grant required permissions - -2. **Copy your OpenHome API Key** - - Go to [OpenHome Dashboard → Settings → API Keys](https://app.openhome.com/dashboard/settings) - - Copy your API key - -3. **Connect the client** - - Paste the API key into the OpenClaw client app - - Click "Connect" - - Wait for "welcome" message in logs (confirms successful connection) - -## Using This Template - -### Step 1: Get the Template -Find the OpenClaw template ability from: -- OpenHome Dashboard abilities library, OR -- [GitHub Repository](https://github.com/OpenHome-dev/abilities) - -### Step 2: Customize for Your Use Case -This template provides the basic structure. Modify it to: - -1. **Define your trigger words** in `config.json`: - ```json - { - "unique_name": "my_custom_openclaw_ability", - "matching_hotwords": [ - "open my development environment", - "start coding session", - "check system health" - ] - } - ``` - -2. **Customize the command logic** in `main.py`: - ```python - async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - # Add your custom logic here - # Example: Parse specific commands, validate input, add confirmations - - await self.capability_worker.speak(f"Sending Inquiry to OpenClaw") - response = await self.capability_worker.exec_local_command(user_inquiry) - - # Process the response as needed - result = self.capability_worker.text_to_text_response(...) - await self.capability_worker.speak(result) - - self.capability_worker.resume_normal_flow() - ``` - -3. **Add command validation** (optional but recommended): - ```python - # Example: Prevent dangerous commands - dangerous_keywords = ["rm -rf", "format", "delete system"] - if any(keyword in user_inquiry.lower() for keyword in dangerous_keywords): - await self.capability_worker.speak("I can't execute that command for safety.") - return - ``` - -4. **Implement multi-step workflows** (optional): - ```python - # Example: Confirm before executing - await self.capability_worker.speak("This will restart your computer. Confirm?") - confirmation = await self.capability_worker.user_response() - if "yes" in confirmation.lower(): - response = await self.capability_worker.exec_local_command("restart") - ``` - -## How It Works -1. User speaks a computer control command -2. OpenHome captures the voice input as text -3. Ability sends the command to your local OpenClaw client -4. OpenClaw executes the command on your computer -5. OpenClaw returns the result (success/failure/output) -6. AI converts the result into a natural spoken response -7. AI speaks the result (max 15 words, one sentence) - -**Smart Features:** -- **Natural Language Processing**: Send plain English commands -- **Automatic Response Formatting**: Technical output → conversational speech -- **Timeout Protection**: 10-second max wait prevents hanging -- **Error Handling**: Clear feedback when commands fail -- **Cross-Platform**: Works on Windows, macOS, and Linux - -## Template Usage Examples - -These examples show how the **unmodified template** would work. Customize the logic for your specific use case. - -### Basic Template Behavior -> **User:** "open Slack" -> **AI:** "Sending Inquiry to OpenClaw" -> *(OpenClaw executes on local machine)* -> **AI:** "Slack is now open." - -### With System Information -> **User:** "check disk usage" -> **AI:** "Sending Inquiry to OpenClaw" -> *(OpenClaw queries system)* -> **AI:** "Disk usage is at 42 percent." - -### Handling Errors -> **User:** "open NonExistentApp" -> **AI:** "Sending Inquiry to OpenClaw" -> *(OpenClaw fails to find app)* -> **AI:** "I couldn't find NonExistentApp on this machine." - -### Custom Ability Example -After customizing the template with multi-step logic: - -> **User:** "start my morning routine" -> **AI:** "Opening Calendar, Email, and Slack" -> *(Executes 3 commands sequentially)* -> **AI:** "Morning apps are ready." - -## Core Template Function - -The template provides one essential function for sending commands to your local machine: - -### `exec_local_command()` -Sends a command/inquiry to your local OpenClaw client and returns the response. - -**Function Signature:** -```python -async def exec_local_command( - self, - command: str | dict, - target_id: str | None = None, - timeout: float = 10.0 -) -``` - -**Parameters:** -- `command` (str | dict): **Required.** The inquiry message or command for OpenClaw -- `target_id` (str | None): **Optional.** Target device identifier (default: "laptop") -- `timeout` (float): **Optional.** Max seconds to wait for response (default: 10.0) - -**Returns:** -- `str`: Response from OpenClaw execution (success message, error, or command output) - -**Template Usage:** -```python -# Basic usage (as shown in template) -response = await self.capability_worker.exec_local_command(user_inquiry) - -# With custom timeout for long-running commands -response = await self.capability_worker.exec_local_command( - "compile large project", - timeout=30.0 -) - -# With specific target device -response = await self.capability_worker.exec_local_command( - "check battery status", - target_id="laptop" -) -``` - -## How the Template Works - -1. **User speaks a command** → Voice input captured by OpenHome -2. **Template receives transcription** → `wait_for_complete_transcription()` -3. **Command sent to OpenClaw** → `exec_local_command(user_inquiry)` -4. **OpenClaw executes locally** → Runs on your computer with your permissions -5. **Response returned** → Success/failure/output comes back from OpenClaw -6. **AI formats for speech** → Converts technical output to natural language (max 15 words) -7. **AI speaks result** → User hears the outcome - -**Response Formatting Rules (Built into Template):** -The template automatically converts technical output into conversational speech: -- ✅ "Slack is now open." (action confirmed) -- ✅ "Disk usage is at 42 percent." (useful info extracted) -- ✅ "I couldn't find Slack on this machine." (error explained) -- ❌ Avoids: JSON blocks, markdown, code snippets, raw command output -- **Constraint**: Maximum 1 sentence, 15 words or less - -## Example Abilities You Can Build - -### 1. Development Environment Controller -```python -# Trigger: "start coding session" -# Opens IDE, starts local servers, opens documentation -async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - commands = [ - "open Visual Studio Code", - "start local dev server on port 3000", - "open browser to localhost:3000" - ] - - for cmd in commands: - await self.capability_worker.exec_local_command(cmd) - - await self.capability_worker.speak("Development environment is ready.") - self.capability_worker.resume_normal_flow() -``` - -### 2. System Health Monitor -```python -# Trigger: "check system health" -# Reports CPU, memory, disk, and battery status -async def first_function(self): - metrics = [ - ("CPU usage", "get cpu usage"), - ("Memory usage", "get memory usage"), - ("Disk space", "get disk usage"), - ("Battery level", "get battery level") - ] - - report = [] - for name, cmd in metrics: - response = await self.capability_worker.exec_local_command(cmd) - report.append(f"{name}: {response}") - - await self.capability_worker.speak(", ".join(report)) - self.capability_worker.resume_normal_flow() -``` - -### 3. Smart Screenshot Tool -```python -# Trigger: "take screenshot of active window" -# Captures, saves with timestamp, confirms location -async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - # Extract what to capture - if "full screen" in user_inquiry.lower(): - cmd = "screenshot fullscreen save to ~/Desktop" - elif "active window" in user_inquiry.lower(): - cmd = "screenshot active window save to ~/Desktop" - else: - cmd = "screenshot selection save to ~/Desktop" - - response = await self.capability_worker.exec_local_command(cmd, timeout=15.0) - - # Parse filename from response and confirm - await self.capability_worker.speak(f"Screenshot saved: {response}") - self.capability_worker.resume_normal_flow() -``` - -### 4. Application Manager with Confirmation -```python -# Trigger: "close all browsers" -# Lists open browsers, asks confirmation, closes them -async def first_function(self): - # Get list of open browsers - response = await self.capability_worker.exec_local_command("list open browsers") - - if "none" in response.lower(): - await self.capability_worker.speak("No browsers are open.") - self.capability_worker.resume_normal_flow() - return - - # Confirm before closing - await self.capability_worker.speak(f"Found: {response}. Close all?") - confirmation = await self.capability_worker.user_response() - - if "yes" in confirmation.lower(): - await self.capability_worker.exec_local_command("close all browsers") - await self.capability_worker.speak("All browsers closed.") - else: - await self.capability_worker.speak("Cancelled.") - - self.capability_worker.resume_normal_flow() -``` - -## Troubleshooting - -### OpenClaw Client Won't Connect -- Verify API key is correct (copy from Dashboard → Settings → API Keys) -- Check if daemon is running: `openclaw status` -- Restart the OpenClaw client app -- Check logs in the client for error messages - -### Commands Timeout or Fail -- Increase timeout: `exec_local_command(command, timeout=20.0)` -- Check OpenClaw daemon status: `openclaw status` -- Verify the command is valid for your OS -- Check OpenClaw client logs for execution errors - -### Permission Errors (macOS) -- Go to System Settings → Privacy & Security -- Find the blocked app notification -- Click "Open Anyway" -- Grant permissions when prompted (Accessibility, Automation, etc.) - -### Commands Not Executing -- Verify OpenClaw client shows "Connected" status -- Test a simple command like "what time is it" -- Check if the ability is correctly registered in OpenHome -- Review OpenClaw client logs for connection issues - -## Security & Privacy -- OpenClaw runs locally on your machine — no commands are sent to external servers -- API key authenticates OpenHome → OpenClaw connection -- You control what commands the ability can execute -- Review all permissions carefully when installing the client - -## Best Practices for Building with This Template - -### 1. Define Clear Trigger Words -Choose specific, unambiguous trigger phrases in `config.json`: -```json -{ - "matching_hotwords": [ - "start development session", - "open my coding setup", - "launch dev environment" - ] -} -``` - -Avoid overly generic triggers that might conflict with other abilities. - -### 2. Add Command Validation -Protect users from accidentally running dangerous commands: -```python -# Blacklist approach -DANGEROUS_COMMANDS = ["rm -rf", "format", "delete system", "shutdown -h now"] - -if any(danger in user_inquiry.lower() for danger in DANGEROUS_COMMANDS): - await self.capability_worker.speak("I can't execute that for safety reasons.") - return -``` - -### 3. Implement Confirmation for Destructive Actions -```python -if "restart" in user_inquiry.lower() or "shutdown" in user_inquiry.lower(): - await self.capability_worker.speak("This will restart your computer. Are you sure?") - confirm = await self.capability_worker.user_response() - if "yes" not in confirm.lower(): - await self.capability_worker.speak("Cancelled.") - return -``` - -### 4. Handle Timeouts Appropriately -Adjust timeout based on expected command duration: -```python -# Quick commands (default 10s is fine) -response = await self.capability_worker.exec_local_command("open Chrome") - -# Long-running commands (increase timeout) -response = await self.capability_worker.exec_local_command( - "compile entire project", - timeout=60.0 # 1 minute -) -``` - -### 5. Parse and Format Responses -Don't just echo raw OpenClaw output: -```python -response = await self.capability_worker.exec_local_command("get battery level") - -# Bad: "Battery: 73% (charging, 2:15 remaining)" -# Good: Extract just the useful info -battery_level = extract_percentage(response) # Your parsing logic -await self.capability_worker.speak(f"Battery is at {battery_level} percent.") -``` - -### 6. Add Error Handling -```python -try: - response = await self.capability_worker.exec_local_command( - user_inquiry, - timeout=15.0 - ) - - if "error" in response.lower() or "failed" in response.lower(): - await self.capability_worker.speak("That command didn't work. Try something else.") - else: - # Process successful response - ... - -except asyncio.TimeoutError: - await self.capability_worker.speak("That command took too long. It might still be running.") -except Exception as e: - self.worker.editor_logging_handler.error(f"Command failed: {e}") - await self.capability_worker.speak("Something went wrong. Check the logs.") -``` - -### 7. Chain Commands for Complex Workflows -```python -# Example: "prepare for meeting" -workflow = [ - ("Opening calendar", "open Calendar app"), - ("Starting video", "open Zoom"), - ("Opening notes", "open Notes app"), -] - -for description, command in workflow: - await self.capability_worker.speak(description) - await self.capability_worker.exec_local_command(command) - await asyncio.sleep(1) # Brief pause between commands - -await self.capability_worker.speak("Ready for your meeting.") -``` - -## Template Code Walkthrough - -### Key Components - -**1. Wait for User Input:** -```python -user_inquiry = await self.capability_worker.wait_for_complete_transcription() -``` -Gets the full voice command before processing. - -**2. Send to OpenClaw:** -```python -response = await self.capability_worker.exec_local_command(user_inquiry) -``` -Sends command to local machine, returns result. - -**3. Format Response:** -```python -check_response_system_prompt = """You are a voice assistant...""" -result = self.capability_worker.text_to_text_response( - "Original user request: '%s'. Command result: %s" % (user_inquiry, response), - history, - check_response_system_prompt, -) -``` -LLM converts technical output → natural speech (15 words max). - -**4. Speak and Resume:** -```python -await self.capability_worker.speak(result) -self.capability_worker.resume_normal_flow() -``` -Delivers result and returns control to main assistant. - -### Modifying the Template - -**To add pre-processing:** -```python -async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - # ⬇️ ADD YOUR LOGIC HERE - if "screenshot" in user_inquiry.lower(): - user_inquiry = "take screenshot and save to desktop" - # ⬆️ - - response = await self.capability_worker.exec_local_command(user_inquiry) - # ... rest of template -``` - -**To add post-processing:** -```python -async def first_function(self): - # ... template code to get response - - # ⬇️ ADD YOUR LOGIC HERE - if "screenshot saved" in response.lower(): - # Extract filename and offer to open - await self.capability_worker.speak("Screenshot saved. Open it?") - confirm = await self.capability_worker.user_response() - if "yes" in confirm.lower(): - await self.capability_worker.exec_local_command("open last screenshot") - # ⬆️ - - self.capability_worker.resume_normal_flow() -``` - -**To add multi-turn interaction:** -```python -async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - # First command - response1 = await self.capability_worker.exec_local_command(user_inquiry) - await self.capability_worker.speak(response1) - - # Ask for follow-up - await self.capability_worker.speak("What else should I do?") - next_command = await self.capability_worker.user_response() - - # Second command - response2 = await self.capability_worker.exec_local_command(next_command) - await self.capability_worker.speak(response2) - - self.capability_worker.resume_normal_flow() -``` - -## Important Template Notes - -### This is a Starting Point -- **The template is intentionally minimal** — it's designed to be modified -- Don't use it as-is for production — customize it for your use case! -- The real power comes from your specific implementation - -### Security Considerations -- OpenClaw runs with **your user permissions** on local machine -- Commands execute exactly as if you typed them in terminal -- **Always add validation** for any user-provided input -- Use **confirmation prompts** for destructive operations (restart, delete, etc.) -- Review all commands before enabling in production - -### Client Must Stay Running -- OpenClaw client must run in background for ability to work -- If client disconnects, commands will fail -- Monitor client logs for connection issues -- Consider adding retry logic for failed commands - -### Response Formatting -- 15-word limit ensures concise voice responses -- Technical output is automatically cleaned up by LLM -- You can modify the formatting prompt for different styles -- Balance between information density and speakability - -### Testing Strategy -1. Test with simple, safe commands first ("what time is it") -2. Verify timeout handling with long-running commands -3. Test error scenarios (invalid commands, disconnected client) -4. Check response formatting with various output types -5. **Test on target OS** (commands vary by platform: Windows/macOS/Linux) - -## Technical Architecture -``` -Voice Input → OpenHome Ability → exec_local_command() - ↓ - OpenClaw Client - (via WebSocket) - ↓ - OpenClaw Daemon - (with LLM API) - ↓ - Local System Execution - (apps, files, etc.) - ↓ - Response ← AI Formatting ← Template -``` - -## Links & Resources - -**Required Downloads:** -- **[OpenClaw Client](https://drive.google.com/drive/folders/10qK75I-bFB2D98YJ6dH3tQFsvEk44Y7-)** — Download for your OS (required) - -**OpenHome:** -- [Dashboard](https://app.openhome.com/dashboard) -- [API Key Management](https://app.openhome.com/dashboard/settings) — Get your API key here -- [Abilities Library](https://app.openhome.com/dashboard/abilities) - -**OpenClaw:** -- CLI Help: `openclaw --help` -- Check Status: `openclaw status` -- View Logs: Check client app logs tab -- **Required:** Configure with an LLM API key (OpenAI, Anthropic, etc.) during `openclaw onboard` - -## Quick Start Checklist - -### Setup (One-Time) -- [ ] Install OpenClaw: `npm install -g openclaw@latest` -- [ ] Initialize daemon: `openclaw onboard --install-daemon` -- [ ] **Configure with LLM API key** (OpenAI/Anthropic/etc.) -- [ ] Download OpenClaw client from link above -- [ ] Run client and paste OpenHome API key -- [ ] Verify "Connected" status and "welcome" message - -### Template Usage -- [ ] Get template from OpenHome dashboard or GitHub -- [ ] Define your trigger words in `config.json` -- [ ] Customize `first_function()` for your use case -- [ ] Add command validation and safety checks -- [ ] Test with safe commands first -- [ ] Add error handling and timeouts -- [ ] Deploy your custom ability! - -## Support & Contribution - -If you build something cool with this template: -- 🎉 Share it with the OpenHome community -- 💡 Contribute improvements back to the template -- 🤝 Help others troubleshoot in community forums -- 📝 Document your use case for future builders - -## Final Reminder - -⚠️ **This template is a foundation, not a finished product.** - -The power of OpenClaw integration comes from YOUR customization: -- Define specific trigger words -- Implement domain-specific logic -- Add safety validations -- Create multi-step workflows -- Build something unique! - -Don't just deploy the template as-is — make it yours! 🚀 diff --git a/templates/OpenClaw/__init__.py b/templates/OpenClaw/__init__.py deleted file mode 100644 index 8b137891..00000000 --- a/templates/OpenClaw/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/templates/OpenClaw/main.py b/templates/OpenClaw/main.py deleted file mode 100644 index 907afc11..00000000 --- a/templates/OpenClaw/main.py +++ /dev/null @@ -1,46 +0,0 @@ -from src.agent.capability import MatchingCapability -from src.main import AgentWorker -from src.agent.capability_worker import CapabilityWorker - - -class OpentestCapability(MatchingCapability): - worker: AgentWorker = None - capability_worker: CapabilityWorker = None - - # Do not change following tag of register capability - # {{register capability}} - - async def first_function(self): - user_inquiry = await self.capability_worker.wait_for_complete_transcription() - - history = [] - - history.append( - { - "role": "user", - "content": user_inquiry, - }, - ) - # history.append( - # { - # "role": "assistant", - # "content": terminal_command, - # }, - # ) - # Execute the generated command - await self.capability_worker.speak(f"Sending Inquiry to OpenClaw") - response = await self.capability_worker.exec_local_command(user_inquiry) - - self.worker.editor_logging_handler.info(response) - # Speak the response - - await self.capability_worker.speak(response["data"]) - # Resume the normal workflow - self.capability_worker.resume_normal_flow() - - def call(self, worker: AgentWorker): - # Initialize the worker and capability worker - self.worker = worker - self.capability_worker = CapabilityWorker(self) - - self.worker.session_tasks.create(self.first_function()) From 6d77de8400c538d340a9a2ec41ee989936fd2446 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 15 Mar 2026 22:42:37 +0500 Subject: [PATCH 07/10] Add Enphase Solar Monitor V2 - historical data, comparisons, lifetime stats, panel health --- community/enphase-solar-monitor/README.md | 22 +- community/enphase-solar-monitor/main.py | 677 ++++++++++++++++------ 2 files changed, 516 insertions(+), 183 deletions(-) diff --git a/community/enphase-solar-monitor/README.md b/community/enphase-solar-monitor/README.md index f7e70b84..3e7d3581 100644 --- a/community/enphase-solar-monitor/README.md +++ b/community/enphase-solar-monitor/README.md @@ -1,6 +1,13 @@ -# Enphase Solar Monitor +# Enphase Solar Monitor (V2) -Voice-activated solar dashboard for Enphase systems (IQ Gateway with microinverters). +Voice-activated solar dashboard for Enphase systems (IQ Gateway with microinverters). Fetches production, consumption, battery, and historical data from Enphase Cloud API v4. + +## V2 Features + +- **Historical data:** Yesterday, this week, this month +- **Comparisons:** Today vs yesterday +- **Lifetime stats:** Total production since installation +- **Panel health:** Microinverter status ## Demo Mode @@ -14,7 +21,7 @@ Voice-activated solar dashboard for Enphase systems (IQ Gateway with microinvert ## What It Does -Ask "how's my solar?" to get real-time production, consumption, and battery status. Data is delivered as natural spoken responses. +Ask "how's my solar?" to get real-time production, consumption, and battery status. Data is delivered as natural spoken responses. V2 adds historical summaries, today-vs-yesterday comparison, lifetime totals, and panel health. ## Trigger Words @@ -175,9 +182,18 @@ This ability is built for the OpenHome sandbox: ## Supported Queries +**V1 (Real-time):** - **Solar snapshot:** "How's my solar?", "Solar status" - **Battery:** "Battery level", "Battery status" - **Consumption:** "How much am I using?" - **Grid:** "Am I exporting?", "Grid status" - **Today:** "Solar today", "Today's production" - **Health:** "System health", "Panel status" + +**V2 (Historical):** +- **Yesterday:** "How much yesterday?", "Yesterday's production" +- **This week:** "This week", "Weekly total", "How much this week" +- **This month:** "This month", "Monthly total" +- **Compare:** "Better than yesterday?", "Compared to yesterday" +- **Lifetime:** "Total production ever", "Lifetime", "All time" +- **Panel health:** "Are all panels working?", "Microinverter status" diff --git a/community/enphase-solar-monitor/main.py b/community/enphase-solar-monitor/main.py index 9ddf83a5..9d18da85 100644 --- a/community/enphase-solar-monitor/main.py +++ b/community/enphase-solar-monitor/main.py @@ -1,12 +1,14 @@ """ -Enphase Solar Monitor - OpenHome Ability -Voice-activated solar dashboard for Enphase systems (IQ Gateway with microinverters). +Enphase Solar Monitor - OpenHome Ability V2 +Voice-activated solar dashboard for Enphase systems. Fetches production, consumption, and battery data from Enphase Cloud API v4. + +V2 Features: Historical data, comparisons, lifetime stats, panel health """ import json import time -from datetime import datetime, timezone +from datetime import datetime, timezone, timedelta from typing import Callable, Optional import requests @@ -23,13 +25,26 @@ EXIT_WORDS = ["stop", "quit", "exit", "done", "cancel"] PREFS_FILE = "enphase_solar_prefs.json" -# Hardcoded from config.json - file access forbidden at registration time +# Hardcoded configuration - OpenHome blocks file access at registration time UNIQUE_NAME = "enphase_solar_monitor" MATCHING_HOTWORDS = [ - "solar", "solar status", "solar production", "how's my solar", - "hows my solar", "how is my solar", "enphase", "solar panels", - "battery level", "battery status", "my battery status", "battery", - "am I exporting", "grid status", "solar today", "check my solar", "solar power", + "solar", + "solar status", + "solar production", + "how's my solar", + "hows my solar", + "how is my solar", + "enphase", + "solar panels", + "battery level", + "battery status", + "my battery status", + "battery", + "am I exporting", + "grid status", + "solar today", + "check my solar", + "solar power", ] ERROR_RESPONSES = { @@ -44,7 +59,6 @@ class EnphaseSolarMonitorCapability(MatchingCapability): """Voice-activated Enphase solar monitoring capability.""" - # {{register_capability}} worker: AgentWorker = None capability_worker: CapabilityWorker = None @@ -60,27 +74,30 @@ def call(self, worker: AgentWorker): self.capability_worker = CapabilityWorker(self.worker) self.worker.session_tasks.create(self.run_solar_monitor()) - async def _load_prefs(self) -> dict: + async def _load_prefs(self): """Load preferences using OpenHome File Storage API.""" try: if await self.capability_worker.check_if_file_exists(PREFS_FILE, False): - raw = await self.capability_worker.read_file(PREFS_FILE, False) - prefs = json.loads(raw) + content = await self.capability_worker.read_file(PREFS_FILE, False) + prefs = json.loads(content) if DEMO_MODE and not prefs.get("system_id"): prefs.setdefault("has_battery", True) prefs.setdefault("has_consumption", True) return prefs except Exception as e: self.worker.editor_logging_handler.error(f"Failed to load prefs: {e}") + if DEMO_MODE: return {"has_battery": True, "has_consumption": True} return {} - async def _save_prefs(self, prefs: dict) -> None: + async def _save_prefs(self, prefs): """Save preferences using OpenHome File Storage API.""" try: await self.capability_worker.write_file( - PREFS_FILE, json.dumps(prefs, indent=2), False, mode="w" + PREFS_FILE, + json.dumps(prefs, indent=2), + False, ) except Exception as e: self.worker.editor_logging_handler.error(f"Failed to save prefs: {e}") @@ -112,35 +129,77 @@ async def _refresh_access_token(self) -> bool: self.worker.editor_logging_handler.error(f"Token refresh failed: {e}") return False - async def _api_call( - self, endpoint: str, extra_params: Optional[dict] = None - ) -> dict: - """Make an Enphase API call. Returns dict with data or {"error": "error_type"}.""" + async def _api_call(self, endpoint: str, extra_params: Optional[dict] = None): + """Make an authenticated Enphase API call with auto-retry on 401.""" if DEMO_MODE: - return self._demo_response(endpoint) + now = datetime.now(timezone.utc) + + if endpoint == "summary": + return { + "current_power": 4200, + "energy_today": 28000, + "energy_lifetime": 15000000, + "status": "normal", + "last_report_at": now.isoformat(), + } + if endpoint == "encharge": + return { + "state_of_charge": 0.73, + "status": "charging", + "available_energy": 8500, + } + if endpoint == "consumption_stats": + return { + "consumption": 3100, + "energy_today": 22000, + } + if "energy_lifetime" in endpoint: + days = [] + for i in range(7, 0, -1): + date = (now - timedelta(days=i)).strftime("%Y-%m-%d") + energy = 25000 + (i * 1500) + days.append({"date": date, "wh": energy}) + return {"intervals": days} + if endpoint == "inventory" or endpoint == "devices": + devices = [] + for i in range(24): + devices.append({ + "serial_num": f"12345{i:02d}", + "device_status": ["normal", "normal", "normal", "power"][i % 4], + "last_report_date": now.isoformat(), + }) + return {"envoys": [{"devices": devices}]} + + return {"error": "unknown_endpoint"} + try: prefs = await self._load_prefs() system_id = prefs.get("system_id") if not system_id: return {"error": "no_system_id"} - access_token = prefs.get("access_token") - if not access_token: - return {"error": "auth_failed"} + url = f"{ENPHASE_BASE_URL}/systems/{system_id}/{endpoint}" - params = {"key": prefs.get("api_key", ""), "access_token": access_token} + params = {"key": prefs.get("api_key")} if extra_params: params.update(extra_params) - response = requests.get(url, params=params, timeout=15) + + headers = {"Authorization": f"Bearer {prefs.get('access_token')}"} + response = requests.get(url, headers=headers, params=params, timeout=15) + + if response.status_code == 401: + if await self._refresh_access_token(): + prefs = await self._load_prefs() + headers = {"Authorization": f"Bearer {prefs.get('access_token')}"} + response = requests.get(url, headers=headers, params=params, timeout=15) + else: + return {"error": "auth_failed"} + if response.status_code == 200: return response.json() - elif response.status_code == 401: - if await self._refresh_access_token(): - return await self._api_call(endpoint, extra_params) - return {"error": "auth_failed"} - elif response.status_code == 404: - return {"error": "system_not_found"} elif response.status_code == 429: return {"error": "rate_limited"} + elif response.status_code == 404: + return {"error": "system_not_found"} else: self.worker.editor_logging_handler.error( f"Enphase API {endpoint}: {response.status_code}" @@ -152,71 +211,28 @@ async def _api_call( self.worker.editor_logging_handler.error(f"API call error: {e}") return {"error": str(e)} - def _demo_response(self, endpoint: str) -> dict: - """Return realistic fake data for demo mode.""" - now = datetime.now(timezone.utc) - ts = now.strftime("%Y-%m-%dT%H:%M:%S+00:00") - if "stats" in endpoint or "summary" in endpoint: - return { - "intervals": [ - { - "end_at": ts, - "powr": 4200, - "enwh": 28000, - } - ], - "meta": {"status": "normal"}, - } - if "battery" in endpoint or "storage" in endpoint: - return { - "intervals": [ - { - "end_at": ts, - "powr": -1500, - "percent_full": 73, - } - ], - } - if "consumption" in endpoint: - return { - "intervals": [ - { - "end_at": ts, - "enwh": 3100, - "powr": 3100, - } - ], - } - if "grid" in endpoint or "net" in endpoint: - return { - "intervals": [ - { - "end_at": ts, - "powr": -1500, - } - ], - } - return {"intervals": [], "meta": {"status": "normal"}} - - async def _get_cached_or_fetch( - self, cache_key: str, fetch_function: Callable - ) -> dict: - """Check cache first, fetch if expired. Cache TTL: 15 minutes.""" + async def _get_cached_or_fetch(self, cache_key: str, fetch_function: Callable): + """Check cache first, fetch if expired or missing. Cache TTL: 15 minutes.""" try: prefs = await self._load_prefs() cache = prefs.get("cache", {}) + if cache_key in cache: cached_data = cache[cache_key] timestamp = cached_data.get("timestamp", 0) - if time.time() - timestamp < CACHE_TTL: + age = time.time() - timestamp + if age < CACHE_TTL: self.worker.editor_logging_handler.info(f"Cache hit: {cache_key}") return cached_data.get("data", {}) + self.worker.editor_logging_handler.info(f"Cache miss: {cache_key}") data = await fetch_function() + if not isinstance(data, dict) or "error" not in data: cache[cache_key] = {"timestamp": time.time(), "data": data} prefs["cache"] = cache await self._save_prefs(prefs) + return data except Exception as e: self.worker.editor_logging_handler.error(f"Cache error: {e}") @@ -236,10 +252,44 @@ def _format_energy(self, watt_hours: Optional[float]) -> str: kwh = watt_hours / 1000.0 return f"{round(kwh, 1)} kilowatt hours" - def _format_battery(self, percentage: Optional[float]) -> str: - if percentage is None: + def _format_megawatt_hours(self, watt_hours: Optional[float]) -> str: + if watt_hours is None: return "unknown" - return f"{round(percentage)} percent" + mwh = watt_hours / 1000000.0 + if mwh < 1: + return self._format_energy(watt_hours) + return f"{round(mwh, 1)} megawatt hours" + + def _format_battery(self, soc_decimal: Optional[float]) -> str: + if soc_decimal is None: + return "unknown" + percentage = round(soc_decimal * 100) + return f"{percentage} percent" + + def _format_timestamp_age(self, timestamp_str: Optional[str]) -> str: + if not timestamp_str: + return "from the latest reading" + try: + dt = datetime.fromisoformat(timestamp_str.replace("Z", "+00:00")) + age_seconds = (datetime.now(timezone.utc) - dt).total_seconds() + age_minutes = age_seconds / 60 + if age_minutes < 20: + return "as of about 15 minutes ago" + elif age_minutes < 60: + return f"as of about {round(age_minutes)} minutes ago" + else: + return f"as of about {round(age_minutes / 60, 1)} hours ago" + except Exception: + return "from the latest reading" + + def _calculate_percentage_change(self, old_value: float, new_value: float) -> str: + if old_value == 0: + return "significantly higher" + change = ((new_value - old_value) / old_value) * 100 + if abs(change) < 1: + return "about the same" + direction = "up" if change > 0 else "down" + return f"{direction} {abs(round(change))} percent" def _is_exit_word(self, text: Optional[str]) -> bool: if not text: @@ -248,15 +298,27 @@ def _is_exit_word(self, text: Optional[str]) -> bool: def _classify_intent(self, user_input: str) -> str: system_prompt = """Classify the user's solar system query into ONE of these intents: -- solar_snapshot: General status, "how's my solar", overall view -- battery_status: Battery level, charging status -- consumption: How much am I using, consumption -- grid_status: Am I exporting, grid status -- today_summary: Today's totals -- system_health: System health, panel status + +V1 Intents: +- solar_snapshot: "how's my solar", "solar status", "check my solar", "give me a summary" +- battery_status: "battery level", "battery percentage", "what's my battery" +- consumption: "how much am I using", "consumption", "usage", "power usage" +- grid_status: "grid status", "am I exporting", "grid import", "grid export" +- today_summary: "today's total", "how much today", "today so far", "production today" +- system_health: "system health", "is my system ok", "system status" + +V2 Historical Intents: +- yesterday_summary: "how much yesterday", "yesterday's production", "yesterday" +- this_week: "this week", "weekly total", "week's production", "how much this week" +- this_month: "this month", "monthly total", "how much this month", "month's production" +- compare_yesterday: "better than yesterday", "compared to yesterday", "am I doing better" +- lifetime_stats: "total production ever", "lifetime", "all time", "total ever" +- panel_health: "are all panels working", "panel status", "microinverters", "panel health" + - unknown: Anything else Respond with ONLY the intent name, nothing else.""" + intent = self.capability_worker.text_to_text_response( prompt_text=f"User query: {user_input}", system_prompt=system_prompt, @@ -269,15 +331,27 @@ def _speak_error(self, error_key: str) -> str: async def run_solar_monitor(self) -> None: try: - await self.capability_worker.speak("Sure! Let me check your solar system.") + if not DEMO_MODE: + prefs = await self._load_prefs() + if not prefs.get("system_id") or not prefs.get("api_key"): + await self.capability_worker.speak( + "You haven't set up your Enphase system yet. " + "Add your system ID and API credentials in the preferences file." + ) + return + await self._handle_solar_snapshot() + while True: await self.capability_worker.speak("Anything else about your solar?") response = await self.capability_worker.user_response() + if not response or self._is_exit_word(response): await self.capability_worker.speak("Okay, talk to you later!") break + intent = self._classify_intent(response) + if intent == "solar_snapshot": await self._handle_solar_snapshot() elif intent == "battery_status": @@ -290,164 +364,407 @@ async def run_solar_monitor(self) -> None: await self._handle_today_summary() elif intent == "system_health": await self._handle_system_health() + elif intent == "yesterday_summary": + await self._handle_yesterday_summary() + elif intent == "this_week": + await self._handle_this_week() + elif intent == "this_month": + await self._handle_this_month() + elif intent == "compare_yesterday": + await self._handle_compare_yesterday() + elif intent == "lifetime_stats": + await self._handle_lifetime_stats() + elif intent == "panel_health": + await self._handle_panel_health() else: await self.capability_worker.speak( "I didn't catch that. You can ask about production, " - "battery, consumption, or grid status." + "consumption, battery, grid status, or historical data." ) except Exception as e: self.worker.editor_logging_handler.error(f"Solar monitor error: {e}") - await self.capability_worker.speak( - "Something went wrong. Try again later." - ) + await self.capability_worker.speak("Something went wrong. Try again later.") finally: self.capability_worker.resume_normal_flow() async def _handle_solar_snapshot(self) -> None: async def fetch(): - return await self._api_call("stats?granularity=day&start_at=2020-01-01") + return await self._api_call("summary") - stats = await self._get_cached_or_fetch("stats", fetch) - if isinstance(stats, dict) and "error" in stats: - await self.capability_worker.speak( - self._speak_error(stats["error"]) - ) + data = await self._get_cached_or_fetch("summary", fetch) + + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) return - intervals = stats.get("intervals", []) - power = 0 - energy_today = 0 - if intervals: - last = intervals[-1] - power = last.get("powr", 0) - energy_today = last.get("enwh", 0) + + power = data.get("current_power") + energy_today = data.get("energy_today") + last_report = data.get("last_report_at") + + staleness = self._format_timestamp_age(last_report) power_str = self._format_power(power) energy_str = self._format_energy(energy_today) + await self.capability_worker.speak( - f"You're producing {power_str} right now, as of about 15 minutes ago." + f"You're producing {power_str} right now, {staleness}." ) await self.capability_worker.speak( f"Today you've generated {energy_str}." ) + prefs = await self._load_prefs() + if prefs.get("has_battery"): await self._handle_battery_status() + if prefs.get("has_consumption"): - await self._handle_consumption() - await self._handle_grid_status() + async def fetch_consumption(): + return await self._api_call("consumption_stats") + + consumption_data = await self._get_cached_or_fetch("consumption_stats", fetch_consumption) + if not (isinstance(consumption_data, dict) and "error" in consumption_data): + if isinstance(consumption_data, list) and len(consumption_data) > 0: + consumption_data = consumption_data[-1] + consumption = consumption_data.get("consumption") + consumption_str = self._format_power(consumption) + await self.capability_worker.speak(f"You're using {consumption_str} right now.") + + try: + yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") + async def fetch_yesterday(): + return await self._api_call( + f"energy_lifetime?start_date={yesterday}&end_date={yesterday}" + ) + yesterday_data = await self._get_cached_or_fetch(f"energy_{yesterday}", fetch_yesterday) + + if not (isinstance(yesterday_data, dict) and "error" in yesterday_data): + intervals = yesterday_data.get("intervals", []) + if intervals: + yesterday_energy = intervals[0].get("wh", 0) + if yesterday_energy > 0: + change = self._calculate_percentage_change(yesterday_energy, energy_today) + await self.capability_worker.speak( + f"You're {change} compared to yesterday." + ) + except Exception as e: + self.worker.editor_logging_handler.info(f"Yesterday comparison skipped: {e}") async def _handle_battery_status(self) -> None: prefs = await self._load_prefs() if not prefs.get("has_battery"): - await self.capability_worker.speak( - "Your system doesn't have a battery configured." - ) + await self.capability_worker.speak("Your system doesn't have battery storage.") return async def fetch(): - return await self._api_call("stats?granularity=day&start_at=2020-01-01") + return await self._api_call("encharge") - battery = await self._get_cached_or_fetch("battery", fetch) - if isinstance(battery, dict) and "error" in battery: - await self.capability_worker.speak( - self._speak_error(battery["error"]) - ) - return - intervals = battery.get("intervals", []) - if not intervals: - await self.capability_worker.speak("No battery data available.") + data = await self._get_cached_or_fetch("encharge", fetch) + + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) return - last = intervals[-1] - soc = last.get("percent_full", 0) - power = last.get("powr", 0) + + if isinstance(data, list) and len(data) > 0: + data = data[0] + + soc = data.get("state_of_charge") + status = data.get("status", "idle") soc_str = self._format_battery(soc) - if power < -50: - status = "and charging." - elif power > 50: - status = "and discharging." - else: - status = "and idle." - await self.capability_worker.speak( - f"Your battery is at {soc_str} {status}" - ) + + status_map = { + "charging": "and charging.", + "discharging": "and discharging.", + "idle": "and idle.", + } + status_phrase = status_map.get((status or "").lower(), "and idle.") + + await self.capability_worker.speak(f"Your battery is at {soc_str} {status_phrase}") async def _handle_consumption(self) -> None: prefs = await self._load_prefs() if not prefs.get("has_consumption"): - await self.capability_worker.speak( - "Your system doesn't have consumption monitoring." - ) + await self.capability_worker.speak("Your system doesn't have consumption monitoring.") return async def fetch(): - return await self._api_call("stats?granularity=day&start_at=2020-01-01") + return await self._api_call("consumption_stats") - consumption = await self._get_cached_or_fetch("consumption", fetch) - if isinstance(consumption, dict) and "error" in consumption: - await self.capability_worker.speak( - self._speak_error(consumption["error"]) - ) + data = await self._get_cached_or_fetch("consumption_stats", fetch) + + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) return - intervals = consumption.get("intervals", []) - power = intervals[-1].get("powr", 0) if intervals else 0 - power_str = self._format_power(power) - await self.capability_worker.speak( - f"You're using {power_str} right now." - ) + + if isinstance(data, list) and len(data) > 0: + data = data[-1] + + consumption = data.get("consumption") + energy_today = data.get("energy_today") + consumption_str = self._format_power(consumption) + energy_str = self._format_energy(energy_today) + + await self.capability_worker.speak(f"You're using {consumption_str} right now.") + await self.capability_worker.speak(f"Today you've used {energy_str}.") async def _handle_grid_status(self) -> None: prefs = await self._load_prefs() if not prefs.get("has_consumption"): + await self.capability_worker.speak( + "Your system doesn't have consumption monitoring, " + "so I can't tell grid import or export." + ) return - async def fetch(): - return await self._api_call("stats?granularity=day&start_at=2020-01-01") + async def fetch_summary(): + return await self._api_call("summary") + + async def fetch_consumption(): + return await self._api_call("consumption_stats") + + summary = await self._get_cached_or_fetch("summary", fetch_summary) + consumption_data = await self._get_cached_or_fetch("consumption_stats", fetch_consumption) - grid = await self._get_cached_or_fetch("grid", fetch) - if isinstance(grid, dict) and "error" in grid: + if isinstance(summary, dict) and "error" in summary: + await self.capability_worker.speak(self._speak_error(summary["error"])) return - intervals = grid.get("intervals", []) - power = intervals[-1].get("powr", 0) if intervals else 0 - power_str = self._format_power(abs(power)) - if power < -100: + if isinstance(consumption_data, dict) and "error" in consumption_data: + await self.capability_worker.speak(self._speak_error(consumption_data["error"])) + return + + if isinstance(consumption_data, list) and len(consumption_data) > 0: + consumption_data = consumption_data[-1] + + production = summary.get("current_power") or 0 + consumption = consumption_data.get("consumption") or 0 + net = production - consumption + last_report = summary.get("last_report_at") + staleness = self._format_timestamp_age(last_report) + + if net > 0: await self.capability_worker.speak( - f"You're sending {power_str} to the grid." + f"You're sending {self._format_power(net)} to the grid, {staleness}." ) - elif power > 100: + elif net < 0: await self.capability_worker.speak( - f"You're drawing {power_str} from the grid." + f"You're pulling {self._format_power(abs(net))} from the grid, {staleness}." ) else: - await self.capability_worker.speak("You're roughly net zero with the grid.") + await self.capability_worker.speak( + f"You're balanced with the grid right now, {staleness}." + ) async def _handle_today_summary(self) -> None: async def fetch(): - return await self._api_call("stats?granularity=day&start_at=2020-01-01") + return await self._api_call("summary") + + data = await self._get_cached_or_fetch("summary", fetch) + + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) + return + + energy_today = data.get("energy_today") + energy_str = self._format_energy(energy_today) + + await self.capability_worker.speak(f"Today so far you've generated {energy_str}.") + + async def _handle_system_health(self) -> None: + async def fetch(): + return await self._api_call("summary") + + data = await self._get_cached_or_fetch("summary", fetch) - stats = await self._get_cached_or_fetch("stats", fetch) - if isinstance(stats, dict) and "error" in stats: + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) + return + + status = data.get("status", "unknown") + + if status == "normal": + await self.capability_worker.speak("Your system is healthy and reporting normally.") + else: await self.capability_worker.speak( - self._speak_error(stats["error"]) + "Your system is reporting an issue. Check the Enphase app for details." ) + + async def _handle_yesterday_summary(self) -> None: + yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") + + async def fetch(): + return await self._api_call( + f"energy_lifetime?start_date={yesterday}&end_date={yesterday}" + ) + + data = await self._get_cached_or_fetch(f"energy_{yesterday}", fetch) + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) return - intervals = stats.get("intervals", []) - energy_today = intervals[-1].get("enwh", 0) if intervals else 0 - energy_str = self._format_energy(energy_today) + + intervals = data.get("intervals", []) + if not intervals: + await self.capability_worker.speak("I don't have data for yesterday yet.") + return + + yesterday_energy = intervals[0].get("wh", 0) + energy_str = self._format_energy(yesterday_energy) + + await self.capability_worker.speak(f"Yesterday you generated {energy_str}.") + + async def _handle_this_week(self) -> None: + today = datetime.now() + week_start = (today - timedelta(days=today.weekday())).strftime("%Y-%m-%d") + today_str = today.strftime("%Y-%m-%d") + + async def fetch(): + return await self._api_call( + f"energy_lifetime?start_date={week_start}&end_date={today_str}" + ) + + data = await self._get_cached_or_fetch(f"energy_week_{week_start}", fetch) + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) + return + + intervals = data.get("intervals", []) + if not intervals: + await self.capability_worker.speak("I don't have weekly data yet.") + return + + total_wh = sum(day.get("wh", 0) for day in intervals) + avg_wh = total_wh / len(intervals) if intervals else 0 + best_day = max(intervals, key=lambda d: d.get("wh", 0)) + best_day_wh = best_day.get("wh", 0) + best_day_date = best_day.get("date", "") + + try: + day_name = datetime.strptime(best_day_date, "%Y-%m-%d").strftime("%A") + except Exception: + day_name = "one day" + + total_str = self._format_energy(total_wh) + avg_str = self._format_energy(avg_wh) + best_str = self._format_energy(best_day_wh) + await self.capability_worker.speak( - f"Today so far you've generated {energy_str}." + f"This week you've generated {total_str} total. " + f"That's an average of {avg_str} per day." ) + await self.capability_worker.speak(f"Your best day was {day_name} with {best_str}.") + + async def _handle_this_month(self) -> None: + today = datetime.now() + month_start = today.replace(day=1).strftime("%Y-%m-%d") + today_str = today.strftime("%Y-%m-%d") - async def _handle_system_health(self) -> None: async def fetch(): - return await self._api_call("stats?granularity=day&start_at=2020-01-01") + return await self._api_call( + f"energy_lifetime?start_date={month_start}&end_date={today_str}" + ) - stats = await self._get_cached_or_fetch("stats", fetch) - if isinstance(stats, dict) and "error" in stats: - await self.capability_worker.speak( - self._speak_error(stats["error"]) + data = await self._get_cached_or_fetch(f"energy_month_{month_start}", fetch) + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) + return + + intervals = data.get("intervals", []) + if not intervals: + await self.capability_worker.speak("I don't have monthly data yet.") + return + + total_wh = sum(day.get("wh", 0) for day in intervals) + avg_wh = total_wh / len(intervals) if intervals else 0 + + total_str = self._format_energy(total_wh) + avg_str = self._format_energy(avg_wh) + + await self.capability_worker.speak( + f"This month you've generated {total_str} total. " + f"That's an average of {avg_str} per day." + ) + + async def _handle_compare_yesterday(self) -> None: + async def fetch_today(): + return await self._api_call("summary") + + today_data = await self._get_cached_or_fetch("summary", fetch_today) + if isinstance(today_data, dict) and "error" in today_data: + await self.capability_worker.speak(self._speak_error(today_data["error"])) + return + + yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") + + async def fetch_yesterday(): + return await self._api_call( + f"energy_lifetime?start_date={yesterday}&end_date={yesterday}" ) + + yesterday_data = await self._get_cached_or_fetch(f"energy_{yesterday}", fetch_yesterday) + if isinstance(yesterday_data, dict) and "error" in yesterday_data: + await self.capability_worker.speak("I don't have yesterday's data to compare.") return - meta = stats.get("meta", {}) - status = meta.get("status", "normal") + + today_energy = today_data.get("energy_today", 0) + intervals = yesterday_data.get("intervals", []) + yesterday_energy = intervals[0].get("wh", 0) if intervals else 0 + + if yesterday_energy == 0: + await self.capability_worker.speak("I don't have enough data to compare yet.") + return + + change = self._calculate_percentage_change(yesterday_energy, today_energy) + today_str = self._format_energy(today_energy) + yesterday_str = self._format_energy(yesterday_energy) + await self.capability_worker.speak( - f"Your system health is {status}." + f"You're {change} compared to yesterday. " + f"Yesterday you made {yesterday_str}, today you're at {today_str}." ) + + async def _handle_lifetime_stats(self) -> None: + async def fetch(): + return await self._api_call("summary") + + data = await self._get_cached_or_fetch("summary", fetch) + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) + return + + lifetime_wh = data.get("energy_lifetime", 0) + lifetime_str = self._format_megawatt_hours(lifetime_wh) + kwh = lifetime_wh / 1000 + + await self.capability_worker.speak( + f"Since installation, you've generated {lifetime_str} total. " + f"That's {round(kwh)} kilowatt hours." + ) + + async def _handle_panel_health(self) -> None: + async def fetch(): + return await self._api_call("inventory") + + data = await self._get_cached_or_fetch("inventory", fetch) + if isinstance(data, dict) and "error" in data: + await self.capability_worker.speak(self._speak_error(data["error"])) + return + + envoys = data.get("envoys", []) + if not envoys: + await self.capability_worker.speak("I can't get panel data right now.") + return + + devices = envoys[0].get("devices", []) + total_devices = len(devices) + + offline = [d for d in devices if d.get("device_status") != "normal"] + offline_count = len(offline) + + if offline_count == 0: + await self.capability_worker.speak( + f"All {total_devices} microinverters are reporting normally. Your system is healthy." + ) + else: + await self.capability_worker.speak( + f"You have {offline_count} microinverter{'s' if offline_count > 1 else ''} " + f"not reporting normally out of {total_devices} total. " + "Check the Enphase app for details." + ) From a4b5da7cf62879c22f5662e3580e40a61b6407f6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Mar 2026 17:44:09 +0000 Subject: [PATCH 08/10] style: auto-format Python files with autoflake + autopep8 --- community/enphase-solar-monitor/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/community/enphase-solar-monitor/main.py b/community/enphase-solar-monitor/main.py index 9d18da85..beb4a69f 100644 --- a/community/enphase-solar-monitor/main.py +++ b/community/enphase-solar-monitor/main.py @@ -431,6 +431,7 @@ async def fetch_consumption(): try: yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") + async def fetch_yesterday(): return await self._api_call( f"energy_lifetime?start_date={yesterday}&end_date={yesterday}" From 4ccc9d4d13c7e71ffcf65366c48b2dcdee2f72e0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Mar 2026 20:52:29 +0500 Subject: [PATCH 09/10] Fix SDK compliance: add delete-then-write pattern for _save_prefs --- community/enphase-solar-monitor/main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/community/enphase-solar-monitor/main.py b/community/enphase-solar-monitor/main.py index beb4a69f..84d98756 100644 --- a/community/enphase-solar-monitor/main.py +++ b/community/enphase-solar-monitor/main.py @@ -92,8 +92,12 @@ async def _load_prefs(self): return {} async def _save_prefs(self, prefs): - """Save preferences using OpenHome File Storage API.""" + """Save preferences using OpenHome File Storage API with delete-then-write pattern.""" try: + # SDK requirement: delete file before writing + if await self.capability_worker.check_if_file_exists(PREFS_FILE, False): + await self.capability_worker.delete_file(PREFS_FILE, False) + await self.capability_worker.write_file( PREFS_FILE, json.dumps(prefs, indent=2), @@ -431,7 +435,6 @@ async def fetch_consumption(): try: yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") - async def fetch_yesterday(): return await self._api_call( f"energy_lifetime?start_date={yesterday}&end_date={yesterday}" From dd6838233689eaf39adc312fd4d87bc7d19acbc3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 18 Mar 2026 15:54:04 +0000 Subject: [PATCH 10/10] style: auto-format Python files with autoflake + autopep8 --- community/enphase-solar-monitor/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/community/enphase-solar-monitor/main.py b/community/enphase-solar-monitor/main.py index 84d98756..a24b63e4 100644 --- a/community/enphase-solar-monitor/main.py +++ b/community/enphase-solar-monitor/main.py @@ -435,6 +435,7 @@ async def fetch_consumption(): try: yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") + async def fetch_yesterday(): return await self._api_call( f"energy_lifetime?start_date={yesterday}&end_date={yesterday}"