agent-usage-manager 0.2.5__tar.gz → 0.2.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agent_usage_manager-0.2.5/README.md → agent_usage_manager-0.2.6/PKG-INFO +53 -3
- agent_usage_manager-0.2.5/PKG-INFO → agent_usage_manager-0.2.6/README.md +18 -22
- agent_usage_manager-0.2.5/agent_usage_manager/agents.yaml → agent_usage_manager-0.2.6/agent_usage_manager/agents.default.yaml +38 -50
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/agent_usage_manager/app.py +16 -6
- agent_usage_manager-0.2.6/pyproject.toml +55 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/tests/test_design_docs.py +5 -6
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/uv.lock +1 -1
- agent_usage_manager-0.2.5/pyproject.toml +0 -31
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/.github/workflows/ci.yml +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/.github/workflows/publish.yml +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/.gitignore +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/AGENTS.md +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/CLAUDE.md +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/LICENSE +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/agent_usage_manager/__init__.py +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/agent_usage_manager/cli.py +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/agent_usage_manager/static/index.html +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/demo.tape +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/docs/dashboard-live.gif +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/docs/dashboard-live.png +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/docs/dashboard.png +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/docs/demo.gif +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/docs/design/HLD.md +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/docs/design/LLD.md +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/requirements.txt +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/run.sh +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/tests/test_smoke.py +0 -0
- {agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/tests/test_synthetic.py +0 -0
|
@@ -1,17 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: agent-usage-manager
|
|
3
|
+
Version: 0.2.6
|
|
4
|
+
Summary: htop for AI agents — liveness, CPU/mem/GPU usage, and a kill switch for headless agents (openclaw, hermes, ollama, vllm, claude-code).
|
|
5
|
+
Project-URL: Homepage, https://github.com/minglong51/agent-usage-manager
|
|
6
|
+
Project-URL: Repository, https://github.com/minglong51/agent-usage-manager
|
|
7
|
+
Project-URL: Issues, https://github.com/minglong51/agent-usage-manager/issues
|
|
8
|
+
Project-URL: Newsletter, https://buttondown.com/minglong51
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai-agents,gpu,llm,monitoring,observability,ollama,vllm
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Web Environment
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
18
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: System :: Monitoring
|
|
25
|
+
Classifier: Topic :: System :: Systems Administration
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
|
+
Requires-Dist: fastapi>=0.110
|
|
28
|
+
Requires-Dist: psutil>=5.9
|
|
29
|
+
Requires-Dist: pyyaml>=6.0
|
|
30
|
+
Requires-Dist: uvicorn[standard]>=0.27
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
1
36
|
# agent-usage-manager
|
|
2
37
|
|
|
3
38
|
A small web dashboard for **headless AI agents** running on a machine —
|
|
4
39
|
OpenClaw, Hermes, Claude Code, Ollama, vLLM, llama.cpp, or anything you name. It
|
|
5
40
|
shows which agents are alive and what they're costing you (CPU, memory, GPU), and
|
|
6
41
|
gives you a **kill button** per agent. Think `htop`, scoped to just your agents —
|
|
7
|
-
the [screenshot below](docs/dashboard.png) is a real run on a fleet node.
|
|
42
|
+
the [screenshot below](https://raw.githubusercontent.com/minglong51/agent-usage-manager/main/docs/dashboard.png) is a real run on a fleet node.
|
|
8
43
|
|
|
9
44
|
No database, no auth framework (one static token file gates the kill switch),
|
|
10
45
|
four direct dependencies (FastAPI, uvicorn, psutil, PyYAML). Runs on macOS and Linux. It is a
|
|
11
46
|
per-node monitor and guarded local control panel: fleet schedulers may consume
|
|
12
47
|
its read-only telemetry, but should own their own scheduling and actuation.
|
|
13
48
|
|
|
14
|
-

|
|
49
|
+

|
|
15
50
|
|
|
16
51
|
*A real run: ten agents grouped by process tree (`+N` = children rolled up),
|
|
17
52
|
per-agent CPU/memory/uptime, launchd-supervised jobs flagged, and a kill button
|
|
@@ -39,7 +74,10 @@ uvx agent-usage-manager # then open http://127.0.0.1:8765 (opens automatica
|
|
|
39
74
|
One command — no install, no virtualenv, no leftovers. Other install options,
|
|
40
75
|
config, and flags: [Install & run](#install--run).
|
|
41
76
|
|
|
42
|
-

|
|
77
|
+

|
|
78
|
+
|
|
79
|
+
*Field notes on running agents with discipline go out on the
|
|
80
|
+
[Agent Discipline](https://buttondown.com/minglong51) list — a few emails a month.*
|
|
43
81
|
|
|
44
82
|
## What it does
|
|
45
83
|
|
|
@@ -179,6 +217,18 @@ This is the important part — a web page that can kill processes needs guardrai
|
|
|
179
217
|
actions. That is deliberate (owner-only tailnet + token-gated actions), but do
|
|
180
218
|
not read "loopback-only" as "not network-reachable" — a proxy in front is not
|
|
181
219
|
a trust boundary.
|
|
220
|
+
- **Fronting it with a proxy needs `AUM_TRUSTED_HOSTS`.** The DNS-rebinding guard
|
|
221
|
+
refuses any request whose `Host` is a non-local DNS name — which is exactly what
|
|
222
|
+
a proxy forwards. Opt that one name in explicitly:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
AUM_TRUSTED_HOSTS=box.your-tailnet.ts.net agent-usage-manager
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Comma-separated for several. Only add a name nobody else can mint a cert for on
|
|
229
|
+
this node; a name you don't control reopens the hole the guard exists to close.
|
|
230
|
+
Empty by default — out of the box only `localhost`, `127.0.0.1` and `::1` are
|
|
231
|
+
accepted.
|
|
182
232
|
|
|
183
233
|
## Limits & known issues
|
|
184
234
|
|
|
@@ -1,36 +1,17 @@
|
|
|
1
|
-
Metadata-Version: 2.5
|
|
2
|
-
Name: agent-usage-manager
|
|
3
|
-
Version: 0.2.5
|
|
4
|
-
Summary: htop for AI agents — liveness, CPU/mem/GPU usage, and a kill switch for headless agents (openclaw, hermes, ollama, vllm, claude-code).
|
|
5
|
-
Project-URL: Homepage, https://github.com/minglong51/agent-usage-manager
|
|
6
|
-
Project-URL: Repository, https://github.com/minglong51/agent-usage-manager
|
|
7
|
-
License: MIT
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Keywords: ai-agents,gpu,llm,monitoring,observability,ollama,vllm
|
|
10
|
-
Requires-Python: >=3.9
|
|
11
|
-
Requires-Dist: fastapi>=0.110
|
|
12
|
-
Requires-Dist: psutil>=5.9
|
|
13
|
-
Requires-Dist: pyyaml>=6.0
|
|
14
|
-
Requires-Dist: uvicorn[standard]>=0.27
|
|
15
|
-
Provides-Extra: dev
|
|
16
|
-
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
17
|
-
Requires-Dist: pytest>=7; extra == 'dev'
|
|
18
|
-
Description-Content-Type: text/markdown
|
|
19
|
-
|
|
20
1
|
# agent-usage-manager
|
|
21
2
|
|
|
22
3
|
A small web dashboard for **headless AI agents** running on a machine —
|
|
23
4
|
OpenClaw, Hermes, Claude Code, Ollama, vLLM, llama.cpp, or anything you name. It
|
|
24
5
|
shows which agents are alive and what they're costing you (CPU, memory, GPU), and
|
|
25
6
|
gives you a **kill button** per agent. Think `htop`, scoped to just your agents —
|
|
26
|
-
the [screenshot below](docs/dashboard.png) is a real run on a fleet node.
|
|
7
|
+
the [screenshot below](https://raw.githubusercontent.com/minglong51/agent-usage-manager/main/docs/dashboard.png) is a real run on a fleet node.
|
|
27
8
|
|
|
28
9
|
No database, no auth framework (one static token file gates the kill switch),
|
|
29
10
|
four direct dependencies (FastAPI, uvicorn, psutil, PyYAML). Runs on macOS and Linux. It is a
|
|
30
11
|
per-node monitor and guarded local control panel: fleet schedulers may consume
|
|
31
12
|
its read-only telemetry, but should own their own scheduling and actuation.
|
|
32
13
|
|
|
33
|
-

|
|
14
|
+

|
|
34
15
|
|
|
35
16
|
*A real run: ten agents grouped by process tree (`+N` = children rolled up),
|
|
36
17
|
per-agent CPU/memory/uptime, launchd-supervised jobs flagged, and a kill button
|
|
@@ -58,7 +39,10 @@ uvx agent-usage-manager # then open http://127.0.0.1:8765 (opens automatica
|
|
|
58
39
|
One command — no install, no virtualenv, no leftovers. Other install options,
|
|
59
40
|
config, and flags: [Install & run](#install--run).
|
|
60
41
|
|
|
61
|
-

|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
*Field notes on running agents with discipline go out on the
|
|
45
|
+
[Agent Discipline](https://buttondown.com/minglong51) list — a few emails a month.*
|
|
62
46
|
|
|
63
47
|
## What it does
|
|
64
48
|
|
|
@@ -198,6 +182,18 @@ This is the important part — a web page that can kill processes needs guardrai
|
|
|
198
182
|
actions. That is deliberate (owner-only tailnet + token-gated actions), but do
|
|
199
183
|
not read "loopback-only" as "not network-reachable" — a proxy in front is not
|
|
200
184
|
a trust boundary.
|
|
185
|
+
- **Fronting it with a proxy needs `AUM_TRUSTED_HOSTS`.** The DNS-rebinding guard
|
|
186
|
+
refuses any request whose `Host` is a non-local DNS name — which is exactly what
|
|
187
|
+
a proxy forwards. Opt that one name in explicitly:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
AUM_TRUSTED_HOSTS=box.your-tailnet.ts.net agent-usage-manager
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Comma-separated for several. Only add a name nobody else can mint a cert for on
|
|
194
|
+
this node; a name you don't control reopens the hole the guard exists to close.
|
|
195
|
+
Empty by default — out of the box only `localhost`, `127.0.0.1` and `::1` are
|
|
196
|
+
accepted.
|
|
201
197
|
|
|
202
198
|
## Limits & known issues
|
|
203
199
|
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# Default configuration shipped with the package. It is used only when you have
|
|
2
|
+
# no agents.yaml of your own: `--config` wins, then ./agents.yaml in the current
|
|
3
|
+
# directory, then this file. Copy it somewhere and edit rather than editing it
|
|
4
|
+
# in place — a package upgrade replaces this file.
|
|
5
|
+
#
|
|
1
6
|
# Which processes count as "agents". A process matches if the pattern hits its
|
|
2
7
|
# executable name + first few arguments (case-insensitive substring or regex) —
|
|
3
8
|
# NOT the entire command line, so a process that merely mentions an agent name
|
|
@@ -68,38 +73,35 @@ ignore:
|
|
|
68
73
|
|
|
69
74
|
# Optional: per-instance labels from launchd job labels — the supervised-fleet
|
|
70
75
|
# counterpart of tmux_labels below. Several LaunchAgents running the same
|
|
71
|
-
# binary
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
launchd_labels: "^
|
|
76
|
+
# binary all hit one agents: entry and land as indistinguishable rows, and tmux
|
|
77
|
+
# never sees them. When a matched root's own launchd job label matches this
|
|
78
|
+
# regex, the first capture group (the whole label if no group) becomes the row
|
|
79
|
+
# label — churn tracking, alert transitions, and /metrics all get per-instance
|
|
80
|
+
# identity. tmux_labels wins when both apply. Empty/absent = off.
|
|
81
|
+
#
|
|
82
|
+
# launchd_labels: "^com\\.example\\.worker-(.+)$" # → worker-1, worker-2
|
|
78
83
|
|
|
79
84
|
# Optional: per-instance labels from tmux session names. A fleet of identical
|
|
80
|
-
# agents (e.g. several claude-code bots, one per tmux session
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
|
|
85
|
+
# agents (e.g. several claude-code bots, one per tmux session) all hit one
|
|
86
|
+
# agents: entry above and land as N indistinguishable rows — their cmdlines
|
|
87
|
+
# can't tell them apart, because matching deliberately sees only the executable
|
|
88
|
+
# + first args. The tmux session each one runs in IS its identity: when a
|
|
89
|
+
# matched root (or an ancestor) is a tmux pane whose session name matches this
|
|
90
|
+
# regex, the row is labeled with the first capture group (the whole session
|
|
91
|
+
# name if there is no group). Sessions that don't match keep their agents:
|
|
92
|
+
# label, so incidental tmux use never renames rows.
|
|
93
|
+
#
|
|
94
|
+
# tmux_labels: "^bot-(.+)$" # session bot-worker1 → row label worker1
|
|
89
95
|
|
|
90
|
-
# Labels whose idle state is NORMAL — agents that wait for work (bots parked
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
# reasoning as `idle` being opt-in for alerts below. Case-insensitive
|
|
96
|
+
# Labels whose idle state is NORMAL — agents that wait for work (bots parked on
|
|
97
|
+
# a chat poll, gateways waiting for requests). They get no "idle" badge: badging
|
|
98
|
+
# the whole waiting fleet wallpapers the dashboard and trains badge-blindness.
|
|
99
|
+
# Same reasoning as `idle` being opt-in for alerts below. Case-insensitive
|
|
95
100
|
# substrings of the row label (incl. tmux-derived ones), like ignore:.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
# frontdoor, engineering_*) — suppression matches the BASE
|
|
101
|
-
# matcher label as well as the instance label
|
|
102
|
-
- codex
|
|
101
|
+
#
|
|
102
|
+
# idle_ok:
|
|
103
|
+
# - gateway
|
|
104
|
+
# - worker
|
|
103
105
|
|
|
104
106
|
# GPU sampling: nvidia-smi is used automatically when present (Linux/NVIDIA).
|
|
105
107
|
# On Apple Silicon there is no per-process GPU API, so the GPU column is blank.
|
|
@@ -113,29 +115,15 @@ idle_ok:
|
|
|
113
115
|
# fleet of agents that wait for work, idle is the NORMAL state, and alerting on
|
|
114
116
|
# it floods the channel every time the server restarts and re-learns the fleet.
|
|
115
117
|
#
|
|
116
|
-
#
|
|
118
|
+
# Nothing is wired by default — uncomment and point it at your own channel, then
|
|
119
|
+
# prove it with `agent-usage-manager test-alert` before a real badge depends on
|
|
120
|
+
# it. Two things worth knowing before you turn `hot` on: for inference agents
|
|
121
|
+
# pegged CPU IS the job, and spawn-heavy agents look like churn while working.
|
|
122
|
+
#
|
|
117
123
|
# alerts:
|
|
118
124
|
# command: 'terminal-notifier -title agent-usage-manager -message "$AUM_MSG"'
|
|
119
125
|
# cooldown: 600 # seconds, default 600
|
|
120
126
|
# flags: [hot, churn, leak] # default; add idle only if you really want it
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
#
|
|
124
|
-
# positives — "codex churn" during legitimate spawn work and "claude-code hot"
|
|
125
|
-
# during a working session; for inference agents, pegged-CPU IS the job.
|
|
126
|
-
# Badges stay live on the dashboard + machinery panel; the feed line rides the
|
|
127
|
-
# next digest. Genuine breakage has louder, independent signals (mcp-autoheal
|
|
128
|
-
# GAVE UP, cron-health, sync-bot liveness). `hot` dropped from alerting
|
|
129
|
-
# entirely.
|
|
130
|
-
# Ref discipline (2026-07-30): one stable ref per (agent, flag) + --upsert-open,
|
|
131
|
-
# so a repeat firing UPDATES the single open card in place instead of stacking
|
|
132
|
-
# one per cooldown expiry (nine churn cards in five days); the refreshed card
|
|
133
|
-
# carries the latest cpu/mem/pid snapshot. fyi level = feed-only, riding the
|
|
134
|
-
# digest exactly like the retired notify.py --feed-only wiring did.
|
|
135
|
-
alerts:
|
|
136
|
-
command: '"$HOME/workspace/founder-agent-os/bin/attention" add --level fyi --source usage-manager --title "$AUM_MSG" --body "$AUM_MSG" --ref "usage-manager:$AUM_LABEL:$AUM_FLAG" --upsert-open'
|
|
137
|
-
cooldown: 7200 # 2 h per (agent, flag)
|
|
138
|
-
flags: [churn, leak]
|
|
139
|
-
leak_floor_mb: 1536 # bots legitimately ratchet RSS as session
|
|
140
|
-
# context grows; only push leak alerts once
|
|
141
|
-
# the absolute footprint is actually large
|
|
127
|
+
# leak_floor_mb: 1536 # only alert on leak once the absolute footprint
|
|
128
|
+
# # is large — long-running agents legitimately
|
|
129
|
+
# # ratchet RSS as their context grows
|
|
@@ -41,7 +41,10 @@ def _resolve_config() -> Path:
|
|
|
41
41
|
cwd_cfg = Path.cwd() / "agents.yaml"
|
|
42
42
|
if cwd_cfg.exists():
|
|
43
43
|
return cwd_cfg
|
|
44
|
-
|
|
44
|
+
local = BASE / "agents.yaml"
|
|
45
|
+
if local.exists():
|
|
46
|
+
return local
|
|
47
|
+
return BASE / "agents.default.yaml"
|
|
45
48
|
|
|
46
49
|
|
|
47
50
|
CONFIG_PATH = _resolve_config()
|
|
@@ -688,11 +691,18 @@ async def _lifespan(_: FastAPI):
|
|
|
688
691
|
app = FastAPI(title="agent-usage-manager", lifespan=_lifespan)
|
|
689
692
|
|
|
690
693
|
|
|
691
|
-
# Loopback names are always local.
|
|
692
|
-
#
|
|
693
|
-
#
|
|
694
|
-
#
|
|
695
|
-
|
|
694
|
+
# Loopback names are always local. Anything else must be opted in per install via
|
|
695
|
+
# AUM_TRUSTED_HOSTS (comma-separated hostnames) — typically the FQDN of a reverse
|
|
696
|
+
# proxy or tailnet front door that preserves the Host header, e.g.
|
|
697
|
+
# `tailscale serve --https=8448` fronting this app. Only add a name that nobody
|
|
698
|
+
# else can mint a cert for on this node; any other name reopens the DNS-rebinding
|
|
699
|
+
# hole _host_allowed exists to close.
|
|
700
|
+
def _configured_trusted_hosts() -> set[str]:
|
|
701
|
+
raw = os.environ.get("AUM_TRUSTED_HOSTS", "")
|
|
702
|
+
return {h.strip().lower() for h in raw.split(",") if h.strip()}
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
_LOCAL_HOSTS = {"localhost", "127.0.0.1", "::1"} | _configured_trusted_hosts()
|
|
696
706
|
|
|
697
707
|
|
|
698
708
|
def _hostname_of(hostport: str) -> str:
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "agent-usage-manager"
|
|
7
|
+
version = "0.2.6"
|
|
8
|
+
description = "htop for AI agents — liveness, CPU/mem/GPU usage, and a kill switch for headless agents (openclaw, hermes, ollama, vllm, claude-code)."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
keywords = ["ai-agents", "monitoring", "gpu", "ollama", "vllm", "llm", "observability"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
"Environment :: Web Environment",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Intended Audience :: System Administrators",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: MacOS :: MacOS X",
|
|
20
|
+
"Operating System :: POSIX :: Linux",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: System :: Monitoring",
|
|
27
|
+
"Topic :: System :: Systems Administration",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"fastapi>=0.110",
|
|
31
|
+
"uvicorn[standard]>=0.27",
|
|
32
|
+
"psutil>=5.9",
|
|
33
|
+
"pyyaml>=6.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
dev = ["pytest>=7", "httpx>=0.27"]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/minglong51/agent-usage-manager"
|
|
41
|
+
Repository = "https://github.com/minglong51/agent-usage-manager"
|
|
42
|
+
Issues = "https://github.com/minglong51/agent-usage-manager/issues"
|
|
43
|
+
Newsletter = "https://buttondown.com/minglong51"
|
|
44
|
+
|
|
45
|
+
[project.scripts]
|
|
46
|
+
agent-usage-manager = "agent_usage_manager.cli:main"
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.wheel]
|
|
49
|
+
packages = ["agent_usage_manager"]
|
|
50
|
+
# agents.yaml is the maintainer's live config in a source checkout, not a
|
|
51
|
+
# shippable default — the wheel carries agents.default.yaml instead.
|
|
52
|
+
exclude = ["agent_usage_manager/agents.yaml"]
|
|
53
|
+
|
|
54
|
+
[tool.hatch.build.targets.sdist]
|
|
55
|
+
exclude = ["agent_usage_manager/agents.yaml"]
|
|
@@ -17,6 +17,9 @@ context only.
|
|
|
17
17
|
|
|
18
18
|
This file is shared verbatim across repos — it locates its own repo root, so it works
|
|
19
19
|
at any depth. Do not fork it per repo.
|
|
20
|
+
|
|
21
|
+
Canonical home: ~/dotfiles/design-doc-contract/test_design_docs.py — patch there, then
|
|
22
|
+
propagate with ~/dotfiles/local-bin/design-doc-checker-sync.
|
|
20
23
|
"""
|
|
21
24
|
|
|
22
25
|
import re
|
|
@@ -59,9 +62,7 @@ def contract_files() -> list[Path]:
|
|
|
59
62
|
|
|
60
63
|
def contract_path() -> Path:
|
|
61
64
|
"""The contract file carrying the map. Prefers AGENTS.md when both have it."""
|
|
62
|
-
candidates = [
|
|
63
|
-
p for p in contract_files() if FENCE.search(p.read_text(encoding="utf-8"))
|
|
64
|
-
]
|
|
65
|
+
candidates = [p for p in contract_files() if FENCE.search(p.read_text(encoding="utf-8"))]
|
|
65
66
|
if not candidates:
|
|
66
67
|
raise ValueError(
|
|
67
68
|
f"no ```design-doc-map fence in {[p.name for p in contract_files()]} at {REPO}"
|
|
@@ -160,9 +161,7 @@ def drift(doc: str, paths: list[str]) -> dict[str, object]:
|
|
|
160
161
|
return {"doc": doc, "untracked": True, "added": [], "removed": [], "commits": 0}
|
|
161
162
|
|
|
162
163
|
def modules(filt: str) -> list[str]:
|
|
163
|
-
out = git(
|
|
164
|
-
"diff", f"--diff-filter={filt}", "--name-only", f"{sha}..HEAD", "--", *paths
|
|
165
|
-
)
|
|
164
|
+
out = git("diff", f"--diff-filter={filt}", "--name-only", f"{sha}..HEAD", "--", *paths)
|
|
166
165
|
return [p for p in out.splitlines() if p and not IS_TEST.search(p)]
|
|
167
166
|
|
|
168
167
|
return {
|
|
@@ -8,7 +8,7 @@ resolution-markers = [
|
|
|
8
8
|
|
|
9
9
|
[[package]]
|
|
10
10
|
name = "agent-usage-manager"
|
|
11
|
-
version = "0.2.
|
|
11
|
+
version = "0.2.6"
|
|
12
12
|
source = { editable = "." }
|
|
13
13
|
dependencies = [
|
|
14
14
|
{ name = "fastapi", version = "0.128.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["hatchling"]
|
|
3
|
-
build-backend = "hatchling.build"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "agent-usage-manager"
|
|
7
|
-
version = "0.2.5"
|
|
8
|
-
description = "htop for AI agents — liveness, CPU/mem/GPU usage, and a kill switch for headless agents (openclaw, hermes, ollama, vllm, claude-code)."
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
license = { text = "MIT" }
|
|
11
|
-
requires-python = ">=3.9"
|
|
12
|
-
keywords = ["ai-agents", "monitoring", "gpu", "ollama", "vllm", "llm", "observability"]
|
|
13
|
-
dependencies = [
|
|
14
|
-
"fastapi>=0.110",
|
|
15
|
-
"uvicorn[standard]>=0.27",
|
|
16
|
-
"psutil>=5.9",
|
|
17
|
-
"pyyaml>=6.0",
|
|
18
|
-
]
|
|
19
|
-
|
|
20
|
-
[project.optional-dependencies]
|
|
21
|
-
dev = ["pytest>=7", "httpx>=0.27"]
|
|
22
|
-
|
|
23
|
-
[project.urls]
|
|
24
|
-
Homepage = "https://github.com/minglong51/agent-usage-manager"
|
|
25
|
-
Repository = "https://github.com/minglong51/agent-usage-manager"
|
|
26
|
-
|
|
27
|
-
[project.scripts]
|
|
28
|
-
agent-usage-manager = "agent_usage_manager.cli:main"
|
|
29
|
-
|
|
30
|
-
[tool.hatch.build.targets.wheel]
|
|
31
|
-
packages = ["agent_usage_manager"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agent_usage_manager-0.2.5 → agent_usage_manager-0.2.6}/agent_usage_manager/static/index.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|