From 873ec75586612a2a6a28a5bd0364770aba7bae14 Mon Sep 17 00:00:00 2001 From: MacRimi Date: Wed, 18 Mar 2026 19:32:38 +0100 Subject: [PATCH] update notification service --- AppImage/components/notification-settings.tsx | 2 + AppImage/scripts/flask_notification_routes.py | 11 +- AppImage/scripts/notification_manager.py | 11 +- AppImage/scripts/notification_templates.py | 100 +++++++++++++++--- 4 files changed, 110 insertions(+), 14 deletions(-) diff --git a/AppImage/components/notification-settings.tsx b/AppImage/components/notification-settings.tsx index 36b3f41f..31a0b3b0 100644 --- a/AppImage/components/notification-settings.tsx +++ b/AppImage/components/notification-settings.tsx @@ -467,6 +467,7 @@ export function NotificationSettings() { ai_model: cfg.ai_model, ai_language: cfg.ai_language, ai_ollama_url: cfg.ai_ollama_url, + ai_openai_base_url: cfg.ai_openai_base_url, hostname: cfg.hostname, webhook_secret: cfg.webhook_secret, webhook_allowed_ips: cfg.webhook_allowed_ips, @@ -604,6 +605,7 @@ export function NotificationSettings() { api_key: config.ai_api_key, model: config.ai_model, ollama_url: config.ai_ollama_url, + openai_base_url: config.ai_openai_base_url, }), }) setAiTestResult(data) diff --git a/AppImage/scripts/flask_notification_routes.py b/AppImage/scripts/flask_notification_routes.py index 87ec64d5..b7bb7be9 100644 --- a/AppImage/scripts/flask_notification_routes.py +++ b/AppImage/scripts/flask_notification_routes.py @@ -127,6 +127,7 @@ def test_ai_connection(): api_key = data.get('api_key', '') model = data.get('model', '') ollama_url = data.get('ollama_url', 'http://localhost:11434') + openai_base_url = data.get('openai_base_url', '') # Validate required fields if provider != 'ollama' and not api_key: @@ -152,12 +153,20 @@ def test_ai_connection(): from ai_providers import get_provider, AIProviderError + # Determine base_url based on provider + if provider == 'ollama': + base_url = ollama_url + elif provider == 'openai': + base_url = openai_base_url # Empty string means use default OpenAI API + else: + base_url = '' + try: ai_provider = get_provider( provider, api_key=api_key, model=model, - base_url=ollama_url + base_url=base_url ) result = ai_provider.test_connection() diff --git a/AppImage/scripts/notification_manager.py b/AppImage/scripts/notification_manager.py index ae549e8a..3f1f6815 100644 --- a/AppImage/scripts/notification_manager.py +++ b/AppImage/scripts/notification_manager.py @@ -1453,6 +1453,11 @@ class NotificationManager: ch_overrides['events'][event_type_key] = (saved or default) == 'true' channel_overrides[ch_type] = ch_overrides + # Build AI detail levels per channel + ai_detail_levels = {} + for ch_type in CHANNEL_TYPES: + ai_detail_levels[ch_type] = self._config.get(f'ai_detail_level_{ch_type}', 'standard') + config = { 'enabled': self._enabled, 'channels': channels, @@ -1461,9 +1466,13 @@ class NotificationManager: 'event_types_by_group': event_types_by_group, 'channel_overrides': channel_overrides, 'ai_enabled': self._config.get('ai_enabled', 'false') == 'true', - 'ai_provider': self._config.get('ai_provider', 'openai'), + 'ai_provider': self._config.get('ai_provider', 'groq'), 'ai_api_key': self._config.get('ai_api_key', ''), 'ai_model': self._config.get('ai_model', ''), + 'ai_language': self._config.get('ai_language', 'en'), + 'ai_ollama_url': self._config.get('ai_ollama_url', 'http://localhost:11434'), + 'ai_openai_base_url': self._config.get('ai_openai_base_url', ''), + 'ai_detail_levels': ai_detail_levels, 'hostname': self._config.get('hostname', ''), 'webhook_secret': self._config.get('webhook_secret', ''), 'webhook_allowed_ips': self._config.get('webhook_allowed_ips', ''), diff --git a/AppImage/scripts/notification_templates.py b/AppImage/scripts/notification_templates.py index 16520a22..f796d9a4 100644 --- a/AppImage/scripts/notification_templates.py +++ b/AppImage/scripts/notification_templates.py @@ -762,7 +762,7 @@ TEMPLATES = { }, 'pve_update': { 'title': '{hostname}: Proxmox VE {new_version} available', - 'body': 'A new Proxmox VE release is available.\nCurrent: {current_version} → New: {new_version}\n{details}', + 'body': 'A new Proxmox VE release is available.\nCurrent: {current_version}\nNew: {new_version}\n{details}', 'label': 'Proxmox VE update available', 'group': 'updates', 'default_enabled': True, @@ -1261,12 +1261,51 @@ Your task is to translate and reformat incoming server alert messages into {lang - brief → 2-3 lines, essential data only (status + key metric) - standard → short paragraph covering who/what/where and the key value - detailed → full technical breakdown of all available fields -8. Keep the "hostname: " prefix in the title. Translate only the descriptive part. +9. Keep the "hostname: " prefix in the title. Translate only the descriptive part. Example: "pve01: Updates available" → "pve01: Actualizaciones disponibles" -9. EMPTY LIST VALUES — if the input contains a list field that is empty, "none", or "0": +10. EMPTY LIST VALUES — if the input contains a list field that is empty, "none", or "0": - Always write the translated word for "none" on the line after the label, never leave it blank. - - Example (English input "none"): 📋 Important packages:\n📋 none - - Example (Spanish output): 📋 Paquetes importantes:\n📋 ninguno + - Example (English input "none"): 🗂️ Important packages:\n• none + - Example (Spanish output): 🗂️ Paquetes importantes:\n• ninguno +11. DEDUPLICATION — input may contain redundant or repeated information from multiple monitoring sources: + - Identify and merge duplicate facts (same device, same error, same metric mentioned twice) + - Present each unique fact exactly once in a clear, consolidated form + - If the same data appears in different formats, choose the most informative version +12. PROXMOX CONTEXT — silently translate Proxmox technical references into plain language. + Never explain what the term means — just use the human-readable equivalent directly. + + Service / process name mapping (replace the raw name with the friendly form): + - "pve-container@XXXX.service" → "Container CT XXXX" + - "qemu-server@XXXX.service" → "Virtual Machine VM XXXX" + - "pvesr-XXXX" → "storage replication job for XXXX" + - "vzdump" → "backup process" + - "pveproxy" → "Proxmox web proxy" + - "pvedaemon" → "Proxmox daemon" + - "pvestatd" → "Proxmox statistics service" + - "pvescheduler" → "Proxmox task scheduler" + - "pve-cluster" → "Proxmox cluster service" + - "corosync" → "cluster communication service" + - "ceph-osd@N" → "Ceph storage disk N" + - "ceph-mon" → "Ceph monitor service" + + systemd message patterns (rewrite the whole phrase, not just the service name): + - "systemd[1]: pve-container@9000.service: Failed" + → "Container CT 9000 service failed" + - "systemd[1]: qemu-server@100.service: Failed with result 'exit-code'" + → "Virtual Machine VM 100 failed to start" + - "systemd[1]: Started pve-container@9000.service" + → "Container CT 9000 started" + + ATA / SMART / kernel error patterns (replace raw kernel log with plain description): + - "ata8.00: exception Emask 0x1 SAct 0x4ce0 SErr 0x40000 action 0x0" + → "ATA controller error on port 8" + - "blk_update_request: I/O error, dev sdX, sector NNNN" + → "I/O error on disk /dev/sdX at sector NNNN" + - "SCSI error: return code = 0x08000002" + → "SCSI communication error" + + Apply these mappings everywhere: in the body narrative, in field values, and when + the raw technical string appears inside a longer sentence. {emoji_instructions} ═══ KNOWN MESSAGE TYPES AND HOW TO FORMAT THEM ═══ @@ -1285,14 +1324,39 @@ UPDATES (update_summary / pve_update): Output body must show each count on its own line with its label. For the package list: use "• " (bullet + space) before each package name, NOT the 📋 emoji. The 📋 emoji goes only on the "Important packages:" header line. - Example packages block: - 📋 Important packages: + + EXAMPLE — pve_update (new Proxmox VE version): + - First line: plain sentence announcing the new version (no emoji — it goes on the title) + - Blank line after the intro sentence + - Current version line: 🔹 prefix + - New version line: 🟢 prefix + - Blank line before packages block + - Packages header: 🗂️ prefix + - Package lines: 📌 prefix (not bullet •), include version arrow as: v{{old}} ➜ v{{new}} + + EXAMPLE — pve_update: + [TITLE] + 🆕 pve01: Proxmox VE 9.1.6 available + [BODY] + 🚀 A new Proxmox VE release is available. + + 🔹 Current: 9.1.4 + 🟢 New: 9.1.6 + + 🗂️ Important packages: + 📌 pve-manager (v9.1.4 ➜ v9.1.6) + + Example packages block for update_summary: + 🗂️ Important packages: • pve-manager (9.1.4 -> 9.1.6) • qemu-server (9.1.3 -> 9.1.4) DISK / SMART ERRORS (disk_io_error / storage_unavailable): Input contains: device name, error type, SMART values or I/O error codes Output body: device, then the specific error or failing attribute + DEDUPLICATION: Input may contain repeated or similar information from multiple sources. + If you see the same device, error count, or technical details mentioned multiple times, + consolidate them into a single, clear statement. Never repeat the same information twice. RESOURCES (cpu_high / ram_high / temp_high / load_high): Input contains: current value, threshold, core count @@ -1330,7 +1394,7 @@ CRITICAL OUTPUT RULES: # Emoji instructions injected into AI_SYSTEM_PROMPT for rich channels (Telegram, Discord, Pushover) AI_EMOJI_INSTRUCTIONS = """ -9. EMOJI USAGE — place ONE emoji at the START of EVERY non-empty line (title and each body line). +EMOJI USAGE — place ONE emoji at the START of EVERY non-empty line (title and each body line). Never skip a line. Never put the emoji at the end. Never use two emojis on the same line. Use these exact emoji for each kind of content: @@ -1377,7 +1441,8 @@ AI_EMOJI_INSTRUCTIONS = """ 🔒 security updates / actualizaciones de seguridad / jail 🔄 proxmox updates / actualizaciones de proxmox ⚙️ kernel updates / actualizaciones del kernel / service - 📋 important packages / paquetes importantes + 📋 important packages header (update_summary) + 🗂️ important packages header (pve_update) / file index / archive listing 🌐 source IP / IP origen 👤 user / usuario 📝 reason / motivo / razón / details @@ -1413,7 +1478,7 @@ AI_EMOJI_INSTRUCTIONS = """ 🔄 Proxmox updates: 0 ⚙️ Kernel updates: 0 - 📋 Important packages: + 🗂️ Important packages: • none EXAMPLE — updates message (with important packages): @@ -1425,10 +1490,21 @@ AI_EMOJI_INSTRUCTIONS = """ 🔄 Proxmox updates: 14 ⚙️ Kernel updates: 1 - 📋 Important packages: + 🗂️ Important packages: • pve-manager (9.1.4 -> 9.1.6) • qemu-server (9.1.3 -> 9.1.4) • pve-container (6.0.18 -> 6.1.2) + EXAMPLE — pve_update (new Proxmox VE version): + [TITLE] + 🆕 pve01: Proxmox VE 9.1.6 available + [BODY] + 🚀 A new Proxmox VE release is available. + + 🔹 Current: 9.1.4 + 🟢 New: 9.1.6 + + 🗂️ Important packages: + 📌 pve-manager (v9.1.4 ➜ v9.1.6) EXAMPLE — backup complete with multiple VMs: [TITLE] @@ -1488,7 +1564,7 @@ AI_EMOJI_INSTRUCTIONS = """ # No emoji instructions for email/plain text channels AI_NO_EMOJI_INSTRUCTIONS = """ -9. DO NOT use any emojis or special Unicode symbols. Plain ASCII text only for email compatibility.""" +DO NOT use any emojis or special Unicode symbols. Plain ASCII text only for email compatibility.""" class AIEnhancer: