1 line
4.0 KiB
JSON
1 line
4.0 KiB
JSON
{"repo": "carl0sfelipe/ai-usage-hub", "files": {"collectors/opencode_go.py": {"9391a5b8c6da99502fb60b48e13e3b0921c09f05": {"t": 1785846939.4375556, "n": 3685, "h": "96b38b2cb7aab005", "c": "from __future__ import annotations\n\nfrom datetime import datetime, timedelta\n\nimport httpx\n\nfrom collectors.base import LimitWindow, ProviderSnapshot\nfrom collectors.vault import get_vault_credential\n\n\nclass OpenCodeGoCollector:\n provider_id = \"opencode_go\"\n\n def __init__(self, config: dict):\n self._base_url = config.get(\"base_url\", \"https://api.opencode.ai/zen/go/v1\").rstrip(\"/\")\n\n @property\n def _api_key(self) -> str:\n return get_vault_credential(\"OPENCODE_GO_API_KEY\")\n\n async def fetch(self) -> ProviderSnapshot | None:\n key = self._api_key\n if not key:\n return ProviderSnapshot(\n provider_id=self.provider_id,\n plan_name=\"OpenCode Go\",\n status=\"error\",\n error=\"OPENCODE_GO_API_KEY not found in vault\",\n )\n try:\n async with httpx.AsyncClient(timeout=10) as client:\n resp = await client.get(\n f\"{self._base_url}/usage\",\n headers={\"Authorization\": f\"Bearer {key}\"},\n )\n resp.raise_for_status()\n try:\n data = resp.json()\n except Exception:\n return ProviderSnapshot(\n provider_id=self.provider_id,\n plan_name=\"OpenCode Go\",\n status=\"error\",\n error=f\"Non-JSON response (HTTP {resp.status_code}): {resp.text[:200]}\",\n )\n except Exception as e:\n return ProviderSnapshot(\n provider_id=self.provider_id,\n plan_name=\"OpenCode Go\",\n status=\"error\",\n error=str(e),\n )\n\n limits = []\n windows = [\n (\"rolling_5h\", \"five_hour\"),\n (\"weekly\", \"weekly\"),\n (\"monthly\", \"monthly\"),\n ]\n for window_type, key_name in windows:\n w = data.get(key_name) or data.get(window_type)\n if not w:\n continue\n used = float(w.get(\"used\", w.get(\"usage\", 0)))\n total = float(w.get(\"limit\", w.get(\"total\", 1)))\n remaining = max(0, total - used)\n pct = (used / total * 100) if total > 0 else 0\n reset_at = None\n if w.get(\"reset_at\"):\n try:\n reset_at = datetime.fromisoformat(w[\"reset_at\"].replace(\"Z\", \"+00:00\"))\n except (ValueError, TypeError):\n pass\n elif w.get(\"resets_in_seconds\"):\n reset_at = datetime.now() + timedelta(seconds=int(w[\"resets_in_seconds\"]))\n limits.append(LimitWindow(\n window_type=window_type,\n usage_value=used,\n limit_value=total,\n remaining_value=remaining,\n usage_percent=pct,\n reset_at=reset_at,\n unit=\"usd\",\n ))\n\n return ProviderSnapshot(\n provider_id=self.provider_id,\n plan_name=\"OpenCode Go ($10/mo)\",\n status=\"active\",\n limits=limits,\n spend_today_usd=data.get(\"today_usd\"),\n )\n\n async def health_check(self) -> bool:\n key = self._api_key\n if not key:\n return False\n try:\n async with httpx.AsyncClient(timeout=5) as client:\n resp = await client.get(\n f\"{self._base_url}/usage\",\n headers={\"Authorization\": f\"Bearer {key}\"},\n )\n return resp.status_code == 200\n except Exception:\n return False\n"}}}} |