agentflow-dashboard 0.3.0 → 0.3.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 +24 -7
- package/dist/{chunk-2FTN742J.js → chunk-EDHK4NJD.js} +168 -17
- package/dist/cli.cjs +4 -1
- package/dist/cli.js +2 -147
- package/dist/index.cjs +160 -12
- package/dist/index.js +1 -1
- package/dist/public/dashboard.js +401 -25
- package/dist/public/debug.html +43 -0
- package/dist/public/index.html +214 -0
- package/dist/server.cjs +1350 -0
- package/dist/server.js +6 -0
- package/package.json +2 -2
- package/public/dashboard.js +401 -25
- package/public/debug.html +43 -0
- package/public/index.html +214 -0
package/README.md
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
|
-
# AgentFlow Dashboard
|
|
1
|
+
# AgentFlow Dashboard v0.3.0
|
|
2
2
|
|
|
3
|
-
Real-time monitoring dashboard for AgentFlow - Visualize agent execution graphs and performance metrics
|
|
3
|
+
Real-time monitoring dashboard for AgentFlow - Visualize agent execution graphs and performance metrics with comprehensive agent infrastructure monitoring.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **Multi-
|
|
7
|
+
### **🎯 Universal Agent Monitoring**
|
|
8
|
+
- **Alfred Integration** - Full Alfred worker and conversation monitoring
|
|
9
|
+
- **OpenClaw Support** - OpenClaw gateway and agent trace ingestion
|
|
10
|
+
- **Multi-Framework** - Supports LangChain, CrewAI, AutoGen, Mastra, and more
|
|
11
|
+
- **Real-time Updates** - Live WebSocket connections with instant trace updates
|
|
12
|
+
|
|
13
|
+
### **🛠️ Enhanced Process Health**
|
|
14
|
+
- **Process Tagging** - Smart categorization (`main`, `agents`, `browser`, `context`, `exec`, `read`, `tool`, `think`, `user`, `write`)
|
|
15
|
+
- **Tree View Structure** - Hierarchical process relationships with parent-child visualization
|
|
16
|
+
- **Infrastructure Detection** - Automatic detection of Milvus, Redis, PostgreSQL, and vector databases
|
|
17
|
+
- **Resource Monitoring** - CPU, memory, and uptime tracking for all processes
|
|
18
|
+
|
|
19
|
+
### **💬 LLM Conversation Tracking**
|
|
20
|
+
- **Session Parsing** - Full Alfred and OpenClaw conversation logs
|
|
21
|
+
- **Token Usage** - OpenRouter, Claude, and other provider usage statistics
|
|
22
|
+
- **Model Interactions** - Complete LLM request/response chains with metadata
|
|
23
|
+
- **Activity Filtering** - Filter traces by agent activity type and behavior
|
|
24
|
+
|
|
25
|
+
### **📊 Performance & Visualization**
|
|
26
|
+
- **Interactive Graphs** - Cytoscape.js execution flow visualization
|
|
27
|
+
- **Timeline View** - Waterfall execution timeline with duration metrics
|
|
28
|
+
- **Success Metrics** - Agent performance, failure rates, and health monitoring
|
|
11
29
|
- **Responsive Design** - Works on desktop and mobile devices
|
|
12
|
-
- **Zero Configuration** - Auto-discovers trace files and starts monitoring
|
|
13
30
|
|
|
14
31
|
## Quick Start
|
|
15
32
|
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import express from "express";
|
|
3
|
+
import * as fs3 from "fs";
|
|
4
|
+
import { createServer } from "http";
|
|
5
|
+
import * as path3 from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { WebSocketServer } from "ws";
|
|
8
|
+
import { discoverProcessConfig, auditProcesses } from "agentflow-core";
|
|
9
|
+
|
|
1
10
|
// src/stats.ts
|
|
2
11
|
import { getFailures, getHungNodes, getStats } from "agentflow-core";
|
|
3
12
|
var AgentStats = class {
|
|
@@ -950,16 +959,154 @@ var TraceWatcher = class extends EventEmitter {
|
|
|
950
959
|
}
|
|
951
960
|
};
|
|
952
961
|
|
|
953
|
-
// src/
|
|
954
|
-
import express from "express";
|
|
962
|
+
// src/cli.ts
|
|
955
963
|
import * as fs2 from "fs";
|
|
956
|
-
import
|
|
964
|
+
import * as os from "os";
|
|
957
965
|
import * as path2 from "path";
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
966
|
+
var VERSION = "0.3.1";
|
|
967
|
+
function getLanAddress() {
|
|
968
|
+
const interfaces = os.networkInterfaces();
|
|
969
|
+
for (const name of Object.keys(interfaces)) {
|
|
970
|
+
for (const iface of interfaces[name] || []) {
|
|
971
|
+
if (iface.family === "IPv4" && !iface.internal) {
|
|
972
|
+
return iface.address;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return null;
|
|
977
|
+
}
|
|
978
|
+
function printBanner(config, traceCount, stats) {
|
|
979
|
+
var _a;
|
|
980
|
+
const lan = getLanAddress();
|
|
981
|
+
const host = config.host || "localhost";
|
|
982
|
+
const port = config.port;
|
|
983
|
+
const isPublic = host === "0.0.0.0";
|
|
984
|
+
console.log(`
|
|
985
|
+
___ _ _____ _
|
|
986
|
+
/ _ \\ __ _ ___ _ __ | |_| ___| | _____ __
|
|
987
|
+
| |_| |/ _\` |/ _ \\ '_ \\| __| |_ | |/ _ \\ \\ /\\ / /
|
|
988
|
+
| _ | (_| | __/ | | | |_| _| | | (_) \\ V V /
|
|
989
|
+
|_| |_|\\__, |\\___|_| |_|\\__|_| |_|\\___/ \\_/\\_/
|
|
990
|
+
|___/ dashboard v${VERSION}
|
|
991
|
+
|
|
992
|
+
See your agents think.
|
|
993
|
+
|
|
994
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
995
|
+
\u2502 \u{1F916} Agents \u2502 TRACE FILES \u2502 \u{1F4CA} AgentFlow \u2502 SHOWS YOU \u2502 \u{1F310} Your browser \u2502
|
|
996
|
+
\u2502 Execute tasks, \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500> \u2502 Reads traces, \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500> \u2502 Interactive \u2502
|
|
997
|
+
\u2502 write JSON \u2502 \u2502 builds graphs, \u2502 \u2502 graph, timeline, \u2502
|
|
998
|
+
\u2502 trace files. \u2502 \u2502 serves dashboard.\u2502 \u2502 metrics, health. \u2502
|
|
999
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
1000
|
+
|
|
1001
|
+
Runs locally. Your data never leaves your machine.
|
|
1002
|
+
|
|
1003
|
+
Tabs: \u{1F3AF} Graph \xB7 \u23F1\uFE0F Timeline \xB7 \u{1F4CA} Metrics \xB7 \u{1F6E0}\uFE0F Process Health \xB7 \u26A0\uFE0F Errors
|
|
1004
|
+
|
|
1005
|
+
Traces: ${config.tracesDir}${((_a = config.dataDirs) == null ? void 0 : _a.length) ? "\n Data dirs: " + config.dataDirs.join("\n ") : ""}
|
|
1006
|
+
Loaded: ${traceCount} traces \xB7 ${stats.totalAgents} agents \xB7 ${stats.totalExecutions} executions
|
|
1007
|
+
Success: ${stats.globalSuccessRate.toFixed(1)}%${stats.activeAgents > 0 ? ` \xB7 ${stats.activeAgents} active now` : ""}
|
|
1008
|
+
CORS: ${config.enableCors ? "enabled" : "disabled"}
|
|
1009
|
+
WebSocket: live updates enabled
|
|
1010
|
+
|
|
1011
|
+
\u2192 http://localhost:${port}${isPublic && lan ? `
|
|
1012
|
+
\u2192 http://${lan}:${port} (LAN)` : ""}
|
|
1013
|
+
`);
|
|
1014
|
+
}
|
|
1015
|
+
async function startDashboard() {
|
|
1016
|
+
const args = process.argv.slice(2);
|
|
1017
|
+
const config = {
|
|
1018
|
+
port: 3e3,
|
|
1019
|
+
tracesDir: "./traces",
|
|
1020
|
+
host: "localhost",
|
|
1021
|
+
enableCors: false
|
|
1022
|
+
};
|
|
1023
|
+
for (let i = 0; i < args.length; i++) {
|
|
1024
|
+
switch (args[i]) {
|
|
1025
|
+
case "--port":
|
|
1026
|
+
case "-p":
|
|
1027
|
+
config.port = parseInt(args[++i]) || 3e3;
|
|
1028
|
+
break;
|
|
1029
|
+
case "--traces":
|
|
1030
|
+
case "-t":
|
|
1031
|
+
config.tracesDir = args[++i];
|
|
1032
|
+
break;
|
|
1033
|
+
case "--host":
|
|
1034
|
+
case "-h":
|
|
1035
|
+
config.host = args[++i];
|
|
1036
|
+
break;
|
|
1037
|
+
case "--data-dir":
|
|
1038
|
+
if (!config.dataDirs) config.dataDirs = [];
|
|
1039
|
+
config.dataDirs.push(args[++i]);
|
|
1040
|
+
break;
|
|
1041
|
+
case "--cors":
|
|
1042
|
+
config.enableCors = true;
|
|
1043
|
+
break;
|
|
1044
|
+
case "--help":
|
|
1045
|
+
printHelp();
|
|
1046
|
+
process.exit(0);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
const tracesPath = path2.resolve(config.tracesDir);
|
|
1050
|
+
if (!fs2.existsSync(tracesPath)) {
|
|
1051
|
+
fs2.mkdirSync(tracesPath, { recursive: true });
|
|
1052
|
+
}
|
|
1053
|
+
config.tracesDir = tracesPath;
|
|
1054
|
+
console.log("\nStarting AgentFlow Dashboard...\n");
|
|
1055
|
+
const dashboard = new DashboardServer(config);
|
|
1056
|
+
process.on("SIGINT", async () => {
|
|
1057
|
+
console.log("\n\u{1F6D1} Shutting down dashboard...");
|
|
1058
|
+
await dashboard.stop();
|
|
1059
|
+
process.exit(0);
|
|
1060
|
+
});
|
|
1061
|
+
process.on("SIGTERM", async () => {
|
|
1062
|
+
await dashboard.stop();
|
|
1063
|
+
process.exit(0);
|
|
1064
|
+
});
|
|
1065
|
+
try {
|
|
1066
|
+
await dashboard.start();
|
|
1067
|
+
setTimeout(() => {
|
|
1068
|
+
const stats = dashboard.getStats();
|
|
1069
|
+
const traces = dashboard.getTraces();
|
|
1070
|
+
printBanner(config, traces.length, stats);
|
|
1071
|
+
}, 1500);
|
|
1072
|
+
} catch (error) {
|
|
1073
|
+
console.error("\u274C Failed to start dashboard:", error);
|
|
1074
|
+
process.exit(1);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
function printHelp() {
|
|
1078
|
+
console.log(`
|
|
1079
|
+
\u{1F4CA} AgentFlow Dashboard v${VERSION} \u2014 See your agents think.
|
|
1080
|
+
|
|
1081
|
+
Usage:
|
|
1082
|
+
agentflow-dashboard [options]
|
|
1083
|
+
npx agentflow-dashboard [options]
|
|
1084
|
+
|
|
1085
|
+
Options:
|
|
1086
|
+
-p, --port <number> Server port (default: 3000)
|
|
1087
|
+
-t, --traces <path> Traces directory (default: ./traces)
|
|
1088
|
+
-h, --host <address> Host address (default: localhost)
|
|
1089
|
+
--data-dir <path> Extra data directory for process discovery (repeatable)
|
|
1090
|
+
--cors Enable CORS headers
|
|
1091
|
+
--help Show this help message
|
|
1092
|
+
|
|
1093
|
+
Examples:
|
|
1094
|
+
agentflow-dashboard --traces ./traces --host 0.0.0.0 --cors
|
|
1095
|
+
agentflow-dashboard -p 8080 -t /var/log/agentflow
|
|
1096
|
+
agentflow-dashboard --traces ./traces --data-dir ./workers --data-dir ./cron
|
|
1097
|
+
|
|
1098
|
+
Tabs:
|
|
1099
|
+
\u{1F3AF} Graph Interactive Cytoscape.js execution graph
|
|
1100
|
+
\u23F1\uFE0F Timeline Waterfall view of node durations
|
|
1101
|
+
\u{1F4CA} Metrics Success rates, durations, node breakdown
|
|
1102
|
+
\u{1F6E0}\uFE0F Process Health PID files, systemd, workers, orphans
|
|
1103
|
+
\u26A0\uFE0F Errors Failed and hung nodes with metadata
|
|
1104
|
+
`);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// src/server.ts
|
|
961
1108
|
var __filename = fileURLToPath(import.meta.url);
|
|
962
|
-
var __dirname =
|
|
1109
|
+
var __dirname = path3.dirname(__filename);
|
|
963
1110
|
var DashboardServer = class {
|
|
964
1111
|
constructor(config) {
|
|
965
1112
|
this.config = config;
|
|
@@ -989,8 +1136,8 @@ var DashboardServer = class {
|
|
|
989
1136
|
next();
|
|
990
1137
|
});
|
|
991
1138
|
}
|
|
992
|
-
const publicDir =
|
|
993
|
-
if (
|
|
1139
|
+
const publicDir = path3.join(__dirname, "../public");
|
|
1140
|
+
if (fs3.existsSync(publicDir)) {
|
|
994
1141
|
this.app.use(express.static(publicDir));
|
|
995
1142
|
}
|
|
996
1143
|
this.app.get("/api/traces", (req, res) => {
|
|
@@ -1062,7 +1209,7 @@ var DashboardServer = class {
|
|
|
1062
1209
|
}
|
|
1063
1210
|
const discoveryDirs = [
|
|
1064
1211
|
this.config.tracesDir,
|
|
1065
|
-
|
|
1212
|
+
path3.dirname(this.config.tracesDir),
|
|
1066
1213
|
...this.config.dataDirs || []
|
|
1067
1214
|
];
|
|
1068
1215
|
const processConfig = discoverProcessConfig(discoveryDirs);
|
|
@@ -1077,8 +1224,8 @@ var DashboardServer = class {
|
|
|
1077
1224
|
}
|
|
1078
1225
|
});
|
|
1079
1226
|
this.app.get("*", (req, res) => {
|
|
1080
|
-
const indexPath =
|
|
1081
|
-
if (
|
|
1227
|
+
const indexPath = path3.join(__dirname, "../public/index.html");
|
|
1228
|
+
if (fs3.existsSync(indexPath)) {
|
|
1082
1229
|
res.sendFile(indexPath);
|
|
1083
1230
|
} else {
|
|
1084
1231
|
res.status(404).send("Dashboard not found - public files may not be built");
|
|
@@ -1135,21 +1282,21 @@ var DashboardServer = class {
|
|
|
1135
1282
|
});
|
|
1136
1283
|
}
|
|
1137
1284
|
async start() {
|
|
1138
|
-
return new Promise((
|
|
1285
|
+
return new Promise((resolve3) => {
|
|
1139
1286
|
const host = this.config.host || "localhost";
|
|
1140
1287
|
this.server.listen(this.config.port, host, () => {
|
|
1141
1288
|
console.log(`AgentFlow Dashboard running at http://${host}:${this.config.port}`);
|
|
1142
1289
|
console.log(`Watching traces in: ${this.config.tracesDir}`);
|
|
1143
|
-
|
|
1290
|
+
resolve3();
|
|
1144
1291
|
});
|
|
1145
1292
|
});
|
|
1146
1293
|
}
|
|
1147
1294
|
async stop() {
|
|
1148
|
-
return new Promise((
|
|
1295
|
+
return new Promise((resolve3) => {
|
|
1149
1296
|
this.watcher.stop();
|
|
1150
1297
|
this.server.close(() => {
|
|
1151
1298
|
console.log("Dashboard server stopped");
|
|
1152
|
-
|
|
1299
|
+
resolve3();
|
|
1153
1300
|
});
|
|
1154
1301
|
});
|
|
1155
1302
|
}
|
|
@@ -1160,9 +1307,13 @@ var DashboardServer = class {
|
|
|
1160
1307
|
return this.watcher.getAllTraces();
|
|
1161
1308
|
}
|
|
1162
1309
|
};
|
|
1310
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
1311
|
+
startDashboard().catch(console.error);
|
|
1312
|
+
}
|
|
1163
1313
|
|
|
1164
1314
|
export {
|
|
1165
1315
|
AgentStats,
|
|
1166
1316
|
TraceWatcher,
|
|
1167
|
-
DashboardServer
|
|
1317
|
+
DashboardServer,
|
|
1318
|
+
startDashboard
|
|
1168
1319
|
};
|
package/dist/cli.cjs
CHANGED
|
@@ -1201,9 +1201,12 @@ var DashboardServer = class {
|
|
|
1201
1201
|
return this.watcher.getAllTraces();
|
|
1202
1202
|
}
|
|
1203
1203
|
};
|
|
1204
|
+
if (import_meta.url === `file://${process.argv[1]}`) {
|
|
1205
|
+
startDashboard().catch(console.error);
|
|
1206
|
+
}
|
|
1204
1207
|
|
|
1205
1208
|
// src/cli.ts
|
|
1206
|
-
var VERSION = "0.
|
|
1209
|
+
var VERSION = "0.3.1";
|
|
1207
1210
|
function getLanAddress() {
|
|
1208
1211
|
const interfaces = os.networkInterfaces();
|
|
1209
1212
|
for (const name of Object.keys(interfaces)) {
|
package/dist/cli.js
CHANGED
|
@@ -1,151 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
|
|
5
|
-
// src/cli.ts
|
|
6
|
-
import * as fs from "fs";
|
|
7
|
-
import * as os from "os";
|
|
8
|
-
import * as path from "path";
|
|
9
|
-
var VERSION = "0.2.2";
|
|
10
|
-
function getLanAddress() {
|
|
11
|
-
const interfaces = os.networkInterfaces();
|
|
12
|
-
for (const name of Object.keys(interfaces)) {
|
|
13
|
-
for (const iface of interfaces[name] || []) {
|
|
14
|
-
if (iface.family === "IPv4" && !iface.internal) {
|
|
15
|
-
return iface.address;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
function printBanner(config, traceCount, stats) {
|
|
22
|
-
var _a;
|
|
23
|
-
const lan = getLanAddress();
|
|
24
|
-
const host = config.host || "localhost";
|
|
25
|
-
const port = config.port;
|
|
26
|
-
const isPublic = host === "0.0.0.0";
|
|
27
|
-
console.log(`
|
|
28
|
-
___ _ _____ _
|
|
29
|
-
/ _ \\ __ _ ___ _ __ | |_| ___| | _____ __
|
|
30
|
-
| |_| |/ _\` |/ _ \\ '_ \\| __| |_ | |/ _ \\ \\ /\\ / /
|
|
31
|
-
| _ | (_| | __/ | | | |_| _| | | (_) \\ V V /
|
|
32
|
-
|_| |_|\\__, |\\___|_| |_|\\__|_| |_|\\___/ \\_/\\_/
|
|
33
|
-
|___/ dashboard v${VERSION}
|
|
34
|
-
|
|
35
|
-
See your agents think.
|
|
36
|
-
|
|
37
|
-
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
38
|
-
\u2502 \u{1F916} Agents \u2502 TRACE FILES \u2502 \u{1F4CA} AgentFlow \u2502 SHOWS YOU \u2502 \u{1F310} Your browser \u2502
|
|
39
|
-
\u2502 Execute tasks, \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500> \u2502 Reads traces, \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500> \u2502 Interactive \u2502
|
|
40
|
-
\u2502 write JSON \u2502 \u2502 builds graphs, \u2502 \u2502 graph, timeline, \u2502
|
|
41
|
-
\u2502 trace files. \u2502 \u2502 serves dashboard.\u2502 \u2502 metrics, health. \u2502
|
|
42
|
-
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
43
|
-
|
|
44
|
-
Runs locally. Your data never leaves your machine.
|
|
45
|
-
|
|
46
|
-
Tabs: \u{1F3AF} Graph \xB7 \u23F1\uFE0F Timeline \xB7 \u{1F4CA} Metrics \xB7 \u{1F6E0}\uFE0F Process Health \xB7 \u26A0\uFE0F Errors
|
|
47
|
-
|
|
48
|
-
Traces: ${config.tracesDir}${((_a = config.dataDirs) == null ? void 0 : _a.length) ? "\n Data dirs: " + config.dataDirs.join("\n ") : ""}
|
|
49
|
-
Loaded: ${traceCount} traces \xB7 ${stats.totalAgents} agents \xB7 ${stats.totalExecutions} executions
|
|
50
|
-
Success: ${stats.globalSuccessRate.toFixed(1)}%${stats.activeAgents > 0 ? ` \xB7 ${stats.activeAgents} active now` : ""}
|
|
51
|
-
CORS: ${config.enableCors ? "enabled" : "disabled"}
|
|
52
|
-
WebSocket: live updates enabled
|
|
53
|
-
|
|
54
|
-
\u2192 http://localhost:${port}${isPublic && lan ? `
|
|
55
|
-
\u2192 http://${lan}:${port} (LAN)` : ""}
|
|
56
|
-
`);
|
|
57
|
-
}
|
|
58
|
-
async function startDashboard() {
|
|
59
|
-
const args = process.argv.slice(2);
|
|
60
|
-
const config = {
|
|
61
|
-
port: 3e3,
|
|
62
|
-
tracesDir: "./traces",
|
|
63
|
-
host: "localhost",
|
|
64
|
-
enableCors: false
|
|
65
|
-
};
|
|
66
|
-
for (let i = 0; i < args.length; i++) {
|
|
67
|
-
switch (args[i]) {
|
|
68
|
-
case "--port":
|
|
69
|
-
case "-p":
|
|
70
|
-
config.port = parseInt(args[++i]) || 3e3;
|
|
71
|
-
break;
|
|
72
|
-
case "--traces":
|
|
73
|
-
case "-t":
|
|
74
|
-
config.tracesDir = args[++i];
|
|
75
|
-
break;
|
|
76
|
-
case "--host":
|
|
77
|
-
case "-h":
|
|
78
|
-
config.host = args[++i];
|
|
79
|
-
break;
|
|
80
|
-
case "--data-dir":
|
|
81
|
-
if (!config.dataDirs) config.dataDirs = [];
|
|
82
|
-
config.dataDirs.push(args[++i]);
|
|
83
|
-
break;
|
|
84
|
-
case "--cors":
|
|
85
|
-
config.enableCors = true;
|
|
86
|
-
break;
|
|
87
|
-
case "--help":
|
|
88
|
-
printHelp();
|
|
89
|
-
process.exit(0);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
const tracesPath = path.resolve(config.tracesDir);
|
|
93
|
-
if (!fs.existsSync(tracesPath)) {
|
|
94
|
-
fs.mkdirSync(tracesPath, { recursive: true });
|
|
95
|
-
}
|
|
96
|
-
config.tracesDir = tracesPath;
|
|
97
|
-
console.log("\nStarting AgentFlow Dashboard...\n");
|
|
98
|
-
const dashboard = new DashboardServer(config);
|
|
99
|
-
process.on("SIGINT", async () => {
|
|
100
|
-
console.log("\n\u{1F6D1} Shutting down dashboard...");
|
|
101
|
-
await dashboard.stop();
|
|
102
|
-
process.exit(0);
|
|
103
|
-
});
|
|
104
|
-
process.on("SIGTERM", async () => {
|
|
105
|
-
await dashboard.stop();
|
|
106
|
-
process.exit(0);
|
|
107
|
-
});
|
|
108
|
-
try {
|
|
109
|
-
await dashboard.start();
|
|
110
|
-
setTimeout(() => {
|
|
111
|
-
const stats = dashboard.getStats();
|
|
112
|
-
const traces = dashboard.getTraces();
|
|
113
|
-
printBanner(config, traces.length, stats);
|
|
114
|
-
}, 1500);
|
|
115
|
-
} catch (error) {
|
|
116
|
-
console.error("\u274C Failed to start dashboard:", error);
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function printHelp() {
|
|
121
|
-
console.log(`
|
|
122
|
-
\u{1F4CA} AgentFlow Dashboard v${VERSION} \u2014 See your agents think.
|
|
123
|
-
|
|
124
|
-
Usage:
|
|
125
|
-
agentflow-dashboard [options]
|
|
126
|
-
npx agentflow-dashboard [options]
|
|
127
|
-
|
|
128
|
-
Options:
|
|
129
|
-
-p, --port <number> Server port (default: 3000)
|
|
130
|
-
-t, --traces <path> Traces directory (default: ./traces)
|
|
131
|
-
-h, --host <address> Host address (default: localhost)
|
|
132
|
-
--data-dir <path> Extra data directory for process discovery (repeatable)
|
|
133
|
-
--cors Enable CORS headers
|
|
134
|
-
--help Show this help message
|
|
135
|
-
|
|
136
|
-
Examples:
|
|
137
|
-
agentflow-dashboard --traces ./traces --host 0.0.0.0 --cors
|
|
138
|
-
agentflow-dashboard -p 8080 -t /var/log/agentflow
|
|
139
|
-
agentflow-dashboard --traces ./traces --data-dir ./workers --data-dir ./cron
|
|
140
|
-
|
|
141
|
-
Tabs:
|
|
142
|
-
\u{1F3AF} Graph Interactive Cytoscape.js execution graph
|
|
143
|
-
\u23F1\uFE0F Timeline Waterfall view of node durations
|
|
144
|
-
\u{1F4CA} Metrics Success rates, durations, node breakdown
|
|
145
|
-
\u{1F6E0}\uFE0F Process Health PID files, systemd, workers, orphans
|
|
146
|
-
\u26A0\uFE0F Errors Failed and hung nodes with metadata
|
|
147
|
-
`);
|
|
148
|
-
}
|
|
2
|
+
startDashboard
|
|
3
|
+
} from "./chunk-EDHK4NJD.js";
|
|
149
4
|
export {
|
|
150
5
|
startDashboard
|
|
151
6
|
};
|