fix: emit 0-1 limit fractions and refresh the agents panel

Omarchy's panel treats percent as a fraction (1.0 = 100%). Vendor
creditUsagePercent is 0-100, so 1.0 was rendering as a full bar.
After writing grok.json, ping omarchy.agents refresh so the widget
rescans without a shell restart.
This commit is contained in:
Ebeneezer 2026-08-20 15:39:06 -07:00
parent 4df21f20a0
commit 88073c4bea
3 changed files with 45 additions and 6 deletions

View file

@ -18,6 +18,7 @@ import datetime as dt
import json
import os
import re
import subprocess
import sys
import tempfile
import urllib.error
@ -89,6 +90,19 @@ def _iso_reset(value: Any) -> str | None:
return parsed.isoformat()
def _fraction_used(raw: float) -> float:
"""Map a vendor percent into the panel's 0..1 fraction.
Same rule as Omarchy's Claude collector: any value >= 1 is a 0-100
percentage, so 1.0 is 1% not 100%.
"""
if raw < 0:
return 0.0
if raw >= 1:
return min(1.0, raw / 100.0)
return min(1.0, raw)
def limits_from_billing(payload: Mapping[str, Any]) -> list[dict[str, Any]]:
config = payload.get("config") if isinstance(payload.get("config"), dict) else payload
if not isinstance(config, dict):
@ -102,7 +116,7 @@ def limits_from_billing(payload: Mapping[str, Any]) -> list[dict[str, Any]]:
percent = (used / limit) * 100.0
if percent is None:
return []
percent = max(0.0, min(100.0, percent))
fraction = _fraction_used(percent)
period = config.get("currentPeriod")
end = None
@ -114,7 +128,8 @@ def limits_from_billing(payload: Mapping[str, Any]) -> list[dict[str, Any]]:
return [
{
"label": "Weekly",
"percent": percent,
"title": "Weekly",
"percent": fraction,
"resetsAt": _iso_reset(end),
}
]
@ -375,6 +390,23 @@ def default_usage_dir(env: Mapping[str, str], home: Path) -> Path:
return root / "omarchy" / "agents" / "usage"
def notify_panel() -> None:
"""Ask the live Omarchy agents widget to rescan usage files."""
env = os.environ.copy()
env.setdefault("OMARCHY_PATH", "/usr/share/omarchy")
try:
subprocess.run(
["omarchy-shell", "-q", "omarchy.agents", "refresh"],
env=env,
timeout=8,
check=False,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except (OSError, subprocess.SubprocessError):
return
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(
description="Collect SuperGrok weekly usage for the Omarchy agents panel."
@ -402,6 +434,7 @@ def main(argv: list[str] | None = None) -> int:
)
if result.path is not None:
print(f"wrote {result.path}", file=sys.stderr)
notify_panel()
return 0
json.dump(record, sys.stdout, separators=(",", ":"), sort_keys=True)
sys.stdout.write("\n")

View file

@ -5,6 +5,7 @@ Wants=network-online.target
[Service]
Type=oneshot
Environment=OMARCHY_PATH=/usr/share/omarchy
ExecStart=%h/.local/bin/omarchy-grok-usage --write
Nice=10

View file

@ -67,7 +67,7 @@ class TestBillingMap(unittest.TestCase):
limits = m.limits_from_billing(payload)
self.assertEqual(len(limits), 1)
self.assertEqual(limits[0]["label"], "Weekly")
self.assertEqual(limits[0]["percent"], 31.5)
self.assertEqual(limits[0]["percent"], 0.315)
self.assertEqual(limits[0]["resetsAt"], "2026-08-27T00:00:00+00:00")
def test_falls_back_to_used_over_limit(self) -> None:
@ -79,7 +79,7 @@ class TestBillingMap(unittest.TestCase):
}
}
limits = m.limits_from_billing(payload)
self.assertEqual(limits[0]["percent"], 40.0)
self.assertEqual(limits[0]["percent"], 0.4)
self.assertEqual(limits[0]["resetsAt"], "2026-09-01T00:00:00+00:00")
def test_empty_billing_yields_no_limits(self) -> None:
@ -88,7 +88,12 @@ class TestBillingMap(unittest.TestCase):
def test_percent_clamped_to_100(self) -> None:
payload = {"config": {"creditUsagePercent": 140}}
limits = m.limits_from_billing(payload)
self.assertEqual(limits[0]["percent"], 100.0)
self.assertEqual(limits[0]["percent"], 1.0)
def test_one_point_zero_is_one_percent_not_full(self) -> None:
payload = {"config": {"creditUsagePercent": 1.0}}
limits = m.limits_from_billing(payload)
self.assertEqual(limits[0]["percent"], 0.01)
class TestTierLabel(unittest.TestCase):
@ -260,7 +265,7 @@ class TestCollect(unittest.TestCase):
)
blob = json.dumps(record)
self.assertNotIn(FAKE_TOKEN, blob)
self.assertEqual(record["limits"][0]["percent"], 12)
self.assertEqual(record["limits"][0]["percent"], 0.12)
self.assertEqual(record["tierLabel"], "SuperGrok")
self.assertTrue(record["ready"])