atlasbot: strengthen subjective insights
This commit is contained in:
parent
8842662239
commit
20364a262c
@ -16,7 +16,7 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: atlasbot
|
app: atlasbot
|
||||||
annotations:
|
annotations:
|
||||||
checksum/atlasbot-configmap: manual-atlasbot-66
|
checksum/atlasbot-configmap: manual-atlasbot-67
|
||||||
vault.hashicorp.com/agent-inject: "true"
|
vault.hashicorp.com/agent-inject: "true"
|
||||||
vault.hashicorp.com/role: "comms"
|
vault.hashicorp.com/role: "comms"
|
||||||
vault.hashicorp.com/agent-inject-secret-turn-secret: "kv/data/atlas/comms/turn-shared-secret"
|
vault.hashicorp.com/agent-inject-secret-turn-secret: "kv/data/atlas/comms/turn-shared-secret"
|
||||||
|
|||||||
@ -579,6 +579,10 @@ def _detect_entity(q: str) -> str | None:
|
|||||||
or "architecture" in q
|
or "architecture" in q
|
||||||
or "machine" in q
|
or "machine" in q
|
||||||
or "machines" in q
|
or "machines" in q
|
||||||
|
or "host" in q
|
||||||
|
or "hosts" in q
|
||||||
|
or "hostname" in q
|
||||||
|
or "hostnames" in q
|
||||||
or TITAN_NODE_RE.search(q)
|
or TITAN_NODE_RE.search(q)
|
||||||
):
|
):
|
||||||
return "node"
|
return "node"
|
||||||
@ -1775,20 +1779,29 @@ def _format_insight_text(key: str, text: str) -> str:
|
|||||||
.strip()
|
.strip()
|
||||||
.strip(".")
|
.strip(".")
|
||||||
)
|
)
|
||||||
|
has_jetson = "jetson=" in counts
|
||||||
|
has_amd64 = "amd64=" in counts
|
||||||
detail = f"mixed hardware stack ({counts})"
|
detail = f"mixed hardware stack ({counts})"
|
||||||
flavor = "It blends low-power Pis with Jetson accelerators and a couple of AMD64 nodes."
|
if has_jetson and has_amd64:
|
||||||
|
flavor = "It blends low-power Pis with Jetson accelerators and a couple of AMD64 boxes."
|
||||||
|
elif has_jetson:
|
||||||
|
flavor = "It pairs low-power Pis with Jetson accelerators for edge and AI workloads."
|
||||||
|
elif has_amd64:
|
||||||
|
flavor = "It mixes low-power Pis with a couple of heavier AMD64 nodes."
|
||||||
|
else:
|
||||||
|
flavor = "It is a pretty uniform hardware stack, which is rare for a homelab."
|
||||||
return f"{detail}. {flavor}"
|
return f"{detail}. {flavor}"
|
||||||
if key == "postgres":
|
if key == "postgres":
|
||||||
detail = cleaned.replace("Postgres is at ", "")
|
detail = cleaned.replace("Postgres is at ", "")
|
||||||
return f"Postgres is at {detail}; that suggests moderate load."
|
return f"Postgres is at {detail}; that feels like healthy, steady load rather than strain."
|
||||||
if key == "pods":
|
if key == "pods":
|
||||||
detail = cleaned.replace("There are ", "")
|
detail = cleaned.replace("There are ", "")
|
||||||
return f"Pods look steady ({detail}); the workload mix looks healthy."
|
return f"Pods look steady ({detail}); nothing looks stuck or unhealthy."
|
||||||
if key == "availability":
|
if key == "availability":
|
||||||
return cleaned + " That suggests the cluster is stable right now."
|
return cleaned + " That is the kind of stability I like to see."
|
||||||
if key in ("cpu", "ram"):
|
if key in ("cpu", "ram"):
|
||||||
suffix = (
|
suffix = (
|
||||||
" If you're chasing hotspots, that's the busiest workload right now."
|
" If you're chasing hotspots, that's the node I'd watch first."
|
||||||
if key == "cpu"
|
if key == "cpu"
|
||||||
else " That box is carrying the heaviest memory load right now."
|
else " That box is carrying the heaviest memory load right now."
|
||||||
)
|
)
|
||||||
@ -1799,19 +1812,19 @@ def _format_insight_text(key: str, text: str) -> str:
|
|||||||
def _insight_prefix(prompt: str) -> str:
|
def _insight_prefix(prompt: str) -> str:
|
||||||
q = normalize_query(prompt)
|
q = normalize_query(prompt)
|
||||||
if "coolest" in q:
|
if "coolest" in q:
|
||||||
return "If I had to pick the coolest detail: "
|
return "If I had to pick the coolest detail, I'd say "
|
||||||
if "favorite" in q or "favourite" in q:
|
if "favorite" in q or "favourite" in q:
|
||||||
return "My favorite detail: "
|
return "My favorite detail is "
|
||||||
if "trivia" in q:
|
if "trivia" in q:
|
||||||
return "A bit of trivia I like: "
|
return "A bit of trivia I like: "
|
||||||
if "most interesting" in q:
|
if "most interesting" in q:
|
||||||
return "The most interesting detail to me: "
|
return "The most interesting detail to me is "
|
||||||
if any(word in q for word in ("another", "else", "different", "other")):
|
if any(word in q for word in ("another", "else", "different", "other")):
|
||||||
return "Another interesting detail: "
|
return "Another interesting detail: "
|
||||||
if any(word in q for word in ("unconventional", "weird", "odd", "unique", "surprising")):
|
if any(word in q for word in ("unconventional", "weird", "odd", "unique", "surprising")):
|
||||||
return "What stands out is that "
|
return "What stands out to me is that "
|
||||||
if any(word in q for word in ("interesting", "notable", "fun", "cool")):
|
if any(word in q for word in ("interesting", "notable", "fun", "cool")):
|
||||||
return "One thing I'd highlight: "
|
return "One thing I'd call out is "
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@ -2389,6 +2402,21 @@ def _normalize_reply(value: Any) -> str:
|
|||||||
return _ensure_confidence(text)
|
return _ensure_confidence(text)
|
||||||
|
|
||||||
|
|
||||||
|
def _history_payload_lines(history_payload: list[Any]) -> list[str]:
|
||||||
|
lines: list[str] = []
|
||||||
|
if not isinstance(history_payload, list):
|
||||||
|
return lines
|
||||||
|
for item in history_payload[-12:]:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
for key in ("content", "message", "text", "prompt", "question", "body", "answer", "reply", "response"):
|
||||||
|
val = item.get(key)
|
||||||
|
if isinstance(val, str) and val.strip():
|
||||||
|
lines.append(val.strip())
|
||||||
|
elif isinstance(item, str) and item.strip():
|
||||||
|
lines.append(item.strip())
|
||||||
|
return [line for line in lines if line]
|
||||||
|
|
||||||
|
|
||||||
# Internal HTTP endpoint for cluster answers (website uses this).
|
# Internal HTTP endpoint for cluster answers (website uses this).
|
||||||
class _AtlasbotHandler(BaseHTTPRequestHandler):
|
class _AtlasbotHandler(BaseHTTPRequestHandler):
|
||||||
server_version = "AtlasbotHTTP/1.0"
|
server_version = "AtlasbotHTTP/1.0"
|
||||||
@ -2439,15 +2467,7 @@ class _AtlasbotHandler(BaseHTTPRequestHandler):
|
|||||||
inventory = _snapshot_inventory(snapshot) or node_inventory_live()
|
inventory = _snapshot_inventory(snapshot) or node_inventory_live()
|
||||||
workloads = _snapshot_workloads(snapshot)
|
workloads = _snapshot_workloads(snapshot)
|
||||||
history_payload = payload.get("history") or []
|
history_payload = payload.get("history") or []
|
||||||
history_lines: list[str] = []
|
history_lines = _history_payload_lines(history_payload)
|
||||||
if isinstance(history_payload, list):
|
|
||||||
for item in history_payload[-10:]:
|
|
||||||
if isinstance(item, dict):
|
|
||||||
content = item.get("content") or item.get("message") or ""
|
|
||||||
if isinstance(content, str) and content.strip():
|
|
||||||
history_lines.append(content.strip())
|
|
||||||
elif isinstance(item, str) and item.strip():
|
|
||||||
history_lines.append(item.strip())
|
|
||||||
history_cluster = _history_mentions_cluster(
|
history_cluster = _history_mentions_cluster(
|
||||||
history_lines,
|
history_lines,
|
||||||
inventory=inventory,
|
inventory=inventory,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user