atlasbot: harden quick intent routing

This commit is contained in:
Brad Stein 2026-02-05 15:28:06 -03:00
parent 60a54eb095
commit 7bc481c60e
2 changed files with 19 additions and 7 deletions

View File

@ -1729,6 +1729,7 @@ def _spine_answer(intent: IntentMatch, spine_line: str | None) -> str | None:
"nodes_count": _spine_nodes_answer,
"nodes_ready": _spine_nodes_answer,
"nodes_non_rpi": _spine_non_rpi_answer,
"hardware_mix": _spine_hardware_answer,
"postgres_connections": _spine_postgres_answer,
"postgres_hottest": _spine_postgres_answer,
"namespace_most_pods": _spine_namespace_answer,
@ -1759,6 +1760,10 @@ def _spine_non_rpi_answer(line: str) -> str:
return line
def _spine_hardware_answer(line: str) -> str:
return line
def _spine_hottest_answer(kind: str, line: str) -> str:
metric = kind.split("_", 1)[1]
hottest = _parse_hottest(line, metric)
@ -1799,15 +1804,20 @@ def _spine_from_summary(summary: dict[str, Any]) -> dict[str, str]:
def _spine_from_counts(summary: dict[str, Any]) -> dict[str, str]:
counts = summary.get("counts") if isinstance(summary.get("counts"), dict) else {}
inventory = summary.get("inventory") if isinstance(summary.get("inventory"), dict) else {}
nodes = summary.get("nodes") if isinstance(summary.get("nodes"), dict) else {}
workers = inventory.get("workers") if isinstance(inventory.get("workers"), dict) else {}
total = counts.get("nodes_total")
ready = counts.get("nodes_ready")
not_ready = None
if isinstance(inventory.get("not_ready_names"), list):
total = nodes.get("total")
ready = nodes.get("ready")
not_ready = nodes.get("not_ready")
if total is None:
total = counts.get("nodes_total")
if ready is None:
ready = counts.get("nodes_ready")
if not_ready is None and isinstance(inventory.get("not_ready_names"), list):
not_ready = len(inventory.get("not_ready_names") or [])
workers_ready = workers.get("ready")
workers_total = workers.get("total")
if total is None and ready is None:
if total is None and ready is None and not_ready is None:
return {}
parts = []
if total is not None:

View File

@ -17,8 +17,8 @@ _HOTTEST_TERMS = r"(hottest|hot|highest|max(?:imum)?|peak|top|most|worst|spikies
_CPU_TERMS = r"(cpu|processor|processors|compute|core|cores|load|load\\s+avg|load\\s+average|util(?:ization)?|usage)"
_RAM_TERMS = r"(ram|memory|mem|heap|rss|resident|swap)"
_NET_TERMS = r"(net|network|bandwidth|throughput|traffic|rx|tx|ingress|egress|bits|bytes|packets|pps|bps)"
_IO_TERMS = r"(io|i/o|disk\\s+io|disk\\s+activity|read/?write|storage\\s+io|iops|latency)"
_DISK_TERMS = r"(disk|storage|volume|pvc|filesystem|fs|capacity|space|full|usage)"
_IO_TERMS = r"(\\bio\\b|i/o|disk\\s+io|disk\\s+activity|read/?write|storage\\s+io|iops|latency)"
_DISK_TERMS = r"(disk|storage|volume|pvc|filesystem|fs|capacity|\\bspace\\b|full|usage)"
_PG_TERMS = r"(postgres|postgresql|pg\\b|database|db|sql|psql)"
_CONN_TERMS = r"(connections?|conn|pool|sessions?|clients?|active\\s+connections?|open\\s+connections?)"
_DB_HOT_TERMS = r"(hottest|busiest|most|largest|top|heaviest|noisiest|highest\\s+load)"
@ -26,6 +26,7 @@ _NAMESPACE_TERMS = r"(namespace|namespaces|ns\\b|tenant|workload\\s+namespace)"
_PODS_TERMS = r"(pods?|workloads?|tasks?|containers?|deployments?|jobs?|cronjobs?|daemonsets?|statefulsets?)"
_NON_RPI_TERMS = r"(non[-\\s]?raspberry|not\\s+raspberry|non[-\\s]?rpi|not\\s+rpi|amd64|x86|x86_64|intel|ryzen|jetson|arm64\\b(?!.*rpi))"
_PRESSURE_TERMS = r"(pressure|overload|hotspot|bottleneck|saturation|headroom|strain|stress|critical|warning|at\\s+capacity|near\\s+limit)"
_HARDWARE_TERMS = r"(hardware|arch(?:itecture)?|platform|mix|profile|node\\s+types?)"
def route_intent(question: str) -> IntentMatch | None:
@ -49,6 +50,7 @@ def route_intent(question: str) -> IntentMatch | None:
IntentMatch("nodes_ready", 85),
),
(lambda: _all(_NON_RPI_TERMS) and (_any(_NODE_TERMS) or "cluster" in text), IntentMatch("nodes_non_rpi", 80)),
(lambda: _all(_HARDWARE_TERMS) and (_has(_NODE_TERMS) or "cluster" in text), IntentMatch("hardware_mix", 75)),
(lambda: _all(_HOTTEST_TERMS, _CPU_TERMS), IntentMatch("hottest_cpu", 80)),
(lambda: _all(_HOTTEST_TERMS, _RAM_TERMS), IntentMatch("hottest_ram", 80)),
(lambda: _all(_HOTTEST_TERMS, _NET_TERMS), IntentMatch("hottest_net", 80)),