"""Tiny RAG over 6 runbook snippets using a local embedding model (Ollama). Prints retrieval + grounded answer."""
import json, sys, math, time, urllib.request
OLL = 'http://localhost:11434'
def post(path, body):
    r = urllib.request.urlopen(urllib.request.Request(OLL + path, json.dumps(body).encode(), {'Content-Type': 'application/json'}), timeout=300)
    return json.loads(r.read())
DOCS = {
 'oomkilled.md': 'Pod OOMKilled / exit code 137: the container exceeded its memory limit. Check kubectl describe pod for Last State OOMKilled. Compare usage with kubectl top. Raise the limit or fix the leak. Do not just restart it.',
 'pending.md': 'Pod stuck Pending: the scheduler cannot place it. Read the FailedScheduling event. Usually insufficient cpu/memory requests, taints, or node selectors.',
 'disk-full.md': 'Disk full but du shows little: a deleted file is still held open. Find it with lsof +L1, truncate it via /proc/PID/fd, then fix log rotation.',
 'imagepull.md': 'ImagePullBackOff: check the image name and tag for typos, registry credentials and imagePullSecrets. Read the pod events first.',
 'dns.md': 'DNS issues in pods: check /etc/resolv.conf, search domains and ndots:5. Use fully qualified names for external hosts.',
 'rollback.md': 'Bad deploy: kubectl rollout undo deploy/NAME. Then verify service endpoints, because a rollback does not revert service selectors.',
}
q = sys.argv[1] if len(sys.argv) > 1 else 'my pod keeps dying with exit code 137, what should I do?'
emb = lambda t: post('/api/embeddings', {'model': 'nomic-embed-text', 'prompt': t})['embedding']
def cos(a, b): return sum(x * y for x, y in zip(a, b)) / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))
t0 = time.time(); E = {k: emb(v) for k, v in DOCS.items()}; qe = emb(q)
ranked = sorted(((cos(qe, v), k) for k, v in E.items()), reverse=True)
print('question: ' + q)
print('top matches:')
for s, k in ranked[:3]: print('  %.3f  %s' % (s, k))
ctx = DOCS[ranked[0][1]]
ans = post('/api/generate', {'model': 'qwen2.5:1.5b', 'stream': False, 'options': {'temperature': 0},
          'prompt': 'Answer in 3 short bullet points using ONLY this runbook:\n' + ctx + '\n\nQuestion: ' + q})['response']
print('answer (grounded in %s):' % ranked[0][1]); print(ans.strip())
print('took %.1fs' % (time.time() - t0))
