Bug
CostClaw significantly undercounts token usage and costs when OpenClaw has prompt caching enabled (cacheRetention: "short" or similar). In my setup with ~92% cache hit rates, the dashboard was showing a fraction of actual usage.
Root Cause
The llm_output hook in src/index.ts only captures event.usage.input and event.usage.output:
const inputTokens = event.usage.input ?? 0;
const outputTokens = event.usage.output ?? 0;
event.usage.input contains only the non-cached input tokens. With prompt caching, the bulk of input tokens come via cacheRead and cacheCreation fields, which are ignored entirely. In practice this meant input token counts of 3–6 per call instead of thousands.
Additionally, computeCost() in src/pricing/calculator.ts has no cache pricing logic. Anthropic charges different rates for cached tokens:
- Cache reads: 0.1x input price (90% discount)
- Cache creation: 1.25x input price (25% surcharge)
Impact
On a system with 92% cache hit rates:
- CostClaw reported ~$0.85 total cost
- Actual cost was significantly higher
- Token counts were off by orders of magnitude on the input side
Fix
I've applied the following changes locally and confirmed they work:
1. src/index.ts — capture cache tokens from the event (with fallbacks for multiple field naming conventions):
const cacheReadTokens =
event.usage.cacheRead ??
event.usage.cache_read ??
event.usage.cache_read_input_tokens ??
event.usage.cacheReadInputTokens ?? 0;
const cacheCreationTokens =
event.usage.cacheCreation ??
event.usage.cache_creation ??
event.usage.cache_creation_input_tokens ??
event.usage.cacheCreationInputTokens ?? 0;
2. src/pricing/calculator.ts — add cache-aware cost calculation:
const cacheReadCost = (cacheReadTokens / 1_000_000) * price.inputPer1M * 0.1;
const cacheCreationCost = (cacheCreationTokens / 1_000_000) * price.inputPer1M * 1.25;
3. src/storage/db.ts — migration v2 adding columns:
ALTER TABLE llm_events ADD COLUMN cache_read_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE llm_events ADD COLUMN cache_creation_tokens INTEGER NOT NULL DEFAULT 0;
4. src/storage/queries.ts — update LlmRecord interface, upsertLlmRecord, and all aggregate queries to include cache tokens in totals.
Secondary issue: plugin ID mismatch
package.json declares name "costclaw-telemetry" but openclaw.plugin.json declares id "costclaw". This causes a warning on every OpenClaw startup:
plugins.entries.costclaw: plugin costclaw: plugin id mismatch (manifest uses "costclaw", entry hints "costclaw-telemetry")
Tertiary issue: missing tsconfig.json in npm package
tsconfig.json is in the repo but not in the files array in package.json, so it doesn't ship with the npm package. This prevents users from rebuilding from source after patching.
Happy to submit a PR with these fixes if helpful.
Bug
CostClaw significantly undercounts token usage and costs when OpenClaw has prompt caching enabled (
cacheRetention: "short"or similar). In my setup with ~92% cache hit rates, the dashboard was showing a fraction of actual usage.Root Cause
The
llm_outputhook insrc/index.tsonly capturesevent.usage.inputandevent.usage.output:event.usage.inputcontains only the non-cached input tokens. With prompt caching, the bulk of input tokens come viacacheReadandcacheCreationfields, which are ignored entirely. In practice this meant input token counts of 3–6 per call instead of thousands.Additionally,
computeCost()insrc/pricing/calculator.tshas no cache pricing logic. Anthropic charges different rates for cached tokens:Impact
On a system with 92% cache hit rates:
Fix
I've applied the following changes locally and confirmed they work:
1.
src/index.ts— capture cache tokens from the event (with fallbacks for multiple field naming conventions):2.
src/pricing/calculator.ts— add cache-aware cost calculation:3.
src/storage/db.ts— migration v2 adding columns:4.
src/storage/queries.ts— updateLlmRecordinterface,upsertLlmRecord, and all aggregate queries to include cache tokens in totals.Secondary issue: plugin ID mismatch
package.jsondeclares name"costclaw-telemetry"butopenclaw.plugin.jsondeclares id"costclaw". This causes a warning on every OpenClaw startup:Tertiary issue: missing tsconfig.json in npm package
tsconfig.jsonis in the repo but not in thefilesarray inpackage.json, so it doesn't ship with the npm package. This prevents users from rebuilding from source after patching.Happy to submit a PR with these fixes if helpful.