atlasbot: enforce longhorn-qualified fallback matches
This commit is contained in:
parent
d8c451dc80
commit
ff23e97dec
@ -2125,6 +2125,9 @@ def _doc_intent(query: str) -> bool:
|
|||||||
"triage",
|
"triage",
|
||||||
"recover",
|
"recover",
|
||||||
"remediate",
|
"remediate",
|
||||||
|
"longhorn",
|
||||||
|
"astreae",
|
||||||
|
"asteria",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -4061,6 +4064,7 @@ def _fallback_fact_answer(prompt: str, context: str) -> str:
|
|||||||
hottest_intent = any(word in q for word in ("hottest", "highest", "most", "top", "busiest"))
|
hottest_intent = any(word in q for word in ("hottest", "highest", "most", "top", "busiest"))
|
||||||
metric = _detect_metric(q)
|
metric = _detect_metric(q)
|
||||||
include_hw, _exclude_hw = _detect_hardware_filters(q)
|
include_hw, _exclude_hw = _detect_hardware_filters(q)
|
||||||
|
wants_longhorn = any(word in tokens for word in ("longhorn", "astreae", "asteria"))
|
||||||
|
|
||||||
if hottest_intent and metric in {"cpu", "ram", "net", "io"}:
|
if hottest_intent and metric in {"cpu", "ram", "net", "io"}:
|
||||||
hottest_val = _find_value(f"hottest_{metric}")
|
hottest_val = _find_value(f"hottest_{metric}")
|
||||||
@ -4099,6 +4103,18 @@ def _fallback_fact_answer(prompt: str, context: str) -> str:
|
|||||||
return f"Not ready nodes: {match.group(1)}."
|
return f"Not ready nodes: {match.group(1)}."
|
||||||
|
|
||||||
if count_intent and include_hw:
|
if count_intent and include_hw:
|
||||||
|
if wants_longhorn:
|
||||||
|
for hw in include_hw:
|
||||||
|
for fact, key, val in parsed_facts:
|
||||||
|
key_tokens = set(_tokens(key or fact))
|
||||||
|
if "longhorn" not in key_tokens:
|
||||||
|
continue
|
||||||
|
if hw not in key_tokens:
|
||||||
|
continue
|
||||||
|
nodes = _extract_titan_nodes(val or fact)
|
||||||
|
if nodes:
|
||||||
|
return f"{hw} longhorn nodes: {len(nodes)}."
|
||||||
|
return ""
|
||||||
counts_line = _find_value("nodes_by_hardware_count")
|
counts_line = _find_value("nodes_by_hardware_count")
|
||||||
if counts_line:
|
if counts_line:
|
||||||
counts = _parse_counts(counts_line)
|
counts = _parse_counts(counts_line)
|
||||||
@ -4112,7 +4128,6 @@ def _fallback_fact_answer(prompt: str, context: str) -> str:
|
|||||||
return f"{hw} nodes: {len(items)}."
|
return f"{hw} nodes: {len(items)}."
|
||||||
|
|
||||||
if list_intent and include_hw:
|
if list_intent and include_hw:
|
||||||
wants_longhorn = "longhorn" in tokens
|
|
||||||
if "control" in q:
|
if "control" in q:
|
||||||
cp_by_hw = _find_value("control_plane_by_hardware")
|
cp_by_hw = _find_value("control_plane_by_hardware")
|
||||||
if cp_by_hw:
|
if cp_by_hw:
|
||||||
@ -4206,6 +4221,10 @@ def _fallback_fact_answer(prompt: str, context: str) -> str:
|
|||||||
best_fact = ""
|
best_fact = ""
|
||||||
best_score = -1
|
best_score = -1
|
||||||
for fact in facts:
|
for fact in facts:
|
||||||
|
if wants_longhorn:
|
||||||
|
fact_tokens = set(_tokens(fact))
|
||||||
|
if not ({"longhorn", "astreae", "asteria"} & fact_tokens):
|
||||||
|
continue
|
||||||
key_match = re.match(r"^([\w\s/.-]+):\s*(.+)$", fact)
|
key_match = re.match(r"^([\w\s/.-]+):\s*(.+)$", fact)
|
||||||
if not key_match:
|
if not key_match:
|
||||||
key_match = re.match(r"^([\w\s/.-]+)=\s*(.+)$", fact)
|
key_match = re.match(r"^([\w\s/.-]+)=\s*(.+)$", fact)
|
||||||
|
|||||||
@ -191,3 +191,37 @@ class AtlasbotModeTests(TestCase):
|
|||||||
self.assertNotIn("titan-14", reply)
|
self.assertNotIn("titan-14", reply)
|
||||||
self.assertNotIn("titan-18", reply)
|
self.assertNotIn("titan-18", reply)
|
||||||
self.assertIn("Confidence:", reply)
|
self.assertIn("Confidence:", reply)
|
||||||
|
|
||||||
|
def test_longhorn_query_uses_kb_context_when_snapshot_only_has_generic_rpi4(self):
|
||||||
|
fact_lines = [
|
||||||
|
"rpi4: titan-12, titan-13, titan-14, titan-15, titan-17, titan-18, titan-19",
|
||||||
|
]
|
||||||
|
kb_detail = (
|
||||||
|
"Atlas KB (retrieved):\n"
|
||||||
|
"- metis (knowledge/metis.md)\n"
|
||||||
|
"rpi4 armbian longhorn: titan-13/15/17/19"
|
||||||
|
)
|
||||||
|
|
||||||
|
with (
|
||||||
|
mock.patch.object(self.bot, "_fact_pack_lines", return_value=fact_lines),
|
||||||
|
mock.patch.object(self.bot, "kb_retrieve", return_value=kb_detail),
|
||||||
|
mock.patch.object(self.bot, "_ollama_call", side_effect=AssertionError("LLM should not be called")),
|
||||||
|
):
|
||||||
|
reply = self.bot.open_ended_answer(
|
||||||
|
"which nodes in titan are the rpi4 longhorn nodes?",
|
||||||
|
inventory=[],
|
||||||
|
snapshot=None,
|
||||||
|
workloads=[],
|
||||||
|
history_lines=[],
|
||||||
|
mode="smart",
|
||||||
|
allow_tools=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIn("titan-13", reply)
|
||||||
|
self.assertIn("titan-15", reply)
|
||||||
|
self.assertIn("titan-17", reply)
|
||||||
|
self.assertIn("titan-19", reply)
|
||||||
|
self.assertNotIn("titan-12", reply)
|
||||||
|
self.assertNotIn("titan-14", reply)
|
||||||
|
self.assertNotIn("titan-18", reply)
|
||||||
|
self.assertIn("Confidence:", reply)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user