Mission-Control/src/frontend/docs/COST-TRACKING.md

187 lines
4.6 KiB
Markdown
Raw Normal View History

# Cost Tracking System
Mission Control now tracks real usage costs by reading OpenClaw session data and calculating costs based on actual token usage.
## How It Works
1. **Data Collection**: The `collect-usage.ts` script reads `openclaw status --json` to get current session data
2. **Cost Calculation**: Uses model pricing table to calculate costs based on input/output tokens
3. **Storage**: Saves snapshots to SQLite database (`data/usage-tracking.db`)
4. **API**: The `/api/costs` endpoint queries the database to serve real cost data to the dashboard
## Model Pricing
Current pricing (as of Feb 2026):
| Model | Input ($/M tokens) | Output ($/M tokens) |
|-------|-------------------|---------------------|
| Opus 4.6 | $15.00 | $75.00 |
| Sonnet 4.5 | $3.00 | $15.00 |
| Haiku 3.5 | $0.80 | $4.00 |
| Gemini Flash | $0.15 | $0.60 |
| Gemini Pro | $1.25 | $5.00 |
| Grok 4.1 Fast | $2.00 | $10.00 |
Pricing is defined in `src/lib/pricing.ts`.
## Manual Collection
To collect usage data manually:
```bash
cd /root/.openclaw/workspace/mission-control
npx tsx scripts/collect-usage.ts
```
This will:
- Read current OpenClaw session data
- Calculate costs for each agent + model combination
- Save a snapshot to the database (replacing any existing data for the same hour)
## Automatic Collection (Cron)
To set up hourly automatic collection:
```bash
cd /root/.openclaw/workspace/mission-control
./scripts/setup-cron.sh
```
This adds a cron job that runs every hour at minute 0.
**View cron jobs:**
```bash
crontab -l
```
**View logs:**
```bash
tail -f /var/log/mission-control-usage.log
```
**Remove cron job:**
```bash
crontab -e
# Delete the line containing 'collect-usage.ts'
```
## Database Schema
```sql
CREATE TABLE usage_snapshots (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp INTEGER NOT NULL,
date TEXT NOT NULL, -- YYYY-MM-DD
hour INTEGER NOT NULL, -- 0-23
agent_id TEXT NOT NULL,
model TEXT NOT NULL,
input_tokens INTEGER NOT NULL,
output_tokens INTEGER NOT NULL,
total_tokens INTEGER NOT NULL,
cost REAL NOT NULL,
created_at INTEGER DEFAULT (strftime('%s', 'now'))
);
```
## Querying the Database
**Total cost today:**
```bash
sqlite3 data/usage-tracking.db \
"SELECT SUM(cost) FROM usage_snapshots WHERE date = date('now');"
```
**Cost by agent (last 30 days):**
```bash
sqlite3 data/usage-tracking.db \
"SELECT agent_id, ROUND(SUM(cost), 2) as cost
FROM usage_snapshots
WHERE date >= date('now', '-30 days')
GROUP BY agent_id
ORDER BY cost DESC;"
```
**Cost by model:**
```bash
sqlite3 data/usage-tracking.db \
"SELECT model, ROUND(SUM(cost), 2) as cost
FROM usage_snapshots
WHERE date >= date('now', '-30 days')
GROUP BY model
ORDER BY cost DESC;"
```
**Daily trend (last 7 days):**
```bash
sqlite3 data/usage-tracking.db \
"SELECT date, ROUND(SUM(cost), 2) as cost
FROM usage_snapshots
WHERE date >= date('now', '-7 days')
GROUP BY date
ORDER BY date DESC;"
```
## API Endpoints
### GET /api/costs
Returns cost summary, breakdowns, and trends.
**Query params:**
- `timeframe` (default: `30d`) - Number of days to include in aggregations
**Response:**
```json
{
"today": 0.80,
"yesterday": 1.25,
"thisMonth": 12.50,
"lastMonth": 38.90,
"projected": 52.30,
"budget": 100.00,
"byAgent": [
{ "agent": "main", "cost": 5.50, "tokens": 450000, "percentOfTotal": 44 }
],
"byModel": [
{ "model": "anthropic/claude-sonnet-4-5", "cost": 8.30, "tokens": 890000, "percentOfTotal": 66 }
],
"daily": [
{ "date": "02-20", "cost": 0.80, "input": 12000, "output": 8000 }
],
"hourly": [
{ "hour": "14:00", "cost": 0.12 }
]
}
```
## Troubleshooting
**No data showing up:**
- Run `npx tsx scripts/collect-usage.ts` to collect initial data
- Check database exists: `ls -lh data/usage-tracking.db`
- Query database: `sqlite3 data/usage-tracking.db "SELECT COUNT(*) FROM usage_snapshots;"`
**Unknown model warnings:**
- Update `src/lib/pricing.ts` with new model pricing
- Rebuild: `npm run build`
- Restart: `systemctl restart mission-control`
**Costs seem wrong:**
- Verify pricing in `src/lib/pricing.ts`
- Check token counts: `openclaw status --json | jq '.sessions.byAgent[].recent[].totalTokens'`
- Recalculate: delete database and re-collect
## Future Enhancements
- [ ] Budget alerts (email/Telegram when >80% spent)
- [ ] Export reports (PDF/CSV)
- [ ] Cost forecasting with ML
- [ ] Per-session cost tracking (not just agent totals)
- [ ] Integration with OpenRouter billing API for real invoices
- [ ] Cost optimization suggestions ("switch to Haiku for heartbeats")
---
**Created:** 2026-02-20
**Author:** Tenacitas 🦞