diff --git a/atlasbot/engine/answerer.py b/atlasbot/engine/answerer.py index 4cf52d8..137155c 100644 --- a/atlasbot/engine/answerer.py +++ b/atlasbot/engine/answerer.py @@ -201,6 +201,8 @@ class AnswerEngine: classify.setdefault("needs_snapshot", True) classify.setdefault("answer_style", "direct") classify.setdefault("follow_up", False) + classify.setdefault("focus_entity", "unknown") + classify.setdefault("focus_metric", "unknown") _debug_log("route_parsed", {"classify": classify, "normalized": normalized}) cluster_terms = ( "atlas", @@ -270,6 +272,8 @@ class AnswerEngine: sub_questions = _select_subquestions(parts, normalized, plan.max_subquestions) _debug_log("decompose_parsed", {"sub_questions": sub_questions}) keyword_tokens = _extract_keywords(question, normalized, sub_questions=sub_questions, keywords=keywords) + focus_entity = str(classify.get("focus_entity") or "unknown").lower() + focus_metric = str(classify.get("focus_metric") or "unknown").lower() snapshot_context = "" if classify.get("needs_snapshot"): @@ -295,12 +299,15 @@ class AnswerEngine: hardware_facts = [seg.strip() for seg in line.split(" | ") if seg.strip().startswith("hardware_usage_avg:")] break metric_facts = [line for line in key_facts if re.search(r"\d", line)] - if hardware_facts: + if focus_entity == "node" and hottest_facts: + metric_facts = hottest_facts + key_facts = _merge_fact_lines(metric_facts, key_facts) + elif hardware_facts: metric_facts = hardware_facts key_facts = _merge_fact_lines(metric_facts, key_facts) if classify.get("question_type") in {"metric", "diagnostic"}: 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 focus_entity != "node" and any(tok in lowered_q for tok in ("hardware", "class", "type", "rpi", "jetson", "amd64", "arm64")) and any( tok in lowered_q for tok in ("average", "avg", "mean", "ram", "memory", "cpu", "load") ): hw_top = None @@ -313,7 +320,7 @@ class AnswerEngine: if hw_top: metric_facts = [hw_top] key_facts = _merge_fact_lines(metric_facts, key_facts) - if hottest_facts and not hardware_facts: + if hottest_facts and not hardware_facts and focus_entity != "class": metric_facts = hottest_facts key_facts = _merge_fact_lines(metric_facts, key_facts) if classify.get("question_type") in {"metric", "diagnostic"} and not hottest_facts and not hardware_facts: @@ -1259,6 +1266,10 @@ def _metric_candidate_lines(lines: list[str], keywords: list[str] | None, limit: "pod", "pods", "namespace", + "anomaly", + "anomalies", + "pvc", + "storage", } candidates: list[str] = [] for line in lines: diff --git a/atlasbot/llm/prompts.py b/atlasbot/llm/prompts.py index d3c0cee..fcd536a 100644 --- a/atlasbot/llm/prompts.py +++ b/atlasbot/llm/prompts.py @@ -30,7 +30,8 @@ ROUTE_SYSTEM = ( ROUTE_PROMPT = ( "Return JSON with fields: needs_snapshot (bool), needs_kb (bool), needs_tool (bool), " - "answer_style (direct|insightful), follow_up (bool), question_type (metric|diagnostic|planning|open_ended)." + "answer_style (direct|insightful), follow_up (bool), question_type (metric|diagnostic|planning|open_ended), " + "focus_entity (node|class|namespace|service|cluster|unknown), focus_metric (cpu|ram|net|io|disk|load|pods|storage|unknown)." ) DECOMPOSE_SYSTEM = (