atlasbot: enforce metric routing for namespace pods
This commit is contained in:
parent
aed2606601
commit
cc3739efe4
@ -227,11 +227,19 @@ class AnswerEngine:
|
|||||||
)
|
)
|
||||||
if any(term in normalized.lower() for term in cluster_terms):
|
if any(term in normalized.lower() for term in cluster_terms):
|
||||||
classify["needs_snapshot"] = True
|
classify["needs_snapshot"] = True
|
||||||
|
lowered_norm = normalized.lower()
|
||||||
|
if (
|
||||||
|
("namespace" in lowered_norm and ("pod" in lowered_norm or "pods" in lowered_norm))
|
||||||
|
or re.search(r"\bmost\s+pods\b", lowered_norm)
|
||||||
|
or re.search(r"\bpods\s+running\b", lowered_norm)
|
||||||
|
):
|
||||||
|
classify["question_type"] = "metric"
|
||||||
|
classify["needs_snapshot"] = True
|
||||||
if re.search(r"\b(how many|count|number of|list)\b", normalized.lower()):
|
if re.search(r"\b(how many|count|number of|list)\b", normalized.lower()):
|
||||||
classify["question_type"] = "metric"
|
classify["question_type"] = "metric"
|
||||||
hottest_terms = ("hottest", "highest", "lowest", "most")
|
hottest_terms = ("hottest", "highest", "lowest", "most")
|
||||||
metric_terms = ("cpu", "ram", "memory", "net", "network", "io", "disk", "load", "usage")
|
metric_terms = ("cpu", "ram", "memory", "net", "network", "io", "disk", "load", "usage", "pod", "pods", "namespace")
|
||||||
lowered_question = normalized.lower()
|
lowered_question = f"{question} {normalized}".lower()
|
||||||
if any(term in lowered_question for term in hottest_terms) and any(term in lowered_question for term in metric_terms):
|
if any(term in lowered_question for term in hottest_terms) and any(term in lowered_question for term in metric_terms):
|
||||||
classify["question_type"] = "metric"
|
classify["question_type"] = "metric"
|
||||||
|
|
||||||
@ -312,15 +320,24 @@ class AnswerEngine:
|
|||||||
if self._settings.debug_pipeline:
|
if self._settings.debug_pipeline:
|
||||||
_debug_log("metric_facts_selected", {"facts": metric_facts})
|
_debug_log("metric_facts_selected", {"facts": metric_facts})
|
||||||
if classify.get("question_type") in {"metric", "diagnostic"} and not metric_facts:
|
if classify.get("question_type") in {"metric", "diagnostic"} and not metric_facts:
|
||||||
for line in summary_lines:
|
lowered_q = f"{question} {normalized}".lower()
|
||||||
if "hardware_usage_top:" in line:
|
if "namespace" in lowered_q and "pod" in lowered_q:
|
||||||
metric_facts = [seg.strip() for seg in line.split(" | ") if seg.strip().startswith("hardware_usage_top:")]
|
|
||||||
break
|
|
||||||
if not metric_facts:
|
|
||||||
for line in summary_lines:
|
for line in summary_lines:
|
||||||
if "hardware_usage_avg:" in line:
|
if line.startswith("namespaces_top:"):
|
||||||
metric_facts = [seg.strip() for seg in line.split(" | ") if seg.strip().startswith("hardware_usage_avg:")]
|
metric_facts = [line]
|
||||||
break
|
break
|
||||||
|
if not metric_facts:
|
||||||
|
hardware_tokens = ("hardware", "class", "type", "rpi", "jetson", "amd64", "arm64")
|
||||||
|
if any(tok in lowered_q for tok in hardware_tokens):
|
||||||
|
for line in summary_lines:
|
||||||
|
if "hardware_usage_top:" in line:
|
||||||
|
metric_facts = [seg.strip() for seg in line.split(" | ") if seg.strip().startswith("hardware_usage_top:")]
|
||||||
|
break
|
||||||
|
if not metric_facts:
|
||||||
|
for line in summary_lines:
|
||||||
|
if "hardware_usage_avg:" in line:
|
||||||
|
metric_facts = [seg.strip() for seg in line.split(" | ") if seg.strip().startswith("hardware_usage_avg:")]
|
||||||
|
break
|
||||||
if metric_facts:
|
if metric_facts:
|
||||||
key_facts = _merge_fact_lines(metric_facts, key_facts)
|
key_facts = _merge_fact_lines(metric_facts, key_facts)
|
||||||
if self._settings.debug_pipeline:
|
if self._settings.debug_pipeline:
|
||||||
@ -513,6 +530,19 @@ class AnswerEngine:
|
|||||||
if classify.get("question_type") in {"metric", "diagnostic"} and metric_facts:
|
if classify.get("question_type") in {"metric", "diagnostic"} and metric_facts:
|
||||||
reply = _metric_fact_guard(reply, metric_facts, keyword_tokens)
|
reply = _metric_fact_guard(reply, metric_facts, keyword_tokens)
|
||||||
|
|
||||||
|
if classify.get("question_type") in {"metric", "diagnostic"}:
|
||||||
|
lowered_q = f"{question} {normalized}".lower()
|
||||||
|
if ("io" in lowered_q or "i/o" in lowered_q) and ("node" in lowered_q or "nodes" in lowered_q):
|
||||||
|
io_facts = _extract_hottest_facts(summary_lines, lowered_q)
|
||||||
|
io_line = next((fact for fact in io_facts if fact.startswith("hottest_io_node")), None)
|
||||||
|
if io_line:
|
||||||
|
reply = f"From the latest snapshot: {io_line}."
|
||||||
|
if "namespace" in lowered_q and "pod" in lowered_q:
|
||||||
|
for line in summary_lines:
|
||||||
|
if line.startswith("namespaces_top:"):
|
||||||
|
reply = f"From the latest snapshot: {line}."
|
||||||
|
break
|
||||||
|
|
||||||
if classify.get("question_type") in {"metric", "diagnostic"}:
|
if classify.get("question_type") in {"metric", "diagnostic"}:
|
||||||
lowered_q = f"{question} {normalized}".lower()
|
lowered_q = f"{question} {normalized}".lower()
|
||||||
if any(tok in lowered_q for tok in ("hardware", "class", "type", "rpi", "jetson", "amd64", "arm64")) and any(
|
if any(tok in lowered_q for tok in ("hardware", "class", "type", "rpi", "jetson", "amd64", "arm64")) and any(
|
||||||
@ -1091,6 +1121,8 @@ def _extract_hottest_facts(lines: list[str], question: str) -> list[str]:
|
|||||||
if not facts:
|
if not facts:
|
||||||
return []
|
return []
|
||||||
wanted = []
|
wanted = []
|
||||||
|
if ("io" in lowered or "i/o" in lowered) and ("disk" in lowered or "storage" in lowered):
|
||||||
|
return [fact for fact in facts if fact.startswith("hottest_io_node")]
|
||||||
if any(term in lowered for term in ("cpu", "processor")):
|
if any(term in lowered for term in ("cpu", "processor")):
|
||||||
wanted.append("hottest_cpu_node")
|
wanted.append("hottest_cpu_node")
|
||||||
if any(term in lowered for term in ("ram", "memory")):
|
if any(term in lowered for term in ("ram", "memory")):
|
||||||
@ -1156,6 +1188,9 @@ def _metric_candidate_lines(lines: list[str], keywords: list[str] | None, limit:
|
|||||||
"p95",
|
"p95",
|
||||||
"percent",
|
"percent",
|
||||||
"pressure",
|
"pressure",
|
||||||
|
"pod",
|
||||||
|
"pods",
|
||||||
|
"namespace",
|
||||||
}
|
}
|
||||||
candidates: list[str] = []
|
candidates: list[str] = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user