Activate agent mesh with honest live status and working animations.
Souls now aggregate aliased events (e.g. halal_engine), KPIs reflect 6h activity, active agents animate, and morning scheduler/scripts target cockpit :8610.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<link rel="stylesheet" href="/static/css/hermes.css" />
|
||||
<link rel="stylesheet" href="/static/css/herman-dashboard.css?v=13" />
|
||||
<link rel="stylesheet" href="/static/css/agents-mesh.css?v=8" />
|
||||
<link rel="stylesheet" href="/static/css/agent-characters.css?v=3" />
|
||||
<link rel="stylesheet" href="/static/css/agent-characters.css?v=4" />
|
||||
<script src="/static/js/agent-avatars.js?v=3"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
@@ -46,18 +46,21 @@
|
||||
<div class="hm-neo-kpi-row" style="grid-template-columns:repeat(4,1fr)">
|
||||
<div class="hm-neo-kpi"><div class="hm-neo-kpi-top"><div class="hm-neo-ring" style="--ring-color:#00e5ff;--ring-pct:80%"><div class="hm-neo-ring-inner">🤖</div></div><div><div class="hm-neo-kpi-label">Agents</div><div class="hm-neo-kpi-sub">geregistreerd</div></div></div><div class="hm-neo-kpi-value" x-text="souls.length">0</div><div class="hm-eq"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div></div>
|
||||
<div class="hm-neo-kpi"><div class="hm-neo-kpi-top"><div class="hm-neo-ring" style="--ring-color:#b8ff3c;--ring-pct:70%"><div class="hm-neo-ring-inner">⚡</div></div><div><div class="hm-neo-kpi-label">Events</div><div class="hm-neo-kpi-sub">totaal gelogd</div></div></div><div class="hm-neo-kpi-value" x-text="totalEvents">0</div><div class="hm-eq"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div></div>
|
||||
<div class="hm-neo-kpi"><div class="hm-neo-kpi-top"><div class="hm-neo-ring" style="--ring-color:#ff9f43;--ring-pct:50%"><div class="hm-neo-ring-inner">✓</div></div><div><div class="hm-neo-kpi-label">Actief</div><div class="hm-neo-kpi-sub">agents online</div></div></div><div class="hm-neo-kpi-value" x-text="activeCount">0</div><div class="hm-eq"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div></div>
|
||||
<div class="hm-neo-kpi"><div class="hm-neo-kpi-top"><div class="hm-neo-ring" style="--ring-color:#ff9f43;--ring-pct:50%"><div class="hm-neo-ring-inner">✓</div></div><div><div class="hm-neo-kpi-label">Aan het werk</div><div class="hm-neo-kpi-sub" x-text="idleCount + ' idle · ' + offlineCount + ' offline'">live status</div></div></div><div class="hm-neo-kpi-value" x-text="activeCount">0</div><div class="hm-eq"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div></div>
|
||||
<div class="hm-neo-kpi"><div class="hm-neo-kpi-top"><div class="hm-neo-ring" style="--ring-color:#ffd700;--ring-pct:90%"><div class="hm-neo-ring-inner">👑</div></div><div><div class="hm-neo-kpi-label">Herman</div><div class="hm-neo-kpi-sub">Co-CEO · takenverdeler</div></div></div><div class="hm-neo-kpi-value" style="font-size:1.1rem">Co-CEO</div><div class="hm-eq"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div></div>
|
||||
</div>
|
||||
|
||||
<div class="agents-neo-grid">
|
||||
<template x-for="s in souls" :key="s.agent_key">
|
||||
<article class="agent-soul-card" :class="{ selected: selected?.agent_key === s.agent_key }" @click="select(s.agent_key)">
|
||||
<article class="agent-soul-card" :class="{ selected: selected?.agent_key === s.agent_key, 'is-working': isWorking(s) && !isBusy(s), 'is-busy': isBusy(s) }" @click="select(s.agent_key)">
|
||||
<div class="agent-char-wrap" :class="s.agent_key"
|
||||
:data-agent-avatar="s.agent_key"
|
||||
:data-agent-color="s.avatar_color || '#1e3a5f'"
|
||||
x-init="$nextTick(() => window.AgentAvatars && AgentAvatars.paint($el, s.agent_key, s.avatar_color))"></div>
|
||||
<strong x-text="s.display_name"></strong>
|
||||
<strong>
|
||||
<span x-text="s.display_name"></span>
|
||||
<span class="agent-activity-eq" x-show="isWorking(s) || isBusy(s)" aria-hidden="true"><span></span><span></span><span></span><span></span></span>
|
||||
</strong>
|
||||
<div class="hm-neo-kpi-sub" x-text="s.role_title"></div>
|
||||
<span class="agent-status-pill" :class="statusClass(s)">
|
||||
<span class="dot"></span>
|
||||
@@ -317,12 +320,20 @@ function agentsSoulHub() {
|
||||
meshLegendExec: true,
|
||||
focusTerminalKey: null, focusTerminalName: '', expandedTerminal: null,
|
||||
get totalEvents() { return this.souls.reduce((a,s) => a + (s.event_count||0), 0); },
|
||||
get activeCount() { return this.souls.filter(s => s.is_active !== false).length; },
|
||||
get activeCount() { return this.souls.filter(s => (s.events_6h||0) > 0).length; },
|
||||
get idleCount() { return this.souls.filter(s => (s.events_6h||0) === 0 && (s.event_count||0) > 0).length; },
|
||||
get offlineCount() { return this.souls.filter(s => (s.event_count||0) === 0).length; },
|
||||
isBusy(s) {
|
||||
const st = (s.current_status || '').toLowerCase();
|
||||
return st === 'needs_approval' || st === 'pending' || (s.activity === 'busy') || ((s.events_6h||0) >= 5);
|
||||
},
|
||||
isWorking(s) { return (s.events_6h||0) > 0 || s.working === true; },
|
||||
statusClass(s) {
|
||||
const st = (s.current_status || '').toLowerCase();
|
||||
if (st === 'needs_approval' || st === 'pending') return 'busy';
|
||||
if (st === 'needs_approval' || st === 'pending' || this.isBusy(s)) return 'busy';
|
||||
if (st === 'error' || st === 'rejected') return 'error';
|
||||
if (st === 'completed' || (s.events_6h > 0)) return 'active';
|
||||
if ((s.events_6h||0) > 0 || s.activity === 'active') return 'active';
|
||||
if ((s.event_count||0) === 0) return 'offline';
|
||||
return 'idle';
|
||||
},
|
||||
formatEventTime(ts) {
|
||||
@@ -363,15 +374,17 @@ function agentsSoulHub() {
|
||||
const st = (s.current_status || '').toLowerCase();
|
||||
if (st === 'needs_approval') return 'Wacht op goedkeuring';
|
||||
if (st === 'pending') return 'In wachtrij';
|
||||
if (st === 'completed') return 'Klaar';
|
||||
if (st === 'error') return 'Fout';
|
||||
if (s.current_task) return 'Bezig';
|
||||
return 'Standby';
|
||||
if (this.isBusy(s)) return 'Bezig · live';
|
||||
if ((s.events_6h||0) > 0) return 'Actief · ' + (s.events_6h||0) + '/6u';
|
||||
if ((s.event_count||0) === 0) return 'Offline';
|
||||
return 'Idle';
|
||||
},
|
||||
async init() {
|
||||
this.syncMeshMode();
|
||||
await this.load();
|
||||
await this.loadPendingCount();
|
||||
this._poll = setInterval(() => { this.load(true); this.loadPendingCount(); }, 20000);
|
||||
if (window.PageViz) {
|
||||
window.PageViz.init('agents', (mode) => this.renderViz(mode));
|
||||
}
|
||||
@@ -496,10 +509,16 @@ function agentsSoulHub() {
|
||||
}
|
||||
});
|
||||
},
|
||||
async load() {
|
||||
async load(quiet) {
|
||||
const r = await fetch('/api/agents/souls').then(x => x.json());
|
||||
this.souls = r.items || [];
|
||||
if (this.souls.length && !this.selected) this.select(this.souls[0].agent_key);
|
||||
this.$nextTick(() => {
|
||||
(this.souls || []).forEach((s) => {
|
||||
const el = document.querySelector('[data-agent-avatar="' + s.agent_key + '"]');
|
||||
if (el && window.AgentAvatars) AgentAvatars.paint(el, s.agent_key, s.avatar_color);
|
||||
});
|
||||
});
|
||||
this.renderViz(window.__vizMode || 'neo-bars');
|
||||
this.$nextTick(() => window.AgentAvatars && AgentAvatars.paintAll(this.$root));
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user