atlasbot: enrich facts summary for LLM

This commit is contained in:
Brad Stein 2026-01-27 06:34:37 -03:00
parent a2f4c51e1d
commit 446115f07a
2 changed files with 40 additions and 8 deletions

View File

@ -16,7 +16,7 @@ spec:
labels: labels:
app: atlasbot app: atlasbot
annotations: annotations:
checksum/atlasbot-configmap: manual-atlasbot-30 checksum/atlasbot-configmap: manual-atlasbot-31
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"

View File

@ -723,24 +723,55 @@ def facts_context(
"workloads": _workloads_for_facts(workloads or []), "workloads": _workloads_for_facts(workloads or []),
} }
summary_lines: list[str] = []
nodes_info = facts.get("nodes") if isinstance(facts.get("nodes"), dict) else {}
if nodes_info.get("total") is not None:
summary_lines.append(
f"nodes_total={nodes_info.get('total')}, ready={nodes_info.get('ready')}, not_ready={nodes_info.get('not_ready')}"
)
hottest = facts.get("metrics", {}).get("hottest_nodes") if isinstance(facts.get("metrics"), dict) else {}
if isinstance(hottest, dict) and hottest:
for key in ("cpu", "ram", "net", "io"):
entry = hottest.get(key) if isinstance(hottest.get(key), dict) else {}
node = entry.get("node")
value = entry.get("value")
if node and value is not None:
summary_lines.append(f"hottest_{key}={node} ({value})")
postgres = facts.get("metrics", {}).get("postgres_connections") if isinstance(facts.get("metrics"), dict) else {}
if isinstance(postgres, dict) and postgres:
used = postgres.get("used")
max_conn = postgres.get("max")
if used is not None and max_conn is not None:
summary_lines.append(f"postgres_used={used}, postgres_max={max_conn}")
hottest_db = postgres.get("hottest_db") if isinstance(postgres.get("hottest_db"), dict) else {}
if hottest_db.get("label"):
summary_lines.append(f"postgres_hottest_db={hottest_db.get('label')} ({hottest_db.get('value')})")
rendered = json.dumps(facts, ensure_ascii=False) rendered = json.dumps(facts, ensure_ascii=False)
if len(rendered) <= MAX_FACTS_CHARS: rendered_parts = []
return "Facts (live snapshot):\n" + rendered if summary_lines:
rendered_parts.append("Facts summary:\n" + "\n".join(f"- {line}" for line in summary_lines))
rendered_parts.append("Facts (live snapshot JSON):\n" + rendered)
combined = "\n\n".join(rendered_parts)
if len(combined) <= MAX_FACTS_CHARS:
return combined
trimmed = dict(facts) trimmed = dict(facts)
trimmed.pop("workloads", None) trimmed.pop("workloads", None)
rendered = json.dumps(trimmed, ensure_ascii=False) rendered = json.dumps(trimmed, ensure_ascii=False)
if len(rendered) <= MAX_FACTS_CHARS: combined = "\n\n".join(rendered_parts[:-1] + ["Facts (live snapshot JSON):\n" + rendered])
return "Facts (live snapshot):\n" + rendered if len(combined) <= MAX_FACTS_CHARS:
return combined
trimmed_metrics = dict(trimmed.get("metrics") or {}) trimmed_metrics = dict(trimmed.get("metrics") or {})
trimmed_metrics.pop("node_usage", None) trimmed_metrics.pop("node_usage", None)
trimmed["metrics"] = trimmed_metrics trimmed["metrics"] = trimmed_metrics
rendered = json.dumps(trimmed, ensure_ascii=False) rendered = json.dumps(trimmed, ensure_ascii=False)
if len(rendered) <= MAX_FACTS_CHARS: combined = "\n\n".join(rendered_parts[:-1] + ["Facts (live snapshot JSON):\n" + rendered])
return "Facts (live snapshot):\n" + rendered if len(combined) <= MAX_FACTS_CHARS:
return combined
return "Facts (live snapshot):\n" + rendered[:MAX_FACTS_CHARS] return combined[:MAX_FACTS_CHARS]
def _inventory_sets(inventory: list[dict[str, Any]]) -> dict[str, Any]: def _inventory_sets(inventory: list[dict[str, Any]]) -> dict[str, Any]:
names = [node["name"] for node in inventory] names = [node["name"] for node in inventory]
@ -1724,6 +1755,7 @@ def _ollama_call(hist_key, prompt: str, *, context: str) -> str:
"System: You are Atlas, the Titan lab assistant for Atlas/Othrys. " "System: You are Atlas, the Titan lab assistant for Atlas/Othrys. "
"Be helpful, direct, and concise. " "Be helpful, direct, and concise. "
"Use the provided context and facts as your source of truth. " "Use the provided context and facts as your source of truth. "
"Treat 'hottest' as highest utilization (CPU/RAM/NET/IO) rather than temperature. "
"If you infer or synthesize, say 'Based on the snapshot' and keep it brief. " "If you infer or synthesize, say 'Based on the snapshot' and keep it brief. "
"Prefer exact repo paths and Kubernetes resource names when relevant. " "Prefer exact repo paths and Kubernetes resource names when relevant. "
"Never include or request secret values. " "Never include or request secret values. "