agentflow-dashboard 0.1.3 → 0.1.4

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/index.cjs CHANGED
@@ -49,6 +49,7 @@ var import_chokidar = __toESM(require("chokidar"), 1);
49
49
  var fs = __toESM(require("fs"), 1);
50
50
  var path = __toESM(require("path"), 1);
51
51
  var import_events = require("events");
52
+ var import_agentflow_core = require("agentflow-core");
52
53
  var TraceWatcher = class extends import_events.EventEmitter {
53
54
  watcher;
54
55
  traces = /* @__PURE__ */ new Map();
@@ -81,16 +82,12 @@ var TraceWatcher = class extends import_events.EventEmitter {
81
82
  loadTraceFile(filePath) {
82
83
  try {
83
84
  const content = fs.readFileSync(filePath, "utf8");
84
- const trace = JSON.parse(content);
85
+ const graph = (0, import_agentflow_core.loadGraph)(content);
85
86
  const filename = path.basename(filePath);
86
87
  const stats = fs.statSync(filePath);
87
- trace.filename = filename;
88
- trace.lastModified = stats.mtime.getTime();
89
- if (Array.isArray(trace.nodes)) {
90
- const nodesMap = new Map(trace.nodes);
91
- trace.nodes = nodesMap;
92
- }
93
- this.traces.set(filename, trace);
88
+ graph.filename = filename;
89
+ graph.lastModified = stats.mtime.getTime();
90
+ this.traces.set(filename, graph);
94
91
  return true;
95
92
  } catch (error) {
96
93
  console.error(`Error loading trace file ${filePath}:`, error);
@@ -99,7 +96,7 @@ var TraceWatcher = class extends import_events.EventEmitter {
99
96
  }
100
97
  startWatching() {
101
98
  this.watcher = import_chokidar.default.watch(this.tracesDir, {
102
- ignored: /^\\./,
99
+ ignored: /^\./,
103
100
  persistent: true,
104
101
  ignoreInitial: true
105
102
  });
@@ -142,7 +139,7 @@ var TraceWatcher = class extends import_events.EventEmitter {
142
139
  }
143
140
  getAllTraces() {
144
141
  return Array.from(this.traces.values()).sort((a, b) => {
145
- return (b.lastModified || b.timestamp) - (a.lastModified || a.timestamp);
142
+ return (b.lastModified || b.startTime) - (a.lastModified || a.startTime);
146
143
  });
147
144
  }
148
145
  getTrace(filename) {
@@ -171,7 +168,6 @@ var TraceWatcher = class extends import_events.EventEmitter {
171
168
  console.log("Stopped watching traces directory");
172
169
  }
173
170
  }
174
- // Utility method to get trace statistics
175
171
  getTraceStats() {
176
172
  const total = this.traces.size;
177
173
  const agentCount = this.getAgentIds().length;
@@ -190,81 +186,13 @@ var TraceWatcher = class extends import_events.EventEmitter {
190
186
  }
191
187
  };
192
188
 
193
- // ../core/dist/index.js
194
- function getFailures(graph) {
195
- const failureStatuses = /* @__PURE__ */ new Set(["failed", "hung", "timeout"]);
196
- return [...graph.nodes.values()].filter((node) => failureStatuses.has(node.status));
197
- }
198
- function getHungNodes(graph) {
199
- return [...graph.nodes.values()].filter(
200
- (node) => node.status === "running" && node.endTime === null
201
- );
202
- }
203
- function getDuration(graph) {
204
- const end = graph.endTime ?? Date.now();
205
- return end - graph.startTime;
206
- }
207
- function getDepth(graph) {
208
- const root = graph.nodes.get(graph.rootNodeId);
209
- if (!root) return -1;
210
- function dfs(node, depth) {
211
- if (node.children.length === 0) return depth;
212
- let maxDepth = depth;
213
- for (const childId of node.children) {
214
- const child = graph.nodes.get(childId);
215
- if (!child) continue;
216
- const childDepth = dfs(child, depth + 1);
217
- if (childDepth > maxDepth) maxDepth = childDepth;
218
- }
219
- return maxDepth;
220
- }
221
- return dfs(root, 0);
222
- }
223
- function getStats(graph) {
224
- const byStatus = {
225
- running: 0,
226
- completed: 0,
227
- failed: 0,
228
- hung: 0,
229
- timeout: 0
230
- };
231
- const byType = {
232
- agent: 0,
233
- tool: 0,
234
- subagent: 0,
235
- wait: 0,
236
- decision: 0,
237
- custom: 0
238
- };
239
- let failureCount = 0;
240
- let hungCount = 0;
241
- for (const node of graph.nodes.values()) {
242
- byStatus[node.status]++;
243
- byType[node.type]++;
244
- if (node.status === "failed" || node.status === "timeout" || node.status === "hung") {
245
- failureCount++;
246
- }
247
- if (node.status === "running" && node.endTime === null) {
248
- hungCount++;
249
- }
250
- }
251
- return {
252
- totalNodes: graph.nodes.size,
253
- byStatus,
254
- byType,
255
- depth: getDepth(graph),
256
- duration: getDuration(graph),
257
- failureCount,
258
- hungCount
259
- };
260
- }
261
-
262
189
  // src/stats.ts
190
+ var import_agentflow_core2 = require("agentflow-core");
263
191
  var AgentStats = class {
264
192
  agentMetrics = /* @__PURE__ */ new Map();
265
193
  processedTraces = /* @__PURE__ */ new Set();
266
194
  processTrace(trace) {
267
- const traceKey = `${trace.filename || trace.agentId}-${trace.timestamp}`;
195
+ const traceKey = `${trace.filename || trace.agentId}-${trace.startTime}`;
268
196
  if (this.processedTraces.has(traceKey)) {
269
197
  return;
270
198
  }
@@ -287,7 +215,7 @@ var AgentStats = class {
287
215
  }
288
216
  const analysis = this.analyzeExecution(trace);
289
217
  metrics.totalExecutions++;
290
- metrics.lastExecution = Math.max(metrics.lastExecution, trace.timestamp);
218
+ metrics.lastExecution = Math.max(metrics.lastExecution, trace.startTime);
291
219
  const trigger = trace.trigger || "unknown";
292
220
  metrics.triggers[trigger] = (metrics.triggers[trigger] || 0) + 1;
293
221
  if (analysis.success) {
@@ -302,7 +230,7 @@ var AgentStats = class {
302
230
  metrics.avgExecutionTime = (currentAvg * (count - 1) + analysis.executionTime) / count;
303
231
  }
304
232
  metrics.recentActivity.push({
305
- timestamp: trace.timestamp,
233
+ timestamp: trace.startTime,
306
234
  success: analysis.success,
307
235
  executionTime: analysis.executionTime,
308
236
  trigger
@@ -314,23 +242,22 @@ var AgentStats = class {
314
242
  }
315
243
  analyzeExecution(trace) {
316
244
  try {
317
- const stats = getStats(trace);
318
- const failures = getFailures(trace);
319
- const hungNodes = getHungNodes(trace);
245
+ const stats = (0, import_agentflow_core2.getStats)(trace);
246
+ const failures = (0, import_agentflow_core2.getFailures)(trace);
247
+ const hungNodes = (0, import_agentflow_core2.getHungNodes)(trace);
320
248
  return {
321
249
  success: failures.length === 0 && hungNodes.length === 0,
322
- executionTime: stats.totalTime || 0,
250
+ executionTime: stats.duration || 0,
323
251
  nodeCount: stats.totalNodes || 0,
324
252
  failureCount: failures.length,
325
253
  hungCount: hungNodes.length
326
254
  };
327
255
  } catch (error) {
328
256
  console.warn("Error analyzing trace with AgentFlow:", error);
329
- const nodes = trace.nodes instanceof Map ? Array.from(trace.nodes.values()) : Array.isArray(trace.nodes) ? trace.nodes.map(([, node]) => node) : [];
257
+ const nodes = trace.nodes instanceof Map ? Array.from(trace.nodes.values()) : [];
330
258
  const failedNodes = nodes.filter((node) => node.status === "failed").length;
331
- const success = failedNodes === 0;
332
259
  return {
333
- success,
260
+ success: failedNodes === 0,
334
261
  executionTime: 0,
335
262
  nodeCount: nodes.length,
336
263
  failureCount: failedNodes,
@@ -420,7 +347,6 @@ var AgentStats = class {
420
347
  hourlySuccessRate: recentExecutions > 0 ? Math.round((recentExecutions - recentFailures) / recentExecutions * 1e4) / 100 : 0
421
348
  };
422
349
  }
423
- // Clear old data (useful for long-running dashboard instances)
424
350
  cleanup() {
425
351
  const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1e3;
426
352
  for (const [agentId, metrics] of this.agentMetrics.entries()) {
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ import chokidar from "chokidar";
13
13
  import * as fs from "fs";
14
14
  import * as path from "path";
15
15
  import { EventEmitter } from "events";
16
+ import { loadGraph } from "agentflow-core";
16
17
  var TraceWatcher = class extends EventEmitter {
17
18
  watcher;
18
19
  traces = /* @__PURE__ */ new Map();
@@ -45,16 +46,12 @@ var TraceWatcher = class extends EventEmitter {
45
46
  loadTraceFile(filePath) {
46
47
  try {
47
48
  const content = fs.readFileSync(filePath, "utf8");
48
- const trace = JSON.parse(content);
49
+ const graph = loadGraph(content);
49
50
  const filename = path.basename(filePath);
50
51
  const stats = fs.statSync(filePath);
51
- trace.filename = filename;
52
- trace.lastModified = stats.mtime.getTime();
53
- if (Array.isArray(trace.nodes)) {
54
- const nodesMap = new Map(trace.nodes);
55
- trace.nodes = nodesMap;
56
- }
57
- this.traces.set(filename, trace);
52
+ graph.filename = filename;
53
+ graph.lastModified = stats.mtime.getTime();
54
+ this.traces.set(filename, graph);
58
55
  return true;
59
56
  } catch (error) {
60
57
  console.error(`Error loading trace file ${filePath}:`, error);
@@ -63,7 +60,7 @@ var TraceWatcher = class extends EventEmitter {
63
60
  }
64
61
  startWatching() {
65
62
  this.watcher = chokidar.watch(this.tracesDir, {
66
- ignored: /^\\./,
63
+ ignored: /^\./,
67
64
  persistent: true,
68
65
  ignoreInitial: true
69
66
  });
@@ -106,7 +103,7 @@ var TraceWatcher = class extends EventEmitter {
106
103
  }
107
104
  getAllTraces() {
108
105
  return Array.from(this.traces.values()).sort((a, b) => {
109
- return (b.lastModified || b.timestamp) - (a.lastModified || a.timestamp);
106
+ return (b.lastModified || b.startTime) - (a.lastModified || a.startTime);
110
107
  });
111
108
  }
112
109
  getTrace(filename) {
@@ -135,7 +132,6 @@ var TraceWatcher = class extends EventEmitter {
135
132
  console.log("Stopped watching traces directory");
136
133
  }
137
134
  }
138
- // Utility method to get trace statistics
139
135
  getTraceStats() {
140
136
  const total = this.traces.size;
141
137
  const agentCount = this.getAgentIds().length;
@@ -154,81 +150,13 @@ var TraceWatcher = class extends EventEmitter {
154
150
  }
155
151
  };
156
152
 
157
- // ../core/dist/index.js
158
- function getFailures(graph) {
159
- const failureStatuses = /* @__PURE__ */ new Set(["failed", "hung", "timeout"]);
160
- return [...graph.nodes.values()].filter((node) => failureStatuses.has(node.status));
161
- }
162
- function getHungNodes(graph) {
163
- return [...graph.nodes.values()].filter(
164
- (node) => node.status === "running" && node.endTime === null
165
- );
166
- }
167
- function getDuration(graph) {
168
- const end = graph.endTime ?? Date.now();
169
- return end - graph.startTime;
170
- }
171
- function getDepth(graph) {
172
- const root = graph.nodes.get(graph.rootNodeId);
173
- if (!root) return -1;
174
- function dfs(node, depth) {
175
- if (node.children.length === 0) return depth;
176
- let maxDepth = depth;
177
- for (const childId of node.children) {
178
- const child = graph.nodes.get(childId);
179
- if (!child) continue;
180
- const childDepth = dfs(child, depth + 1);
181
- if (childDepth > maxDepth) maxDepth = childDepth;
182
- }
183
- return maxDepth;
184
- }
185
- return dfs(root, 0);
186
- }
187
- function getStats(graph) {
188
- const byStatus = {
189
- running: 0,
190
- completed: 0,
191
- failed: 0,
192
- hung: 0,
193
- timeout: 0
194
- };
195
- const byType = {
196
- agent: 0,
197
- tool: 0,
198
- subagent: 0,
199
- wait: 0,
200
- decision: 0,
201
- custom: 0
202
- };
203
- let failureCount = 0;
204
- let hungCount = 0;
205
- for (const node of graph.nodes.values()) {
206
- byStatus[node.status]++;
207
- byType[node.type]++;
208
- if (node.status === "failed" || node.status === "timeout" || node.status === "hung") {
209
- failureCount++;
210
- }
211
- if (node.status === "running" && node.endTime === null) {
212
- hungCount++;
213
- }
214
- }
215
- return {
216
- totalNodes: graph.nodes.size,
217
- byStatus,
218
- byType,
219
- depth: getDepth(graph),
220
- duration: getDuration(graph),
221
- failureCount,
222
- hungCount
223
- };
224
- }
225
-
226
153
  // src/stats.ts
154
+ import { getStats, getFailures, getHungNodes } from "agentflow-core";
227
155
  var AgentStats = class {
228
156
  agentMetrics = /* @__PURE__ */ new Map();
229
157
  processedTraces = /* @__PURE__ */ new Set();
230
158
  processTrace(trace) {
231
- const traceKey = `${trace.filename || trace.agentId}-${trace.timestamp}`;
159
+ const traceKey = `${trace.filename || trace.agentId}-${trace.startTime}`;
232
160
  if (this.processedTraces.has(traceKey)) {
233
161
  return;
234
162
  }
@@ -251,7 +179,7 @@ var AgentStats = class {
251
179
  }
252
180
  const analysis = this.analyzeExecution(trace);
253
181
  metrics.totalExecutions++;
254
- metrics.lastExecution = Math.max(metrics.lastExecution, trace.timestamp);
182
+ metrics.lastExecution = Math.max(metrics.lastExecution, trace.startTime);
255
183
  const trigger = trace.trigger || "unknown";
256
184
  metrics.triggers[trigger] = (metrics.triggers[trigger] || 0) + 1;
257
185
  if (analysis.success) {
@@ -266,7 +194,7 @@ var AgentStats = class {
266
194
  metrics.avgExecutionTime = (currentAvg * (count - 1) + analysis.executionTime) / count;
267
195
  }
268
196
  metrics.recentActivity.push({
269
- timestamp: trace.timestamp,
197
+ timestamp: trace.startTime,
270
198
  success: analysis.success,
271
199
  executionTime: analysis.executionTime,
272
200
  trigger
@@ -283,18 +211,17 @@ var AgentStats = class {
283
211
  const hungNodes = getHungNodes(trace);
284
212
  return {
285
213
  success: failures.length === 0 && hungNodes.length === 0,
286
- executionTime: stats.totalTime || 0,
214
+ executionTime: stats.duration || 0,
287
215
  nodeCount: stats.totalNodes || 0,
288
216
  failureCount: failures.length,
289
217
  hungCount: hungNodes.length
290
218
  };
291
219
  } catch (error) {
292
220
  console.warn("Error analyzing trace with AgentFlow:", error);
293
- const nodes = trace.nodes instanceof Map ? Array.from(trace.nodes.values()) : Array.isArray(trace.nodes) ? trace.nodes.map(([, node]) => node) : [];
221
+ const nodes = trace.nodes instanceof Map ? Array.from(trace.nodes.values()) : [];
294
222
  const failedNodes = nodes.filter((node) => node.status === "failed").length;
295
- const success = failedNodes === 0;
296
223
  return {
297
- success,
224
+ success: failedNodes === 0,
298
225
  executionTime: 0,
299
226
  nodeCount: nodes.length,
300
227
  failureCount: failedNodes,
@@ -384,7 +311,6 @@ var AgentStats = class {
384
311
  hourlySuccessRate: recentExecutions > 0 ? Math.round((recentExecutions - recentFailures) / recentExecutions * 1e4) / 100 : 0
385
312
  };
386
313
  }
387
- // Clear old data (useful for long-running dashboard instances)
388
314
  cleanup() {
389
315
  const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1e3;
390
316
  for (const [agentId, metrics] of this.agentMetrics.entries()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentflow-dashboard",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Real-time monitoring dashboard for AgentFlow - Visualize agent execution graphs and performance",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -27,6 +27,7 @@
27
27
  "start": "node dist/server.js"
28
28
  },
29
29
  "dependencies": {
30
+ "agentflow-core": "^0.1.4",
30
31
  "express": "^4.18.2",
31
32
  "ws": "^8.16.0",
32
33
  "chokidar": "^3.5.3"