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:
parent
b0d92ccbd8
commit
8a735ddcb3
4 changed files with 303 additions and 9 deletions
|
|
@ -361,14 +361,24 @@ here; that's already covered by Claude's own export.
|
|||
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
| Metric | Unit | Kind | Attributes |
|
||||
| -------------------------------------- | ---- | --------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| `hyperhive.agent.turn.duration` | `ms` | histogram | `wake_from`, `result_kind`, `model` |
|
||||
| `hyperhive.agent.turn.count` | — | counter | `wake_from`, `result_kind`, `model` |
|
||||
| `hyperhive.agent.session.count` | — | counter | `model` (incremented once per fresh, non-`--continue`'d session) |
|
||||
| `hyperhive.agent.loose_ends.threads` | — | gauge | none |
|
||||
| `hyperhive.agent.loose_ends.reminders` | — | gauge | none |
|
||||
| `hyperhive.agent.claude_md.lines` | — | gauge | none — recorded from the `CLAUDE.md`-size watch's own ~15-minute tick, **not** per turn like the rows above |
|
||||
| Metric | Unit | Kind | Attributes |
|
||||
| ---------------------------------------- | ---- | --------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| `hyperhive.agent.turn.duration` | `ms` | histogram | `wake_from`, `result_kind`, `model` |
|
||||
| `hyperhive.agent.turn.count` | — | counter | `wake_from`, `result_kind`, `model` |
|
||||
| `hyperhive.agent.session.count` | — | counter | `model` (incremented once per fresh, non-`--continue`'d session) |
|
||||
| `hyperhive.agent.loose_ends.threads` | — | gauge | none |
|
||||
| `hyperhive.agent.loose_ends.reminders` | — | gauge | none |
|
||||
| `hyperhive.agent.claude_md.lines` | — | gauge | none — recorded from the `CLAUDE.md`-size watch's own ~15-minute tick, **not** per turn like the rows above |
|
||||
| `hyperhive.agent.claude_usage.percent` | `%` | gauge | `window` (`five_hour`, `seven_day`, … as the usage endpoint names them) — polled every 5 minutes, **not** per turn |
|
||||
| `hyperhive.agent.claude_usage.resets_at` | `s` | gauge | `window` — unix seconds at which that window resets; same 5-minute poll |
|
||||
|
||||
For the two `claude_usage` gauges the harness polls the Claude subscription
|
||||
usage endpoint (`GET /api/oauth/usage`, the one behind claude's own `/usage`)
|
||||
with the OAuth access token from the agent's own
|
||||
`~/.claude/.credentials.json`. The harness only reads that token and never
|
||||
refreshes it — claude owns refresh-token rotation. An agent with no OAuth
|
||||
session (API-key backends, not yet logged in) or an expired token skips the
|
||||
poll, so a gauge keeps its last value until the next successful poll.
|
||||
|
||||
Resource attributes (`service.name`, `agent`, `hive`, `swarm`) come from the
|
||||
same container-wide `OTEL_RESOURCE_ATTRIBUTES` as everything else in this
|
||||
|
|
|
|||
Loading…
Reference in a new issue