openclaw-trace 1.0.0 → 1.0.1
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/README.md +39 -133
- package/openclaw-trace.js +38 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,35 +28,38 @@ An extension for OpenClaw that provides comprehensive visibility into agent exec
|
|
|
28
28
|
- 🔍 **Step inspection** - Full tool call/result details with expandable views
|
|
29
29
|
- 📤 **API access** - Programmatic access to all metrics via REST API
|
|
30
30
|
|
|
31
|
-
##
|
|
31
|
+
## Prerequisites
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
- **OpenClaw** installed and configured at `~/.openclaw`
|
|
33
|
+
- **[OpenClaw](https://github.com/nicholasgriffintn/openclaw)** installed and configured at `~/.openclaw`
|
|
35
34
|
- **Node.js** v14+ (already required by OpenClaw)
|
|
35
|
+
- At least one agent session (`.jsonl` files in `~/.openclaw/agents/*/sessions/`)
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
## Quick Start
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
npx openclaw-trace
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
No installation needed — runs directly from npm.
|
|
43
|
+
No installation needed — runs directly from npm on macOS, Linux, and Windows.
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
Open **http://localhost:3141** in your browser.
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
npm install -g openclaw-trace
|
|
49
|
-
openclaw-trace
|
|
50
|
-
```
|
|
47
|
+
## Usage
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
```bash
|
|
50
|
+
npx openclaw-trace # run in foreground
|
|
51
|
+
npx openclaw-trace --bg # run as background daemon
|
|
52
|
+
npx openclaw-trace --stop # stop background daemon
|
|
55
53
|
```
|
|
56
54
|
|
|
57
|
-
###
|
|
55
|
+
### Global Install (optional)
|
|
58
56
|
|
|
59
|
-
|
|
57
|
+
```bash
|
|
58
|
+
npm install -g openclaw-trace
|
|
59
|
+
openclaw-trace
|
|
60
|
+
openclaw-trace --bg
|
|
61
|
+
openclaw-trace --stop
|
|
62
|
+
```
|
|
60
63
|
|
|
61
64
|
### Navigation
|
|
62
65
|
|
|
@@ -67,63 +70,38 @@ Open your browser to **http://localhost:3141**
|
|
|
67
70
|
- **Compare Mode** - Click "Compare" button in header → select 2 heartbeats → view delta
|
|
68
71
|
- **API Buttons** - Each heartbeat has 📋 API and ⚠ API buttons to copy URLs for programmatic access
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
## API
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
REST API available at `http://localhost:3141/api/`:
|
|
73
76
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
fi
|
|
85
|
-
|
|
86
|
-
# Get latest heartbeat data
|
|
87
|
-
latest=$(dashboard_latest_hb "promo-assistant-reddit")
|
|
88
|
-
cost=$(echo $latest | jq -r '.totalCost')
|
|
89
|
-
errors=$(echo $latest | jq -r '.errorCount')
|
|
90
|
-
|
|
91
|
-
# Get only error steps from previous run
|
|
92
|
-
errors_only=$(dashboard_latest_errors_only "promo-assistant-reddit")
|
|
93
|
-
```
|
|
77
|
+
| Endpoint | Description |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `/api/agents` | List all agents with stats |
|
|
80
|
+
| `/api/agent/:id` | Get specific agent details |
|
|
81
|
+
| `/api/latest?agent=X` | Get latest heartbeat |
|
|
82
|
+
| `/api/heartbeat?agent=X&hb=N` | Get specific heartbeat by index |
|
|
83
|
+
| `/api/heartbeats?agent=X&errors=true` | Query heartbeats with filters |
|
|
84
|
+
| `/api/budget` | Get current budget status |
|
|
85
|
+
| `/api/daily?days=N` | Get daily cost breakdown |
|
|
86
|
+
| `/api/stats` | Overall system statistics |
|
|
94
87
|
|
|
95
|
-
|
|
96
|
-
- `/api/agents` - List all agents with stats
|
|
97
|
-
- `/api/agent/:id` - Get specific agent details
|
|
98
|
-
- `/api/latest?agent=X` - Get latest heartbeat
|
|
99
|
-
- `/api/heartbeat?agent=X&hb=N` - Get specific heartbeat by index
|
|
100
|
-
- `/api/heartbeats?agent=X&errors=true` - Query heartbeats with filters
|
|
101
|
-
- `/api/budget` - Get current budget status
|
|
102
|
-
- `/api/daily?days=N` - Get daily cost breakdown
|
|
103
|
-
- `/api/stats` - Overall system statistics
|
|
88
|
+
Add `&errors_only=true` to any heartbeat endpoint to get only steps with errors.
|
|
104
89
|
|
|
105
|
-
|
|
106
|
-
Add `&errors_only=true` to any heartbeat endpoint to get only steps with errors. Perfect for debugging and self-correction loops.
|
|
107
|
-
|
|
108
|
-
See [API.md](API.md) and [ERRORS_ONLY_FEATURE.md](ERRORS_ONLY_FEATURE.md) for complete documentation.
|
|
90
|
+
See [API.md](API.md) for complete documentation.
|
|
109
91
|
|
|
110
92
|
## Configuration
|
|
111
93
|
|
|
112
94
|
### Budget Settings
|
|
113
95
|
|
|
114
|
-
|
|
96
|
+
Create `~/.openclaw/canvas/budget.json`:
|
|
115
97
|
|
|
116
98
|
```json
|
|
117
99
|
{
|
|
118
|
-
"daily": 10.00,
|
|
119
|
-
"monthly": 200.00
|
|
100
|
+
"daily": 10.00,
|
|
101
|
+
"monthly": 200.00
|
|
120
102
|
}
|
|
121
103
|
```
|
|
122
104
|
|
|
123
|
-
The dashboard calculates:
|
|
124
|
-
- **Daily progress**: Today's spend vs daily limit
|
|
125
|
-
- **Projected monthly**: (7-day average × 30) vs monthly limit
|
|
126
|
-
|
|
127
105
|
### Port Configuration
|
|
128
106
|
|
|
129
107
|
To change the default port (3141), edit `openclaw-trace.js`:
|
|
@@ -132,24 +110,6 @@ To change the default port (3141), edit `openclaw-trace.js`:
|
|
|
132
110
|
const PORT = 3141; // Change to your preferred port
|
|
133
111
|
```
|
|
134
112
|
|
|
135
|
-
## Understanding the Metrics
|
|
136
|
-
|
|
137
|
-
### Live Status Dots
|
|
138
|
-
- 🟢 **Green**: Active (heartbeat < 15min ago)
|
|
139
|
-
- 🟡 **Yellow**: Idle (heartbeat < 1hr ago)
|
|
140
|
-
- ⚫ **Grey**: Inactive (heartbeat > 1hr ago)
|
|
141
|
-
|
|
142
|
-
### Cache Hit Rate
|
|
143
|
-
- **>70%**: Excellent (green) - prompt caching is working well
|
|
144
|
-
- **50-70%**: Good (blue) - normal for varied workloads
|
|
145
|
-
- **<50%**: Low (orange) - possible prompt drift or cold starts
|
|
146
|
-
|
|
147
|
-
### Waste Flags
|
|
148
|
-
- **Runaway loop**: >30 steps in one heartbeat
|
|
149
|
-
- **Low cache hit**: <50% cache efficiency (>5 steps)
|
|
150
|
-
- **Large result**: >10k char tool result (likely unscoped snapshot)
|
|
151
|
-
- **Bloated context**: >50k tokens in one step
|
|
152
|
-
|
|
153
113
|
## How It Works
|
|
154
114
|
|
|
155
115
|
The dashboard reads OpenClaw's session JSONL files from:
|
|
@@ -164,17 +124,14 @@ It parses:
|
|
|
164
124
|
- Tool calls (browser, read, write, bash, etc.)
|
|
165
125
|
- Errors and timing data
|
|
166
126
|
|
|
167
|
-
**No external dependencies**
|
|
127
|
+
**No external dependencies** — single file, pure Node.js stdlib + embedded HTML/CSS/JS.
|
|
168
128
|
|
|
169
129
|
## Troubleshooting
|
|
170
130
|
|
|
171
131
|
### Dashboard won't start
|
|
172
132
|
```bash
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
# Kill existing process
|
|
177
|
-
lsof -ti:3141 | xargs kill -9
|
|
133
|
+
npx openclaw-trace --stop # stop any existing instance
|
|
134
|
+
npx openclaw-trace # start fresh
|
|
178
135
|
```
|
|
179
136
|
|
|
180
137
|
### No data showing
|
|
@@ -186,61 +143,10 @@ lsof -ti:3141 | xargs kill -9
|
|
|
186
143
|
- Create `~/.openclaw/canvas/budget.json` with valid JSON
|
|
187
144
|
- Ensure at least one heartbeat exists for today
|
|
188
145
|
|
|
189
|
-
## Integration with OpenClaw
|
|
190
|
-
|
|
191
|
-
This dashboard is designed as a **drop-in extension** for OpenClaw. It:
|
|
192
|
-
- ✅ Reads existing OpenClaw session files (no schema changes)
|
|
193
|
-
- ✅ Works with all 10 platform agents (Threads, Twitter, Reddit, HN, PH, IH, Dev.to, LinkedIn, Medium, TikTok)
|
|
194
|
-
- ✅ Runs independently on a separate port (doesn't interfere with gateway)
|
|
195
|
-
- ✅ Auto-discovers agents from `openclaw.json`
|
|
196
|
-
|
|
197
|
-
### Using with OpenClaw Gateway
|
|
198
|
-
|
|
199
|
-
If you're running the OpenClaw gateway (`openclaw serve`), the dashboard runs alongside it:
|
|
200
|
-
- **Gateway**: `http://localhost:18789`
|
|
201
|
-
- **Dashboard**: `http://localhost:3141`
|
|
202
|
-
|
|
203
|
-
Both can run simultaneously with no conflicts.
|
|
204
|
-
|
|
205
|
-
## Development
|
|
206
|
-
|
|
207
|
-
The entire application is a single `openclaw-trace.js` file (~1350 lines):
|
|
208
|
-
- **Backend**: Node.js HTTP server + JSONL parser
|
|
209
|
-
- **Frontend**: Embedded HTML/CSS/JS (no build step)
|
|
210
|
-
- **Rendering**: Vanilla JS with SVG charts
|
|
211
|
-
|
|
212
|
-
To modify:
|
|
213
|
-
1. Edit `openclaw-trace.js`
|
|
214
|
-
2. Restart the server
|
|
215
|
-
3. Refresh browser (auto-refresh will pick up data changes)
|
|
216
|
-
|
|
217
|
-
## Performance
|
|
218
|
-
|
|
219
|
-
- **Session file reads**: ~50ms for 10 agents with 100+ heartbeats each
|
|
220
|
-
- **Memory usage**: ~30MB RSS
|
|
221
|
-
- **Browser performance**: Handles 1000+ heartbeats smoothly
|
|
222
|
-
|
|
223
|
-
## Roadmap
|
|
224
|
-
|
|
225
|
-
Potential future enhancements:
|
|
226
|
-
- [ ] Webhook alerts when budget exceeds threshold
|
|
227
|
-
- [ ] Per-agent budget allocation
|
|
228
|
-
- [ ] Model comparison (Opus vs Sonnet vs Haiku costs)
|
|
229
|
-
- [ ] Browser extension for inline metrics
|
|
230
|
-
- [ ] Prometheus/Grafana exporter
|
|
231
|
-
|
|
232
146
|
## Contributing
|
|
233
147
|
|
|
234
148
|
Contributions welcome! Please open an issue or PR at https://github.com/Tell-Me-Mo/openclaw-trace
|
|
235
149
|
|
|
236
150
|
## License
|
|
237
151
|
|
|
238
|
-
MIT License - see LICENSE
|
|
239
|
-
|
|
240
|
-
## Acknowledgments
|
|
241
|
-
|
|
242
|
-
Built for the OpenClaw multi-agent framework.
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
**Need help?** Open an issue or reach out in the OpenClaw community.
|
|
152
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
package/openclaw-trace.js
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// OpenClaw Trace
|
|
3
3
|
// Repository: https://github.com/Tell-Me-Mo/openclaw-trace
|
|
4
|
-
// Usage: npx openclaw-trace
|
|
5
|
-
//
|
|
4
|
+
// Usage: npx openclaw-trace (foreground)
|
|
5
|
+
// npx openclaw-trace --bg (background daemon)
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
+
// ── Stop: gracefully shut down a running instance ────────────────────────────
|
|
9
|
+
if (process.argv.includes('--stop')) {
|
|
10
|
+
const http = require('http');
|
|
11
|
+
const req = http.get('http://127.0.0.1:3141/api/shutdown', (res) => {
|
|
12
|
+
console.log('\n 🦞 OpenClaw Trace stopped\n');
|
|
13
|
+
process.exit(0);
|
|
14
|
+
});
|
|
15
|
+
req.on('error', () => {
|
|
16
|
+
console.log('\n No running instance found on port 3141\n');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
|
19
|
+
req.setTimeout(3000, () => { req.destroy(); process.exit(1); });
|
|
20
|
+
} else
|
|
21
|
+
|
|
22
|
+
// ── Background mode: re-spawn as detached process ────────────────────────────
|
|
23
|
+
if (process.argv.includes('--bg')) {
|
|
24
|
+
const { spawn } = require('child_process');
|
|
25
|
+
const args = process.argv.slice(1).filter(a => a !== '--bg');
|
|
26
|
+
const child = spawn(process.execPath, args, {
|
|
27
|
+
detached: true,
|
|
28
|
+
stdio: 'ignore',
|
|
29
|
+
});
|
|
30
|
+
child.unref();
|
|
31
|
+
console.log(`\n 🦞 OpenClaw Trace running in background (pid ${child.pid})`);
|
|
32
|
+
console.log(` → http://localhost:3141`);
|
|
33
|
+
console.log(` Stop: npx openclaw-trace --stop\n`);
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
|
|
8
37
|
const http = require('http');
|
|
9
38
|
const fs = require('fs');
|
|
10
39
|
const path = require('path');
|
|
@@ -910,6 +939,13 @@ http.createServer(async (req, res) => {
|
|
|
910
939
|
return;
|
|
911
940
|
}
|
|
912
941
|
|
|
942
|
+
// GET /api/shutdown - graceful shutdown
|
|
943
|
+
if (url === '/api/shutdown') {
|
|
944
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
945
|
+
res.end(JSON.stringify({ status: 'shutting down' }));
|
|
946
|
+
process.exit(0);
|
|
947
|
+
}
|
|
948
|
+
|
|
913
949
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
914
950
|
res.end(HTML);
|
|
915
951
|
}).listen(PORT, () => {
|