@burnguard/agent 1.0.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/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +48 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +86 -0
- package/dist/parser.js.map +1 -0
- package/dist/sender.d.ts +8 -0
- package/dist/sender.d.ts.map +1 -0
- package/dist/sender.js +101 -0
- package/dist/sender.js.map +1 -0
- package/dist/watcher.d.ts +6 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +103 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +27 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface AgentConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
backendUrl: string;
|
|
4
|
+
logDirectory: string;
|
|
5
|
+
reconnectInterval: number;
|
|
6
|
+
maxReconnectAttempts: number;
|
|
7
|
+
batchSize: number;
|
|
8
|
+
batchInterval: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function loadConfig(): AgentConfig;
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAeD,wBAAgB,UAAU,IAAI,WAAW,CA8CxC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadConfig = loadConfig;
|
|
7
|
+
const os_1 = __importDefault(require("os"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function resolveHome(filepath) {
|
|
10
|
+
if (filepath.startsWith("~")) {
|
|
11
|
+
return path_1.default.join(os_1.default.homedir(), filepath.slice(1));
|
|
12
|
+
}
|
|
13
|
+
return filepath;
|
|
14
|
+
}
|
|
15
|
+
function getCliArg(name) {
|
|
16
|
+
const prefix = `--${name}=`;
|
|
17
|
+
const arg = process.argv.find((a) => a.startsWith(prefix));
|
|
18
|
+
return arg ? arg.slice(prefix.length) : undefined;
|
|
19
|
+
}
|
|
20
|
+
function loadConfig() {
|
|
21
|
+
const apiKey = getCliArg("api-key") ??
|
|
22
|
+
process.env.BURNGUARD_API_KEY ??
|
|
23
|
+
"";
|
|
24
|
+
if (!apiKey) {
|
|
25
|
+
console.error("Error: API key is required. Set BURNGUARD_API_KEY or pass --api-key=<key>");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const backendUrl = getCliArg("backend-url") ??
|
|
29
|
+
process.env.BURNGUARD_BACKEND_URL ??
|
|
30
|
+
"wss://api.burnguard.dev/api/ws";
|
|
31
|
+
const logDirectory = resolveHome(getCliArg("log-dir") ??
|
|
32
|
+
process.env.BURNGUARD_LOG_DIR ??
|
|
33
|
+
"~/.openclaw/sessions");
|
|
34
|
+
const reconnectInterval = parseInt(getCliArg("reconnect-interval") ?? "5000", 10);
|
|
35
|
+
const maxReconnectAttempts = parseInt(getCliArg("max-reconnect") ?? "10", 10);
|
|
36
|
+
const batchSize = parseInt(getCliArg("batch-size") ?? "50", 10);
|
|
37
|
+
const batchInterval = parseInt(getCliArg("batch-interval") ?? "2000", 10);
|
|
38
|
+
return {
|
|
39
|
+
apiKey,
|
|
40
|
+
backendUrl,
|
|
41
|
+
logDirectory,
|
|
42
|
+
reconnectInterval,
|
|
43
|
+
maxReconnectAttempts,
|
|
44
|
+
batchSize,
|
|
45
|
+
batchInterval,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;AA0BA,gCA8CC;AAxED,4CAAoB;AACpB,gDAAwB;AAYxB,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,CAAC;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED,SAAgB,UAAU;IACxB,MAAM,MAAM,GACV,SAAS,CAAC,SAAS,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,EAAE,CAAC;IAEL,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,2EAA2E,CAC5E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GACd,SAAS,CAAC,aAAa,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,qBAAqB;QACjC,gCAAgC,CAAC;IAEnC,MAAM,YAAY,GAAG,WAAW,CAC9B,SAAS,CAAC,SAAS,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,sBAAsB,CACvB,CAAC;IAEF,MAAM,iBAAiB,GAAG,QAAQ,CAChC,SAAS,CAAC,oBAAoB,CAAC,IAAI,MAAM,EACzC,EAAE,CACH,CAAC;IAEF,MAAM,oBAAoB,GAAG,QAAQ,CACnC,SAAS,CAAC,eAAe,CAAC,IAAI,IAAI,EAClC,EAAE,CACH,CAAC;IAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IAChE,MAAM,aAAa,GAAG,QAAQ,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IAE1E,OAAO;QACL,MAAM;QACN,UAAU;QACV,YAAY;QACZ,iBAAiB;QACjB,oBAAoB;QACpB,SAAS;QACT,aAAa;KACd,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const config_1 = require("./config");
|
|
5
|
+
const watcher_1 = require("./watcher");
|
|
6
|
+
const sender_1 = require("./sender");
|
|
7
|
+
console.log("=================================");
|
|
8
|
+
console.log(" BurnGuard Agent v1.0.0");
|
|
9
|
+
console.log(" Real-Time Cost Monitoring");
|
|
10
|
+
console.log("=================================");
|
|
11
|
+
console.log();
|
|
12
|
+
const config = (0, config_1.loadConfig)();
|
|
13
|
+
console.log(`[agent] Backend URL: ${config.backendUrl}`);
|
|
14
|
+
console.log(`[agent] Log directory: ${config.logDirectory}`);
|
|
15
|
+
console.log(`[agent] Batch size: ${config.batchSize}, interval: ${config.batchInterval}ms`);
|
|
16
|
+
console.log();
|
|
17
|
+
const sender = (0, sender_1.createSender)(config);
|
|
18
|
+
const watcher = (0, watcher_1.createWatcher)(config.logDirectory, (metrics) => {
|
|
19
|
+
console.log(`[agent] Parsed ${metrics.length} metric(s), sending to backend...`);
|
|
20
|
+
sender.send(metrics);
|
|
21
|
+
});
|
|
22
|
+
console.log(`[agent] Watching for JSONL files in: ${config.logDirectory}`);
|
|
23
|
+
console.log("[agent] Press Ctrl+C to stop.");
|
|
24
|
+
console.log();
|
|
25
|
+
function shutdown() {
|
|
26
|
+
console.log("\n[agent] Shutting down...");
|
|
27
|
+
watcher.close();
|
|
28
|
+
sender.close();
|
|
29
|
+
console.log("[agent] Goodbye.");
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
process.on("SIGINT", shutdown);
|
|
33
|
+
process.on("SIGTERM", shutdown);
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,qCAAsC;AACtC,uCAA0C;AAC1C,qCAAwC;AAExC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AACjD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;AACxC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAC3C,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AACjD,OAAO,CAAC,GAAG,EAAE,CAAC;AAEd,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;AAE5B,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;AACzD,OAAO,CAAC,GAAG,CAAC,0BAA0B,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;AAC7D,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,SAAS,eAAe,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC;AAC5F,OAAO,CAAC,GAAG,EAAE,CAAC;AAEd,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,MAAM,CAAC,CAAC;AAEpC,MAAM,OAAO,GAAG,IAAA,uBAAa,EAAC,MAAM,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE;IAC7D,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,MAAM,mCAAmC,CAAC,CAAC;IACjF,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,GAAG,CAAC,wCAAwC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;AAC3E,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;AAC7C,OAAO,CAAC,GAAG,EAAE,CAAC;AAEd,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC1C,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ParsedMetric {
|
|
2
|
+
sessionId: string;
|
|
3
|
+
timestamp: number;
|
|
4
|
+
model: string;
|
|
5
|
+
category: string;
|
|
6
|
+
inputTokens: number;
|
|
7
|
+
outputTokens: number;
|
|
8
|
+
costCents: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function parseJsonlLine(line: string): ParsedMetric | null;
|
|
11
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AA6CD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAiDhE"}
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseJsonlLine = parseJsonlLine;
|
|
4
|
+
/** Model pricing: [input_per_1M_tokens_cents, output_per_1M_tokens_cents] */
|
|
5
|
+
const MODEL_PRICING = {
|
|
6
|
+
"claude-opus-4": [1500, 7500],
|
|
7
|
+
"claude-sonnet-4": [300, 1500],
|
|
8
|
+
"claude-haiku-3.5": [25, 125],
|
|
9
|
+
};
|
|
10
|
+
function calculateCost(model, inputTokens, outputTokens) {
|
|
11
|
+
const pricing = MODEL_PRICING[model];
|
|
12
|
+
if (!pricing)
|
|
13
|
+
return 0;
|
|
14
|
+
const [inputRate, outputRate] = pricing;
|
|
15
|
+
const cost = (inputTokens / 1_000_000) * inputRate +
|
|
16
|
+
(outputTokens / 1_000_000) * outputRate;
|
|
17
|
+
return Math.round(cost);
|
|
18
|
+
}
|
|
19
|
+
function detectCategory(data) {
|
|
20
|
+
if (typeof data.type === "string") {
|
|
21
|
+
const t = data.type.toLowerCase();
|
|
22
|
+
if (t.includes("heartbeat") || t.includes("ping"))
|
|
23
|
+
return "heartbeat";
|
|
24
|
+
if (t.includes("tool") || t.includes("function"))
|
|
25
|
+
return "tool_use";
|
|
26
|
+
if (t.includes("error"))
|
|
27
|
+
return "error";
|
|
28
|
+
return t;
|
|
29
|
+
}
|
|
30
|
+
if (data.heartbeat || data.is_heartbeat)
|
|
31
|
+
return "heartbeat";
|
|
32
|
+
if (data.tool_name || data.function_call)
|
|
33
|
+
return "tool_use";
|
|
34
|
+
return "conversation";
|
|
35
|
+
}
|
|
36
|
+
function extractSessionId(data) {
|
|
37
|
+
if (typeof data.session_id === "string")
|
|
38
|
+
return data.session_id;
|
|
39
|
+
if (typeof data.sessionId === "string")
|
|
40
|
+
return data.sessionId;
|
|
41
|
+
if (typeof data.id === "string")
|
|
42
|
+
return data.id;
|
|
43
|
+
return "unknown";
|
|
44
|
+
}
|
|
45
|
+
function parseJsonlLine(line) {
|
|
46
|
+
const trimmed = line.trim();
|
|
47
|
+
if (!trimmed)
|
|
48
|
+
return null;
|
|
49
|
+
try {
|
|
50
|
+
const data = JSON.parse(trimmed);
|
|
51
|
+
const model = data.model ??
|
|
52
|
+
data.model_name ??
|
|
53
|
+
"";
|
|
54
|
+
if (!model)
|
|
55
|
+
return null;
|
|
56
|
+
const inputTokens = data.input_tokens ??
|
|
57
|
+
data.prompt_tokens ??
|
|
58
|
+
data.tokens_input ??
|
|
59
|
+
0;
|
|
60
|
+
const outputTokens = data.output_tokens ??
|
|
61
|
+
data.completion_tokens ??
|
|
62
|
+
data.tokens_output ??
|
|
63
|
+
0;
|
|
64
|
+
if (inputTokens === 0 && outputTokens === 0)
|
|
65
|
+
return null;
|
|
66
|
+
const costCents = calculateCost(model, inputTokens, outputTokens);
|
|
67
|
+
const category = detectCategory(data);
|
|
68
|
+
const sessionId = extractSessionId(data);
|
|
69
|
+
const timestamp = typeof data.timestamp === "number"
|
|
70
|
+
? data.timestamp
|
|
71
|
+
: Math.floor(Date.now() / 1000);
|
|
72
|
+
return {
|
|
73
|
+
sessionId,
|
|
74
|
+
timestamp,
|
|
75
|
+
model,
|
|
76
|
+
category,
|
|
77
|
+
inputTokens,
|
|
78
|
+
outputTokens,
|
|
79
|
+
costCents,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
|
package/dist/sender.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AgentConfig } from "./config";
|
|
2
|
+
import { ParsedMetric } from "./parser";
|
|
3
|
+
export interface Sender {
|
|
4
|
+
send(metrics: ParsedMetric[]): void;
|
|
5
|
+
close(): void;
|
|
6
|
+
}
|
|
7
|
+
export declare function createSender(config: AgentConfig): Sender;
|
|
8
|
+
//# sourceMappingURL=sender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../src/sender.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IACpC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAyGxD"}
|
package/dist/sender.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createSender = createSender;
|
|
7
|
+
const ws_1 = __importDefault(require("ws"));
|
|
8
|
+
function createSender(config) {
|
|
9
|
+
let ws = null;
|
|
10
|
+
let reconnectAttempts = 0;
|
|
11
|
+
let reconnectTimer = null;
|
|
12
|
+
let batchTimer = null;
|
|
13
|
+
let batch = [];
|
|
14
|
+
let closed = false;
|
|
15
|
+
function connect() {
|
|
16
|
+
if (closed)
|
|
17
|
+
return;
|
|
18
|
+
const url = `${config.backendUrl}?api_key=${config.apiKey}`;
|
|
19
|
+
ws = new ws_1.default(url);
|
|
20
|
+
ws.on("open", () => {
|
|
21
|
+
console.log("[sender] Connected to backend");
|
|
22
|
+
reconnectAttempts = 0;
|
|
23
|
+
});
|
|
24
|
+
ws.on("message", (data) => {
|
|
25
|
+
try {
|
|
26
|
+
const msg = JSON.parse(data.toString());
|
|
27
|
+
if (msg.error) {
|
|
28
|
+
console.error("[sender] Server error:", msg.error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Ignore unparseable messages
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
ws.on("close", () => {
|
|
36
|
+
console.log("[sender] Connection closed");
|
|
37
|
+
ws = null;
|
|
38
|
+
scheduleReconnect();
|
|
39
|
+
});
|
|
40
|
+
ws.on("error", (err) => {
|
|
41
|
+
console.error("[sender] Connection error:", err.message);
|
|
42
|
+
ws?.close();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function scheduleReconnect() {
|
|
46
|
+
if (closed)
|
|
47
|
+
return;
|
|
48
|
+
if (reconnectAttempts >= config.maxReconnectAttempts) {
|
|
49
|
+
console.error(`[sender] Max reconnect attempts (${config.maxReconnectAttempts}) reached. Giving up.`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const delay = config.reconnectInterval * Math.pow(2, reconnectAttempts);
|
|
53
|
+
reconnectAttempts++;
|
|
54
|
+
console.log(`[sender] Reconnecting in ${delay}ms (attempt ${reconnectAttempts}/${config.maxReconnectAttempts})`);
|
|
55
|
+
reconnectTimer = setTimeout(() => {
|
|
56
|
+
connect();
|
|
57
|
+
}, delay);
|
|
58
|
+
}
|
|
59
|
+
function flush() {
|
|
60
|
+
if (batch.length === 0)
|
|
61
|
+
return;
|
|
62
|
+
if (!ws || ws.readyState !== ws_1.default.OPEN)
|
|
63
|
+
return;
|
|
64
|
+
const toSend = batch.splice(0, batch.length);
|
|
65
|
+
for (const metric of toSend) {
|
|
66
|
+
const message = JSON.stringify({
|
|
67
|
+
type: "metric",
|
|
68
|
+
session_id: metric.sessionId,
|
|
69
|
+
model: metric.model,
|
|
70
|
+
category: metric.category,
|
|
71
|
+
input_tokens: metric.inputTokens,
|
|
72
|
+
output_tokens: metric.outputTokens,
|
|
73
|
+
cost_cents: metric.costCents,
|
|
74
|
+
timestamp: metric.timestamp,
|
|
75
|
+
});
|
|
76
|
+
ws.send(message);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Start batch flush interval
|
|
80
|
+
batchTimer = setInterval(flush, config.batchInterval);
|
|
81
|
+
// Initial connection
|
|
82
|
+
connect();
|
|
83
|
+
return {
|
|
84
|
+
send(metrics) {
|
|
85
|
+
batch.push(...metrics);
|
|
86
|
+
if (batch.length >= config.batchSize) {
|
|
87
|
+
flush();
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
close() {
|
|
91
|
+
closed = true;
|
|
92
|
+
if (reconnectTimer)
|
|
93
|
+
clearTimeout(reconnectTimer);
|
|
94
|
+
if (batchTimer)
|
|
95
|
+
clearInterval(batchTimer);
|
|
96
|
+
flush();
|
|
97
|
+
ws?.close();
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=sender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.js","sourceRoot":"","sources":["../src/sender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as chokidar from "chokidar";
|
|
2
|
+
import { ParsedMetric } from "./parser";
|
|
3
|
+
type MetricsCallback = (metrics: ParsedMetric[]) => void;
|
|
4
|
+
export declare function createWatcher(logDir: string, onMetrics: MetricsCallback): chokidar.FSWatcher;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AACrC,OAAO,EAAkB,YAAY,EAAE,MAAM,UAAU,CAAC;AAExD,KAAK,eAAe,GAAG,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;AA4CzD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,eAAe,GACzB,QAAQ,CAAC,SAAS,CA4BpB"}
|
package/dist/watcher.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.createWatcher = createWatcher;
|
|
40
|
+
const fs_1 = __importDefault(require("fs"));
|
|
41
|
+
const path_1 = __importDefault(require("path"));
|
|
42
|
+
const chokidar = __importStar(require("chokidar"));
|
|
43
|
+
const parser_1 = require("./parser");
|
|
44
|
+
const filePositions = new Map();
|
|
45
|
+
function readNewLines(filePath) {
|
|
46
|
+
const currentPos = filePositions.get(filePath) ?? 0;
|
|
47
|
+
let stat;
|
|
48
|
+
try {
|
|
49
|
+
stat = fs_1.default.statSync(filePath);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
if (stat.size <= currentPos)
|
|
55
|
+
return [];
|
|
56
|
+
const fd = fs_1.default.openSync(filePath, "r");
|
|
57
|
+
const buffer = Buffer.alloc(stat.size - currentPos);
|
|
58
|
+
fs_1.default.readSync(fd, buffer, 0, buffer.length, currentPos);
|
|
59
|
+
fs_1.default.closeSync(fd);
|
|
60
|
+
filePositions.set(filePath, stat.size);
|
|
61
|
+
const content = buffer.toString("utf-8");
|
|
62
|
+
return content.split("\n").filter((line) => line.trim().length > 0);
|
|
63
|
+
}
|
|
64
|
+
function processFile(filePath, onMetrics) {
|
|
65
|
+
const lines = readNewLines(filePath);
|
|
66
|
+
if (lines.length === 0)
|
|
67
|
+
return;
|
|
68
|
+
const metrics = [];
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
const metric = (0, parser_1.parseJsonlLine)(line);
|
|
71
|
+
if (metric) {
|
|
72
|
+
metrics.push(metric);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (metrics.length > 0) {
|
|
76
|
+
onMetrics(metrics);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function createWatcher(logDir, onMetrics) {
|
|
80
|
+
const globPattern = path_1.default.join(logDir, "**", "*.jsonl");
|
|
81
|
+
const watcher = chokidar.watch(globPattern, {
|
|
82
|
+
persistent: true,
|
|
83
|
+
ignoreInitial: false,
|
|
84
|
+
awaitWriteFinish: {
|
|
85
|
+
stabilityThreshold: 200,
|
|
86
|
+
pollInterval: 100,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
watcher.on("add", (filePath) => {
|
|
90
|
+
console.log(`[watcher] Tracking new file: ${filePath}`);
|
|
91
|
+
filePositions.set(filePath, 0);
|
|
92
|
+
processFile(filePath, onMetrics);
|
|
93
|
+
});
|
|
94
|
+
watcher.on("change", (filePath) => {
|
|
95
|
+
processFile(filePath, onMetrics);
|
|
96
|
+
});
|
|
97
|
+
watcher.on("error", (error) => {
|
|
98
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
99
|
+
console.error("[watcher] Error:", msg);
|
|
100
|
+
});
|
|
101
|
+
return watcher;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@burnguard/agent",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "BurnGuard local agent - monitors OpenClaw session logs",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"burnguard": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"dev": "tsx watch src/index.ts",
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"start": "node dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"chokidar": "^4.0.3",
|
|
19
|
+
"ws": "^8.18.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^22.13.1",
|
|
23
|
+
"@types/ws": "^8.5.14",
|
|
24
|
+
"tsx": "^4.19.2",
|
|
25
|
+
"typescript": "^5.7.3"
|
|
26
|
+
}
|
|
27
|
+
}
|