Watch
0
0
Fork
You've already forked hyperhive
0

hive-agent: publish Claude subscription usage (5h/7d %) as metrics

A detached task polls GET https://api.anthropic.com/api/oauth/usage every
5 minutes with the OAuth access token from ~/.claude/.credentials.json and
records, per window the response names (five_hour, seven_day,
seven_day_sonnet, ...):

- hyperhive.agent.claude_usage.percent   (%, 0-100)
- hyperhive.agent.claude_usage.resets_at (s, unix seconds)

both labelled window=<name>. Endpoint, the anthropic-beta:
oauth-2025-04-20 header and the {utilization, resets_at} window shape are
taken from the claude-code 2.1.283 bundle's own /usage fetch.

The token is only read, never refreshed: claude owns refresh-token
rotation and a second refresher can log the agent out. An expired token
is skipped until claude's next turn refreshes it. API-key agents
(HIVE_USE_API_KEY, the ACP default) and agents with no credentials file
skip quietly, and the task does nothing when OTEL is not configured.
Request failures and non-2xx statuses warn with the status or transport
error only, never the body or the token.
This commit is contained in:
atlas 2026-09-30 20:26:09 +02:00 • committed by mara
commit 8a735ddcb3
4 changed files with 303 additions and 9 deletions

View file

@ -10,6 +10,7 @@
//! before lib + bin were collapsed into one) plus the serve loop.
mod claude_md_watch;
mod claude_usage_watch;
mod db_migrate;
mod disk_watch;
mod events;
@ -552,6 +553,7 @@ async fn serve_main<S: Surface>(socket: &Path, poll_ms: u64) -> Result<()> {
// bash-task files + verbose event rows). Runs here, not host-side in
// hive-c0re, because the files are agent-owned — see `vacuum` module docs.
tokio::spawn(crate::vacuum::run());
tokio::spawn(claude_usage_watch::run());
// Log web_ui::serve's error instead of dropping it. A bare
// `tokio::spawn(web_ui::serve(...))` discards the JoinHandle, so
// any Err (e.g. EACCES from `bind_unix` when HIVE_WEB_SOCKET points