htop for AI agents — liveness, CPU/mem/GPU usage, and a kill switch for headless agents (openclaw, hermes, ollama, vllm, claude-code).
Project description
agent-usage-manager
A tiny, single-file web dashboard for headless AI agents running on a machine — OpenClaw, Hermes, Claude Code, Ollama, vLLM, llama.cpp, or anything you name. It shows which agents are alive and what they're costing you (CPU, memory, GPU), and gives you a kill button per agent.
No database, no auth layer, no dependencies beyond FastAPI + psutil. Runs on macOS and Linux. Meant to be cloned, configured, and run on any node in a fleet.
AGENT PID STATUS CPU % MEM MB GPU MB UPTIME COMMAND ┆
openclaw +3 48213 ● running 62.4 1840 7320 2h 11m openclaw serve … [kill] [force]
claude-code +9 73590 ● running 97.4 7630 — 1h 02m claude --chann … [kill] [force]
hermes 49001 ● running 18.0 512 — 44m hermes worker … [kill] [force]
ollama 50122 ● running 3.1 9210 14080 6h 02m ollama runner … [kill] [force]
(+N = child processes rolled up under the agent; CPU/mem/GPU are tree totals.)
A live web UI (auto-refreshing every 3s). The rendered GIF lands here once recorded — see
demo.tape.
What it does
- One row per agent. Agents are grouped by process tree — the spawned children
of an agent (inference subprocesses, MCP servers, helpers) are rolled up under it
with a
+Nbadge instead of cluttering the list as separate rows. - Liveness — green dot = running, red = zombie/dead. Status column shows the OS state.
- Usage — CPU %, resident memory (MB), GPU memory (MB, NVIDIA only), and uptime, refreshed every 3s. CPU/mem/GPU are tree totals — the agent's true cost including everything it spawned.
- Kill the tree —
killsends SIGTERM to the agent and its children (so spawned helpers don't leak resources),forcesends SIGKILL. SIGTERM auto-escalates to SIGKILL after 3s. The confirm dialog tells you how many child processes will stop.
Safety
This is the important part — a web page that can kill processes needs guardrails:
- Allowlist only. Only processes matching a pattern in
agents.yamlare ever listed or killable. The kill endpoint re-checks the match server-side before sending any signal, so the dashboard can never be used to kill an arbitrary PID. - Protected patterns. Anything matching
protect:inagents.yaml— plus the monitor's own process and PID 1 — shows a disabled, greyed-out kill button and is refused server-side. - Secret redaction. Command lines often carry tokens/keys in env vars or flags
(
FOO_TOKEN=...,--api-key ...,sk-...,ghp_..., JWTs). The command column redacts these to***before they ever reach the browser — safe to screenshot. - Bind local by default. It listens on
127.0.0.1. Don't expose it to a network without putting auth in front of it (reverse proxy + basic auth, SSH tunnel, etc.) — it has no built-in authentication.
Quick start
Run it without installing anything (needs uv):
uvx agent-usage-manager
# open http://127.0.0.1:8765
Or install it:
pipx install agent-usage-manager # or: pip install agent-usage-manager
agent-usage-manager --port 8765
From a clone (for hacking on it):
git clone <this-repo> && cd agent-usage-manager
./run.sh # venv + editable install, serves on :8765
It opens the dashboard in your browser automatically. Flags: --host, --port,
--config /path/to/agents.yaml, --no-browser (for headless/server use).
Configure which processes are "agents"
Edit agents.yaml:
agents:
- label: openclaw # shown as the badge in the UI
match: openclaw # case-insensitive substring of the command line
- label: hermes
match: hermes
- label: claude-code
match: "claude(\\s|$|-code)"
regex: true # treat `match` as a regex instead of substring
protect: # never killable, even if matched above
- uvicorn
A process matches if the pattern hits its full command line or its process name.
Point at a different file with AGENTS_CONFIG=/path/to/agents.yaml.
GPU notes
Per-process GPU memory comes from nvidia-smi when it's on PATH (Linux / NVIDIA).
Apple Silicon has no per-process GPU accounting API, so the GPU column stays blank
on Macs — CPU and memory are the meaningful resource signals there.
API
GET /api/agents→{ agents: [...], host, cpu_count, ts }POST /api/kill/{pid}?force=false→ SIGTERM (or SIGKILL withforce=true)
Run as a service
Linux (systemd), ~/.config/systemd/user/agent-usage-manager.service:
[Unit]
Description=agent usage manager
[Service]
ExecStart=%h/agent-usage-manager/.venv/bin/uvicorn app:app --port 8765
WorkingDirectory=%h/agent-usage-manager
Restart=on-failure
[Install]
WantedBy=default.target
systemctl --user enable --now agent-usage-manager
Development
git clone https://github.com/minglong51/agent-usage-manager && cd agent-usage-manager
pip install -e ".[dev]"
pytest -q
CI runs the test suite on Linux + macOS (Python 3.9 and 3.12) on every push and PR.
Cross-platform note: kill uses psutil's terminate()/kill(), which map to
SIGTERM/SIGKILL on POSIX and TerminateProcess on Windows.
License
MIT
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 agent_usage_manager-0.1.2.tar.gz.
File metadata
- Download URL: agent_usage_manager-0.1.2.tar.gz
- Upload date:
- Size: 13.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d199b0dfb3af607c403d0aa29fb7d65bdf5a6c6fe8fce9ebd09762e50798247
|
|
| MD5 |
849e4e4083f9f7903bd7bbdc237ca762
|
|
| BLAKE2b-256 |
f823cc7ef298e8c36f0bfe2d79c9b5c98bbf2af24d4314f60f074f11ac46afab
|
File details
Details for the file agent_usage_manager-0.1.2-py3-none-any.whl.
File metadata
- Download URL: agent_usage_manager-0.1.2-py3-none-any.whl
- Upload date:
- Size: 13.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f774a79c3a72cb26980bc49d6d3d931073c35e1be871bfcd992a6013a462a97d
|
|
| MD5 |
6d42c7490d37faeffb1f6ff9fd8dae8f
|
|
| BLAKE2b-256 |
7d2ca407477c1bb423598a19a90302f6ac6bc19add28022cf8a82d3583eb48a0
|