Initial commit: Agentic OS troubleshooting platform

Self-hosted, Docker-based agentic troubleshooting platform: FastAPI backend +
LangGraph agent, Next.js UI, tiered LLM routing (local Ollama -> Gemini ->
DeepSeek -> OpenRouter), MCP server manager, encrypted device credentials,
RBAC, audit log, project-memory + Obsidian integrations, and editable
troubleshooting decision rules tuned for the GeneseasX vessel stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-14 22:11:07 +03:00
commit 6185b9b85a
126 changed files with 14565 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
"""Tests for troubleshooting decision rules."""
from __future__ import annotations
import os
from pathlib import Path
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-unit-tests-only")
_test_dir = Path(__file__).resolve().parent
_backend_root = _test_dir.parent
_rules_file = _backend_root / "rules" / "troubleshooting.yaml"
if not _rules_file.is_file():
_rules_file = _backend_root.parent / "rules" / "troubleshooting.yaml"
os.environ["TROUBLESHOOTING_RULES_PATH"] = str(_rules_file)
from app.services.troubleshooting_rules import ( # noqa: E402
invalidate_rules_cache,
load_rules,
match_rule,
select_devices_for_issue,
)
def _devices():
return [
{"catalog_key": "proxmox", "name": "pve"},
{"catalog_key": "pfsense", "name": "fw"},
{"catalog_key": "docker_vm", "name": "docker"},
{"catalog_key": "asterisk_geneseasx", "name": "voip"},
]
def test_match_no_registration_rule():
invalidate_rules_cache()
rule = match_rule("SIP phones down", "Phone won't register on crew VLAN")
assert rule is not None
assert rule.id == "no-registration"
assert "pfsense" in rule.devices
def test_match_broad_health():
invalidate_rules_cache()
rule = match_rule("Full check", "health check of all systems")
assert rule is not None
assert rule.broad is True
def test_task4_issue_selects_proxmox_only():
"""Scoped VM task must not trigger full-stack sweep."""
invalidate_rules_cache()
selected, rule = select_devices_for_issue(
_devices(),
"Check status of all running VMs and provide config for each VM",
title="Proxmox VM status",
)
keys = [d["catalog_key"] for d in selected]
assert keys == ["proxmox"]
assert rule is None or rule.id == "proxmox-vm-inventory"
def test_multi_device_status_includes_all_named():
"""Issue naming two devices must diagnose both even when a single-device rule matches."""
invalidate_rules_cache()
selected, rule = select_devices_for_issue(
_devices(),
"check status of proxmox and pfsense",
title="Irinas box",
)
keys = [d["catalog_key"] for d in selected]
assert keys == ["proxmox", "pfsense"]
assert rule is not None
assert rule.id == "proxmox-vm-inventory"
def test_unmatched_issue_selects_nothing():
invalidate_rules_cache()
selected, _rule = select_devices_for_issue(
_devices(),
"something completely unrelated with no device keywords",
title="Mystery",
)
assert selected == []
def test_broad_issue_selects_all_devices():
invalidate_rules_cache()
selected, rule = select_devices_for_issue(
_devices(),
"Run a full stack health check on everything",
title="Weekly audit",
)
assert rule is not None
assert rule.broad is True
assert len(selected) == 4
def test_select_devices_order():
invalidate_rules_cache()
selected, rule = select_devices_for_issue(
_devices(),
"one-way audio on SIP calls",
title="VoIP issue",
)
assert rule is not None
assert rule.id == "one-way-audio"
keys = [d["catalog_key"] for d in selected]
assert keys == ["pfsense", "asterisk_geneseasx"]
def test_load_rules_has_device_keywords():
invalidate_rules_cache()
data = load_rules(force=True)
assert "asterisk_geneseasx" in data.get("device_keywords", {})