""" Custom Pulse & Brain configuration. Define your own pulse checks (zero cost) and brain tasks (uses tokens). """ import subprocess from typing import Any, Dict, List import requests from pulse_brain import BrainTask, CheckType, PulseCheck # === PULSE CHECKS (Pure Python, Zero Cost) === def check_server_uptime() -> Dict[str, Any]: """Check if server is responsive (pure Python, no agent).""" try: response = requests.get( "http://localhost:8000/health", timeout=5 ) status = "ok" if response.status_code == 200 else "error" return { "status": status, "message": f"Server responded: {response.status_code}", } except Exception as e: return { "status": "error", "message": f"Server unreachable: {e}", } def check_docker_containers() -> Dict[str, Any]: """Check Docker container status (pure Python).""" try: result = subprocess.run( ["docker", "ps", "--format", "{{.Status}}"], capture_output=True, text=True, timeout=5, ) if result.returncode != 0: return { "status": "error", "message": "Docker check failed", } unhealthy = sum( 1 for line in result.stdout.split("\n") if "unhealthy" in line.lower() ) if unhealthy > 0: message = f"{unhealthy} unhealthy container(s)" else: message = "All containers healthy" return { "status": "error" if unhealthy > 0 else "ok", "unhealthy_count": unhealthy, "message": message, } except Exception as e: return {"status": "error", "message": str(e)} def check_plex_server() -> Dict[str, Any]: """Check if Plex is running (pure Python).""" try: response = requests.get( "http://localhost:32400/identity", timeout=5 ) is_ok = response.status_code == 200 return { "status": "ok" if is_ok else "warn", "message": ( "Plex server is running" if is_ok else "Plex unreachable" ), } except Exception as e: return { "status": "warn", "message": f"Plex check failed: {e}", } def check_unifi_controller() -> Dict[str, Any]: """Check UniFi controller (pure Python).""" try: requests.get( "https://localhost:8443", verify=False, timeout=5 ) return { "status": "ok", "message": "UniFi controller responding", } except Exception as e: return { "status": "error", "message": f"UniFi unreachable: {e}", } def check_gpu_temperature() -> Dict[str, Any]: """Check GPU temperature (pure Python, requires nvidia-smi).""" try: result = subprocess.run( [ "nvidia-smi", "--query-gpu=temperature.gpu", "--format=csv,noheader", ], capture_output=True, text=True, timeout=5, ) if result.returncode != 0: return {"status": "ok", "message": "GPU check skipped"} temp = int(result.stdout.strip()) if temp > 85: status = "error" elif temp > 75: status = "warn" else: status = "ok" return { "status": status, "temperature": temp, "message": f"GPU temperature: {temp}C", } except Exception: return {"status": "ok", "message": "GPU check skipped"} def check_star_citizen_patch() -> Dict[str, Any]: """Check for Star Citizen patches (pure Python, placeholder).""" return { "status": "ok", "new_patch": False, "message": "No new Star Citizen patches", } # === CUSTOM PULSE CHECKS === CUSTOM_PULSE_CHECKS: List[PulseCheck] = [ PulseCheck( "server-uptime", check_server_uptime, interval_seconds=60, ), PulseCheck( "docker-health", check_docker_containers, interval_seconds=120, ), PulseCheck( "plex-status", check_plex_server, interval_seconds=300, ), PulseCheck( "unifi-controller", check_unifi_controller, interval_seconds=300, ), PulseCheck( "gpu-temp", check_gpu_temperature, interval_seconds=60, ), PulseCheck( "star-citizen", check_star_citizen_patch, interval_seconds=3600, ), ] # === BRAIN TASKS (Agent/SDK, Uses Tokens) === CUSTOM_BRAIN_TASKS: List[BrainTask] = [ BrainTask( name="server-medic", check_type=CheckType.CONDITIONAL, prompt_template=( "Server is down!\n\n" "Status: $message\n\n" "Please analyze:\n" "1. What could cause this?\n" "2. What should I check first?\n" "3. Should I restart services?\n\n" "Be concise and actionable." ), condition_func=lambda data: data.get("status") == "error", send_to_platform="slack", send_to_channel="C_ALERTS", ), BrainTask( name="docker-diagnostician", check_type=CheckType.CONDITIONAL, prompt_template=( "Docker containers unhealthy!\n\n" "Unhealthy count: $unhealthy_count\n\n" "Please diagnose:\n" "1. What might cause container health issues?\n" "2. Should I restart them?\n" "3. What logs should I check?" ), condition_func=lambda data: ( data.get("unhealthy_count", 0) > 0 ), send_to_platform="telegram", send_to_channel="123456789", ), BrainTask( name="gpu-thermal-advisor", check_type=CheckType.CONDITIONAL, prompt_template=( "GPU temperature is high!\n\n" "Current: $temperatureC\n\n" "Please advise:\n" "1. Is this dangerous?\n" "2. What can I do to cool it down?\n" "3. Should I stop current workloads?" ), condition_func=lambda data: ( data.get("temperature", 0) > 80 ), ), BrainTask( name="homelab-briefing", check_type=CheckType.SCHEDULED, schedule_time="08:00", prompt_template=( "Good morning! Homelab status report:\n\n" "Server: $server_message\n" "Docker: $docker_message\n" "Plex: $plex_message\n" "UniFi: $unifi_message\n" "Star Citizen: $star_citizen_message\n\n" "Overnight summary:\n" "1. Any services restart?\n" "2. Notable events?\n" "3. Action items for today?\n\n" "Keep it brief and friendly." ), send_to_platform="slack", send_to_channel="C_HOMELAB", ), BrainTask( name="homelab-evening-report", check_type=CheckType.SCHEDULED, schedule_time="22:00", prompt_template=( "Evening homelab report:\n\n" "Today's status:\n" "- Server uptime: $server_message\n" "- Docker health: $docker_message\n" "- GPU temp: $gpu_message\n\n" "Summary:\n" "1. Any issues today?\n" "2. Services that needed attention?\n" "3. Overnight monitoring notes?" ), send_to_platform="telegram", send_to_channel="123456789", ), BrainTask( name="patch-notifier", check_type=CheckType.CONDITIONAL, prompt_template=( "New Star Citizen patch detected!\n\n" "Please:\n" "1. Summarize patch notes (if available)\n" "2. Note any breaking changes\n" "3. Recommend if I should update now or wait" ), condition_func=lambda data: data.get("new_patch", False), send_to_platform="discord", send_to_channel="GAMING_CHANNEL", ), ] def apply_custom_config(pulse_brain: Any) -> None: """Apply custom configuration to PulseBrain instance.""" existing_pulse_names = {c.name for c in pulse_brain.pulse_checks} for check in CUSTOM_PULSE_CHECKS: if check.name not in existing_pulse_names: pulse_brain.pulse_checks.append(check) existing_brain_names = {t.name for t in pulse_brain.brain_tasks} for task in CUSTOM_BRAIN_TASKS: if task.name not in existing_brain_names: pulse_brain.brain_tasks.append(task) print( f"Applied custom config: " f"{len(CUSTOM_PULSE_CHECKS)} pulse checks, " f"{len(CUSTOM_BRAIN_TASKS)} brain tasks" )