diff --git a/meshai/alert_engine.py b/meshai/alert_engine.py index 2f0d235..c6bff8b 100644 --- a/meshai/alert_engine.py +++ b/meshai/alert_engine.py @@ -68,6 +68,7 @@ class AlertEngine: subscription_manager: "SubscriptionManager", config: "MeshIntelligenceConfig", db_path: str = "", + timezone: str = "America/Boise", ): self._health = health_engine self._reporter = reporter @@ -75,6 +76,7 @@ class AlertEngine: self._rules = config.alert_rules self._critical_nodes = set(n.upper() for n in (config.critical_nodes or [])) self._db_path = db_path + self._timezone = timezone self._states: dict[str, AlertState] = {} self._prev_infra_online: dict[int, bool] = {} @@ -266,7 +268,7 @@ class AlertEngine: if self._rules.solar_not_charging and getattr(node, "has_solar", False) and 0 < bat <= 100: try: from zoneinfo import ZoneInfo - tz = ZoneInfo("America/Boise") + tz = ZoneInfo(self._timezone) hour = datetime.now(tz).hour if 8 <= hour <= 18: prev_bat = self._prev_battery.get(node_num) diff --git a/meshai/config.py b/meshai/config.py index 4e2d714..e13a256 100644 --- a/meshai/config.py +++ b/meshai/config.py @@ -330,6 +330,9 @@ class DashboardConfig: class Config: """Main configuration container.""" + # Global settings + timezone: str = "America/Boise" # IANA timezone for local time display + bot: BotConfig = field(default_factory=BotConfig) connection: ConnectionConfig = field(default_factory=ConnectionConfig) response: ResponseConfig = field(default_factory=ResponseConfig) diff --git a/meshai/main.py b/meshai/main.py index 8d626b9..452857d 100644 --- a/meshai/main.py +++ b/meshai/main.py @@ -330,6 +330,7 @@ class MeshAI: subscription_manager=self.subscription_manager, config=mi, db_path="/data/mesh_history.db", + timezone=self.config.timezone, ) logger.info(f"Alert engine initialized (critical: {mi.critical_nodes}, channel: {mi.alert_channel})") @@ -574,7 +575,7 @@ class MeshAI: from datetime import datetime from zoneinfo import ZoneInfo - tz = ZoneInfo("America/Boise") + tz = ZoneInfo(self.config.timezone) now = datetime.now(tz) current_hhmm = now.strftime("%H%M") current_day = now.strftime("%a").lower() diff --git a/meshai/router.py b/meshai/router.py index cc0a60c..61d9b5f 100644 --- a/meshai/router.py +++ b/meshai/router.py @@ -110,8 +110,8 @@ coverage gap, and problem node on the mesh. USE THIS DATA in your response. RESPONSE STYLE: - DETAILED, data-driven responses. Reference specific node names, scores, gateway counts. -- Use LOCAL NAMES from the region descriptions (Magic Valley, Treasure Valley, etc.) -- ALWAYS use local region names: say "Treasure Valley" not "South Western ID", say "Magic Valley" not "South Central ID". The code names mean nothing to users. +- Use LOCAL NAMES from the region descriptions when available. +{region_name_instructions} - When listing nodes, be concise: "BT Base c8d5 — via AIDA" not "BT Base c8d5 (c8d5) is connected via AIDA-MeshMonitor in the South Western ID region." - Don't repeat the region on every line when listing multiple nodes in the same region. Say the region once at the top, then just list the nodes. - Don't include shortnames in parentheses when you're already giving the full name — it's noise. @@ -721,8 +721,21 @@ class MessageRouter: if recommendations: system_prompt += "\n\n" + recommendations - # Add mesh awareness instructions - system_prompt += _MESH_AWARENESS_PROMPT + # Add mesh awareness instructions with dynamic region name mappings + region_name_instructions = "" + if self.config.mesh_intelligence and self.config.mesh_intelligence.regions: + # Build region name mappings for the prompt + mappings = [] + for region in self.config.mesh_intelligence.regions: + local = getattr(region, "local_name", "") or "" + if local and local != region.name: + mappings.append(f'say "{local}" not "{region.name}"') + if mappings: + region_name_instructions = f"- ALWAYS use local region names: {', '.join(mappings)}. The code names mean nothing to users." + + system_prompt += _MESH_AWARENESS_PROMPT.format( + region_name_instructions=region_name_instructions + ) # Build region geography from config dynamically if self.config.mesh_intelligence and self.config.mesh_intelligence.regions: