From 46e0322e6fb6e495d7082d5539b6e0f46091f207 Mon Sep 17 00:00:00 2001 From: MacRimi Date: Wed, 1 Apr 2026 13:01:48 +0200 Subject: [PATCH] update health_persistence.py --- AppImage/scripts/ai_context_enrichment.py | 21 ++++++++++++--- AppImage/scripts/health_persistence.py | 31 ++++++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/AppImage/scripts/ai_context_enrichment.py b/AppImage/scripts/ai_context_enrichment.py index b6367e1c..ea3e86cb 100644 --- a/AppImage/scripts/ai_context_enrichment.py +++ b/AppImage/scripts/ai_context_enrichment.py @@ -304,10 +304,23 @@ def enrich_context_for_ai( context_parts = [] combined_text = f"{title} {body} {journal_context}" - # 1. System uptime (always useful) - uptime = get_system_uptime() - if uptime and uptime != "unknown": - context_parts.append(f"System uptime: {uptime}") + # 1. System uptime - only relevant for errors, not informational notifications + # Uptime helps distinguish startup issues from runtime failures + uptime_relevant_types = [ + 'error', 'critical', 'warning', 'service', 'system', + 'disk', 'smart', 'storage', 'io_error', 'network', + 'cluster', 'ha', 'vm', 'ct', 'container', 'backup' + ] + # Exclude purely informational events + informational_types = ['update', 'upgrade', 'available', 'info', 'resolved'] + + is_uptime_relevant = any(t in event_type.lower() for t in uptime_relevant_types) + is_informational = any(t in event_type.lower() for t in informational_types) + + if is_uptime_relevant and not is_informational: + uptime = get_system_uptime() + if uptime and uptime != "unknown": + context_parts.append(f"System uptime: {uptime}") # 2. Event frequency error_key = data.get('error_key') or data.get('error_id') diff --git a/AppImage/scripts/health_persistence.py b/AppImage/scripts/health_persistence.py index 2fac9f14..4e6437ed 100644 --- a/AppImage/scripts/health_persistence.py +++ b/AppImage/scripts/health_persistence.py @@ -1820,6 +1820,19 @@ class HealthPersistence: 'WHERE id = ?', (device_name, model, size_bytes, now, old_id)) + # If no serial provided, check if a record WITH serial already exists for this device + # This prevents creating duplicate entries (one with serial, one without) + effective_serial = serial or '' + if not serial: + cursor.execute(''' + SELECT serial FROM disk_registry + WHERE device_name = ? AND serial != '' + ORDER BY last_seen DESC LIMIT 1 + ''', (device_name,)) + existing = cursor.fetchone() + if existing and existing[0]: + effective_serial = existing[0] # Use the existing serial + cursor.execute(''' INSERT INTO disk_registry (device_name, serial, model, size_bytes, first_seen, last_seen, removed) VALUES (?, ?, ?, ?, ?, ?, 0) @@ -1828,7 +1841,7 @@ class HealthPersistence: size_bytes = COALESCE(excluded.size_bytes, size_bytes), last_seen = excluded.last_seen, removed = 0 - ''', (device_name, serial or '', model, size_bytes, now, now)) + ''', (device_name, effective_serial, model, size_bytes, now, now)) conn.commit() conn.close() @@ -1847,6 +1860,8 @@ class HealthPersistence: linked observations, which helps with USB disks that may have multiple registry entries (one with serial, one without). """ + clean_dev = device_name.replace('/dev/', '') + if serial: cursor.execute( 'SELECT id FROM disk_registry WHERE serial = ? AND serial != "" ORDER BY last_seen DESC LIMIT 1', @@ -1854,9 +1869,19 @@ class HealthPersistence: row = cursor.fetchone() if row: return row[0] + else: + # No serial provided - first check if a record WITH serial exists for this device + # This prevents returning a duplicate record without serial + cursor.execute(''' + SELECT id FROM disk_registry + WHERE device_name = ? AND serial != '' + ORDER BY last_seen DESC LIMIT 1 + ''', (clean_dev,)) + row = cursor.fetchone() + if row: + return row[0] - # Fallback: match by device_name (strip /dev/ prefix) - clean_dev = device_name.replace('/dev/', '') + # Fallback: match by device_name if prefer_with_observations: # First try to find a registry entry that has observations linked