diff --git a/services/comms/atlasbot-deployment.yaml b/services/comms/atlasbot-deployment.yaml index f4883c4..377a076 100644 --- a/services/comms/atlasbot-deployment.yaml +++ b/services/comms/atlasbot-deployment.yaml @@ -16,7 +16,7 @@ spec: labels: app: atlasbot annotations: - checksum/atlasbot-configmap: manual-atlasbot-30 + checksum/atlasbot-configmap: manual-atlasbot-31 vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/role: "comms" vault.hashicorp.com/agent-inject-secret-turn-secret: "kv/data/atlas/comms/turn-shared-secret" diff --git a/services/comms/scripts/atlasbot/bot.py b/services/comms/scripts/atlasbot/bot.py index a91744d..3f05529 100644 --- a/services/comms/scripts/atlasbot/bot.py +++ b/services/comms/scripts/atlasbot/bot.py @@ -723,24 +723,55 @@ def facts_context( "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) - if len(rendered) <= MAX_FACTS_CHARS: - return "Facts (live snapshot):\n" + rendered + rendered_parts = [] + 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.pop("workloads", None) rendered = json.dumps(trimmed, ensure_ascii=False) - if len(rendered) <= MAX_FACTS_CHARS: - return "Facts (live snapshot):\n" + rendered + combined = "\n\n".join(rendered_parts[:-1] + ["Facts (live snapshot JSON):\n" + rendered]) + if len(combined) <= MAX_FACTS_CHARS: + return combined trimmed_metrics = dict(trimmed.get("metrics") or {}) trimmed_metrics.pop("node_usage", None) trimmed["metrics"] = trimmed_metrics rendered = json.dumps(trimmed, ensure_ascii=False) - if len(rendered) <= MAX_FACTS_CHARS: - return "Facts (live snapshot):\n" + rendered + combined = "\n\n".join(rendered_parts[:-1] + ["Facts (live snapshot JSON):\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]: 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. " "Be helpful, direct, and concise. " "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. " "Prefer exact repo paths and Kubernetes resource names when relevant. " "Never include or request secret values. "