openclaw-smartmeter 0.1.0
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.
- package/CONTRIBUTING.md +148 -0
- package/LICENSE +190 -0
- package/README.md +275 -0
- package/SECURITY.md +89 -0
- package/SKILL.md +0 -0
- package/SPEC.md +708 -0
- package/canvas-template/README.md +166 -0
- package/canvas-template/analysis.public.json +141 -0
- package/canvas-template/app.js +425 -0
- package/canvas-template/index.html +162 -0
- package/canvas-template/preview-server.py +63 -0
- package/canvas-template/styles.css +575 -0
- package/docs/backlog.md +63 -0
- package/package.json +41 -0
- package/src/analyzer/aggregator.js +256 -0
- package/src/analyzer/classifier.js +160 -0
- package/src/analyzer/parser.js +187 -0
- package/src/analyzer/recommender.js +158 -0
- package/src/analyzer/storage.js +31 -0
- package/src/canvas/deployer.js +321 -0
- package/src/cli/commands.js +267 -0
- package/src/cli/index.js +82 -0
- package/src/cli/utils.js +146 -0
- package/src/generator/agent-creator.js +61 -0
- package/src/generator/config-builder.js +163 -0
- package/src/generator/merger.js +27 -0
- package/src/generator/validator.js +54 -0
package/SPEC.md
ADDED
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
# SmartMeter: OpenClaw Cost Optimization Skill
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
SmartMeter analyzes OpenClaw usage patterns and generates optimized `openclaw.json` configurations to reduce AI API costs by 60-75% while maintaining quality.
|
|
6
|
+
|
|
7
|
+
## Core Functionality
|
|
8
|
+
|
|
9
|
+
### Phase 1: Analysis Engine (MVP - Week 1)
|
|
10
|
+
|
|
11
|
+
**Input:** OpenClaw session logs from `~/.openclaw/agents/*/sessions/*.jsonl`
|
|
12
|
+
**Output:** Usage analysis JSON
|
|
13
|
+
|
|
14
|
+
**What to analyze:**
|
|
15
|
+
|
|
16
|
+
1. **Token Usage Patterns**
|
|
17
|
+
- Parse session logs (JSONL format)
|
|
18
|
+
- Extract: `model`, `usage.input`, `usage.output`, `usage.cacheRead`, `usage.cacheWrite`, `cost.total`
|
|
19
|
+
- Aggregate by: model, time of day, day of week
|
|
20
|
+
- Calculate: tokens/request, cost/request, cache hit rate
|
|
21
|
+
|
|
22
|
+
2. **Task Classification**
|
|
23
|
+
- Extract user prompts and assistant responses
|
|
24
|
+
- Classify into categories:
|
|
25
|
+
- `code`: Programming, debugging, code review
|
|
26
|
+
- `write`: Documentation, emails, content creation
|
|
27
|
+
- `research`: Web searches, information gathering
|
|
28
|
+
- `config`: File operations, system tasks
|
|
29
|
+
- `other`: Uncategorized
|
|
30
|
+
- Use keyword matching + prompt length + tool usage as features
|
|
31
|
+
|
|
32
|
+
3. **Model Performance**
|
|
33
|
+
- For each task category, track:
|
|
34
|
+
- Success rate by model (infer from: no errors, no user re-prompts within 5min)
|
|
35
|
+
- Average tokens consumed
|
|
36
|
+
- Average cost
|
|
37
|
+
- User satisfaction signals (explicit positive/negative feedback, task completion)
|
|
38
|
+
|
|
39
|
+
4. **Skill Usage**
|
|
40
|
+
- Parse which skills were invoked in each session
|
|
41
|
+
- Frequency analysis
|
|
42
|
+
- Co-occurrence patterns (which skills are used together)
|
|
43
|
+
|
|
44
|
+
5. **Temporal Patterns**
|
|
45
|
+
- Hour-of-day usage distribution
|
|
46
|
+
- Day-of-week patterns
|
|
47
|
+
- Burst vs. steady usage detection
|
|
48
|
+
|
|
49
|
+
**Technical Requirements:**
|
|
50
|
+
|
|
51
|
+
- Language: Node.js (OpenClaw is Node-based)
|
|
52
|
+
- Parse JSONL efficiently (stream processing for large files)
|
|
53
|
+
- Store analysis in `~/.openclaw/smartmeter/analysis.json`
|
|
54
|
+
- Minimum data: 2 weeks of history (or warn if insufficient)
|
|
55
|
+
|
|
56
|
+
**Implementation Notes:**
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
// Session log format (example)
|
|
60
|
+
{
|
|
61
|
+
"type": "message",
|
|
62
|
+
"message": {
|
|
63
|
+
"role": "assistant",
|
|
64
|
+
"content": "...",
|
|
65
|
+
"usage": {
|
|
66
|
+
"input": 1250,
|
|
67
|
+
"output": 340,
|
|
68
|
+
"cacheRead": 45000,
|
|
69
|
+
"cacheWrite": 0,
|
|
70
|
+
"cost": {"total": 0.0234}
|
|
71
|
+
},
|
|
72
|
+
"model": "anthropic/claude-sonnet-4-5",
|
|
73
|
+
"timestamp": 1738723945279
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Analysis output format
|
|
78
|
+
{
|
|
79
|
+
"period": {
|
|
80
|
+
"start": "2026-01-20T00:00:00Z",
|
|
81
|
+
"end": "2026-02-05T00:00:00Z",
|
|
82
|
+
"days": 14,
|
|
83
|
+
"totalTasks": 847
|
|
84
|
+
},
|
|
85
|
+
"models": {
|
|
86
|
+
"anthropic/claude-opus-4-5": {
|
|
87
|
+
"count": 234,
|
|
88
|
+
"tokens": {"input": 345000, "output": 89000},
|
|
89
|
+
"cost": 187.23,
|
|
90
|
+
"avgCostPerTask": 0.80
|
|
91
|
+
},
|
|
92
|
+
"anthropic/claude-sonnet-4-5": {
|
|
93
|
+
"count": 613,
|
|
94
|
+
"tokens": {"input": 890000, "output": 234000},
|
|
95
|
+
"cost": 234.56,
|
|
96
|
+
"avgCostPerTask": 0.38
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"categories": {
|
|
100
|
+
"code": {
|
|
101
|
+
"count": 312,
|
|
102
|
+
"modelBreakdown": {
|
|
103
|
+
"anthropic/claude-opus-4-5": {
|
|
104
|
+
"count": 98,
|
|
105
|
+
"successRate": 0.96,
|
|
106
|
+
"avgCost": 0.85
|
|
107
|
+
},
|
|
108
|
+
"anthropic/claude-sonnet-4-5": {
|
|
109
|
+
"count": 214,
|
|
110
|
+
"successRate": 0.94,
|
|
111
|
+
"avgCost": 0.38
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"recommendation": {
|
|
115
|
+
"currentModel": "anthropic/claude-opus-4-5",
|
|
116
|
+
"optimalModel": "anthropic/claude-sonnet-4-5",
|
|
117
|
+
"confidence": 0.94,
|
|
118
|
+
"potentialSavings": 45.67
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// ... other categories
|
|
122
|
+
},
|
|
123
|
+
"skills": {
|
|
124
|
+
"github": {"count": 67, "avgTokens": 3400},
|
|
125
|
+
"web-search": {"count": 123, "avgTokens": 8900},
|
|
126
|
+
// ... unused skills
|
|
127
|
+
"unused": ["skill1", "skill2", ...] // 42 skills never used
|
|
128
|
+
},
|
|
129
|
+
"temporal": {
|
|
130
|
+
"hourly": {
|
|
131
|
+
"08": 45, "09": 67, ... // tasks by hour
|
|
132
|
+
},
|
|
133
|
+
"daily": {
|
|
134
|
+
"Mon": 125, "Tue": 134, ...
|
|
135
|
+
},
|
|
136
|
+
"patterns": {
|
|
137
|
+
"burstUsage": true,
|
|
138
|
+
"peakHours": ["08-10", "14-16", "20-22"],
|
|
139
|
+
"quietHours": ["00-06"]
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"caching": {
|
|
143
|
+
"hitRate": 0.42,
|
|
144
|
+
"avgCacheRead": 45000,
|
|
145
|
+
"estimatedCacheSavings": 34.56,
|
|
146
|
+
"recommendation": "Enable long retention + 55min heartbeat"
|
|
147
|
+
},
|
|
148
|
+
"summary": {
|
|
149
|
+
"currentMonthlyCost": 387.45,
|
|
150
|
+
"optimizedMonthlyCost": 126.78,
|
|
151
|
+
"potentialSavings": 260.67,
|
|
152
|
+
"savingsPercentage": 67.3,
|
|
153
|
+
"confidence": "conservative" // or "likely" or "optimistic"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Phase 2: Config Generator (Week 1)
|
|
159
|
+
|
|
160
|
+
**Input:** Analysis JSON from Phase 1
|
|
161
|
+
**Output:** Optimized `openclaw.json` with inline comments
|
|
162
|
+
|
|
163
|
+
**What to generate:**
|
|
164
|
+
|
|
165
|
+
1. **Primary Model Optimization**
|
|
166
|
+
- If current primary is Opus and analysis shows 95%+ success on Sonnet:
|
|
167
|
+
- Change primary to Sonnet
|
|
168
|
+
- Add Opus to fallback
|
|
169
|
+
- Add comment explaining rationale
|
|
170
|
+
|
|
171
|
+
2. **Specialized Agent Creation**
|
|
172
|
+
- For each task category with >50 occurrences:
|
|
173
|
+
- Create dedicated agent
|
|
174
|
+
- Assign optimal model based on analysis
|
|
175
|
+
- Include relevant skills
|
|
176
|
+
- Add budget controls
|
|
177
|
+
- Example agents to generate:
|
|
178
|
+
- `code-reviewer` (if lots of code tasks)
|
|
179
|
+
- `teaching-assistant` (if education patterns detected)
|
|
180
|
+
- `researcher` (if high search usage)
|
|
181
|
+
- `quick-tasks` (for simple operations)
|
|
182
|
+
|
|
183
|
+
3. **Skill Optimization**
|
|
184
|
+
- List unused skills (never invoked in analysis period)
|
|
185
|
+
- Generate `allowBundled: false` config
|
|
186
|
+
- Whitelist only used skills
|
|
187
|
+
- Calculate token savings (skills add ~200-300 tokens each to prompt)
|
|
188
|
+
|
|
189
|
+
4. **Caching Configuration**
|
|
190
|
+
- If burst pattern detected:
|
|
191
|
+
- Set `cacheRetention: "long"`
|
|
192
|
+
- Add heartbeat based on quiet hours
|
|
193
|
+
- If steady usage:
|
|
194
|
+
- Default retention is fine
|
|
195
|
+
|
|
196
|
+
5. **Budget Controls**
|
|
197
|
+
- Calculate current daily average
|
|
198
|
+
- Set daily limit at 120% of average (safety margin)
|
|
199
|
+
- Set weekly limit at 7x daily
|
|
200
|
+
- Configure Telegram alerts at 75%
|
|
201
|
+
|
|
202
|
+
6. **Fallback Chain Optimization**
|
|
203
|
+
- Order models by: cost-effectiveness for user's workload
|
|
204
|
+
- Example: If user does lots of research: Gemini Flash first
|
|
205
|
+
- If user does lots of code: Haiku first
|
|
206
|
+
|
|
207
|
+
**Technical Requirements:**
|
|
208
|
+
|
|
209
|
+
- Deep merge with existing config (don't overwrite user customizations)
|
|
210
|
+
- Preserve user comments
|
|
211
|
+
- Add SmartMeter comments prefixed with `"// SMARTMETER:"`
|
|
212
|
+
- Validate JSON schema before output
|
|
213
|
+
- Create backup of original at `~/.openclaw/openclaw.json.backup-{timestamp}`
|
|
214
|
+
|
|
215
|
+
**Implementation Notes:**
|
|
216
|
+
|
|
217
|
+
```javascript
|
|
218
|
+
// Config generation logic
|
|
219
|
+
function generateOptimizedConfig(analysis, currentConfig) {
|
|
220
|
+
const optimized = deepClone(currentConfig);
|
|
221
|
+
|
|
222
|
+
// 1. Optimize primary model
|
|
223
|
+
if (shouldChangePrimary(analysis)) {
|
|
224
|
+
optimized.agents.defaults.model.primary = getOptimalPrimary(analysis);
|
|
225
|
+
addComment(
|
|
226
|
+
optimized,
|
|
227
|
+
"agents.defaults.model.primary",
|
|
228
|
+
`SmartMeter: Changed from ${currentConfig.agents.defaults.model.primary}. ` +
|
|
229
|
+
`Success rate: ${analysis.models[newModel].successRate}%. ` +
|
|
230
|
+
`Saves $${analysis.summary.potentialSavings}/month`,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// 2. Create specialized agents
|
|
235
|
+
const agentsToCreate = identifySpecializedAgents(analysis);
|
|
236
|
+
for (const agent of agentsToCreate) {
|
|
237
|
+
optimized.agents[agent.name] = generateAgentConfig(agent, analysis);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// 3. Optimize skills
|
|
241
|
+
const usedSkills = analysis.skills.used || [];
|
|
242
|
+
if (usedSkills.length < 20) {
|
|
243
|
+
// Only optimize if significant reduction
|
|
244
|
+
optimized.skills = {
|
|
245
|
+
allowBundled: false,
|
|
246
|
+
allow: usedSkills,
|
|
247
|
+
};
|
|
248
|
+
addComment(
|
|
249
|
+
optimized,
|
|
250
|
+
"skills",
|
|
251
|
+
`SmartMeter: Disabled ${analysis.skills.unused.length} unused skills. ` +
|
|
252
|
+
`Saves ~${analysis.skills.unused.length * 200} tokens/request`,
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// 4. Configure caching
|
|
257
|
+
if (analysis.temporal.patterns.burstUsage) {
|
|
258
|
+
optimized.models = optimized.models || {};
|
|
259
|
+
const primaryModel = optimized.agents.defaults.model.primary;
|
|
260
|
+
optimized.models[primaryModel] = {
|
|
261
|
+
params: {
|
|
262
|
+
cacheRetention: "long",
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// Add heartbeat during quiet hours
|
|
267
|
+
const quietStart = analysis.temporal.patterns.quietHours[0];
|
|
268
|
+
optimized.heartbeat = {
|
|
269
|
+
every: "55m",
|
|
270
|
+
schedule: `*/${quietStart}-06 * * *`, // During quiet hours
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// 5. Budget controls
|
|
275
|
+
const dailyAvg = analysis.summary.currentMonthlyCost / 30;
|
|
276
|
+
optimized.agents.defaults.budget = {
|
|
277
|
+
daily: Math.ceil(((dailyAvg * 1.2) / costPerToken) * 1000), // tokens
|
|
278
|
+
weekly: Math.ceil(((dailyAvg * 7) / costPerToken) * 1000),
|
|
279
|
+
alert: {
|
|
280
|
+
telegram: true,
|
|
281
|
+
threshold: 0.75,
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
return optimized;
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Phase 3: CLI Interface (Week 1)
|
|
290
|
+
|
|
291
|
+
**Commands to implement:**
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Analysis & preview
|
|
295
|
+
smartmeter analyze # Analyze usage, generate report
|
|
296
|
+
smartmeter preview # Show proposed config changes
|
|
297
|
+
smartmeter diff [v1] [v2] # Compare config versions
|
|
298
|
+
smartmeter show # Display full optimized config
|
|
299
|
+
|
|
300
|
+
# Application
|
|
301
|
+
smartmeter apply # Apply optimized config (with backup)
|
|
302
|
+
smartmeter rollback [version] # Rollback to previous config
|
|
303
|
+
|
|
304
|
+
# Monitoring
|
|
305
|
+
smartmeter status # Current optimization status
|
|
306
|
+
smartmeter report [period] # Savings report (week/month)
|
|
307
|
+
smartmeter costs --by-project # Cost breakdown by project
|
|
308
|
+
|
|
309
|
+
# Configuration
|
|
310
|
+
smartmeter config set KEY VALUE # Update SmartMeter settings
|
|
311
|
+
smartmeter history # Show config version history
|
|
312
|
+
|
|
313
|
+
# Iteration
|
|
314
|
+
smartmeter iterate # Check for new optimization opportunities
|
|
315
|
+
smartmeter learn # Update ML model from recent data
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Implementation:**
|
|
319
|
+
|
|
320
|
+
- Use `commander.js` for CLI parsing
|
|
321
|
+
- Store SmartMeter data in `~/.openclaw/smartmeter/`
|
|
322
|
+
- Integrate with OpenClaw's existing `/status` and `/usage` commands
|
|
323
|
+
|
|
324
|
+
### Phase 4: OpenRouter Integration (Week 2)
|
|
325
|
+
|
|
326
|
+
**API Integration:**
|
|
327
|
+
|
|
328
|
+
```javascript
|
|
329
|
+
// Fetch OpenRouter usage
|
|
330
|
+
async function fetchOpenRouterUsage(apiKey) {
|
|
331
|
+
const response = await fetch("https://openrouter.ai/api/v1/auth/key", {
|
|
332
|
+
headers: {
|
|
333
|
+
Authorization: `Bearer ${apiKey}`,
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
const data = await response.json();
|
|
338
|
+
|
|
339
|
+
return {
|
|
340
|
+
credits: {
|
|
341
|
+
total: data.limit,
|
|
342
|
+
used: data.usage,
|
|
343
|
+
remaining: data.limit - data.usage,
|
|
344
|
+
},
|
|
345
|
+
models: data.models || [], // Usage by model
|
|
346
|
+
rate: data.rate || {}, // Current burn rate
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Merge with OpenClaw logs:**
|
|
352
|
+
|
|
353
|
+
- OpenClaw logs have detailed token counts
|
|
354
|
+
- OpenRouter has credit usage and model-specific costs
|
|
355
|
+
- Cross-reference by timestamp
|
|
356
|
+
- Reconcile any discrepancies
|
|
357
|
+
|
|
358
|
+
### Phase 5: Monitoring & Alerts (Week 2)
|
|
359
|
+
|
|
360
|
+
**Telegram Bot Integration:**
|
|
361
|
+
|
|
362
|
+
```javascript
|
|
363
|
+
// Send alert via Telegram
|
|
364
|
+
async function sendTelegramAlert(chatId, message) {
|
|
365
|
+
const botToken = process.env.TELEGRAM_BOT_TOKEN;
|
|
366
|
+
|
|
367
|
+
await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
|
|
368
|
+
method: "POST",
|
|
369
|
+
headers: { "Content-Type": "application/json" },
|
|
370
|
+
body: JSON.stringify({
|
|
371
|
+
chat_id: chatId,
|
|
372
|
+
text: message,
|
|
373
|
+
parse_mode: "Markdown",
|
|
374
|
+
}),
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Alert conditions
|
|
379
|
+
function checkAlerts(usage, budgets) {
|
|
380
|
+
const alerts = [];
|
|
381
|
+
|
|
382
|
+
// Daily budget
|
|
383
|
+
if (usage.today >= budgets.daily * 0.75) {
|
|
384
|
+
alerts.push({
|
|
385
|
+
type: "budget",
|
|
386
|
+
severity: "warning",
|
|
387
|
+
message: `Daily budget 75% used: ${usage.today}/${budgets.daily} tokens`,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Unusual spike
|
|
392
|
+
const avgLast7Days = usage.last7Days / 7;
|
|
393
|
+
if (usage.today > avgLast7Days * 2) {
|
|
394
|
+
alerts.push({
|
|
395
|
+
type: "spike",
|
|
396
|
+
severity: "info",
|
|
397
|
+
message: `Unusual activity: ${usage.today} tokens today vs ${avgLast7Days} avg`,
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Cost anomaly
|
|
402
|
+
const expensiveTask = usage.recentTasks.find((t) => t.cost > 1.0);
|
|
403
|
+
if (expensiveTask) {
|
|
404
|
+
alerts.push({
|
|
405
|
+
type: "cost",
|
|
406
|
+
severity: "warning",
|
|
407
|
+
message: `Expensive task detected: $${expensiveTask.cost} for "${expensiveTask.prompt.slice(0, 50)}..."`,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return alerts;
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Phase 6: Chrome Extension (Week 3 - Optional for MVP)
|
|
416
|
+
|
|
417
|
+
**Architecture:**
|
|
418
|
+
|
|
419
|
+
```
|
|
420
|
+
chrome-extension/
|
|
421
|
+
├── manifest.json # Extension config (Manifest V3)
|
|
422
|
+
├── background/
|
|
423
|
+
│ └── service-worker.js # Background tasks, API polling
|
|
424
|
+
├── popup/
|
|
425
|
+
│ ├── popup.html # Extension popup UI
|
|
426
|
+
│ ├── popup.js # Popup logic
|
|
427
|
+
│ └── popup.css # Styles
|
|
428
|
+
├── content/
|
|
429
|
+
│ └── claude-ai-inject.js # Inject into claude.ai pages
|
|
430
|
+
└── assets/
|
|
431
|
+
├── icon-16.png
|
|
432
|
+
├── icon-48.png
|
|
433
|
+
└── icon-128.png
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**Key features:**
|
|
437
|
+
|
|
438
|
+
1. **Badge:** Show daily spend
|
|
439
|
+
2. **Popup:** Quick stats, model switcher
|
|
440
|
+
3. **Content Script:** Inject cost per message on claude.ai
|
|
441
|
+
4. **Background:** Poll OpenRouter API every 30s
|
|
442
|
+
|
|
443
|
+
## Testing Requirements
|
|
444
|
+
|
|
445
|
+
### Unit Tests
|
|
446
|
+
|
|
447
|
+
- Parser: Parse JSONL correctly
|
|
448
|
+
- Analyzer: Classify tasks accurately
|
|
449
|
+
- Generator: Produce valid JSON
|
|
450
|
+
- Merger: Deep merge without data loss
|
|
451
|
+
|
|
452
|
+
### Integration Tests
|
|
453
|
+
|
|
454
|
+
- End-to-end: Analyze → Generate → Apply → Verify
|
|
455
|
+
- Rollback: Apply → Rollback → Verify original restored
|
|
456
|
+
- Multi-version: Upgrade from OpenClaw v1 → v2
|
|
457
|
+
|
|
458
|
+
### User Testing
|
|
459
|
+
|
|
460
|
+
- Run on real OpenClaw installations
|
|
461
|
+
- Validate savings predictions (compare before/after)
|
|
462
|
+
- Collect feedback on generated configs
|
|
463
|
+
|
|
464
|
+
## Documentation
|
|
465
|
+
|
|
466
|
+
### README.md
|
|
467
|
+
|
|
468
|
+
- Overview
|
|
469
|
+
- Installation
|
|
470
|
+
- Quick start
|
|
471
|
+
- Commands reference
|
|
472
|
+
- FAQ
|
|
473
|
+
|
|
474
|
+
### SKILL.md (OpenClaw format)
|
|
475
|
+
|
|
476
|
+
```markdown
|
|
477
|
+
---
|
|
478
|
+
name: smartmeter
|
|
479
|
+
description: Analyze OpenClaw usage and generate optimized configs to reduce AI costs by 60-75%
|
|
480
|
+
metadata:
|
|
481
|
+
openclaw:
|
|
482
|
+
emoji: "💰"
|
|
483
|
+
requires:
|
|
484
|
+
bins: ["node"]
|
|
485
|
+
user-invocable: true
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
# SmartMeter
|
|
489
|
+
|
|
490
|
+
## Installation
|
|
491
|
+
|
|
492
|
+
\`\`\`bash
|
|
493
|
+
npx clawhub@latest install smartmeter
|
|
494
|
+
\`\`\`
|
|
495
|
+
|
|
496
|
+
## Usage
|
|
497
|
+
|
|
498
|
+
\`\`\`bash
|
|
499
|
+
/smartmeter analyze # Analyze your usage
|
|
500
|
+
/smartmeter preview # See optimization recommendations
|
|
501
|
+
/smartmeter apply # Apply optimized config
|
|
502
|
+
\`\`\`
|
|
503
|
+
|
|
504
|
+
## What it does
|
|
505
|
+
|
|
506
|
+
1. Analyzes 2+ weeks of OpenClaw usage
|
|
507
|
+
2. Identifies tasks that can use cheaper models
|
|
508
|
+
3. Generates specialized agents for different workloads
|
|
509
|
+
4. Optimizes skill loading, caching, and budgets
|
|
510
|
+
5. Projects 60-75% cost savings while maintaining quality
|
|
511
|
+
|
|
512
|
+
## Configuration
|
|
513
|
+
|
|
514
|
+
Store your OpenRouter API key:
|
|
515
|
+
\`\`\`bash
|
|
516
|
+
export OPENROUTER_API_KEY="sk-or-v1-..."
|
|
517
|
+
\`\`\`
|
|
518
|
+
|
|
519
|
+
## Learn more
|
|
520
|
+
|
|
521
|
+
GitHub: https://github.com/YOUR_USERNAME/smartmeter-openclaw
|
|
522
|
+
Docs: https://docs.smartmeter.ai
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### CONTRIBUTING.md
|
|
526
|
+
|
|
527
|
+
- How to contribute
|
|
528
|
+
- Code style
|
|
529
|
+
- Testing guidelines
|
|
530
|
+
- PR process
|
|
531
|
+
|
|
532
|
+
## Security & Privacy
|
|
533
|
+
|
|
534
|
+
### Data Handling
|
|
535
|
+
|
|
536
|
+
- All analysis happens locally
|
|
537
|
+
- No data sent to external servers (except OpenRouter API for usage)
|
|
538
|
+
- User can opt-out of any telemetry
|
|
539
|
+
- OpenRouter API key stored securely in env vars
|
|
540
|
+
|
|
541
|
+
### Config Validation
|
|
542
|
+
|
|
543
|
+
- Validate JSON schema before applying
|
|
544
|
+
- Check for dangerous configs (e.g., infinite budgets)
|
|
545
|
+
- Warn if config will significantly change behavior
|
|
546
|
+
|
|
547
|
+
### Rollback Safety
|
|
548
|
+
|
|
549
|
+
- Always create backup before applying
|
|
550
|
+
- Store last 10 config versions
|
|
551
|
+
- One-command rollback
|
|
552
|
+
|
|
553
|
+
## Performance Requirements
|
|
554
|
+
|
|
555
|
+
### Analysis Speed
|
|
556
|
+
|
|
557
|
+
- Parse 100K lines of JSONL in <10 seconds
|
|
558
|
+
- Generate config in <5 seconds
|
|
559
|
+
- Total analysis time: <30 seconds for 2 weeks of data
|
|
560
|
+
|
|
561
|
+
### Memory
|
|
562
|
+
|
|
563
|
+
- Keep memory usage <200MB during analysis
|
|
564
|
+
- Stream large session files instead of loading entirely
|
|
565
|
+
|
|
566
|
+
### Storage
|
|
567
|
+
|
|
568
|
+
- Analysis data: <10MB per user
|
|
569
|
+
- Config backups: <1MB total (JSON is small)
|
|
570
|
+
|
|
571
|
+
## Future Enhancements (Post-MVP)
|
|
572
|
+
|
|
573
|
+
### Machine Learning
|
|
574
|
+
|
|
575
|
+
- Train model on user feedback (good/bad recommendations)
|
|
576
|
+
- Improve task classification accuracy
|
|
577
|
+
- Predict future costs based on trends
|
|
578
|
+
|
|
579
|
+
### Team Features
|
|
580
|
+
|
|
581
|
+
- Share optimization learnings across team
|
|
582
|
+
- Consolidated billing reports
|
|
583
|
+
- Team-wide agents
|
|
584
|
+
|
|
585
|
+
### Enterprise
|
|
586
|
+
|
|
587
|
+
- Custom optimization rules
|
|
588
|
+
- Approval workflows
|
|
589
|
+
- Compliance reporting
|
|
590
|
+
|
|
591
|
+
## Success Metrics
|
|
592
|
+
|
|
593
|
+
### MVP Success (Week 4)
|
|
594
|
+
|
|
595
|
+
- 100 users install
|
|
596
|
+
- Average 50%+ cost reduction
|
|
597
|
+
- 90%+ user satisfaction with recommendations
|
|
598
|
+
- <5% rollback rate
|
|
599
|
+
|
|
600
|
+
### Growth Targets (Month 3)
|
|
601
|
+
|
|
602
|
+
- 1,000 users
|
|
603
|
+
- $50K+ monthly savings across user base
|
|
604
|
+
- 100+ GitHub stars
|
|
605
|
+
- Featured on Product Hunt
|
|
606
|
+
|
|
607
|
+
## Dependencies
|
|
608
|
+
|
|
609
|
+
```json
|
|
610
|
+
{
|
|
611
|
+
"dependencies": {
|
|
612
|
+
"commander": "^11.0.0", // CLI framework
|
|
613
|
+
"jsonstream": "^1.3.5", // Stream JSON parsing
|
|
614
|
+
"lodash": "^4.17.21", // Utilities
|
|
615
|
+
"chalk": "^5.3.0", // Terminal colors
|
|
616
|
+
"node-fetch": "^3.3.2", // HTTP requests
|
|
617
|
+
"dotenv": "^16.3.1" // Environment variables
|
|
618
|
+
},
|
|
619
|
+
"devDependencies": {
|
|
620
|
+
"jest": "^29.7.0", // Testing
|
|
621
|
+
"eslint": "^8.53.0", // Linting
|
|
622
|
+
"@types/node": "^20.9.0" // TypeScript types
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
## File Structure
|
|
628
|
+
|
|
629
|
+
```
|
|
630
|
+
smartmeter-openclaw/
|
|
631
|
+
├── src/
|
|
632
|
+
│ ├── analyzer/
|
|
633
|
+
│ │ ├── parser.js # Parse OpenClaw session logs
|
|
634
|
+
│ │ ├── classifier.js # Classify tasks
|
|
635
|
+
│ │ ├── aggregator.js # Aggregate statistics
|
|
636
|
+
│ │ └── recommender.js # Generate recommendations
|
|
637
|
+
│ ├── generator/
|
|
638
|
+
│ │ ├── config-builder.js # Build optimized config
|
|
639
|
+
│ │ ├── agent-creator.js # Create specialized agents
|
|
640
|
+
│ │ ├── merger.js # Merge with existing config
|
|
641
|
+
│ │ └── validator.js # Validate config
|
|
642
|
+
│ ├── cli/
|
|
643
|
+
│ │ ├── index.js # CLI entry point
|
|
644
|
+
│ │ ├── commands.js # Command handlers
|
|
645
|
+
│ │ └── utils.js # CLI utilities
|
|
646
|
+
│ ├── monitor/
|
|
647
|
+
│ │ ├── tracker.js # Track ongoing usage
|
|
648
|
+
│ │ ├── alerter.js # Send alerts
|
|
649
|
+
│ │ └── reporter.js # Generate reports
|
|
650
|
+
│ ├── integrations/
|
|
651
|
+
│ │ ├── openrouter.js # OpenRouter API
|
|
652
|
+
│ │ └── telegram.js # Telegram bot
|
|
653
|
+
│ └── index.js # Main entry point
|
|
654
|
+
├── tests/
|
|
655
|
+
│ ├── parser.test.js
|
|
656
|
+
│ ├── generator.test.js
|
|
657
|
+
│ └── integration.test.js
|
|
658
|
+
├── docs/
|
|
659
|
+
│ ├── api.md
|
|
660
|
+
│ ├── architecture.md
|
|
661
|
+
│ └── examples.md
|
|
662
|
+
├── examples/
|
|
663
|
+
│ ├── sample-analysis.json
|
|
664
|
+
│ └── sample-config.json
|
|
665
|
+
├── chrome-extension/ # Optional
|
|
666
|
+
├── package.json
|
|
667
|
+
├── SKILL.md # OpenClaw skill definition
|
|
668
|
+
├── SPEC.md # This file
|
|
669
|
+
├── README.md
|
|
670
|
+
├── CONTRIBUTING.md
|
|
671
|
+
├── LICENSE
|
|
672
|
+
└── .gitignore
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
## Development Phases
|
|
676
|
+
|
|
677
|
+
### Week 1: Core MVP
|
|
678
|
+
|
|
679
|
+
- [ ] Parser (parse session logs)
|
|
680
|
+
- [ ] Analyzer (classify tasks, aggregate stats)
|
|
681
|
+
- [ ] Generator (create optimized config)
|
|
682
|
+
- [ ] CLI basics (analyze, preview, apply)
|
|
683
|
+
- [ ] Basic tests
|
|
684
|
+
- [ ] Documentation
|
|
685
|
+
|
|
686
|
+
### Week 2: Polish & Integration
|
|
687
|
+
|
|
688
|
+
- [ ] OpenRouter integration
|
|
689
|
+
- [ ] Telegram alerts
|
|
690
|
+
- [ ] Monitoring & reporting
|
|
691
|
+
- [ ] Config versioning & rollback
|
|
692
|
+
- [ ] Advanced CLI commands
|
|
693
|
+
- [ ] Comprehensive tests
|
|
694
|
+
|
|
695
|
+
### Week 3: Publishing & Extension
|
|
696
|
+
|
|
697
|
+
- [ ] Publish to ClawHub
|
|
698
|
+
- [ ] Chrome extension (basic)
|
|
699
|
+
- [ ] Website/landing page
|
|
700
|
+
- [ ] Video demo
|
|
701
|
+
- [ ] LinkedIn launch posts
|
|
702
|
+
|
|
703
|
+
### Week 4: Iteration
|
|
704
|
+
|
|
705
|
+
- [ ] User feedback integration
|
|
706
|
+
- [ ] Bug fixes
|
|
707
|
+
- [ ] Performance optimization
|
|
708
|
+
- [ ] A/B testing features
|