diff options
Diffstat (limited to 'deckit')
| -rw-r--r-- | deckit/modules/llm.py | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/deckit/modules/llm.py b/deckit/modules/llm.py new file mode 100644 index 0000000..2e1cda4 --- /dev/null +++ b/deckit/modules/llm.py @@ -0,0 +1,46 @@ +"""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) |
