atlasbot: improve metric parsing and cluster intent

This commit is contained in:
Brad Stein 2026-01-27 21:27:19 -03:00
parent 27e8a77044
commit 832d5acf68

View File

@ -190,6 +190,8 @@ _INSIGHT_HINT_WORDS = {
"surprising", "surprising",
"weird", "weird",
"odd", "odd",
"unusual",
"outlier",
"fun", "fun",
"cool", "cool",
"unique", "unique",
@ -540,6 +542,13 @@ def _detect_operation(q: str) -> str | None:
def _detect_metric(q: str) -> str | None: def _detect_metric(q: str) -> str | None:
tokens = set(_tokens(q)) tokens = set(_tokens(q))
expanded: set[str] = set(tokens)
for token in list(tokens):
for part in re.split(r"[-_]", token):
part = part.strip()
if len(part) >= 2:
expanded.add(part)
tokens = expanded
for metric, phrases in METRIC_HINTS.items(): for metric, phrases in METRIC_HINTS.items():
for phrase in phrases: for phrase in phrases:
if " " in phrase: if " " in phrase:
@ -1271,6 +1280,19 @@ def snapshot_metric_answer(
pending = metrics.get("pods_pending") pending = metrics.get("pods_pending")
failed = metrics.get("pods_failed") failed = metrics.get("pods_failed")
succeeded = metrics.get("pods_succeeded") succeeded = metrics.get("pods_succeeded")
status_terms = ("running", "pending", "failed", "succeeded", "completed")
if sum(1 for term in status_terms if term in q) > 1:
parts = []
if running is not None:
parts.append(f"running {running:.0f}")
if pending is not None:
parts.append(f"pending {pending:.0f}")
if failed is not None:
parts.append(f"failed {failed:.0f}")
if succeeded is not None:
parts.append(f"succeeded {succeeded:.0f}")
if parts:
return _format_confidence(f"Pods: {', '.join(parts)}.", "high")
if "pending" in q and pending is not None: if "pending" in q and pending is not None:
return _format_confidence(f"Pending pods: {pending:.0f}.", "high") return _format_confidence(f"Pending pods: {pending:.0f}.", "high")
if "failed" in q and failed is not None: if "failed" in q and failed is not None:
@ -1345,7 +1367,17 @@ def structured_answer(
if hw_line: if hw_line:
return _format_confidence(hw_line, "high") return _format_confidence(hw_line, "high")
if op == "top" and metric is None: if entity == "node" and op == "status" and metric is None:
summary = _nodes_summary_line(inventory, snapshot)
if summary:
return _format_confidence(summary, "high")
if entity == "node" and metric is None and any(word in q for word in ("hardware", "architecture", "class", "mix")):
hw_line = _hardware_mix_line(inventory)
if hw_line:
return _format_confidence(hw_line, "medium")
if op == "top" and metric is None and not any(word in q for word in ("hardware", "architecture", "class")):
metric = "cpu" metric = "cpu"
# Metrics-first when a metric or top operation is requested. # Metrics-first when a metric or top operation is requested.
@ -2807,8 +2839,11 @@ class _AtlasbotHandler(BaseHTTPRequestHandler):
inventory=inventory, inventory=inventory,
workloads=workloads, workloads=workloads,
) )
cluster_query = _is_cluster_query(cleaned, inventory=inventory, workloads=workloads) or ( cluster_query = (
_is_subjective_query(cleaned) and history_cluster _is_cluster_query(cleaned, inventory=inventory, workloads=workloads)
or history_cluster
or _knowledge_intent(cleaned)
or _is_subjective_query(cleaned)
) )
context = "" context = ""
if cluster_query: if cluster_query:
@ -3347,8 +3382,11 @@ def sync_loop(token: str, room_id: str):
inventory=inventory, inventory=inventory,
workloads=workloads, workloads=workloads,
) )
cluster_query = _is_cluster_query(cleaned_body, inventory=inventory, workloads=workloads) or ( cluster_query = (
_is_subjective_query(cleaned_body) and history_cluster _is_cluster_query(cleaned_body, inventory=inventory, workloads=workloads)
or history_cluster
or _knowledge_intent(cleaned_body)
or _is_subjective_query(cleaned_body)
) )
context = "" context = ""
if cluster_query: if cluster_query: