diff --git a/atlasbot/engine/answerer.py b/atlasbot/engine/answerer.py index 1568416..0cef0b9 100644 --- a/atlasbot/engine/answerer.py +++ b/atlasbot/engine/answerer.py @@ -166,6 +166,7 @@ class AnswerEngine: allowed_nodes = _allowed_nodes(summary) allowed_namespaces = _allowed_namespaces(summary) summary_lines = _summary_lines(snapshot_used) + metric_tokens = _metric_key_tokens(summary_lines) global_facts = _global_facts(summary_lines) kb_summary = self._kb.summary() runbooks = self._kb.runbook_titles(limit=6) @@ -216,6 +217,8 @@ class AnswerEngine: classify.setdefault("follow_up", False) classify.setdefault("focus_entity", "unknown") classify.setdefault("focus_metric", "unknown") + if metric_tokens and keyword_tokens and any(token in metric_tokens for token in keyword_tokens): + classify["needs_snapshot"] = True _debug_log("route_parsed", {"classify": classify, "normalized": normalized}) lowered_question = f"{question} {normalized}".lower() force_metric = bool(re.search(r"\bhow many\b|\bcount\b|\btotal\b", lowered_question)) @@ -1296,6 +1299,21 @@ def _hotspot_evidence(summary: dict[str, Any]) -> list[str]: return lines +def _metric_key_tokens(summary_lines: list[str]) -> set[str]: + tokens: set[str] = set() + for line in summary_lines: + if not isinstance(line, str) or ":" not in line: + continue + key = line.split(":", 1)[0].strip().lower() + if not key: + continue + tokens.add(key) + for part in re.split(r"[_\\s]+", key): + if part: + tokens.add(part) + return tokens + + async def _select_best_candidate( call_llm: Callable[..., Any], question: str,