atlasbot: answer jetson nodes from knowledge
This commit is contained in:
parent
2c3ffdbf95
commit
28570a1f5c
@ -1057,7 +1057,7 @@
|
||||
"node-role.kubernetes.io/worker": "true"
|
||||
},
|
||||
"images": [
|
||||
"registry.bstein.dev/bstein/ariadne:0.1.0-48"
|
||||
"registry.bstein.dev/bstein/ariadne:0.1.0-49"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -711,7 +711,7 @@ workloads:
|
||||
kubernetes.io/arch: arm64
|
||||
node-role.kubernetes.io/worker: 'true'
|
||||
images:
|
||||
- registry.bstein.dev/bstein/ariadne:0.1.0-48
|
||||
- registry.bstein.dev/bstein/ariadne:0.1.0-49
|
||||
- kind: Deployment
|
||||
namespace: maintenance
|
||||
name: maintenance-vault-sync
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -529,9 +529,14 @@ def main() -> int:
|
||||
diagram_path.write_text(diagram, encoding="utf-8")
|
||||
|
||||
# Render runbooks into JSON for lightweight, dependency-free consumption in-cluster.
|
||||
runbooks_dir = out_dir / "runbooks"
|
||||
runbook_dirs = [
|
||||
out_dir / "runbooks",
|
||||
out_dir / "software",
|
||||
]
|
||||
runbooks: list[dict[str, Any]] = []
|
||||
if runbooks_dir.exists():
|
||||
for runbooks_dir in runbook_dirs:
|
||||
if not runbooks_dir.exists():
|
||||
continue
|
||||
for md_file in sorted(runbooks_dir.glob("*.md")):
|
||||
raw = md_file.read_text(encoding="utf-8")
|
||||
fm: dict[str, Any] = {}
|
||||
|
||||
@ -1057,7 +1057,7 @@
|
||||
"node-role.kubernetes.io/worker": "true"
|
||||
},
|
||||
"images": [
|
||||
"registry.bstein.dev/bstein/ariadne:0.1.0-48"
|
||||
"registry.bstein.dev/bstein/ariadne:0.1.0-49"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -711,7 +711,7 @@ workloads:
|
||||
kubernetes.io/arch: arm64
|
||||
node-role.kubernetes.io/worker: 'true'
|
||||
images:
|
||||
- registry.bstein.dev/bstein/ariadne:0.1.0-48
|
||||
- registry.bstein.dev/bstein/ariadne:0.1.0-49
|
||||
- kind: Deployment
|
||||
namespace: maintenance
|
||||
name: maintenance-vault-sync
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -75,6 +75,8 @@ METRIC_HINT_WORDS = {
|
||||
}
|
||||
|
||||
CODE_FENCE_RE = re.compile(r"^```(?:json)?\\s*(.*?)\\s*```$", re.DOTALL)
|
||||
TITAN_NODE_RE = re.compile(r"\\btitan-[0-9a-z]{2}\\b", re.IGNORECASE)
|
||||
TITAN_RANGE_RE = re.compile(r"\\btitan-([0-9a-z]{2})/([0-9a-z]{2})\\b", re.IGNORECASE)
|
||||
|
||||
def _tokens(text: str) -> list[str]:
|
||||
toks = [t.lower() for t in TOKEN_RE.findall(text or "")]
|
||||
@ -233,6 +235,35 @@ def kb_retrieve(query: str, *, limit: int = 3) -> str:
|
||||
used += len(chunk)
|
||||
return "\n".join(parts).strip()
|
||||
|
||||
def _extract_titan_nodes(text: str) -> list[str]:
|
||||
names = {n.lower() for n in TITAN_NODE_RE.findall(text or "") if n}
|
||||
for match in TITAN_RANGE_RE.finditer(text or ""):
|
||||
left, right = match.groups()
|
||||
if left:
|
||||
names.add(f"titan-{left.lower()}")
|
||||
if right:
|
||||
names.add(f"titan-{right.lower()}")
|
||||
return sorted(names)
|
||||
|
||||
def jetson_nodes_from_kb() -> list[str]:
|
||||
for doc in KB.get("runbooks", []):
|
||||
if not isinstance(doc, dict):
|
||||
continue
|
||||
body = str(doc.get("body") or "")
|
||||
for line in body.splitlines():
|
||||
if "jetson" not in line.lower():
|
||||
continue
|
||||
names = _extract_titan_nodes(line)
|
||||
if names:
|
||||
return names
|
||||
return []
|
||||
|
||||
def jetson_nodes_summary(cluster_name: str) -> str:
|
||||
names = jetson_nodes_from_kb()
|
||||
if names:
|
||||
return f"{cluster_name} has {len(names)} Jetson nodes: {', '.join(names)}."
|
||||
return ""
|
||||
|
||||
def catalog_hints(query: str) -> tuple[str, list[tuple[str, str]]]:
|
||||
q = (query or "").strip()
|
||||
if not q or not KB.get("catalog"):
|
||||
@ -729,6 +760,14 @@ def sync_loop(token: str, room_id: str):
|
||||
continue
|
||||
send_msg(token, rid, summary)
|
||||
continue
|
||||
if "jetson" in lower_body:
|
||||
if any(word in lower_body for word in ("cluster", "atlas", "titan", "node", "nodes")):
|
||||
summary = jetson_nodes_summary("Atlas")
|
||||
if summary:
|
||||
send_msg(token, rid, summary)
|
||||
else:
|
||||
send_msg(token, rid, "Jetson inventory is not available in the knowledge base yet.")
|
||||
continue
|
||||
if re.search(r"\bnode names?\b|\bnodes? named\b|\bnaming\b", lower_body):
|
||||
if any(word in lower_body for word in ("cluster", "atlas", "titan")):
|
||||
names_summary = nodes_names_summary("Atlas")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user