"""Claude Code and opencode usage, relayed from llm-cost-dashboard's API. Everything here is read-only. The dashboard stays the owner of the data and the pricing; deck-it only renders it. """ import json import urllib.request from ..module import Module ENDPOINTS = ("/api/claude_limits", "/api/claude_session", "/api/summary") def _fetch_for(base): def fetch(endpoint): with urllib.request.urlopen(base + endpoint, timeout=2) as r: return json.loads(r.read()) return fetch def make(cfg: dict) -> Module: base = cfg.get("llm", {}).get("url", "http://127.0.0.1:8420").rstrip("/") fetch = cfg.get("fetch") or _fetch_for(base) def state(): try: data = {ep: fetch(ep) for ep in ENDPOINTS} except (OSError, ValueError): return {"offline": True} limits = data["/api/claude_limits"] latest = limits[-1] if isinstance(limits, list) and limits else ( limits if isinstance(limits, dict) else {}) return { "offline": False, "claude": { "context_pct": latest.get("context_pct", data["/api/claude_session"].get("context_used")), "five_hour": latest.get("five_hour"), "seven_day": latest.get("seven_day"), "monthly_used": latest.get("extra_used_credits"), "monthly_limit": latest.get("extra_monthly_limit"), }, "opencode": data["/api/summary"], } return Module(name="llm", title="LLM usage", state=state)