atlasbot: prefer qualified longhorn node subsets
This commit is contained in:
parent
d4e58bc105
commit
97f7073f82
@ -4112,6 +4112,7 @@ def _fallback_fact_answer(prompt: str, context: str) -> str:
|
||||
return f"{hw} nodes: {len(items)}."
|
||||
|
||||
if list_intent and include_hw:
|
||||
wants_longhorn = "longhorn" in tokens
|
||||
if "control" in q:
|
||||
cp_by_hw = _find_value("control_plane_by_hardware")
|
||||
if cp_by_hw:
|
||||
@ -4122,11 +4123,59 @@ def _fallback_fact_answer(prompt: str, context: str) -> str:
|
||||
cp_nodes = _find_value("control_plane_nodes")
|
||||
if cp_nodes:
|
||||
return f"Control-plane nodes: {cp_nodes}."
|
||||
if wants_longhorn:
|
||||
for hw in include_hw:
|
||||
best_nodes: list[str] = []
|
||||
best_val = ""
|
||||
for _fact, key, val in parsed_facts:
|
||||
if not key or not val:
|
||||
continue
|
||||
key_tokens = set(_tokens(key))
|
||||
if "longhorn" not in key_tokens:
|
||||
continue
|
||||
if hw not in key_tokens:
|
||||
continue
|
||||
nodes = _extract_titan_nodes(val)
|
||||
if nodes and len(nodes) > len(best_nodes):
|
||||
best_nodes = nodes
|
||||
best_val = val
|
||||
elif not best_nodes and val:
|
||||
best_val = val
|
||||
if best_nodes:
|
||||
return f"{hw} longhorn nodes: {', '.join(best_nodes)}."
|
||||
if best_val:
|
||||
return f"{hw} longhorn nodes: {best_val}."
|
||||
for hw in include_hw:
|
||||
if wants_longhorn:
|
||||
continue
|
||||
hw_line = _find_value(hw)
|
||||
if hw_line:
|
||||
return f"{hw} nodes: {hw_line}."
|
||||
|
||||
if list_intent and "longhorn" in tokens:
|
||||
best_nodes: list[str] = []
|
||||
best_key = ""
|
||||
best_val = ""
|
||||
for _fact, key, val in parsed_facts:
|
||||
if not key or not val:
|
||||
continue
|
||||
key_tokens = set(_tokens(key))
|
||||
if "longhorn" not in key_tokens:
|
||||
continue
|
||||
nodes = _extract_titan_nodes(val)
|
||||
if nodes and len(nodes) > len(best_nodes):
|
||||
best_nodes = nodes
|
||||
best_key = key
|
||||
best_val = val
|
||||
elif not best_nodes and val:
|
||||
best_key = key
|
||||
best_val = val
|
||||
if best_nodes:
|
||||
return f"Longhorn nodes: {', '.join(best_nodes)}."
|
||||
if best_val:
|
||||
label = (best_key or "Longhorn nodes").replace("_", " ").strip()
|
||||
return f"{label.capitalize()}: {best_val}."
|
||||
|
||||
if list_intent and "control" in q:
|
||||
cp_nodes = _find_value("control_plane_nodes")
|
||||
if cp_nodes:
|
||||
|
||||
@ -162,3 +162,32 @@ class AtlasbotModeTests(TestCase):
|
||||
|
||||
self.assertIn("worker nodes", reply.lower())
|
||||
self.assertIn("Confidence:", reply)
|
||||
|
||||
def test_longhorn_rpi4_subset_beats_generic_rpi4_list(self):
|
||||
fact_lines = [
|
||||
"rpi4: titan-12, titan-13, titan-14, titan-15, titan-17, titan-18, titan-19",
|
||||
"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, "_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