mngr usage subcommand: agent-agnostic rolling-window quota / usage CLI (provider plugins implement the data side via the current_usage_snapshot hook)
Project description
imbue-mngr-usage
mngr usage -- agent-agnostic CLI for rolling-window usage / quota data.
What it does
Provides a single mngr usage command that surfaces rolling-window usage data
in human / json / jsonl / format-template output. The command itself knows
nothing about any specific agent type or provider; it walks events files on
disk and renders whatever it finds.
Architecture
This package contains:
- The
mngr usageCLI command and its rendering helpers. - The
UsageSnapshot,WindowSnapshot, andCostSnapshotdata types.
Discovery is by path convention. The CLI walks
<host_dir>/agents/*/events/<source>/usage/events.jsonl (the same shape
mngr transcript uses for events/<source>/common_transcript/...), scans
every event line, and aggregates per <source>: rate-limit windows
collapse freshest-wins (the account-level counter), while cost is grouped
per session_id and filtered to a recency window (--since, default 24h).
The <source> segment is free-form -- whatever the writer plugin chose.
When multiple writers contribute, each renders as its own [source] section in
human output and as an entry in the JSON sources array.
Destroyed agents
A destroyed agent's usage still counts. Before an agent's (or its whole host's)
state directory is deleted, its events/<source>/usage directories are copied to
<local_host_dir>/preserved/<agent-name>--<agent-id>/; for remote agents the
files are pulled to the local machine so they survive host destruction. This is
on by default and
controlled by the preserve_on_destroy option on the usage plugin config (set
it to false to discard usage on destroy).
mngr usage reads these preserved files back by default, so a destroyed
agent's accumulated cost and rate-limit history still counts toward the totals.
Pass --no-preserved (on mngr usage and mngr usage wait) to consider only
live agents.
Output formats
mngr usage(human summary: per-mode cost line(s) + window lines)mngr usage --detail(human + per-session breakdown lines)mngr usage --format json(summary JSON: per-mode aggregatessubscription_costandapi_cost,session_countplus per-mode counts, windows)mngr usage --format json --detail(JSON withsessions[]per source; each session carries acost_modetag)mngr usage --format jsonlmngr usage --format '5h:{five_hour.used_percentage}%/{seven_day.used_percentage}%'
The --detail flag is independent of --verbose (which controls log
level). It toggles only the per-session breakdown surfaces.
Waiting on a predicate
mngr usage wait --until <CEL> blocks until at least one source's CEL
context satisfies every --until expression, then exits 0. Composable with
shell:
mngr usage wait --until 'five_hour.elapsed_percentage > 75 && five_hour.used_percentage < 50' \
&& mngr message my-agent "ok, kick off the next batch"
The CEL context per source mirrors one entry of mngr usage --format json's
sources array. Each window exposes the writer-emitted fields
(used_percentage, resets_at, window_seconds, label, ...) plus the
reader-derived seconds_until_reset, elapsed_seconds, and
elapsed_percentage (the last two require window_seconds from the
writer; absent on variable-duration windows like Claude's overage).
Source-level fields are exposed too. Cost is split by auth mode and
never lumped: subscription_cost.* aggregates sessions whose Claude
Code process was on a Claude.ai Pro/Max subscription (cost is imputed
by Claude Code -- the user actually pays a flat subscription), and
api_cost.* aggregates sessions whose process was on a direct
ANTHROPIC_API_KEY (cost is real billable spend). Pick the mode you
care about, e.g. api_cost.total_cost_usd > 20.0 means "I've spent more
than $20 of real API money across recent sessions". session_count is
the total across both modes; subscription_session_count and
api_session_count break that down per mode. since_seconds and
sessions[] (every session in the window, newest-first, each carrying
a cost_mode of "SUBSCRIPTION" or "API_KEY") are available as well.
Use --since to tighten or widen the aggregation window from its
default (24h). For a per-session predicate, index sessions[] directly
(e.g. sessions[0].cost.total_cost_usd > 5 for the most recent
session's own contribution).
Exit codes mirror mngr wait: 0 matched, 1 error, 2 timeout. Default poll
interval is 30s; use --interval for tighter cadence. To restrict matching
to a specific writer, use the top-level source field in CEL (e.g.
--until 'source == "claude" && five_hour.used_percentage < 50').
Polling from cron (check mode)
For recurring automation, let cron own the cadence: poll the plain
mngr usage --format json snapshot on a schedule and branch in the shell. See
cron automation recipes for worked examples: using up an
about-to-expire 5h window (with a weekly pace check), warming a fresh window the
moment the last one elapses, and working through a queue of task files a couple
at a time.
Implementing a writer plugin
A writer plugin is responsible for producing cost_snapshot events at the
conventional path. The minimal contract is just the JSONL line shape:
{"source":"<your-source>/usage","type":"cost_snapshot","event_id":"evt-<hex>","timestamp":"<ISO 8601>","session_id":"<uuid>","cost":{"total_cost_usd":<float>},"rate_limits":{"<window-key>":{"used_percentage":<float>,"resets_at":<unix-ts>}}}
Every event must carry a session_id (non-empty string) plus at least one
of rate_limits or cost. Events missing session_id are dropped with a
WARNING log naming the source and event_id -- so if you're writing a usage
plugin and don't see your data in mngr usage, check the log first. Any
plausible statusline source has a session identifier handy, so this is
rarely a constraint; if a future tool doesn't, synthesize a stable
per-session id on the writer side. The type field is informational --
the reader doesn't validate it -- but "cost_snapshot" is the current
convention.
Append one line per refresh to:
<agent_state_dir>/events/<your-source>/usage/events.jsonl
mngr usage will pick it up automatically -- no plugin registration with this
package required.
The writer chooses both the window keys and (optionally) per-window
labels. Keys are used by format templates ({<key>.used_percentage}) and
should be identifier-safe if you want format-template support; the per-window
label controls human display (e.g. "5h" vs the literal key "five_hour").
Render order is the writer's insertion order in the JSONL.
Writers may also include "window_seconds": <int> per window to declare a
fixed window duration. When present, mngr usage derives elapsed_seconds
and elapsed_percentage, which mngr usage wait CEL predicates can use to
express "75% of the window has elapsed" without callers hardcoding window
durations. Omit window_seconds for windows without a fixed length (e.g.
Claude's overage indicator).
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file imbue_mngr_usage-0.1.3.tar.gz.
File metadata
- Download URL: imbue_mngr_usage-0.1.3.tar.gz
- Upload date:
- Size: 76.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c84f8a8d7c480a4802cdbdedea3952f45c47e393af41b9ff50a3ff993cb261f5
|
|
| MD5 |
faa315969b2c2108d3b625660f03b6bf
|
|
| BLAKE2b-256 |
10836f02be58fedaa5ddc83abcfa77265c94009a7196ebd4904bd13256933617
|
Provenance
The following attestation bundles were made for imbue_mngr_usage-0.1.3.tar.gz:
Publisher:
publish.yml on imbue-ai/mngr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
imbue_mngr_usage-0.1.3.tar.gz -
Subject digest:
c84f8a8d7c480a4802cdbdedea3952f45c47e393af41b9ff50a3ff993cb261f5 - Sigstore transparency entry: 1822643084
- Sigstore integration time:
-
Permalink:
imbue-ai/mngr@23dc987ee408eb8d8b0c6aef0f5a44f8c8079276 -
Branch / Tag:
refs/tags/v0.2.14 - Owner: https://github.com/imbue-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23dc987ee408eb8d8b0c6aef0f5a44f8c8079276 -
Trigger Event:
push
-
Statement type:
File details
Details for the file imbue_mngr_usage-0.1.3-py3-none-any.whl.
File metadata
- Download URL: imbue_mngr_usage-0.1.3-py3-none-any.whl
- Upload date:
- Size: 48.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8a2a5a58048e2b19e4a81505598776b70695d629aa53e4fa656811463f2cabd
|
|
| MD5 |
15627daab3b5ae528d04454ffbddd14a
|
|
| BLAKE2b-256 |
f7930f7e679f96381877232dbf061d5d1af8217e1f95c4b48edb857ca3eebba9
|
Provenance
The following attestation bundles were made for imbue_mngr_usage-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on imbue-ai/mngr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
imbue_mngr_usage-0.1.3-py3-none-any.whl -
Subject digest:
f8a2a5a58048e2b19e4a81505598776b70695d629aa53e4fa656811463f2cabd - Sigstore transparency entry: 1822645853
- Sigstore integration time:
-
Permalink:
imbue-ai/mngr@23dc987ee408eb8d8b0c6aef0f5a44f8c8079276 -
Branch / Tag:
refs/tags/v0.2.14 - Owner: https://github.com/imbue-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23dc987ee408eb8d8b0c6aef0f5a44f8c8079276 -
Trigger Event:
push
-
Statement type: