Analyse token usage and estimated costs across all registered OpenClaw agents. Dynamically discovers agents, groups sessions by channel category, flags anomalies, and presents a per-agent breakdown with combined totals.
List the contents of ~/.openclaw/agents/. Each subdirectory is an agent.
For each agent directory, attempt to read sessions/sessions.json. If the file does not exist, is empty, or is not valid JSON, skip that agent and note it as "(no session data)" in the output.
Each sessions.json is a JSON object. The keys are session key strings with the format:
text
agent:<agentId>:<channel>:<subtype>[:<identifier>]
For each session entry, extract these fields (all may be absent):
FieldTypeDescriptiontotalTokensintegerTotal tokens consumed in this sessioninputTokensintegerInput/prompt tokensoutputTokensintegerOutput/completion tokensestimatedCostUsdfloatEstimated cost in USDmodelstringModel identifier (e.g. provider/model-name)updatedAtintegerLast update timestamp in epoch milliseconds
The category is the third segment of the session key (index 2 when splitting on :).
Examples:
agent:alice:discord:channel:123456789 -> category = discordagent:alice:telegram:direct:987654321 -> category = telegramagent:bob:cron:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -> category = cronagent:alice:main -> category = mainThe user specifies a time window. If not specified, default to "this week".
WindowBehaviour"this week"Include sessions where updatedAt is within the last 7 days"all time"No filter; include all sessions"last N days"Include sessions where updatedAt is within the last N days
If updatedAt is absent or 0, include the session only when the window is "all time". For all other windows, exclude it.
Convert updatedAt from epoch milliseconds to a date for comparison.
For each agent, group the filtered sessions by category. Within each group, compute:
totalTokens (skip entries where the field is absent)inputTokens (skip entries where the field is absent)outputTokens (skip entries where the field is absent)estimatedCostUsd (skip entries where the field is absent)model values (skip entries where the field is absent)Apply two flags to each category group:
SINKHOLE: totalTokens > 10,000 AND ( estimatedCostUsd is absent across all entries in the group, or the summed cost is less than $0.01).
This indicates high token volume on free or untracked models and may signal wasted computation.
EXPENSIVE: summed estimatedCostUsd > $5.00.
This indicates a high-spend category. Review whether the spend is justified.
A single category can have both flags (high tokens on a mix of free and paid models).
For each agent that has session data, print a heading with the agent name and total session count, then a table with one row per category:
text
## alice (120 sessions)
| Category | Sessions | Tokens | Input | Output | Est. Cost | Models | Flags |
|----------|----------|--------|-------|--------|-----------|--------|-------|
| discord | 80 | 1.2M | 800K | 400K | $42.50 | model-a | EXPENSIVE |
| telegram | 25 | 120K | 80K | 40K | $3.20 | model-a | |
| cron | 10 | 95K | 60K | 35K | $0.00 | model-b | SINKHOLE |
| main | 5 | 20K | 15K | 5K | $0.32 | model-a | |
Sort rows by estimated cost descending within each agent.
For agents skipped in Step 1, print: ## <agent> (no session data)
After all agent sections, print:
text
## Combined Totals
- **Total sessions**: <count>
- **Total tokens**: <sum> (input: <sum>, output: <sum>)
- **Total estimated cost**: $<sum>
### Top 3 by cost
1. <agent>/<category>: $<cost> (<tokens> tokens)
2. ...
3. ...
### Top 3 by token volume
1. <agent>/<category>: <tokens> tokens ($<cost>)
2. ...
3. ...
1.2M, 45K, 320)$- not 0Append exactly one JSON line to:
~/.openclaw/workspace/memory/token-usage-history.ndjson
Create the file if it does not exist. Never modify existing lines.
This step always runs. It does not require explicit user request.
The line is a compact JSON object (no newlines within the record):
json
{"date":"YYYY-MM-DD","window":"<time window>","runAt":<epoch ms>,"agents":[...],"combined":{...}}
FieldTypeDescriptiondatestringUTC date of this run ( YYYY-MM-DD)windowstringTime window used (e.g. "last 1 day", "this week")runAtintegerEpoch milliseconds when the skill ranagentsarrayOne entry per agent that has session datacombinedobjectAggregated totals across all agents
Each agent entry:
json
{
"id": "<agentId>",
"categories": [
{
"category": "<category>",
"sessions": 80,
"totalTokens": 1200000,
"inputTokens": 800000,
"outputTokens": 400000,
"estimatedCostUsd": 42.50,
"models": ["model-a"],
"flags": ["EXPENSIVE"]
}
],
"totals": {
"sessions": 120,
"totalTokens": 1435000,
"inputTokens": 955000,
"outputTokens": 480000,
"estimatedCostUsd": 46.02
}
}
The combined object mirrors the totals shape without an id field.
Use null for any numeric field where all entries in the group had the field absent. Use [] for flags when no flags apply. Agents with no session data are omitted from the record entirely.
Only if the user explicitly requests logging, append a timestamped summary to:
~/.openclaw/workspace/memory/token-diet-log.md
Create the file if it does not exist.
Append in this format:
markdown
## YYYY-MM-DD -- Token Usage Report (window: <time window>)
- Total: <tokens> tokens, $<cost> estimated
- <agent>: <tokens> tokens, $<cost> (<flags if any>)
- ...
- Anomalies: <comma-separated list of flagged agent/category pairs with flag name>
Do not write to this file unless the user explicitly asks.
AccessPathRequiredRead~/.openclaw/agents/*/sessions/sessions.jsonAlwaysWrite~/.openclaw/workspace/memory/token-usage-history.ndjsonAlwaysWrite~/.openclaw/workspace/memory/token-diet-log.mdOnly when user requests logging
No environment variables. No network access. No credentials.