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/dist/public/dashboard.js
CHANGED
|
@@ -30,6 +30,7 @@ class AgentFlowDashboard {
|
|
|
30
30
|
this.searchFilter = '';
|
|
31
31
|
this.statusFilter = 'all';
|
|
32
32
|
this.timeRangeFilter = 'all';
|
|
33
|
+
this.activityFilter = 'all';
|
|
33
34
|
this.isLive = true;
|
|
34
35
|
|
|
35
36
|
this.cy = null;
|
|
@@ -239,6 +240,15 @@ class AgentFlowDashboard {
|
|
|
239
240
|
self.renderTraceList();
|
|
240
241
|
});
|
|
241
242
|
|
|
243
|
+
// Activity filter dropdown (if exists)
|
|
244
|
+
var activityFilter = document.getElementById('activityFilter');
|
|
245
|
+
if (activityFilter) {
|
|
246
|
+
activityFilter.addEventListener('change', function(e) {
|
|
247
|
+
self.activityFilter = e.target.value;
|
|
248
|
+
self.renderTraceList();
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
242
252
|
// Toolbar buttons
|
|
243
253
|
document.getElementById('btnFit').addEventListener('click', function() {
|
|
244
254
|
if (self.cy) self.cy.fit(50);
|
|
@@ -339,7 +349,8 @@ class AgentFlowDashboard {
|
|
|
339
349
|
}
|
|
340
350
|
|
|
341
351
|
var r = this.processHealth;
|
|
342
|
-
var hasContent = r.pidFile || r.systemd || r.workers || (r.orphans && r.orphans.length > 0) ||
|
|
352
|
+
var hasContent = r.pidFile || r.systemd || r.workers || (r.orphans && r.orphans.length > 0) ||
|
|
353
|
+
(r.osProcesses && r.osProcesses.length > 0) || (r.problems && r.problems.length > 0);
|
|
343
354
|
if (!hasContent) {
|
|
344
355
|
section.style.display = 'none';
|
|
345
356
|
return;
|
|
@@ -348,6 +359,7 @@ class AgentFlowDashboard {
|
|
|
348
359
|
section.style.display = '';
|
|
349
360
|
var html = '<h4>Process Health</h4>';
|
|
350
361
|
|
|
362
|
+
// PID File section
|
|
351
363
|
if (r.pidFile) {
|
|
352
364
|
var pf = r.pidFile;
|
|
353
365
|
var cls = pf.alive && pf.matchesProcess ? 'ok' : pf.stale ? 'bad' : 'warn';
|
|
@@ -358,6 +370,7 @@ class AgentFlowDashboard {
|
|
|
358
370
|
html += '</span></div>';
|
|
359
371
|
}
|
|
360
372
|
|
|
373
|
+
// Systemd section
|
|
361
374
|
if (r.systemd) {
|
|
362
375
|
var sd = r.systemd;
|
|
363
376
|
var sdCls = sd.activeState === 'active' ? 'ok' : sd.failed ? 'bad' : 'warn';
|
|
@@ -369,49 +382,298 @@ class AgentFlowDashboard {
|
|
|
369
382
|
html += '</span></div>';
|
|
370
383
|
}
|
|
371
384
|
|
|
385
|
+
// Workers detailed view
|
|
372
386
|
if (r.workers && r.workers.workers) {
|
|
373
|
-
html += '<div class="ph-
|
|
387
|
+
html += '<div class="ph-section">';
|
|
374
388
|
html += '<span class="ph-label">Workers</span>';
|
|
375
|
-
html += '<div class="
|
|
389
|
+
html += '<div class="process-grid">';
|
|
376
390
|
for (var i = 0; i < r.workers.workers.length; i++) {
|
|
377
391
|
var worker = r.workers.workers[i];
|
|
378
|
-
var
|
|
379
|
-
html += '<
|
|
380
|
-
html += '<
|
|
392
|
+
var statusCls = worker.alive ? 'ok' : worker.stale ? 'bad' : 'warn';
|
|
393
|
+
html += '<div class="worker-card ' + statusCls + '">';
|
|
394
|
+
html += '<div class="worker-name">' + escapeHtml(worker.name) + '</div>';
|
|
395
|
+
html += '<div class="worker-details">';
|
|
396
|
+
html += '<span>PID: ' + (worker.pid || '-') + '</span>';
|
|
397
|
+
html += '<span>' + escapeHtml(worker.declaredStatus) + '</span>';
|
|
398
|
+
html += '</div></div>';
|
|
381
399
|
}
|
|
382
400
|
html += '</div></div>';
|
|
383
401
|
}
|
|
384
402
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
html += '<
|
|
390
|
-
html += '</
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
403
|
+
// Agent Services - categorize processes and build tree
|
|
404
|
+
var categorized = this.categorizeProcesses(r.osProcesses || []);
|
|
405
|
+
|
|
406
|
+
if (categorized.agents.length > 0) {
|
|
407
|
+
html += '<div class="ph-section">';
|
|
408
|
+
html += '<span class="ph-label">Agent Services (' + categorized.agents.length + ')</span>';
|
|
409
|
+
|
|
410
|
+
// Build process tree for agents
|
|
411
|
+
var agentTree = this.buildProcessTree(categorized.agents);
|
|
412
|
+
html += this.renderProcessTree(agentTree, 'agent');
|
|
413
|
+
html += '</div>';
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Infrastructure processes
|
|
417
|
+
if (categorized.infrastructure.length > 0) {
|
|
418
|
+
html += '<div class="ph-section">';
|
|
419
|
+
html += '<span class="ph-label">Infrastructure (' + categorized.infrastructure.length + ')</span>';
|
|
420
|
+
|
|
421
|
+
// Build process tree for infrastructure
|
|
422
|
+
var infraTree = this.buildProcessTree(categorized.infrastructure);
|
|
423
|
+
html += this.renderProcessTree(infraTree, 'infrastructure');
|
|
424
|
+
html += '</div>';
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Orphaned processes (uncategorized)
|
|
428
|
+
var uncategorized = this.getUncategorizedOrphans(r.orphans || [], categorized);
|
|
429
|
+
if (uncategorized.length > 0) {
|
|
430
|
+
html += '<div class="ph-section">';
|
|
431
|
+
html += '<span class="ph-label">Orphans (' + uncategorized.length + ')</span>';
|
|
432
|
+
html += '<div class="orphan-list">';
|
|
433
|
+
for (var j = 0; j < uncategorized.length; j++) {
|
|
434
|
+
var o = uncategorized[j];
|
|
435
|
+
html += '<div class="orphan-row">';
|
|
436
|
+
html += '<span class="orphan-pid">PID ' + o.pid + '</span>';
|
|
437
|
+
html += '<span class="orphan-resources">CPU: ' + escapeHtml(o.cpu) + '% | MEM: ' + escapeHtml(o.mem) + '%</span>';
|
|
438
|
+
html += '<span class="orphan-cmd" title="' + escapeHtml(o.cmdline || o.command) + '">' +
|
|
439
|
+
escapeHtml((o.command || '').substring(0, 60)) + (o.command && o.command.length > 60 ? '...' : '') + '</span>';
|
|
440
|
+
html += '</div>';
|
|
400
441
|
}
|
|
401
|
-
html += '</
|
|
442
|
+
html += '</div></div>';
|
|
402
443
|
}
|
|
403
444
|
|
|
445
|
+
// Problems section
|
|
404
446
|
if (r.problems && r.problems.length > 0) {
|
|
405
|
-
html += '<
|
|
447
|
+
html += '<div class="ph-section problems-section">';
|
|
448
|
+
html += '<span class="ph-label problems">Issues</span>';
|
|
449
|
+
html += '<div class="problems-list">';
|
|
406
450
|
for (var k = 0; k < r.problems.length; k++) {
|
|
407
|
-
html += '<
|
|
451
|
+
html += '<div class="problem-item">⚠️ ' + escapeHtml(r.problems[k]) + '</div>';
|
|
408
452
|
}
|
|
409
|
-
html += '</
|
|
453
|
+
html += '</div></div>';
|
|
410
454
|
}
|
|
411
455
|
|
|
412
456
|
section.innerHTML = html;
|
|
413
457
|
}
|
|
414
458
|
|
|
459
|
+
// Helper to categorize processes with enhanced detection and tagging
|
|
460
|
+
categorizeProcesses(processes) {
|
|
461
|
+
var agents = [];
|
|
462
|
+
var infrastructure = [];
|
|
463
|
+
|
|
464
|
+
console.log('Categorizing', processes.length, 'processes');
|
|
465
|
+
|
|
466
|
+
for (var i = 0; i < processes.length; i++) {
|
|
467
|
+
var proc = processes[i];
|
|
468
|
+
var cmd = proc.command.toLowerCase();
|
|
469
|
+
var cmdline = (proc.cmdline || '').toLowerCase();
|
|
470
|
+
var service = this.detectAgentService(cmd, cmdline);
|
|
471
|
+
var component = this.detectInfrastructureComponent(cmd, cmdline);
|
|
472
|
+
var activityTag = this.getProcessActivityTag(cmd, cmdline, proc.pid);
|
|
473
|
+
|
|
474
|
+
if (component) {
|
|
475
|
+
infrastructure.push({
|
|
476
|
+
component: component,
|
|
477
|
+
pid: proc.pid,
|
|
478
|
+
cpu: proc.cpu,
|
|
479
|
+
mem: proc.mem,
|
|
480
|
+
elapsed: proc.elapsed,
|
|
481
|
+
ppid: proc.ppid,
|
|
482
|
+
cmdline: proc.cmdline || proc.command,
|
|
483
|
+
tag: activityTag
|
|
484
|
+
});
|
|
485
|
+
console.log('Detected infrastructure:', proc.pid, component, 'tag:', activityTag);
|
|
486
|
+
}
|
|
487
|
+
else if (service) {
|
|
488
|
+
agents.push({
|
|
489
|
+
service: service,
|
|
490
|
+
pid: proc.pid,
|
|
491
|
+
cpu: proc.cpu,
|
|
492
|
+
mem: proc.mem,
|
|
493
|
+
elapsed: proc.elapsed,
|
|
494
|
+
ppid: proc.ppid,
|
|
495
|
+
cmdline: proc.cmdline || proc.command,
|
|
496
|
+
tag: activityTag
|
|
497
|
+
});
|
|
498
|
+
console.log('Detected agent:', proc.pid, service, 'tag:', activityTag);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
console.log('Categorization result:', {agents: agents.length, infrastructure: infrastructure.length});
|
|
503
|
+
return { agents: agents, infrastructure: infrastructure };
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Enhanced agent service detection
|
|
507
|
+
detectAgentService(cmd, cmdline) {
|
|
508
|
+
// AgentFlow processes
|
|
509
|
+
if (cmdline.includes('agentflow-dashboard')) return 'AgentFlow Dashboard';
|
|
510
|
+
if (cmdline.includes('agentflow live')) return 'AgentFlow Live';
|
|
511
|
+
if (cmdline.includes('agentflow') && cmdline.includes('server')) return 'AgentFlow Server';
|
|
512
|
+
|
|
513
|
+
// OpenClaw ecosystem
|
|
514
|
+
if (cmdline.includes('openclaw-gateway')) return 'OpenClaw Gateway';
|
|
515
|
+
if (cmdline.includes('openclaw-agent')) return 'OpenClaw Agent';
|
|
516
|
+
if (cmdline.includes('openclaw') && cmdline.includes('worker')) return 'OpenClaw Worker';
|
|
517
|
+
if (cmdline.includes('claw-gateway')) return 'Claw Gateway';
|
|
518
|
+
|
|
519
|
+
// Alfred workers and processes
|
|
520
|
+
if (cmdline.includes('alfred') && cmdline.includes('curator')) return 'Alfred Curator';
|
|
521
|
+
if (cmdline.includes('alfred') && cmdline.includes('janitor')) return 'Alfred Janitor';
|
|
522
|
+
if (cmdline.includes('alfred') && cmdline.includes('distiller')) return 'Alfred Distiller';
|
|
523
|
+
if (cmdline.includes('alfred') && cmdline.includes('surveyor')) return 'Alfred Surveyor';
|
|
524
|
+
if (cmdline.includes('alfred') && (cmdline.includes('worker') || cmdline.includes('daemon'))) return 'Alfred Worker';
|
|
525
|
+
if (cmdline.includes('.alfred')) return 'Alfred Process';
|
|
526
|
+
|
|
527
|
+
// AI/ML agent frameworks
|
|
528
|
+
if (cmdline.includes('langchain') && cmdline.includes('agent')) return 'LangChain Agent';
|
|
529
|
+
if (cmdline.includes('crewai')) return 'CrewAI Agent';
|
|
530
|
+
if (cmdline.includes('autogen')) return 'AutoGen Agent';
|
|
531
|
+
if (cmdline.includes('mastra')) return 'Mastra Agent';
|
|
532
|
+
|
|
533
|
+
// Node.js/Python AI processes
|
|
534
|
+
if ((cmd.includes('node') || cmd.includes('python')) &&
|
|
535
|
+
(cmdline.includes('agent') || cmdline.includes('ai') || cmdline.includes('llm'))) {
|
|
536
|
+
return 'AI Agent Process';
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Temporal workflow processes
|
|
540
|
+
if (cmdline.includes('temporal') && (cmdline.includes('worker') || cmdline.includes('agent'))) {
|
|
541
|
+
return 'Temporal Agent';
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Generic agent indicators
|
|
545
|
+
if (cmdline.includes('agent') &&
|
|
546
|
+
(cmdline.includes('server') || cmdline.includes('worker') || cmdline.includes('daemon'))) {
|
|
547
|
+
return 'Agent Service';
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Enhanced infrastructure component detection
|
|
554
|
+
detectInfrastructureComponent(cmd, cmdline) {
|
|
555
|
+
// Debug logging
|
|
556
|
+
if (cmdline.includes('milvus')) {
|
|
557
|
+
console.log('Found Milvus process:', cmdline.substring(0, 100));
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Vector databases
|
|
561
|
+
if (cmd.includes('milvus') || cmdline.includes('milvus')) return 'Milvus Vector DB';
|
|
562
|
+
if (cmd.includes('weaviate') || cmdline.includes('weaviate')) return 'Weaviate Vector DB';
|
|
563
|
+
if (cmd.includes('pinecone') || cmdline.includes('pinecone')) return 'Pinecone Vector DB';
|
|
564
|
+
if (cmd.includes('qdrant') || cmdline.includes('qdrant')) return 'Qdrant Vector DB';
|
|
565
|
+
|
|
566
|
+
// Traditional databases
|
|
567
|
+
if (cmd.includes('redis') || cmdline.includes('redis')) return 'Redis Cache';
|
|
568
|
+
if (cmd.includes('postgres') || cmdline.includes('postgres')) return 'PostgreSQL';
|
|
569
|
+
if (cmd.includes('mongodb') || cmdline.includes('mongo')) return 'MongoDB';
|
|
570
|
+
|
|
571
|
+
// Message queues and workflows
|
|
572
|
+
if (cmdline.includes('temporal') && cmdline.includes('server')) return 'Temporal Server';
|
|
573
|
+
if (cmd.includes('rabbitmq') || cmdline.includes('rabbitmq')) return 'RabbitMQ';
|
|
574
|
+
if (cmd.includes('kafka') || cmdline.includes('kafka')) return 'Apache Kafka';
|
|
575
|
+
|
|
576
|
+
// Observability
|
|
577
|
+
if (cmdline.includes('prometheus')) return 'Prometheus';
|
|
578
|
+
if (cmdline.includes('grafana')) return 'Grafana';
|
|
579
|
+
if (cmdline.includes('jaeger')) return 'Jaeger Tracing';
|
|
580
|
+
|
|
581
|
+
// Container/orchestration
|
|
582
|
+
if (cmd.includes('docker') && !cmdline.includes('agent')) return 'Docker';
|
|
583
|
+
if (cmd.includes('k3s') || cmd.includes('kubectl')) return 'Kubernetes';
|
|
584
|
+
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// Get orphans that weren't categorized
|
|
589
|
+
getUncategorizedOrphans(orphans, categorized) {
|
|
590
|
+
var allCategorizedPids = categorized.agents.concat(categorized.infrastructure).map(function(p) { return p.pid; });
|
|
591
|
+
return orphans.filter(function(o) { return allCategorizedPids.indexOf(o.pid) === -1; });
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Build hierarchical process tree from flat process list
|
|
595
|
+
buildProcessTree(processes) {
|
|
596
|
+
var tree = [];
|
|
597
|
+
var processMap = {};
|
|
598
|
+
|
|
599
|
+
// Create a map of all processes
|
|
600
|
+
for (var i = 0; i < processes.length; i++) {
|
|
601
|
+
var proc = processes[i];
|
|
602
|
+
processMap[proc.pid] = {
|
|
603
|
+
process: proc,
|
|
604
|
+
children: []
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// Build parent-child relationships
|
|
609
|
+
for (var j = 0; j < processes.length; j++) {
|
|
610
|
+
var proc = processes[j];
|
|
611
|
+
if (proc.ppid && processMap[proc.ppid]) {
|
|
612
|
+
// This process has a parent in our categorized list
|
|
613
|
+
processMap[proc.ppid].children.push(processMap[proc.pid]);
|
|
614
|
+
} else {
|
|
615
|
+
// This is a root process (no parent in our list)
|
|
616
|
+
tree.push(processMap[proc.pid]);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
return tree;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// Render process tree with indentation
|
|
624
|
+
renderProcessTree(tree, type) {
|
|
625
|
+
var html = '<div class="process-tree">';
|
|
626
|
+
|
|
627
|
+
for (var i = 0; i < tree.length; i++) {
|
|
628
|
+
html += this.renderProcessNode(tree[i], type, 0);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
html += '</div>';
|
|
632
|
+
return html;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Render individual process node recursively
|
|
636
|
+
renderProcessNode(node, type, depth) {
|
|
637
|
+
var proc = node.process;
|
|
638
|
+
var indent = 'padding-left: ' + (depth * 20) + 'px;';
|
|
639
|
+
var cpuNum = parseFloat(proc.cpu) || 0;
|
|
640
|
+
var cpuCls = type === 'agent'
|
|
641
|
+
? (cpuNum > 50 ? 'high' : cpuNum > 10 ? 'medium' : 'low')
|
|
642
|
+
: (cpuNum > 20 ? 'high' : cpuNum > 5 ? 'medium' : 'low');
|
|
643
|
+
|
|
644
|
+
var serviceName = type === 'agent' ? proc.service : proc.component;
|
|
645
|
+
|
|
646
|
+
var html = '<div class="process-node ' + type + '-node ' + cpuCls + '" style="' + indent + '">';
|
|
647
|
+
|
|
648
|
+
// Process icon and name
|
|
649
|
+
if (depth > 0) {
|
|
650
|
+
html += '<span class="tree-connector">└─ </span>';
|
|
651
|
+
}
|
|
652
|
+
html += '<div class="process-main">';
|
|
653
|
+
html += '<div class="process-name" title="' + escapeHtml(proc.cmdline) + '">' + escapeHtml(serviceName) + '</div>';
|
|
654
|
+
|
|
655
|
+
// Add activity tag
|
|
656
|
+
if (proc.tag && proc.tag !== 'other') {
|
|
657
|
+
html += '<span class="activity-tag tag-' + proc.tag + '">' + proc.tag + '</span>';
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
html += '<div class="process-metrics">';
|
|
661
|
+
html += '<span class="pid-badge">PID: ' + proc.pid + '</span>';
|
|
662
|
+
html += '<span class="cpu-badge">CPU: ' + escapeHtml(proc.cpu) + '%</span>';
|
|
663
|
+
html += '<span class="mem-badge">MEM: ' + escapeHtml(proc.mem) + '%</span>';
|
|
664
|
+
html += '<span class="time-badge">Up: ' + escapeHtml(proc.elapsed) + '</span>';
|
|
665
|
+
html += '</div>';
|
|
666
|
+
html += '</div>';
|
|
667
|
+
html += '</div>';
|
|
668
|
+
|
|
669
|
+
// Render children recursively
|
|
670
|
+
for (var i = 0; i < node.children.length; i++) {
|
|
671
|
+
html += this.renderProcessNode(node.children[i], type, depth + 1);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return html;
|
|
675
|
+
}
|
|
676
|
+
|
|
415
677
|
// ---------------------------------------------------------------------------
|
|
416
678
|
// Rendering: Trace list (limit to 100 most recent for perf)
|
|
417
679
|
// ---------------------------------------------------------------------------
|
|
@@ -456,6 +718,14 @@ class AgentFlowDashboard {
|
|
|
456
718
|
});
|
|
457
719
|
}
|
|
458
720
|
|
|
721
|
+
// Activity filter
|
|
722
|
+
if (this.activityFilter && this.activityFilter !== 'all') {
|
|
723
|
+
var activityTarget = this.activityFilter;
|
|
724
|
+
filtered = filtered.filter(function(t) {
|
|
725
|
+
return self.getTraceActivity(t) === activityTarget;
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
|
|
459
729
|
countEl.textContent = filtered.length + ' of ' + this.traces.length + ' traces';
|
|
460
730
|
|
|
461
731
|
// Render max 100 items for performance
|
|
@@ -1530,6 +1800,112 @@ class AgentFlowDashboard {
|
|
|
1530
1800
|
this.reconnectAttempts = 0;
|
|
1531
1801
|
this.connectWebSocket();
|
|
1532
1802
|
}
|
|
1803
|
+
|
|
1804
|
+
// Categorize traces by activity type
|
|
1805
|
+
getTraceActivity(trace) {
|
|
1806
|
+
if (!trace) return 'unknown';
|
|
1807
|
+
|
|
1808
|
+
var agentId = (trace.agentId || '').toLowerCase();
|
|
1809
|
+
var name = (trace.name || '').toLowerCase();
|
|
1810
|
+
var filename = (trace.filename || '').toLowerCase();
|
|
1811
|
+
|
|
1812
|
+
// Check for specific agent types
|
|
1813
|
+
if (agentId.includes('main') || name.includes('main')) return 'main';
|
|
1814
|
+
if (agentId.includes('agent') || name.includes('agent')) return 'agents';
|
|
1815
|
+
|
|
1816
|
+
// Check filename patterns
|
|
1817
|
+
if (filename.includes('browser') || name.includes('browser')) return 'browser';
|
|
1818
|
+
if (filename.includes('context') || name.includes('context')) return 'context';
|
|
1819
|
+
|
|
1820
|
+
// Check for activity types in trace content
|
|
1821
|
+
var nodes = trace.nodes || {};
|
|
1822
|
+
var nodeTypes = [];
|
|
1823
|
+
|
|
1824
|
+
if (nodes instanceof Map) {
|
|
1825
|
+
nodes.forEach(function(node) {
|
|
1826
|
+
if (node.type) nodeTypes.push(node.type);
|
|
1827
|
+
});
|
|
1828
|
+
} else if (typeof nodes === 'object') {
|
|
1829
|
+
for (var nodeId in nodes) {
|
|
1830
|
+
var node = nodes[nodeId];
|
|
1831
|
+
if (node && node.type) nodeTypes.push(node.type);
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
// Categorize based on node types and content
|
|
1836
|
+
if (nodeTypes.includes('tool') || nodeTypes.includes('exec')) return 'exec';
|
|
1837
|
+
if (nodeTypes.includes('read') || name.includes('read')) return 'read';
|
|
1838
|
+
if (nodeTypes.includes('write') || name.includes('write')) return 'write';
|
|
1839
|
+
if (nodeTypes.includes('think') || name.includes('think')) return 'think';
|
|
1840
|
+
if (nodeTypes.includes('user') || name.includes('user')) return 'user';
|
|
1841
|
+
if (nodeTypes.includes('tool')) return 'tool';
|
|
1842
|
+
|
|
1843
|
+
return 'other';
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
// Tag processes by activity type
|
|
1847
|
+
getProcessActivityTag(cmd, cmdline, pid) {
|
|
1848
|
+
// Main processes (primary orchestrators)
|
|
1849
|
+
if (cmdline.includes('main') || cmdline.includes('orchestrator') ||
|
|
1850
|
+
cmdline.includes('coordinator') || cmdline.includes('master')) {
|
|
1851
|
+
return 'main';
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
// Agent processes
|
|
1855
|
+
if (cmdline.includes('agent') && !cmdline.includes('browser')) {
|
|
1856
|
+
return 'agents';
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// Browser/UI processes
|
|
1860
|
+
if (cmdline.includes('browser') || cmdline.includes('chrome') ||
|
|
1861
|
+
cmdline.includes('firefox') || cmdline.includes('dashboard')) {
|
|
1862
|
+
return 'browser';
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
// Context/memory processes
|
|
1866
|
+
if (cmdline.includes('context') || cmdline.includes('memory') ||
|
|
1867
|
+
cmdline.includes('cache') || cmdline.includes('embedding')) {
|
|
1868
|
+
return 'context';
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
// Execution processes
|
|
1872
|
+
if (cmdline.includes('exec') || cmdline.includes('runner') ||
|
|
1873
|
+
cmdline.includes('executor') || cmdline.includes('worker')) {
|
|
1874
|
+
return 'exec';
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
// Read operations
|
|
1878
|
+
if (cmdline.includes('read') || cmdline.includes('scanner') ||
|
|
1879
|
+
cmdline.includes('parser') || cmdline.includes('loader')) {
|
|
1880
|
+
return 'read';
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
// Tool processes
|
|
1884
|
+
if (cmdline.includes('tool') || cmdline.includes('utility') ||
|
|
1885
|
+
cmdline.includes('helper') || cmdline.includes('script')) {
|
|
1886
|
+
return 'tool';
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
// Thinking/AI processes
|
|
1890
|
+
if (cmdline.includes('think') || cmdline.includes('reason') ||
|
|
1891
|
+
cmdline.includes('llm') || cmdline.includes('model')) {
|
|
1892
|
+
return 'think';
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
// User interface processes
|
|
1896
|
+
if (cmdline.includes('ui') || cmdline.includes('frontend') ||
|
|
1897
|
+
cmdline.includes('interface') || cmdline.includes('client')) {
|
|
1898
|
+
return 'user';
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
// Write/output processes
|
|
1902
|
+
if (cmdline.includes('write') || cmdline.includes('output') ||
|
|
1903
|
+
cmdline.includes('export') || cmdline.includes('save')) {
|
|
1904
|
+
return 'write';
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
return 'other';
|
|
1908
|
+
}
|
|
1533
1909
|
}
|
|
1534
1910
|
|
|
1535
1911
|
// Initialize
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head><title>Test Dashboard API</title></head>
|
|
4
|
+
<body>
|
|
5
|
+
<script>
|
|
6
|
+
fetch('/api/process-health')
|
|
7
|
+
.then(r => r.json())
|
|
8
|
+
.then(data => {
|
|
9
|
+
console.log('Process Health Data:', data);
|
|
10
|
+
|
|
11
|
+
// Test categorization
|
|
12
|
+
const processes = data.osProcesses || [];
|
|
13
|
+
let agents = [];
|
|
14
|
+
let infrastructure = [];
|
|
15
|
+
|
|
16
|
+
processes.forEach(proc => {
|
|
17
|
+
const cmd = proc.command.toLowerCase();
|
|
18
|
+
const cmdline = (proc.cmdline || '').toLowerCase();
|
|
19
|
+
|
|
20
|
+
// Test infrastructure detection
|
|
21
|
+
if (cmd.includes('milvus') || cmdline.includes('milvus')) {
|
|
22
|
+
infrastructure.push({component: 'Milvus Vector DB', ...proc});
|
|
23
|
+
} else if (cmdline.includes('agentflow-dashboard')) {
|
|
24
|
+
agents.push({service: 'AgentFlow Dashboard', ...proc});
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
console.log('Detected Infrastructure:', infrastructure);
|
|
29
|
+
console.log('Detected Agents:', agents);
|
|
30
|
+
|
|
31
|
+
document.body.innerHTML = `
|
|
32
|
+
<h2>Process Health Debug</h2>
|
|
33
|
+
<h3>Infrastructure (${infrastructure.length}):</h3>
|
|
34
|
+
<ul>${infrastructure.map(i => `<li>PID ${i.pid}: ${i.component} (CPU: ${i.cpu}%)</li>`).join('')}</ul>
|
|
35
|
+
<h3>Agents (${agents.length}):</h3>
|
|
36
|
+
<ul>${agents.map(a => `<li>PID ${a.pid}: ${a.service} (CPU: ${a.cpu}%)</li>`).join('')}</ul>
|
|
37
|
+
<h3>Total OS Processes: ${processes.length}</h3>
|
|
38
|
+
`;
|
|
39
|
+
})
|
|
40
|
+
.catch(console.error);
|
|
41
|
+
</script>
|
|
42
|
+
</body>
|
|
43
|
+
</html>
|