agentmetrics-openclaw 0.2.0 → 0.2.3
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 +66 -47
- package/index.ts +40 -22
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,76 +1,95 @@
|
|
|
1
1
|
# agentmetrics-openclaw
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/agentmetrics-openclaw)
|
|
4
|
+
[](../LICENSE)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Zero-code observability for [OpenClaw](https://openclaw.dev) agents. Install the plugin, set your API key, and every agent session is tracked automatically — tokens, cost, tools, subagents, context health, and reliability.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
→ **[agentmetrics.dev/docs/integrations/openclaw](https://agentmetrics.dev/docs/integrations/openclaw)**
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|---|---|
|
|
11
|
-
| Status (success / failed) | `agent_end.success` |
|
|
12
|
-
| Duration | `agent_end.durationMs` |
|
|
13
|
-
| Model & provider | `llm_output` |
|
|
14
|
-
| Input tokens | `llm_output.usage.input` |
|
|
15
|
-
| Output tokens | `llm_output.usage.output` |
|
|
16
|
-
| Cache read tokens | `llm_output.usage.cacheRead` |
|
|
17
|
-
| Cache write tokens | `llm_output.usage.cacheWrite` |
|
|
18
|
-
| Tool call count | `after_tool_call` (counted) |
|
|
19
|
-
| Tool error count | `after_tool_call.error` (counted) |
|
|
20
|
-
| Step count | `agent_end.messages.length` |
|
|
21
|
-
| Error message | `agent_end.error` |
|
|
22
|
-
|
|
23
|
-
All token buckets are accumulated across the full run — multi-turn, multi-LLM-call runs are handled correctly.
|
|
10
|
+
---
|
|
24
11
|
|
|
25
|
-
##
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- OpenClaw 2026.3.2 or later
|
|
15
|
+
- Node.js 22 or later
|
|
16
|
+
- An AgentMetrics API key — [get one at agentmetrics.dev](https://agentmetrics.dev/signup)
|
|
26
17
|
|
|
27
|
-
|
|
18
|
+
---
|
|
28
19
|
|
|
29
|
-
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
30
23
|
openclaw plugins install agentmetrics-openclaw
|
|
31
24
|
```
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
---
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
## Setup
|
|
29
|
+
|
|
30
|
+
**1. Set your API key**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# macOS / Linux
|
|
34
|
+
echo 'export AGENTMETRICS_API_KEY=am_live_...' >> ~/.bashrc && source ~/.bashrc
|
|
35
|
+
|
|
36
|
+
# Windows (PowerShell)
|
|
37
|
+
$Env:AGENTMETRICS_API_KEY = "am_live_..."
|
|
37
38
|
```
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
**2. Trust the plugin** (silences the security scan advisory)
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
```bash
|
|
43
|
+
openclaw config set plugins.allow '["agentmetrics"]'
|
|
44
|
+
```
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
**3. Restart the gateway**
|
|
47
|
+
|
|
48
|
+
```bash
|
|
44
49
|
openclaw gateway restart
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
**4. Verify**
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
openclaw plugins list
|
|
56
|
+
# agentmetrics loaded
|
|
57
|
+
```
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
---
|
|
50
60
|
|
|
51
|
-
|
|
61
|
+
## What gets tracked
|
|
52
62
|
|
|
53
|
-
|
|
54
|
-
plugins:
|
|
55
|
-
agentmetrics:
|
|
56
|
-
apiKey: am_your_key_here
|
|
57
|
-
endpoint: https://api.agentmetrics.dev # optional
|
|
58
|
-
```
|
|
63
|
+
Every agent session reports automatically:
|
|
59
64
|
|
|
60
|
-
|
|
65
|
+
| Signal | Detail |
|
|
66
|
+
|---|---|
|
|
67
|
+
| **Cost** | Computed from token counts and model pricing |
|
|
68
|
+
| **Latency** | Wall-clock duration per run |
|
|
69
|
+
| **Tokens** | Input, output, cache read, cache write |
|
|
70
|
+
| **Tools** | Call count, errors, per-tool duration |
|
|
71
|
+
| **Subagents** | Spawned count, error count |
|
|
72
|
+
| **Context health** | Compaction count, reset count |
|
|
73
|
+
| **Reliability** | Success/failure, full error message |
|
|
61
74
|
|
|
62
|
-
|
|
75
|
+
---
|
|
63
76
|
|
|
64
|
-
##
|
|
77
|
+
## Troubleshooting
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
**"dangerous code patterns" warning on install**
|
|
80
|
+
Safe to ignore. The plugin reads `AGENTMETRICS_API_KEY` and sends it as a Bearer token to the AgentMetrics API. Add `agentmetrics` to `plugins.allow` to suppress it permanently.
|
|
81
|
+
|
|
82
|
+
**"manifest id does not match package name" warning**
|
|
83
|
+
Not an error. The plugin's internal manifest id is `agentmetrics`; the npm package name is `agentmetrics-openclaw`. Use `agentmetrics` (not the npm name) in `plugins.allow`.
|
|
84
|
+
|
|
85
|
+
**Runs not appearing in the dashboard**
|
|
86
|
+
1. Check the key is set: `echo $AGENTMETRICS_API_KEY`
|
|
87
|
+
2. Verify the plugin loads: `openclaw plugins list`
|
|
88
|
+
3. Restart the gateway after any env var change
|
|
89
|
+
4. Confirm your `openclaw.json` has a `name` field
|
|
69
90
|
|
|
70
|
-
|
|
91
|
+
---
|
|
71
92
|
|
|
72
|
-
##
|
|
93
|
+
## License
|
|
73
94
|
|
|
74
|
-
|
|
75
|
-
- Docs: [agentmetrics.dev/docs](https://agentmetrics.dev/docs)
|
|
76
|
-
- GitHub: [github.com/andausman/agentmetrics](https://github.com/andausman/agentmetrics)
|
|
95
|
+
[MIT](../LICENSE)
|
package/index.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { randomUUID } from "crypto";
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// pluginConfig overrides env vars — set once in register()
|
|
4
4
|
let API_KEY: string | undefined;
|
|
5
5
|
let BASE_URL: string;
|
|
6
6
|
|
|
7
|
+
interface PluginApi {
|
|
8
|
+
config: Record<string, unknown>;
|
|
9
|
+
pluginConfig?: Record<string, unknown>;
|
|
10
|
+
registerAutoEnableProbe?: (probe: () => boolean) => void;
|
|
11
|
+
registerCli?: (registrar: {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
commands: Array<{ name: string; description: string; handler: () => void }>;
|
|
15
|
+
}) => void;
|
|
16
|
+
on: (hookName: string, handler: (...args: unknown[]) => void) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
7
19
|
// ─── Types (sourced from openclaw/src/plugins/hook-types.ts) ──────────────────
|
|
8
20
|
|
|
9
21
|
type AgentContext = {
|
|
@@ -164,6 +176,7 @@ interface RunMeta {
|
|
|
164
176
|
model?: string;
|
|
165
177
|
provider?: string;
|
|
166
178
|
sessionKey?: string;
|
|
179
|
+
startedAt: number; // run-level start time for accurate duration
|
|
167
180
|
}
|
|
168
181
|
|
|
169
182
|
const sessions = new Map<string, SessionMeta>();
|
|
@@ -226,6 +239,7 @@ function emptyRun(sessionKey?: string): RunMeta {
|
|
|
226
239
|
toolCalls: 0, toolErrors: 0, toolNames: new Set(),
|
|
227
240
|
subagentsSpawned: 0, subagentErrors: 0,
|
|
228
241
|
sessionKey,
|
|
242
|
+
startedAt: Date.now(),
|
|
229
243
|
};
|
|
230
244
|
}
|
|
231
245
|
|
|
@@ -250,21 +264,33 @@ const plugin = {
|
|
|
250
264
|
additionalProperties: false,
|
|
251
265
|
} as const,
|
|
252
266
|
|
|
253
|
-
register(api:
|
|
267
|
+
register(api: PluginApi) {
|
|
254
268
|
// Config: pluginConfig > env vars
|
|
255
|
-
API_KEY = api.
|
|
269
|
+
API_KEY = (api.pluginConfig?.apiKey as string | undefined) ?? process.env.AGENTMETRICS_API_KEY;
|
|
256
270
|
BASE_URL = (
|
|
257
|
-
api.
|
|
271
|
+
(api.pluginConfig?.endpoint as string | undefined) ??
|
|
258
272
|
process.env.AGENTMETRICS_URL ??
|
|
259
273
|
"https://api.agentmetrics.dev"
|
|
260
274
|
).replace(/\/$/, "");
|
|
261
275
|
|
|
262
|
-
// Auto-enable when
|
|
276
|
+
// Auto-enable when a key is available (env var or plugin config)
|
|
263
277
|
if (typeof api.registerAutoEnableProbe === "function") {
|
|
264
|
-
api.registerAutoEnableProbe(() => !!
|
|
278
|
+
api.registerAutoEnableProbe(() => !!API_KEY);
|
|
265
279
|
}
|
|
266
280
|
|
|
267
|
-
if (!API_KEY)
|
|
281
|
+
if (!API_KEY) {
|
|
282
|
+
console.log(
|
|
283
|
+
"\n AgentMetrics: no API key found.\n" +
|
|
284
|
+
" Your agent runs are not being tracked.\n" +
|
|
285
|
+
" Get an API key at https://agentmetrics.dev and set AGENTMETRICS_API_KEY.\n"
|
|
286
|
+
);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
console.log(
|
|
291
|
+
`\n AgentMetrics active — sending data to ${BASE_URL}\n` +
|
|
292
|
+
` View your dashboard → https://agentmetrics.dev\n`
|
|
293
|
+
);
|
|
268
294
|
|
|
269
295
|
// CLI: openclaw agentmetrics status
|
|
270
296
|
if (typeof api.registerCli === "function") {
|
|
@@ -291,16 +317,12 @@ const plugin = {
|
|
|
291
317
|
}
|
|
292
318
|
|
|
293
319
|
// ── gateway_start ─────────────────────────────────────────────────────
|
|
320
|
+
// Activity only — gateway events are infrastructure, not agent runs.
|
|
321
|
+
// We do NOT call send() here to avoid polluting the agents list.
|
|
294
322
|
api.on("gateway_start", (event: GatewayStartEvent, _ctx: GatewayContext) => {
|
|
295
323
|
sendActivity("gateway_start", "openclaw-gateway", undefined, undefined, {
|
|
296
324
|
port: event.port,
|
|
297
325
|
});
|
|
298
|
-
send({
|
|
299
|
-
trace_id: randomUUID(),
|
|
300
|
-
agent_id: "openclaw-gateway",
|
|
301
|
-
status: "success",
|
|
302
|
-
metadata: { event_type: "gateway_start", port: event.port },
|
|
303
|
-
});
|
|
304
326
|
});
|
|
305
327
|
|
|
306
328
|
// ── gateway_stop ──────────────────────────────────────────────────────
|
|
@@ -308,12 +330,6 @@ const plugin = {
|
|
|
308
330
|
sendActivity("gateway_stop", "openclaw-gateway", undefined, undefined, {
|
|
309
331
|
reason: event.reason,
|
|
310
332
|
});
|
|
311
|
-
send({
|
|
312
|
-
trace_id: randomUUID(),
|
|
313
|
-
agent_id: "openclaw-gateway",
|
|
314
|
-
status: "success",
|
|
315
|
-
metadata: { event_type: "gateway_stop", reason: event.reason },
|
|
316
|
-
});
|
|
317
333
|
});
|
|
318
334
|
|
|
319
335
|
// ── session_start ─────────────────────────────────────────────────────
|
|
@@ -400,7 +416,6 @@ const plugin = {
|
|
|
400
416
|
output_tokens: event.usage?.output,
|
|
401
417
|
cache_read: event.usage?.cacheRead,
|
|
402
418
|
cache_write: event.usage?.cacheWrite,
|
|
403
|
-
// Running totals for the dashboard
|
|
404
419
|
total_input: run.inputTokens,
|
|
405
420
|
total_output: run.outputTokens,
|
|
406
421
|
});
|
|
@@ -535,10 +550,13 @@ const plugin = {
|
|
|
535
550
|
(run?.cacheReadTokens ?? 0) +
|
|
536
551
|
(run?.cacheWriteTokens ?? 0);
|
|
537
552
|
|
|
553
|
+
// Use run-level duration (accurate) — fall back to session duration only if unavailable
|
|
554
|
+
const durationMs = event.durationMs ?? (run ? Date.now() - run.startedAt : undefined);
|
|
555
|
+
|
|
538
556
|
// Real-time: notify dashboard the run finished
|
|
539
557
|
sendActivity("run_end", agentId, sessionKey, ctx.runId, {
|
|
540
558
|
status: event.success ? "success" : "failed",
|
|
541
|
-
duration_ms:
|
|
559
|
+
duration_ms: durationMs,
|
|
542
560
|
total_tokens: totalTokens || undefined,
|
|
543
561
|
tool_calls: run?.toolCalls,
|
|
544
562
|
error: event.error?.slice(0, 200),
|
|
@@ -549,7 +567,7 @@ const plugin = {
|
|
|
549
567
|
trace_id: session?.traceId ?? randomUUID(),
|
|
550
568
|
agent_id: agentId,
|
|
551
569
|
status: event.success ? "success" : "failed",
|
|
552
|
-
duration_ms:
|
|
570
|
+
duration_ms: durationMs,
|
|
553
571
|
model: run?.model,
|
|
554
572
|
model_provider: run?.provider,
|
|
555
573
|
input_tokens: run?.inputTokens ?? 0,
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentmetrics-openclaw",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgentMetrics observability plugin for OpenClaw agents",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://agentmetrics.dev",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/
|
|
10
|
+
"url": "git+https://github.com/andalabx/agentmetrics-sdk.git"
|
|
11
11
|
},
|
|
12
12
|
"keywords": ["openclaw", "agentmetrics", "observability", "ai-agents", "monitoring"],
|
|
13
13
|
"peerDependencies": {
|