agentflow-dashboard 0.7.0 → 0.7.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 +5 -1
- package/dist/{chunk-GA2Y6E62.js → chunk-3S4AAIPA.js} +60 -38
- package/dist/cli.cjs +60 -38
- package/dist/cli.js +1 -1
- package/dist/client/assets/index-DSuI0NgP.js +50 -0
- package/dist/client/index.html +1 -1
- package/dist/index.cjs +60 -38
- package/dist/index.js +1 -1
- package/dist/server.cjs +60 -38
- package/dist/server.js +1 -1
- package/package.json +1 -1
- package/dist/client/assets/index-BQUye2Lc.js +0 -50
package/README.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
# AgentFlow Dashboard v0.
|
|
1
|
+
# AgentFlow Dashboard v0.7.1
|
|
2
2
|
|
|
3
3
|
Real-time monitoring dashboard for AI agent systems. Visualize execution graphs, session transcripts, and performance metrics from any agent framework.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
+
### Error Surfacing
|
|
8
|
+
- **Crystal-clear error tracking** — Failed node errors (`state.error` and `metadata.error`) are surfaced in all detail views: Flame Chart, Agent Flow, Summary, and Transcript
|
|
9
|
+
- Error messages like `"403 Forbidden — Key limit exceeded"` appear directly in the UI — no more digging through log files
|
|
10
|
+
|
|
7
11
|
### Universal Agent Monitoring
|
|
8
12
|
- **Multi-Format Ingestion** - AgentFlow JSON traces, JSONL session logs (Claude Code compatible), structured log files, cron run logs
|
|
9
13
|
- **Auto-Discovery** - Recursively scans directories for trace files, watches for new files in real-time
|
|
@@ -2061,11 +2061,23 @@ async function startDashboard() {
|
|
|
2061
2061
|
case "--cors":
|
|
2062
2062
|
config.enableCors = true;
|
|
2063
2063
|
break;
|
|
2064
|
+
case "--no-collector":
|
|
2065
|
+
config.enableCollector = false;
|
|
2066
|
+
break;
|
|
2067
|
+
case "--collector-token":
|
|
2068
|
+
config.collectorAuthToken = args[++i];
|
|
2069
|
+
break;
|
|
2064
2070
|
case "--help":
|
|
2065
2071
|
printHelp();
|
|
2066
2072
|
process.exit(0);
|
|
2067
2073
|
}
|
|
2068
2074
|
}
|
|
2075
|
+
if (!config.collectorAuthToken && process.env.AGENTFLOW_COLLECTOR_TOKEN) {
|
|
2076
|
+
config.collectorAuthToken = process.env.AGENTFLOW_COLLECTOR_TOKEN;
|
|
2077
|
+
}
|
|
2078
|
+
if (process.env.AGENTFLOW_NO_COLLECTOR === "true") {
|
|
2079
|
+
config.enableCollector = false;
|
|
2080
|
+
}
|
|
2069
2081
|
const tracesPath = path2.resolve(config.tracesDir);
|
|
2070
2082
|
if (!fs2.existsSync(tracesPath)) {
|
|
2071
2083
|
fs2.mkdirSync(tracesPath, { recursive: true });
|
|
@@ -2108,6 +2120,8 @@ Options:
|
|
|
2108
2120
|
-h, --host <address> Host address (default: localhost)
|
|
2109
2121
|
--data-dir <path> Extra data directory for process discovery (repeatable)
|
|
2110
2122
|
--cors Enable CORS headers
|
|
2123
|
+
--no-collector Disable OTLP trace collector (POST /v1/traces)
|
|
2124
|
+
--collector-token <tok> Require auth token for collector (or set AGENTFLOW_COLLECTOR_TOKEN)
|
|
2111
2125
|
--help Show this help message
|
|
2112
2126
|
|
|
2113
2127
|
Examples:
|
|
@@ -2686,46 +2700,54 @@ var DashboardServer = class {
|
|
|
2686
2700
|
res.status(500).json({ error: "Failed to update directory config" });
|
|
2687
2701
|
}
|
|
2688
2702
|
});
|
|
2689
|
-
this.
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2703
|
+
if (this.config.enableCollector !== false) {
|
|
2704
|
+
this.app.post("/v1/traces", express.json({ limit: "10mb" }), (req, res) => {
|
|
2705
|
+
try {
|
|
2706
|
+
if (this.config.collectorAuthToken) {
|
|
2707
|
+
const auth = req.headers.authorization;
|
|
2708
|
+
if (!auth || auth !== `Bearer ${this.config.collectorAuthToken}`) {
|
|
2709
|
+
return res.status(401).json({ error: "Unauthorized \u2014 provide Authorization: Bearer <token>" });
|
|
2710
|
+
}
|
|
2697
2711
|
}
|
|
2698
|
-
const
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2712
|
+
const traces = parseOtlpPayload(req.body);
|
|
2713
|
+
let ingested = 0;
|
|
2714
|
+
for (const trace of traces) {
|
|
2715
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
2716
|
+
for (const [id, node] of Object.entries(trace.nodes)) {
|
|
2717
|
+
nodes.set(id, { ...node, state: {} });
|
|
2718
|
+
}
|
|
2719
|
+
const watched = {
|
|
2720
|
+
id: trace.id,
|
|
2721
|
+
rootNodeId: Object.keys(trace.nodes)[0] ?? "",
|
|
2722
|
+
agentId: trace.agentId,
|
|
2723
|
+
name: trace.name,
|
|
2724
|
+
trigger: trace.trigger,
|
|
2725
|
+
startTime: trace.startTime,
|
|
2726
|
+
endTime: trace.endTime,
|
|
2727
|
+
status: trace.status,
|
|
2728
|
+
nodes,
|
|
2729
|
+
edges: [],
|
|
2730
|
+
events: [],
|
|
2731
|
+
metadata: { ...trace.metadata, adapterSource: "otel" },
|
|
2732
|
+
sessionEvents: [],
|
|
2733
|
+
sourceType: "session",
|
|
2734
|
+
filename: `otel-${trace.id}`,
|
|
2735
|
+
lastModified: Date.now(),
|
|
2736
|
+
sourceDir: "http-collector"
|
|
2737
|
+
};
|
|
2738
|
+
this.watcher.traces.set(`otel:${trace.id}`, watched);
|
|
2739
|
+
ingested++;
|
|
2740
|
+
}
|
|
2741
|
+
if (ingested > 0) {
|
|
2742
|
+
this.broadcast({ type: "traces-updated", count: ingested });
|
|
2743
|
+
}
|
|
2744
|
+
res.json({ ok: true, tracesIngested: ingested });
|
|
2745
|
+
} catch (error) {
|
|
2746
|
+
console.error("OTLP collector error:", error);
|
|
2747
|
+
res.status(400).json({ error: "Failed to parse OTLP payload" });
|
|
2722
2748
|
}
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
console.error("OTLP collector error:", error);
|
|
2726
|
-
res.status(400).json({ error: "Failed to parse OTLP payload" });
|
|
2727
|
-
}
|
|
2728
|
-
});
|
|
2749
|
+
});
|
|
2750
|
+
}
|
|
2729
2751
|
this.app.get("/health", (_req, res) => {
|
|
2730
2752
|
res.json({
|
|
2731
2753
|
status: "ok",
|
package/dist/cli.cjs
CHANGED
|
@@ -2563,46 +2563,54 @@ var DashboardServer = class {
|
|
|
2563
2563
|
res.status(500).json({ error: "Failed to update directory config" });
|
|
2564
2564
|
}
|
|
2565
2565
|
});
|
|
2566
|
-
this.
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2566
|
+
if (this.config.enableCollector !== false) {
|
|
2567
|
+
this.app.post("/v1/traces", import_express.default.json({ limit: "10mb" }), (req, res) => {
|
|
2568
|
+
try {
|
|
2569
|
+
if (this.config.collectorAuthToken) {
|
|
2570
|
+
const auth = req.headers.authorization;
|
|
2571
|
+
if (!auth || auth !== `Bearer ${this.config.collectorAuthToken}`) {
|
|
2572
|
+
return res.status(401).json({ error: "Unauthorized \u2014 provide Authorization: Bearer <token>" });
|
|
2573
|
+
}
|
|
2574
2574
|
}
|
|
2575
|
-
const
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2575
|
+
const traces = parseOtlpPayload(req.body);
|
|
2576
|
+
let ingested = 0;
|
|
2577
|
+
for (const trace of traces) {
|
|
2578
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
2579
|
+
for (const [id, node] of Object.entries(trace.nodes)) {
|
|
2580
|
+
nodes.set(id, { ...node, state: {} });
|
|
2581
|
+
}
|
|
2582
|
+
const watched = {
|
|
2583
|
+
id: trace.id,
|
|
2584
|
+
rootNodeId: Object.keys(trace.nodes)[0] ?? "",
|
|
2585
|
+
agentId: trace.agentId,
|
|
2586
|
+
name: trace.name,
|
|
2587
|
+
trigger: trace.trigger,
|
|
2588
|
+
startTime: trace.startTime,
|
|
2589
|
+
endTime: trace.endTime,
|
|
2590
|
+
status: trace.status,
|
|
2591
|
+
nodes,
|
|
2592
|
+
edges: [],
|
|
2593
|
+
events: [],
|
|
2594
|
+
metadata: { ...trace.metadata, adapterSource: "otel" },
|
|
2595
|
+
sessionEvents: [],
|
|
2596
|
+
sourceType: "session",
|
|
2597
|
+
filename: `otel-${trace.id}`,
|
|
2598
|
+
lastModified: Date.now(),
|
|
2599
|
+
sourceDir: "http-collector"
|
|
2600
|
+
};
|
|
2601
|
+
this.watcher.traces.set(`otel:${trace.id}`, watched);
|
|
2602
|
+
ingested++;
|
|
2603
|
+
}
|
|
2604
|
+
if (ingested > 0) {
|
|
2605
|
+
this.broadcast({ type: "traces-updated", count: ingested });
|
|
2606
|
+
}
|
|
2607
|
+
res.json({ ok: true, tracesIngested: ingested });
|
|
2608
|
+
} catch (error) {
|
|
2609
|
+
console.error("OTLP collector error:", error);
|
|
2610
|
+
res.status(400).json({ error: "Failed to parse OTLP payload" });
|
|
2599
2611
|
}
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
console.error("OTLP collector error:", error);
|
|
2603
|
-
res.status(400).json({ error: "Failed to parse OTLP payload" });
|
|
2604
|
-
}
|
|
2605
|
-
});
|
|
2612
|
+
});
|
|
2613
|
+
}
|
|
2606
2614
|
this.app.get("/health", (_req, res) => {
|
|
2607
2615
|
res.json({
|
|
2608
2616
|
status: "ok",
|
|
@@ -2981,11 +2989,23 @@ async function startDashboard() {
|
|
|
2981
2989
|
case "--cors":
|
|
2982
2990
|
config.enableCors = true;
|
|
2983
2991
|
break;
|
|
2992
|
+
case "--no-collector":
|
|
2993
|
+
config.enableCollector = false;
|
|
2994
|
+
break;
|
|
2995
|
+
case "--collector-token":
|
|
2996
|
+
config.collectorAuthToken = args[++i];
|
|
2997
|
+
break;
|
|
2984
2998
|
case "--help":
|
|
2985
2999
|
printHelp();
|
|
2986
3000
|
process.exit(0);
|
|
2987
3001
|
}
|
|
2988
3002
|
}
|
|
3003
|
+
if (!config.collectorAuthToken && process.env.AGENTFLOW_COLLECTOR_TOKEN) {
|
|
3004
|
+
config.collectorAuthToken = process.env.AGENTFLOW_COLLECTOR_TOKEN;
|
|
3005
|
+
}
|
|
3006
|
+
if (process.env.AGENTFLOW_NO_COLLECTOR === "true") {
|
|
3007
|
+
config.enableCollector = false;
|
|
3008
|
+
}
|
|
2989
3009
|
const tracesPath = path3.resolve(config.tracesDir);
|
|
2990
3010
|
if (!fs3.existsSync(tracesPath)) {
|
|
2991
3011
|
fs3.mkdirSync(tracesPath, { recursive: true });
|
|
@@ -3028,6 +3048,8 @@ Options:
|
|
|
3028
3048
|
-h, --host <address> Host address (default: localhost)
|
|
3029
3049
|
--data-dir <path> Extra data directory for process discovery (repeatable)
|
|
3030
3050
|
--cors Enable CORS headers
|
|
3051
|
+
--no-collector Disable OTLP trace collector (POST /v1/traces)
|
|
3052
|
+
--collector-token <tok> Require auth token for collector (or set AGENTFLOW_COLLECTOR_TOKEN)
|
|
3031
3053
|
--help Show this help message
|
|
3032
3054
|
|
|
3033
3055
|
Examples:
|